-
Notifications
You must be signed in to change notification settings - Fork 171
Android Transport Multiplexing
Multiplexing allows SDL to use a single RFCOMM/SPP bluetooth channel or AOA connection for many different apps. This is extremely important due to the fact that different Android headsets have different limits to the amount of RFCOMM/SPP channels available. AOA also only allows a single app to access its file descriptor so the library must find a way to share that transport pipe.
In this diagram we see how each app will talk with the router service. After an app is registered with the router service, the router service will map them to their requested sessions. Apps can send data to the head unit by sending byte arrays as an extra in intents addressed to the router service. When the router service receives bytes, it puts them through a packet state machine (seen in the next figure) and it find the correct app binding for the corresponding session in the packet. It then sends the formed packet as part of a bundle in a message sent through the binding of the correct app. For a developer, this all happens in the background and there is no reason for them to worry about it.
The router service only contains a single RFCOMM channel connection to the head unit which means it is only able send a serial line of bytes that form complete packets. The service therefore gives each packet a weight or priority based on the original timestamp of packet's request and size. It will favor packets that are small or have been waiting the longest to increase the overall average latency. Each app keeps a serial queue of packets that it wishes to send out to avoid them arriving out-of-order. The router service is notified when there is a new packet in any queue awaiting being wrote out. After the packet is sent, the router service will query all the apps for the packet in the front of their respective queues. It compares the priority of each of these packets and sends out the one with the highest value. It repeats this process until no packets are left to send and awaits to be notified again.
The diagram shows the start to finish of the router's read-and-pass system. The router service is responsible for reading in data from the head unit. The router service reads in one byte at a time. It then processes that through a packet state machine. If a valid packet is formed, it will attempt to find an app for the session id contained in the packet. If there is no app mapped to that session id, it will check to see if that packet is a start session ACK. If it is, it will see if there are any open requests for a session for any app. If it finds one, it will send the packet to that app and create a mapping between that session id and that app. If it fails at any point during these last three checks it will throw away the packet. The only special case that is created is when a packet is a v1 packet. In this case legacy mode will be enabled which is described in the following diagram.
Here we take a look on how legacy mode should work. Due to old implementations of SDL in currently used vehicles there is a limitation of one session per RFCOMM/SPP channel. This prevents multiplexing from working as only one app would be able to connect at a time. So instead, when the router service receives a v1 packet it reverts to legacy mode. The router service will disconnect its RFCOMM/SPP channel and send all registered clients a hardware disconnect intent with a flag that is set TRUE for legacy mode. When the clients receive this message, they will destroy their multiplex transport and create a new legacy bluetooth connection. At this point, the interaction would be very similar to how it worked before multiplexing was introduced. The one different here is that once the bluetooth connection is ended, each app sets their legacy flag to false and restarts back into the normal multiplexing mode. The router service also watches for this disconnect; once it receives the intent for the disconnect it will restart its own listening RFCOMM/SPP channel and await for the next connection.