Remove C++ btsnooz parser in favor of Python script. am: de307331a2
am: cb2328e58b
* commit 'cb2328e58beb9be876e7b6557d049b972fdea2a4':
Remove C++ btsnooz parser in favor of Python script.
This commit is contained in:
@@ -1,37 +0,0 @@
|
|||||||
# Copyright (C) 2014 The Android Open Source Project
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
LOCAL_PATH := $(call my-dir)
|
|
||||||
|
|
||||||
supported_platforms := linux # For now... Needs to be tested on MacOS/Windows
|
|
||||||
cur_platform := $(filter $(HOST_OS),$(supported_platforms))
|
|
||||||
|
|
||||||
ifdef cur_platform
|
|
||||||
|
|
||||||
# Host executable
|
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
LOCAL_MODULE := btsnooz
|
|
||||||
LOCAL_SRC_FILES := btsnooz.cpp btsnooz_utils.cpp
|
|
||||||
LOCAL_C_INCLUDES := external/zlib system/bt
|
|
||||||
LOCAL_CFLAGS += -std=c++11 -W -Wall
|
|
||||||
LOCAL_STATIC_LIBRARIES := libz
|
|
||||||
|
|
||||||
ifeq ($(HOST_OS),linux)
|
|
||||||
LOCAL_LDLIBS += -lresolv
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(BUILD_HOST_EXECUTABLE)
|
|
||||||
|
|
||||||
endif #cur_platform
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2015 Google, Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "btsnooz_utils.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
if (argc > 3) {
|
|
||||||
std::cerr << "Usage: " << argv[0] << " [input_file] [output_file]\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<char> buffer;
|
|
||||||
|
|
||||||
int read = 0;
|
|
||||||
if (argc < 3) {
|
|
||||||
std::cerr << "<Reading from stdin>\n";
|
|
||||||
read = readLog(std::cin, buffer);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
std::cerr << "<Reading " << argv[1] << ">\n";
|
|
||||||
std::ifstream ff(argv[1]);
|
|
||||||
read = readLog(ff, buffer);
|
|
||||||
ff.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read == 0) {
|
|
||||||
std::cerr << "File not found or not BTSNOOP data block....\n";
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cerr << std::setw(8) << read << " bytes of base64 data read\n";
|
|
||||||
|
|
||||||
read = base64Decode(buffer);
|
|
||||||
if (read <= 0) {
|
|
||||||
std::cerr << "Decoding base64 data failed...\n";
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cerr << std::setw(8) << read << " bytes of compressed data decoded\n";
|
|
||||||
|
|
||||||
std::vector<uint8_t> uncompressed;
|
|
||||||
read = inflate(buffer, uncompressed);
|
|
||||||
if (read <= 0) {
|
|
||||||
std::cerr << "Error inflating data...\n";
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cerr << std::setw(8) << read << " bytes of data inflated\n";
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
std::cerr << "<Writing to stdout>\n";
|
|
||||||
read = writeBtSnoop(std::cout, uncompressed);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
const int arg = argc > 2 ? 2 : 1;
|
|
||||||
std::cerr << "<Writing " << argv[arg] << ">\n";
|
|
||||||
std::ofstream ff(argv[arg]);
|
|
||||||
read = writeBtSnoop(ff, uncompressed);
|
|
||||||
ff.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cerr << std::setw(8) << read << " btsnoop packets written\n";
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,244 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2015 Google, Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
#include <string.h> // for memcpy
|
|
||||||
#include <vector>
|
|
||||||
#include <resolv.h>
|
|
||||||
#include <zlib.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "btif/include/btif_debug_btsnoop.h"
|
|
||||||
#include "hci/include/bt_hci_bdroid.h"
|
|
||||||
#include "stack/include/bt_types.h"
|
|
||||||
#include "stack/include/hcidefs.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Epoch in microseconds since 01/01/0000.
|
|
||||||
#define BTSNOOP_EPOCH_DELTA 0x00dcddb30f2f8000ULL
|
|
||||||
|
|
||||||
#define INITIAL_BUFFER_SIZE 131072
|
|
||||||
#define INFLATE_BUFFER 16384
|
|
||||||
|
|
||||||
#define LOG_PREFIX "--- BEGIN:BTSNOOP_LOG_SUMMARY"
|
|
||||||
#define LOG_POSTFIX "--- END:BTSNOOP_LOG_SUMMARY"
|
|
||||||
|
|
||||||
#define H4_DIRECTION_SENT 0
|
|
||||||
#define H4_DIRECTION_RECEIVED 1
|
|
||||||
|
|
||||||
static uint8_t packetTypeToFlags(const uint8_t type) {
|
|
||||||
switch (type << 8) {
|
|
||||||
case MSG_HC_TO_STACK_HCI_ERR:
|
|
||||||
case MSG_HC_TO_STACK_HCI_ACL:
|
|
||||||
case MSG_HC_TO_STACK_HCI_SCO:
|
|
||||||
case MSG_HC_TO_STACK_HCI_EVT:
|
|
||||||
case MSG_HC_TO_STACK_L2C_SEG_XMIT:
|
|
||||||
return H4_DIRECTION_RECEIVED;
|
|
||||||
|
|
||||||
case MSG_STACK_TO_HC_HCI_ACL:
|
|
||||||
case MSG_STACK_TO_HC_HCI_SCO:
|
|
||||||
case MSG_STACK_TO_HC_HCI_CMD:
|
|
||||||
return H4_DIRECTION_SENT;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t packetTypeToHciType(const uint8_t type) {
|
|
||||||
switch (type << 8 & 0xFF00) {
|
|
||||||
case MSG_STACK_TO_HC_HCI_CMD:
|
|
||||||
return HCIT_TYPE_COMMAND;
|
|
||||||
|
|
||||||
case MSG_HC_TO_STACK_HCI_EVT:
|
|
||||||
return HCIT_TYPE_EVENT;
|
|
||||||
|
|
||||||
case MSG_STACK_TO_HC_HCI_ACL:
|
|
||||||
case MSG_HC_TO_STACK_HCI_ACL:
|
|
||||||
return HCIT_TYPE_ACL_DATA;
|
|
||||||
|
|
||||||
case MSG_STACK_TO_HC_HCI_SCO:
|
|
||||||
case MSG_HC_TO_STACK_HCI_SCO:
|
|
||||||
return HCIT_TYPE_SCO_DATA;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t writeBtSnoop(std::ostream &out, std::vector<uint8_t> &in) {
|
|
||||||
if (in.size() < sizeof(btsnooz_preamble_t))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Get preamble
|
|
||||||
|
|
||||||
uint8_t *p = in.data();
|
|
||||||
btsnooz_preamble_t *preamble = reinterpret_cast<btsnooz_preamble_t*>(p);
|
|
||||||
if (preamble->version != BTSNOOZ_CURRENT_VERSION)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Write header
|
|
||||||
|
|
||||||
const uint8_t header[] = {
|
|
||||||
0x62, 0x74, 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0xea
|
|
||||||
};
|
|
||||||
|
|
||||||
out.write(reinterpret_cast<const char*>(header), sizeof(header));
|
|
||||||
|
|
||||||
// Calculate first timestamp
|
|
||||||
|
|
||||||
uint64_t first_ts = preamble->last_timestamp_ms + BTSNOOP_EPOCH_DELTA;
|
|
||||||
size_t left = in.size() - sizeof(btsnooz_preamble_t);
|
|
||||||
p = in.data() + sizeof(btsnooz_preamble_t);
|
|
||||||
|
|
||||||
while (left > sizeof(btsnooz_header_t)) {
|
|
||||||
btsnooz_header_t *p_hdr = reinterpret_cast<btsnooz_header_t*>(p);
|
|
||||||
p += sizeof(btsnooz_header_t) + (p_hdr->length - 1);
|
|
||||||
left -= sizeof(btsnooz_header_t) + (p_hdr->length - 1);
|
|
||||||
|
|
||||||
first_ts -= p_hdr->delta_time_ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process packets
|
|
||||||
|
|
||||||
size_t packets = 0;
|
|
||||||
left = in.size() - sizeof(btsnooz_preamble_t);
|
|
||||||
p = in.data() + sizeof(btsnooz_preamble_t);
|
|
||||||
|
|
||||||
while (left > sizeof(btsnooz_header_t)) {
|
|
||||||
btsnooz_header_t *p_hdr = reinterpret_cast<btsnooz_header_t*>(p);
|
|
||||||
p += sizeof(btsnooz_header_t);
|
|
||||||
left -= sizeof(btsnooz_header_t);
|
|
||||||
|
|
||||||
const uint32_t h_length = htonl(p_hdr->length);
|
|
||||||
out.write(reinterpret_cast<const char*>(&h_length), 4);
|
|
||||||
out.write(reinterpret_cast<const char*>(&h_length), 4);
|
|
||||||
|
|
||||||
const uint32_t h_flags = htonl(packetTypeToFlags(p_hdr->type));
|
|
||||||
out.write(reinterpret_cast<const char*>(&h_flags), 4);
|
|
||||||
|
|
||||||
const uint32_t h_dropped = 0;
|
|
||||||
out.write(reinterpret_cast<const char*>(&h_dropped), 4);
|
|
||||||
|
|
||||||
first_ts += p_hdr->delta_time_ms;
|
|
||||||
const uint32_t h_time_hi = htonl(first_ts >> 32);
|
|
||||||
const uint32_t h_time_lo = htonl(first_ts & 0xFFFFFFFF);
|
|
||||||
out.write(reinterpret_cast<const char*>(&h_time_hi), 4);
|
|
||||||
out.write(reinterpret_cast<const char*>(&h_time_lo), 4);
|
|
||||||
|
|
||||||
const uint8_t type = packetTypeToHciType(p_hdr->type);
|
|
||||||
out.write(reinterpret_cast<const char*>(&type), 1);
|
|
||||||
|
|
||||||
out.write(reinterpret_cast<const char*>(p), p_hdr->length - 1);
|
|
||||||
|
|
||||||
p += p_hdr->length - 1;
|
|
||||||
left -= p_hdr->length - 1;
|
|
||||||
|
|
||||||
++packets;
|
|
||||||
}
|
|
||||||
|
|
||||||
return packets;
|
|
||||||
}
|
|
||||||
|
|
||||||
int readLog(std::istream &in, std::vector<char> &buffer) {
|
|
||||||
buffer.reserve(INITIAL_BUFFER_SIZE);
|
|
||||||
|
|
||||||
std::string line;
|
|
||||||
|
|
||||||
const std::string log_prefix(LOG_PREFIX);
|
|
||||||
const std::string log_postfix(LOG_POSTFIX);
|
|
||||||
|
|
||||||
bool in_block = false;
|
|
||||||
|
|
||||||
while (std::getline(in, line)) {
|
|
||||||
// Ensure line endings aren't wonky...
|
|
||||||
|
|
||||||
if (!line.empty() && line[line.size() - 1] == '\r')
|
|
||||||
line.erase(line.end() - 1);
|
|
||||||
|
|
||||||
// Detect block
|
|
||||||
|
|
||||||
if (!in_block) {
|
|
||||||
if (line.compare(0, log_prefix.length(), log_prefix) == 0)
|
|
||||||
in_block = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.compare(0, log_postfix.length(), log_postfix) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Process data
|
|
||||||
|
|
||||||
buffer.insert(buffer.end(), line.begin(), line.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer.size() != 0)
|
|
||||||
buffer.push_back(0);
|
|
||||||
|
|
||||||
return buffer.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
int base64Decode(std::vector<char> &buffer) {
|
|
||||||
char *p = buffer.data();
|
|
||||||
return b64_pton(p, reinterpret_cast<uint8_t*>(p), buffer.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
int inflate(std::vector<char> &in, std::vector<uint8_t> &out) {
|
|
||||||
out.reserve(in.size());
|
|
||||||
|
|
||||||
uint8_t buffer[INFLATE_BUFFER];
|
|
||||||
z_stream zs;
|
|
||||||
|
|
||||||
int ret = inflateInit(&zs);
|
|
||||||
if (Z_OK != ret)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Copy preamble as-is
|
|
||||||
|
|
||||||
for (size_t i = 0; i != sizeof(btsnooz_preamble_t); ++i) {
|
|
||||||
out.push_back(in[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// De-compress data
|
|
||||||
|
|
||||||
zs.avail_in = in.size() - sizeof(btsnooz_preamble_t);;
|
|
||||||
zs.next_in = reinterpret_cast<uint8_t*>(in.data()) + sizeof(btsnooz_preamble_t);
|
|
||||||
|
|
||||||
do {
|
|
||||||
zs.avail_out = INFLATE_BUFFER;
|
|
||||||
zs.next_out = buffer;
|
|
||||||
|
|
||||||
ret = inflate(&zs, Z_NO_FLUSH);
|
|
||||||
|
|
||||||
size_t read = INFLATE_BUFFER - zs.avail_out;
|
|
||||||
uint8_t *p = buffer;
|
|
||||||
while (read--)
|
|
||||||
out.push_back(*p++);
|
|
||||||
} while (zs.avail_out == 0);
|
|
||||||
|
|
||||||
inflateEnd(&zs);
|
|
||||||
|
|
||||||
return out.size();
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright (C) 2015 Google, Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
size_t writeBtSnoop(std::ostream &out, std::vector<uint8_t> &in);
|
|
||||||
int readLog(std::istream &in, std::vector<char> &buffer);
|
|
||||||
int base64Decode(std::vector<char> &buffer);
|
|
||||||
int inflate(std::vector<char> &in, std::vector<uint8_t> &out);
|
|
||||||
Reference in New Issue
Block a user