niolabs / python-xbee

Python tools for working with XBee radios
MIT License
101 stars 45 forks source link

Waiting forever to receive a package #49

Closed eroniki closed 6 years ago

eroniki commented 7 years ago

In the _wait_for_frame method of the base class, I realize something that might hurt the overall performance of the package. As the package is waiting for the packet to receive, it stays in the loop (listening the serial port) until remaining bytes becomes 0. The link below highlights to mentioned hunk of the code. https://github.com/nioinnovation/python-xbee/blob/master/xbee/base.py#L124L159

However, there is a problem I have realized with this logic while using the code. Say, after the transmitter starts sending the packages, it resets itself or stops sending the remaining bytes. If this happens, the code gets stuck in the loop at L144.

I am not sure if I am interpreting the code in the wrong way or this is the intended behavior. For my experience, the RF modules which are close the communication range lost signal and the receiver gets stuck in the mentioned loop. Maybe there should be default timeout to complete packet reconstruction after which the class can raise an exception.

If the issue is found reasonable, I can create a pull request by the end of the day.

jamesleesaunders commented 7 years ago

Hi @eroniki Thanks for looking into this and offering to create a PR. I think I understand the possible bug scenario you describe after a incomplete frame comes in possibly causing _wait_for_frame() to end up in infinite loop however I have not been able to work out just looking at the code whether this is a real possibility.

Please, by all means if you want to put together a PR for this that would be excellent. One thing which would be extremely helpful is if you can re-create (and then fix) the potential issue using the unit tests. I think you should be able to re-create it using the 'Fake.py' serial emulator.

I would also like one of the owners @mattdodge or @hansmosh to also cast their eyes and opinion over this as I am still learning!

Thanks again,

Jim

jamesleesaunders commented 7 years ago

Hi @eroniki Did you get any further with your investigations? Is this still an issue?

mattdodge commented 7 years ago

Hmm, I'm not totally sure, it depends on the behavior of serial.read() and the frame (haven't tested myself yet). If the frame is read and it says it will have 100 bytes but then not all of those bytes make it to the serial connection it may spin forever. I'm just not sure what self.serial.read() will do if there are no more bytes, my gut would guess that it would block though.

I do think we should be able to reproduce or at least confirm via testing though

eroniki commented 7 years ago

@mattdodge @jamesleesaunders I started writing my thesis so my schedule is a little bit cramped. However, the first thing I will try is to test the behaviour with the fake serial module. I will post the updates here.

jamesleesaunders commented 7 years ago

Hi @eroniki I hope your thesis is going well. Did you get a moment to look more into this. No worries if not we are all busy peeps!

eroniki commented 7 years ago

Hey @jamesleesaunders, thanks for your wishes (I think I need some extra motivation like this, lol). I will defend on Sept. 1st after which I am completely free, and python-xbee is the first thing in my list to complete.

jamesleesaunders commented 6 years ago

Hi @eroniki no pressure but did you come to any revelations on this issue? Would love to see your proposed code PR if you work it out.

rowjay commented 6 years ago

Hey, I've been having the same issue with a device in API mode AP[2]. After reading the docstring on the XBeeBase constructor, I set escaped=True when creating a XBee instance for devices in API escaped mode.

eg. xbee = XBee(serial_port, escaped=True)

This solves the problem here. It would be handy to detect the API mode automatically though. I will look into this another day.