Skip to content

Timeout during apply_profile() #162

Closed
@tonyborries

Description

@tonyborries

TLDR: during apply_profile when re-opening the serial connection, we reset the operating mode to API_MODE and if the module is running in ESCAPED_API_MODE, any packets which happen to get escaped will cause a failure.

I'm attempting to apply a profile to a local XBee device. Of note I'm using ESCAPED_API_MODE on the module.

Below is the example I'm trying:

def main():
    device = XBeeDevice(PORT, BAUD_RATE)
    try:
        device.open()
        print("Updating profile '%s'...\n" % PROFILE_PATH)
        device.apply_profile(PROFILE_PATH, progress_callback=progress_callback)
        print("\nProfile updated successfully!")
    except Exception as e:
        print(str(e))
        exit(1)
    finally:
        if device.is_open():
            device.close()

I receive the following error:

Error re-configuring XBee device serial port: Response not received in the configured timeout.

I tracked this down to an issue during the re-opening of the device after applying the serial settings (in _ProfileUpdater._check_port_settings_changed()). During the re-open, the operating_mode in the python code is reset to API_MODE while the module is still running in ESCAPED_API_MODE. It appears that the behavior is specific to the exact settings of the profile, in that I would hit frame id 0x13 after the re-open, which escapes the id, causing the packet to be ignored since it has the extra escape character.

This function mimics the behavior of profile._check_port_settings_changed() that leads to the Exception. It can be seen that there are two failures, one where the failing frame_id (note, not the starting_frame id) is 0x11 and one for 0x13, both of which get escaped.

def replicateBug():

    device = XBeeDevice(PORT, BAUD_RATE)

    for starting_frame in range(0x0d, 0x14):
        # Set the frame id to check by incrementing to it
        while device.get_current_frame_id() != starting_frame:
            device._get_next_frame_id()

#         print("Testing current FrameID: 0x{0:02x}".format(device.get_current_frame_id()))
        try:
            device.close()  # This is necessary to stop the frames read thread.
            device.open()
        except Exception as e:
            print(e)
            print("Frame ID 0x{0:02x} Failed".format(starting_frame))
        else:
            print("Frame ID 0x{0:02x} Succeeded".format(starting_frame))

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions