Skip to content

Bug: Sniffle crashing when attempting reconnection #103

@XenoKovah

Description

@XenoKovah

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions