btsnoop.cc revision 04bb236d873005ccb5950cb8e8f1f348499e032e
15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 39891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson * Copyright (C) 2014 Google, Inc. 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at: 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License. 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati#define LOG_TAG "btsnoop" 20a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati 21a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati#include <assert.h> 22a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati#include <errno.h> 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <fcntl.h> 24611f3abf1c12a9f568114e46a21e70c74eaf6a60Sharvil Nanavati#include <stdbool.h> 25a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati#include <stdio.h> 26a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati#include <stdlib.h> 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/stat.h> 28a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati#include <sys/time.h> 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <unistd.h> 305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 31fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson#include "btsnoop.h" 32fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson#include "bt_types.h" 33fbbd42b1fc1aae7a106f46275ab1fd86452cce78Zach Johnson#include "hci_layer.h" 3444802768c447ab480d4227b3a852a97d923b816dSharvil Nanavati#include "osi/include/log.h" 359891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson#include "stack_config.h" 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 37611f3abf1c12a9f568114e46a21e70c74eaf6a60Sharvil Nanavatitypedef enum { 38611f3abf1c12a9f568114e46a21e70c74eaf6a60Sharvil Nanavati kCommandPacket = 1, 39611f3abf1c12a9f568114e46a21e70c74eaf6a60Sharvil Nanavati kAclPacket = 2, 40611f3abf1c12a9f568114e46a21e70c74eaf6a60Sharvil Nanavati kScoPacket = 3, 41611f3abf1c12a9f568114e46a21e70c74eaf6a60Sharvil Nanavati kEventPacket = 4 42a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati} packet_type_t; 435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 44a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati// Epoch in microseconds since 01/01/0000. 45a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavatistatic const uint64_t BTSNOOP_EPOCH_DELTA = 0x00dcddb30f2f8000ULL; 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 479891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic const stack_config_t *stack_config; 48f1d68e95f34921361dced60b1b53e3fef8401f03Kim Schulz 499891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic int logfile_fd = INVALID_FD; 509891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic bool module_started; 519891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic bool is_logging; 529891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic bool logging_enabled_via_api; 539891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 549891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson// TODO(zachoverflow): merge btsnoop and btsnoop_net together 55a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavativoid btsnoop_net_open(); 56a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavativoid btsnoop_net_close(); 57a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavativoid btsnoop_net_write(const void *data, size_t length); 585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 599891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic void btsnoop_write_packet(packet_type_t type, const uint8_t *packet, bool is_received); 609891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic void update_logging(); 619891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 629891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson// Module lifecycle functions 639891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 649891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic future_t *start_up(void) { 659891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson module_started = true; 669891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson update_logging(); 679891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 689891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson return NULL; 699891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson} 709891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 719891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic future_t *shut_down(void) { 729891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson module_started = false; 739891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson update_logging(); 749891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 759891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson return NULL; 769891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson} 779891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 789891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonconst module_t btsnoop_module = { 799891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson .name = BTSNOOP_MODULE, 809891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson .init = NULL, 819891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson .start_up = start_up, 829891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson .shut_down = shut_down, 839891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson .clean_up = NULL, 849891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson .dependencies = { 859891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson STACK_CONFIG_MODULE, 869891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson NULL 879891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson } 889891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson}; 899891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 909891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson// Interface functions 919891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 929891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic void set_api_wants_to_log(bool value) { 939891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson logging_enabled_via_api = value; 949891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson update_logging(); 959891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson} 969891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 979891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic void capture(const BT_HDR *buffer, bool is_received) { 989891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson const uint8_t *p = buffer->data + buffer->offset; 999891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1009891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson if (logfile_fd == INVALID_FD) 1019891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson return; 1029891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1039891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson switch (buffer->event & MSG_EVT_MASK) { 1049891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson case MSG_HC_TO_STACK_HCI_EVT: 1059891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson btsnoop_write_packet(kEventPacket, p, false); 1069891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson break; 1079891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson case MSG_HC_TO_STACK_HCI_ACL: 1089891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson case MSG_STACK_TO_HC_HCI_ACL: 1099891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson btsnoop_write_packet(kAclPacket, p, is_received); 1109891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson break; 1119891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson case MSG_HC_TO_STACK_HCI_SCO: 1129891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson case MSG_STACK_TO_HC_HCI_SCO: 1139891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson btsnoop_write_packet(kScoPacket, p, is_received); 1149891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson break; 1159891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson case MSG_STACK_TO_HC_HCI_CMD: 1169891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson btsnoop_write_packet(kCommandPacket, p, true); 1179891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson break; 1189891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson } 1199891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson} 1209891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1219891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic const btsnoop_t interface = { 1229891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson set_api_wants_to_log, 1239891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson capture 1249891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson}; 1259891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1269891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonconst btsnoop_t *btsnoop_get_interface() { 1279891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson stack_config = stack_config_get_interface(); 1289891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson return &interface; 1299891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson} 1309891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1319891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson// Internal functions 1329891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1339891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnsonstatic void update_logging() { 1349891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson bool should_log = module_started && 1359891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson (logging_enabled_via_api || stack_config->get_btsnoop_turned_on()); 1369891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1379891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson if (should_log == is_logging) 1389891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson return; 1399891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1409891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson is_logging = should_log; 1419891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson if (should_log) { 1429891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson btsnoop_net_open(); 1439891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 14404bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson const char *log_path = stack_config->get_btsnoop_log_path(); 14504bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson 14604bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson // Save the old log if configured to do so 14704bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson if (stack_config->get_btsnoop_should_save_last()) { 14804bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson char last_log_path[PATH_MAX]; 14904bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson snprintf(last_log_path, PATH_MAX, "%s.last", log_path); 15004bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson if (!rename(log_path, last_log_path) && errno != ENOENT) 15104bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson LOG_ERROR("%s unable to rename '%s' to '%s': %s", __func__, log_path, last_log_path, strerror(errno)); 15204bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson } 1539891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 15404bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson logfile_fd = open(log_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); 1559891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson if (logfile_fd == INVALID_FD) { 15604bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson LOG_ERROR("%s unable to open '%s': %s", __func__, log_path, strerror(errno)); 15704bb236d873005ccb5950cb8e8f1f348499e032eZach Johnson is_logging = false; 1589891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson return; 1599891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson } 1609891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1619891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson write(logfile_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16); 1629891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson } else { 1639891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson if (logfile_fd != INVALID_FD) 1649891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson close(logfile_fd); 1659891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 1669891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson logfile_fd = INVALID_FD; 1679891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson btsnoop_net_close(); 1689891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson } 1699891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson} 1709891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson 171a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavatistatic uint64_t btsnoop_timestamp(void) { 172a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati struct timeval tv; 173a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati gettimeofday(&tv, NULL); 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 175a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati // Timestamp is in microseconds. 176a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati uint64_t timestamp = tv.tv_sec * 1000 * 1000LL; 177a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati timestamp += tv.tv_usec; 178a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati timestamp += BTSNOOP_EPOCH_DELTA; 179a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati return timestamp; 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 182611f3abf1c12a9f568114e46a21e70c74eaf6a60Sharvil Nanavatistatic void btsnoop_write(const void *data, size_t length) { 1839891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson if (logfile_fd != INVALID_FD) 1849891f32471b5c01cf58e4d7dadb04cb3024a9a88Zach Johnson write(logfile_fd, data, length); 185a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati 186a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati btsnoop_net_write(data, length); 187a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati} 188a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati 189a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavatistatic void btsnoop_write_packet(packet_type_t type, const uint8_t *packet, bool is_received) { 190227f6b08abb4e786a8951dde128388cd025ee63fChris Manton int length_he = 0; 191a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati int length; 192a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati int flags; 193a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati int drops = 0; 194a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati switch (type) { 195a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati case kCommandPacket: 196a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati length_he = packet[2] + 4; 197a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati flags = 2; 198a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati break; 199a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati case kAclPacket: 200a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati length_he = (packet[3] << 8) + packet[2] + 5; 201a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati flags = is_received; 202a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati break; 203a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati case kScoPacket: 204a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati length_he = packet[2] + 4; 205a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati flags = is_received; 206a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati break; 207a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati case kEventPacket: 208a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati length_he = packet[1] + 3; 209a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati flags = 3; 210a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati break; 211a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati } 212a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati 213a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati uint64_t timestamp = btsnoop_timestamp(); 214a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati uint32_t time_hi = timestamp >> 32; 215a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati uint32_t time_lo = timestamp & 0xFFFFFFFF; 216a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati 217a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati length = htonl(length_he); 218a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati flags = htonl(flags); 219a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati drops = htonl(drops); 220a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati time_hi = htonl(time_hi); 221a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati time_lo = htonl(time_lo); 222a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati 223a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati btsnoop_write(&length, 4); 224a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati btsnoop_write(&length, 4); 225a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati btsnoop_write(&flags, 4); 226a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati btsnoop_write(&drops, 4); 227a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati btsnoop_write(&time_hi, 4); 228a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati btsnoop_write(&time_lo, 4); 229a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati btsnoop_write(&type, 1); 230a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati btsnoop_write(packet, length_he - 1); 231a7d7eb78b826cde99adb67fb7078aca85ea61da3Sharvil Nanavati} 232