189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach/****************************************************************************** 289f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * 389f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * Copyright (C) 2015 Google Inc. 489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * 589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * Licensed under the Apache License, Version 2.0 (the "License"); 689f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * you may not use this file except in compliance with the License. 789f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * You may obtain a copy of the License at: 889f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * 989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * http://www.apache.org/licenses/LICENSE-2.0 1089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * 1189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * Unless required by applicable law or agreed to in writing, software 1289f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * distributed under the License is distributed on an "AS IS" BASIS, 1389f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * See the License for the specific language governing permissions and 1589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * limitations under the License. 1689f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach * 1789f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach ******************************************************************************/ 1889f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 1989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach#include <stdio.h> 2089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach#include <string.h> 2189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach#include <time.h> 2289f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 23873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach#include "btcore/include/bdaddr.h" 2489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach#include "btif/include/btif_debug.h" 2589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach#include "btif/include/btif_debug_conn.h" 2689f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 2789f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach#define NUM_CONNECTION_EVENTS 16 28873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach#define TEMP_BUFFER_SIZE 30 2989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 3089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbachtypedef struct conn_event_t { 3189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach uint64_t ts; 3289f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach btif_debug_conn_state_t state; 3389f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach bt_bdaddr_t bda; 3489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach tGATT_DISCONN_REASON disconnect_reason; 3589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach} conn_event_t; 3689f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 3789f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbachstatic conn_event_t connection_events[NUM_CONNECTION_EVENTS]; 3889f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbachstatic uint8_t current_event = 0; 3989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 4089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbachstatic char *format_ts(const uint64_t ts, char *buffer, int len) { 4189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach const uint64_t ms = ts / 1000; 4289f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach const time_t secs = ms / 1000; 4389f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach struct tm *ptm = localtime(&secs); 4489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 45bd194901dbbd2abebfe2510a1e97bb8d3a75102bAjay Panicker char tempbuff[20]; 46bd194901dbbd2abebfe2510a1e97bb8d3a75102bAjay Panicker strftime(tempbuff, sizeof(tempbuff), "%m-%d %H:%M:%S", ptm); 47bd194901dbbd2abebfe2510a1e97bb8d3a75102bAjay Panicker snprintf(buffer, len, "%s.%03u", tempbuff, (uint16_t)(ms % 1000)); 4889f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 4989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach return buffer; 5089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach} 5189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 5289f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbachstatic char *format_state(const btif_debug_conn_state_t state) { 5389f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach switch (state) { 5489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach case BTIF_DEBUG_CONNECTED: 5589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach return "CONNECTED "; 5689f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach case BTIF_DEBUG_DISCONNECTED: 5789f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach return "DISCONNECTED"; 5889f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach } 5989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach return "UNKNOWN"; 6089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach} 6189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 6289f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbachstatic void next_event() { 6389f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach ++current_event; 6489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach if (current_event == NUM_CONNECTION_EVENTS) 6589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach current_event = 0; 6689f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach} 6789f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 6889f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbachvoid btif_debug_conn_state(const bt_bdaddr_t bda, const btif_debug_conn_state_t state, 6989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach const tGATT_DISCONN_REASON disconnect_reason) { 7089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach next_event(); 7189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 7289f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach conn_event_t *evt = &connection_events[current_event]; 7389f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach evt->ts = btif_debug_ts(); 7489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach evt->state = state; 7589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach evt->disconnect_reason = disconnect_reason; 7689f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach memcpy(&evt->bda, &bda, sizeof(bt_bdaddr_t)); 7789f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach} 7889f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 7989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbachvoid btif_debug_conn_dump(int fd) { 8089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach const uint8_t current_event_local = current_event; // Cache to avoid threading issues 8189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach uint8_t dump_event = current_event_local; 82873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach char ts_buffer[TEMP_BUFFER_SIZE] = {0}; 83873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach char name_buffer[TEMP_BUFFER_SIZE] = {0}; 8489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 8589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach dprintf(fd, "\nConnection Events:\n"); 8689f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach if (connection_events[dump_event].ts == 0) 8789f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach dprintf(fd, " None\n"); 8889f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 8989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach while (connection_events[dump_event].ts) { 9089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach conn_event_t *evt = &connection_events[dump_event]; 91873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach dprintf(fd, " %s %s %s", 92873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach format_ts(evt->ts, ts_buffer, sizeof(ts_buffer)), 9389f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach format_state(evt->state), 94873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach bdaddr_to_string(&evt->bda, name_buffer, sizeof(name_buffer)) 9589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach ); 96873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach if (evt->state == BTIF_DEBUG_DISCONNECTED) 97873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach dprintf(fd, " reason=%d", evt->disconnect_reason); 98873ca2f973321f67df845e8658ede02bf5d9ee0bAndre Eisenbach dprintf(fd,"\n"); 9989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 10089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach // Go to previous event; wrap if needed 10189f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach if (dump_event > 0) 10289f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach --dump_event; 10389f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach else 10489f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach dump_event = NUM_CONNECTION_EVENTS - 1; 10589f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach 10689f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach // Check if we dumped all events 10789f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach if (dump_event == current_event_local) 10889f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach break; 10989f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach } 11089f5e411d9ef31436741288a2267e46dd744e273Andre Eisenbach} 111