SDL is theoretically transport agnostic, meaning it can work over any potential transport. However, due to limitations of app platforms, only certain transports are available for connecting to given app platforms.
The first step in using SDL is to establish a connection over a primary transport.
SDL has the ability to register a session across multiple transports. This is useful for certain scenarios where a higher bandwidth transport is needed to perform more data intensive operations of SDL (such as video/audio streaming), but that transport isn't good for establishing or maintaining the connection.
Primary or secondary transport
Bluetooth connections established to an Android device require a few prerequisites and processes. First, the bluetooth's Advanced Audio Distribution Profile (A2DP) and Hands Free Profile (HFP) must be connected for the SDL Android router service to start listening on an RFCOMM channel using the Serial Port Profile (SPP). The Android device will use a router service that allows multiple apps to bind to it and utilize a single transport connection. This allows for a greater chance that the SDL library can obtain one of the RFCOMM channels available on the device, as most devices have rather low limits. In some cases, apps might not bind to the router service and listen on their own bluetooth transport. These apps must also be connected.
queryForConnectedService(context)
). However, the hardware will have to perform an SDP query to know that this has occurred. Primary or secondary transport
Android has a specification called AOA that allows apps to communicate over a USB connection. The default implementation of AOA on the Android device is very limited. Users must select an app to receive the "USB device" upon connection on the device. However, the SDL Android library leverages its already existing functionality of multiplexing a single transport connection through a router service to allow multiple apps to use the AOA connection.
Secondary transport only
Due to limitations for the iOS platform (discussed in the next section), Android can only use the TCP transport as a secondary transport in production. The hardware will send the connection information after a primary transport is connected through an SDL packet.
Primary transport only
Apple has a proprietary technology called iAP that apps connect through to communicate data over Bluetooth or USB. Unfortunately, this means that none of that information can be shared here. You will have to build and certify your hardware as part of Apple's MFi program in order to enable the Bluetooth and USB transports, which are also the only primary transport available. Therefore, without MFi certification and building support for the iAP transport, your hardware cannot support production iOS devices and apps.
The way IAP works is that you have a protocol string that a hardware device and an app declare that they can use. When iOS sees a hardware device with a known protocol string, it notifies all apps that declare that protocol string. The app can then open a 1-1 connection with the hardware using that protocol string as an identifier for the connection.
There are two different connection strategies that the iOS library uses. The first is the "hub" strategy for connecting to a single-session iAP protocol. This method is only included in the library as legacy support and should not be implemented in new modules. The hub strategy was developed to allow multiple apps to connect to the hardware before multiple apps could use the same protocol string.
The hardware has to make 30 protocol strings available. Each app will attempt to connect to one protocol (prot0
, called the control protocol) in order to receive one byte of data. That data is a number 1-29. The app will then disconnect from the control protocol and connect to a data protocol corresponding to the number they received (prot1-prot29).
Because many apps are attempting to connect to the control protocol in order to receive their protocol string number, the app is given a timeout based on a hash of the app’s name. The apps will try to connect to the control string after that timeout. If they fail, they’ll wait the timeout 3 more times and attempt to connect to get their data protocol number.
This strategy works, but has some large downsides. The more apps that try to connect to the control protocol, the more collisions will result, and the less reliable the connection becomes. Once more than four or five apps connect, the connection will degrade quickly and some apps may connect sometimes and not other times.
Multi-Session is a newer iAP feature that allows multiple connections to a single protocol string. Every app can connect to the multi-session protocol string without needing to wait or needing to manage connection timing. This is the preferred method to connect iOS SDL apps because it eliminates a lot of the stability issues that have been observed with the single-session method. See this evolution proposal for its acceptance into the project.
Secondary transport only
iOS has a very strict limitation that no TCP connection can be maintained while an app is in the background. For this reason TCP can only be a secondary transport and should only be used for video streaming applications, which already have this limitation. The hardware will send the connection information to the library after a primary transport is connected through an SDL packet, and the library will then take care of attempting to connect to the IP address and port.
Primary transport only
The only transport currently available by default in the SDL Java SE library is a web socket server connection. The Java SE app should usually run directly on the same device as the SDL Core and HMI (i.e. it should be an embedded application).
Determining when the Java SE app should start listening to that web socket port will need to be defined by the SDL Core integrator. This will likely be during start up of the device. The Java SE app can simply be started and wait for the user to select the application from the application list. See the 0158 - Cloud App Transport Adapter proposal for more information.
Currently the Java SE client library does not support a secondary transport because the WebSocket transport is already high bandwidth.
Primary Transport Only
Java EE is usually built around Java Beans in order to easily handle many simultaneous connections that each have their own, independent state. This is another example of a proprietary or separately licensed transport. Because of this, the Java EE library has what's called a Custom Transport. This also developers to hook into the Java EE Bean framework without the SDL library having to include that code into the library itself.
Java EE apps are designed to be long running applications that live on an off-board server. The SDL Core implementation will connect out to these applications once they are selected from the app list on the HMI. See the 0158 - Cloud App Transport Adapter proposal for more information.
The previous flow for JavaSE can be followed as the difference will depend on the type of custom transport used. For most cases, using Java Beans is the best flow and will only differ in adding multiple connections to the app via independent instances created by a type of load balancer.
Currently the Java EE client library does not support a secondary transport as the websocket transport is already high bandwidth.
View on GitHub.com