44import os
55import re
66import struct
7+ import time
78
89
910def create_new_bt_snoop_file (filename : str ) -> None :
@@ -36,7 +37,7 @@ def log_data_clean(data: str) -> str:
3637 return cleaned
3738
3839
39- def parse_log (input_path : str , output_tag : str ) -> None :
40+ def parse_log (input_path : str , output_tag : str , has_timestamp : bool = True ) -> None :
4041 if not os .path .exists (input_path ):
4142 print (f"Error: The file '{ input_path } ' does not exist." )
4243 return
@@ -53,10 +54,9 @@ def parse_log(input_path: str, output_tag: str) -> None:
5354 if not line :
5455 continue
5556 parts = line .split ()
56- if len (parts ) < 10 :
57+ if len (parts ) < 2 :
5758 continue
5859 parts_wo_ln = parts [1 :]
59- # Check for literal in the first token
6060 literal = None
6161 if ':' in parts_wo_ln [0 ]:
6262 literal_part , sep , ts_byte = parts_wo_ln [0 ].partition (':' )
@@ -66,16 +66,18 @@ def parse_log(input_path: str, output_tag: str) -> None:
6666 else :
6767 literal = None
6868 if literal :
69- # Parse timestamp
70- try :
71- timestamp_bytes = bytes (int (b , 16 ) for b in parts_wo_ln [1 :9 ])
72- except Exception :
73- continue
74- timestamp_us = int .from_bytes (timestamp_bytes , byteorder = 'little' , signed = False )
75- hci_data = ' ' .join (parts_wo_ln [9 :])
69+ if has_timestamp :
70+ try :
71+ timestamp_bytes = bytes (int (b , 16 ) for b in parts_wo_ln [1 :9 ])
72+ timestamp_us = int .from_bytes (timestamp_bytes , byteorder = 'little' , signed = False )
73+ hci_data = ' ' .join (parts_wo_ln [9 :])
74+ except Exception :
75+ continue
76+ else :
77+ timestamp_us = int (time .time () * 1e6 )
78+ hci_data = ' ' .join (parts_wo_ln [1 :])
7679 if not hci_data :
7780 continue
78- # Determine indicator and direction
7981 if literal == 'C:' :
8082 hci_data = '01 ' + hci_data
8183 direction = 0
@@ -93,13 +95,16 @@ def parse_log(input_path: str, output_tag: str) -> None:
9395 append_hci_to_bt_snoop_file (output_file , direction , hci_data , timestamp_us )
9496 parsed_num += 1
9597 else :
96- # No literal: treat as advertising report
97- try :
98- timestamp_bytes = bytes (int (b , 16 ) for b in parts [1 :9 ])
99- except Exception :
100- continue
101- timestamp_us = int .from_bytes (timestamp_bytes , byteorder = 'little' , signed = False )
102- adv_data = ' ' .join (parts [9 :])
98+ if has_timestamp :
99+ try :
100+ timestamp_bytes = bytes (int (b , 16 ) for b in parts [1 :9 ])
101+ timestamp_us = int .from_bytes (timestamp_bytes , byteorder = 'little' , signed = False )
102+ adv_data = ' ' .join (parts [9 :])
103+ except Exception :
104+ continue
105+ else :
106+ timestamp_us = int (time .time () * 1e6 )
107+ adv_data = ' ' .join (parts [1 :])
103108 if not adv_data :
104109 continue
105110 hci_data = '04 3e ' + adv_data
@@ -120,10 +125,14 @@ def main() -> None:
120125 parser = argparse .ArgumentParser (description = 'Log Parsing Tool' )
121126 parser .add_argument ('-p' , '--path' , required = True , help = 'Path to the input log file' )
122127 parser .add_argument ('-o' , '--output' , required = True , help = 'Name tag for the output file' )
128+ parser .add_argument (
129+ '--has-ts' ,
130+ action = 'store_true' ,
131+ default = False ,
132+ help = 'Set this if the input file has timestamp bytes at the beginning (default: False)' ,
133+ )
123134 args = parser .parse_args ()
124- input_path = args .path
125- output_tag = args .output
126- parse_log (input_path , output_tag )
135+ parse_log (args .path , args .output , has_timestamp = args .has_ts )
127136
128137
129138if __name__ == '__main__' :
0 commit comments