-
Notifications
You must be signed in to change notification settings - Fork 148
Description
I have a desire to have Sniffle automatically attempt reconnection, indefinitely, for a tool I'm building on top of Sniffle to do GATT enumeration. (I would see to termination of Sniffle after a timeout period. Though I suppose a --timeout
option might be appropriate too.)
Sultan pointed out that reconnection can be achieved by looking for the state going to PAUSED, and then just reconnecting at that point. I did that, and sometimes it worked and achieved my goal of connecting to something which otherwise would have failed in the first try. But other times it crashed Sniffle/Linux in such a way that serial connections via screen would work after the dongle was unplugged and replugged, but serial connections via Sniffle's sniff_receiver.py would just re-kill the serial connection again at that point. Which is why I think it's somehow affecting Linux as well. But sniff_receiver.py or scanner.py become inoperable until Linux reboot - just physically turning the dongle off and on is insufficient.
The code I used to do the reconnection was as follows:
try:
while True:
msg = globals.hw.recv_and_decode()
ret = print_message(msg, args.quiet)
if(ret == "restart"):
# It timed out. Go ahead and try to connect again
print("Connect timeout... restarting")
globals._aa = globals.hw.initiate_conn(mac_bytes, not args.public)
create_pcap_CONNECT_IND(args, mac_bytes, globals._aa, central_bdaddr_bytes) # create_pcap_CONNECT_IND() structured roughly based on code in https://github.com/nccgroup/Sniffle/issues/83
except KeyboardInterrupt:
# Tear down with an LL_TERMINATE_IND, otherwise it will be harder to re-connect again afterwards,
# because some devices may keep the connection open too long, and don't start advertising again right away
# 0x13 = error code "Remote user terminated connection"
print("Terminating connection with LL_TERMINATE_IND")
write_outbound_pkt(3, b'\x02\x13') # write_outbound_pkt from https://github.com/nccgroup/Sniffle/issues/83
time.sleep(.1)
exit(-1)
and
def print_message(msg, quiet):
global hw
if isinstance(msg, PacketMessage):
print_packet(msg, quiet)
elif isinstance(msg, DebugMessage):
print(msg)
elif isinstance(msg, StateMessage):
print(msg)
if msg.new_state == SnifferState.MASTER:
globals.hw.decoder_state.cur_aa = globals._aa
if msg.new_state == SnifferState.PAUSED: # It has probably timed out trying to connect. Tell it to connect again
return "restart"
(Note: my globals are prefixed with globals.
compared to the original code, because my tool got too big and I started breaking it up into multiple files, including a globals.py
).
My testing was performed on Ubuntu 22.04.2 LTS and sniffle at commit 84b1ec0 and with Sonoff dongles running the 2Mbaud firmware.