ukBaz / python-bluezero

A simple Python interface to Bluez
MIT License
395 stars 112 forks source link

Notification based image transfer takes longer and longer when chaining 10 devices #319

Closed Owenber123 closed 2 years ago

Owenber123 commented 3 years ago

Hello All, I have 10 devices on a test bench. My Client takes turns connecting to each device and running a variety of tests on a variety of different characteristics. One of the tests is based on an image that is transferred over one of the characteristics. The workflow goes:

  1. Start listening for an image transfer with an image_transmission callback function on the enabled notifications of that characteristic
  2. Send 3 characteristic values, the last of which is a delay until restarting the peripheral.
  3. Reconnect to the device after it restarts.
  4. The peripheral knows to start transmitting the image after the reconnect.
  5. Collect the image in chunks and run tests

The problem I am seeing is as I progress down the line of devices. Between steps 3 and 4 I get an incremental delay that nears 50 seconds by the last device which is not okay for our application. From debugging I know that each connection occurs within a few seconds and the client is then waiting for packets from the devices for the rest of the delay. All of the devices are programmed with the same firmware image so this should not be a problem with the peripheral logic. I have also monitored btmon and can see the image transfer successfully. The delay seems to occur after the driver and before the application. I'm looking for any advice or direction to solve this growing delay. Thanks in advanced, Owen

ukBaz commented 3 years ago

There is not an obvious cause, from what you've said, that is coming to mind as to where the problem might be. It does sound like there is a loop somewhere that is getting bigger and bigger as you go down the line.

My assumption from what you have written is that the 10 devices get tested individually. It just so happens that you do them in batches of 10, but it could be any number. So I am assuming that the same script is invoked 10 times but with a different peripheral address parameter each time. As each device would be starting with the same information, it is difficult to see where the list would get bigger.

Bluezero does do some look up of information with GetManagedObjects which requires iterating over the device information that BlueZ is storing. If this was the source of the problem, then if you ran the tests a second time you would see the slow down on device 1. As you haven't mentioned this as a problem, my assumption is that this is not the cause.

After a device connects, there is a brief delay as the GATT database (ServicesResolved) is established. It is not obvious to me that this would take longer on the 10th device than the first.

Have you ran the Python profiler on your code? https://docs.python.org/3/library/profile.html. That might help to narrow down where the issue is.

Owenber123 commented 3 years ago

ukBaz,

Thank you for the ideas. I have been busy on the new firmware of my device but found that running sudo service bluetooth restart between every batch of devices is a temporary fix. Whatever is building up is cleared by the restart. The restart also gives me a "D-Bus setup failed: Name already in use" sometimes so I'm questioning my adapter logic and will look into this more.

This is definitely something I will be revisiting as it is not a real solution. Another thing I found was that during my test I disconnect and reconnect and was not waiting long enough between those two calls. Somehow the test continued but very very slowly. A simple delay between the two seems to have cleared up a lot of delay. I will try the profiler at some point in the near future and give an update.

Thanks for the help, Owen

ukBaz commented 3 years ago

Link to question on stackoverflow for reference: https://stackoverflow.com/q/66712236/7721752

ukBaz commented 2 years ago

No update for a while so closing. Please update the ticket if you did find a solution