xref: /btstack/src/hci_dump.c (revision 128d6c999a4a7cc321497ddbaddd9cd6c8d1edef)
179662672Smatthias.ringwald /*
2a0c35809S[email protected]  * Copyright (C) 2014 BlueKitchen GmbH
31713bceaSmatthias.ringwald  *
41713bceaSmatthias.ringwald  * Redistribution and use in source and binary forms, with or without
51713bceaSmatthias.ringwald  * modification, are permitted provided that the following conditions
61713bceaSmatthias.ringwald  * are met:
71713bceaSmatthias.ringwald  *
81713bceaSmatthias.ringwald  * 1. Redistributions of source code must retain the above copyright
91713bceaSmatthias.ringwald  *    notice, this list of conditions and the following disclaimer.
101713bceaSmatthias.ringwald  * 2. Redistributions in binary form must reproduce the above copyright
111713bceaSmatthias.ringwald  *    notice, this list of conditions and the following disclaimer in the
121713bceaSmatthias.ringwald  *    documentation and/or other materials provided with the distribution.
131713bceaSmatthias.ringwald  * 3. Neither the name of the copyright holders nor the names of
141713bceaSmatthias.ringwald  *    contributors may be used to endorse or promote products derived
151713bceaSmatthias.ringwald  *    from this software without specific prior written permission.
166b64433eSmatthias.ringwald  * 4. Any redistribution, use, or modification is done solely for
176b64433eSmatthias.ringwald  *    personal benefit and not for any commercial purpose or for
186b64433eSmatthias.ringwald  *    monetary gain.
191713bceaSmatthias.ringwald  *
20a0c35809S[email protected]  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
211713bceaSmatthias.ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
221713bceaSmatthias.ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
231713bceaSmatthias.ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
241713bceaSmatthias.ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
251713bceaSmatthias.ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
261713bceaSmatthias.ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
271713bceaSmatthias.ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
281713bceaSmatthias.ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
291713bceaSmatthias.ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
301713bceaSmatthias.ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311713bceaSmatthias.ringwald  * SUCH DAMAGE.
321713bceaSmatthias.ringwald  *
33a0c35809S[email protected]  * Please inquire about commercial licensing options at
34a0c35809S[email protected]  * [email protected]
356b64433eSmatthias.ringwald  *
361713bceaSmatthias.ringwald  */
371713bceaSmatthias.ringwald 
38e501bae0SMatthias Ringwald #define BTSTACK_FILE__ "hci_dump.c"
39ab2c6ae4SMatthias Ringwald 
401713bceaSmatthias.ringwald /*
4179662672Smatthias.ringwald  *  hci_dump.c
4279662672Smatthias.ringwald  *
43*128d6c99SMatthias Ringwald  *  Dump HCI trace in various formats based on platform-specific implementation
4479662672Smatthias.ringwald  */
4579662672Smatthias.ringwald 
467907f069SMatthias Ringwald #include "btstack_config.h"
47*128d6c99SMatthias Ringwald #include "btstack_debug.h"
48*128d6c99SMatthias Ringwald #include "btstack_bool.h"
49*128d6c99SMatthias Ringwald #include "btstack_util.h"
50a1d7dd1fSmatthias.ringwald 
51*128d6c99SMatthias Ringwald static const hci_dump_t * hci_dump_impl;
52*128d6c99SMatthias Ringwald static int  max_nr_packets;
53*128d6c99SMatthias Ringwald static int  nr_packets;
548b658ebcSmatthias.ringwald 
558a37b10aSMatthias Ringwald // levels: debug, info, error
56*128d6c99SMatthias Ringwald static bool log_level_enabled[3] = { 1, 1, 1};
578a37b10aSMatthias Ringwald 
58*128d6c99SMatthias Ringwald static bool hci_dump_log_level_active(int log_level){
59*128d6c99SMatthias Ringwald     if (hci_dump_impl == NULL) return false;
60*128d6c99SMatthias Ringwald     if (log_level < HCI_DUMP_LOG_LEVEL_DEBUG) return false;
61*128d6c99SMatthias Ringwald     if (log_level > HCI_DUMP_LOG_LEVEL_ERROR) return false;
62*128d6c99SMatthias Ringwald     return log_level_enabled[log_level];
63d9659922Smatthias.ringwald }
6479662672Smatthias.ringwald 
65*128d6c99SMatthias Ringwald void hci_dump_init(const hci_dump_t * impl){
66*128d6c99SMatthias Ringwald     max_nr_packets = -1;
67*128d6c99SMatthias Ringwald     nr_packets = 0;
68*128d6c99SMatthias Ringwald     hci_dump_impl = impl;
69*128d6c99SMatthias Ringwald }
70*128d6c99SMatthias Ringwald 
712992c131Smatthias.ringwald void hci_dump_set_max_packets(int packets){
722992c131Smatthias.ringwald     max_nr_packets = packets;
732992c131Smatthias.ringwald }
74*128d6c99SMatthias Ringwald 
75*128d6c99SMatthias Ringwald void hci_dump_packet(uint8_t packet_type, uint8_t in, uint8_t *packet, uint16_t len) {
76*128d6c99SMatthias Ringwald     if (hci_dump_impl == NULL) return;
77*128d6c99SMatthias Ringwald     if (max_nr_packets > 0){
78*128d6c99SMatthias Ringwald         if ((nr_packets >= max_nr_packets) && (hci_dump_impl->reset != NULL)) {
79*128d6c99SMatthias Ringwald             nr_packets = 0;
80*128d6c99SMatthias Ringwald             (*hci_dump_impl->reset)();
81*128d6c99SMatthias Ringwald         }
82*128d6c99SMatthias Ringwald         nr_packets++;
83*128d6c99SMatthias Ringwald     }
84*128d6c99SMatthias Ringwald     (*hci_dump_impl->log_packet)(packet_type, in, packet, len);
85*128d6c99SMatthias Ringwald }
86*128d6c99SMatthias Ringwald 
87*128d6c99SMatthias Ringwald void hci_dump_log(int log_level, const char * format, ...){
88*128d6c99SMatthias Ringwald     if (!hci_dump_log_level_active(log_level)) return;
89*128d6c99SMatthias Ringwald 
90*128d6c99SMatthias Ringwald     va_list argptr;
91*128d6c99SMatthias Ringwald     va_start(argptr, format);
92*128d6c99SMatthias Ringwald     (*hci_dump_impl->log_message)(format, argptr);
93*128d6c99SMatthias Ringwald     va_end(argptr);
94*128d6c99SMatthias Ringwald }
95*128d6c99SMatthias Ringwald 
96*128d6c99SMatthias Ringwald #ifdef __AVR__
97*128d6c99SMatthias Ringwald void hci_dump_log_P(int log_level, PGM_P format, ...){
98*128d6c99SMatthias Ringwald     if (!hci_dump_log_level_active(log_level)) return;
99*128d6c99SMatthias Ringwald 
100*128d6c99SMatthias Ringwald     va_list argptr;
101*128d6c99SMatthias Ringwald     va_start(argptr, format);
102*128d6c99SMatthias Ringwald     (*hci_dump_impl->log_packet_P)(format, argptr);
103*128d6c99SMatthias Ringwald     va_end(argptr);
104*128d6c99SMatthias Ringwald }
1057c5f7483Smatthias.ringwald #endif
1062992c131Smatthias.ringwald 
107*128d6c99SMatthias Ringwald void hci_dump_enable_log_level(int log_level, int enable){
108*128d6c99SMatthias Ringwald     if (log_level < HCI_DUMP_LOG_LEVEL_DEBUG) return;
109*128d6c99SMatthias Ringwald     if (log_level > HCI_DUMP_LOG_LEVEL_ERROR) return;
110*128d6c99SMatthias Ringwald     log_level_enabled[log_level] = enable != 0;
111*128d6c99SMatthias Ringwald }
112*128d6c99SMatthias Ringwald 
113*128d6c99SMatthias Ringwald void hci_dump_setup_header_packetlogger(uint8_t * buffer, uint32_t tv_sec, uint32_t tv_us, uint8_t packet_type, uint8_t in, uint16_t len){
114*128d6c99SMatthias Ringwald     big_endian_store_32( buffer, 0, HCI_DUMP_HEADER_SIZE_PACKETLOGGER - 4 + len);
1155fa31a99SMatthias Ringwald     big_endian_store_32( buffer, 4, tv_sec);
1165fa31a99SMatthias Ringwald     big_endian_store_32( buffer, 8, tv_us);
1175fa31a99SMatthias Ringwald     uint8_t packet_logger_type = 0;
1185fa31a99SMatthias Ringwald     switch (packet_type){
1195fa31a99SMatthias Ringwald         case HCI_COMMAND_DATA_PACKET:
1205fa31a99SMatthias Ringwald             packet_logger_type = 0x00;
1215fa31a99SMatthias Ringwald             break;
1225fa31a99SMatthias Ringwald         case HCI_ACL_DATA_PACKET:
1235fa31a99SMatthias Ringwald             packet_logger_type = in ? 0x03 : 0x02;
1245fa31a99SMatthias Ringwald             break;
1255fa31a99SMatthias Ringwald         case HCI_SCO_DATA_PACKET:
1265fa31a99SMatthias Ringwald             packet_logger_type = in ? 0x09 : 0x08;
1275fa31a99SMatthias Ringwald             break;
1285fa31a99SMatthias Ringwald         case HCI_EVENT_PACKET:
1295fa31a99SMatthias Ringwald             packet_logger_type = 0x01;
1305fa31a99SMatthias Ringwald             break;
1315fa31a99SMatthias Ringwald         case LOG_MESSAGE_PACKET:
1325fa31a99SMatthias Ringwald             packet_logger_type = 0xfc;
1335fa31a99SMatthias Ringwald             break;
1345fa31a99SMatthias Ringwald         default:
1355fa31a99SMatthias Ringwald             return;
1365fa31a99SMatthias Ringwald     }
1375fa31a99SMatthias Ringwald     buffer[12] = packet_logger_type;
1385fa31a99SMatthias Ringwald }
1395fa31a99SMatthias Ringwald 
140*128d6c99SMatthias Ringwald void hci_dump_setup_header_bluez(uint8_t * buffer, uint32_t tv_sec, uint32_t tv_us, uint8_t packet_type, uint8_t in, uint16_t len){
1414ea43905SMatthias Ringwald     little_endian_store_16( buffer, 0u, 1u + len);
1425fa31a99SMatthias Ringwald     buffer[2] = in;
1435fa31a99SMatthias Ringwald     buffer[3] = 0;
1445fa31a99SMatthias Ringwald     little_endian_store_32( buffer, 4, tv_sec);
1455fa31a99SMatthias Ringwald     little_endian_store_32( buffer, 8, tv_us);
1465fa31a99SMatthias Ringwald     buffer[12] = packet_type;
1475fa31a99SMatthias Ringwald }
148