Bluetooth Implementation - tiredboffin/fffw GitHub Wiki

Proprietary Pairing

  • BLE pairing and bonding are not used; data exchanges are not encrypted.
  • When in pairing mode, the Camera periodically broadcasts advertisements that include an unmodifiable Camera Advertised Name, Camera Remote UUID, and Manufacturer data, which together serve as an Authentication Token.
  • The Camera Advertised Name is formed by combining the model name with the last 4 hex digits of the Camera’s Unique Number. For example: 2A09XT-42A09. It cannot be changed through UI.
  • The Camera Remote UUID is: 117c4142-edd4-4c77-8696-dd18eebb770a.
  • The Manufacturer data contains a Fujifilm tag and is 5 bytes long. The first byte is fixed to 02, and the remaining four bytes are used as the Authentication Token.
  • Newer cameras also broadcast BLE advertisements that include the XApp UUID: af854c2e-b214-458e-97e2-912c4ecf2cb8.
  • Both types of advertisements are sent intermittently, making the newer camera discoverable by both Camera Remote and XApp applications.
  • The Manufacturer data, or Authentication Token, differs between advertisements with the XApp UUID and those with the Camera Remote UUID. When the app registers the camera, it sends the Authentication Token to the Camera, allowing the camera to determine whether it is pairing with XApp or Camera Remote.
  • The Authentication Token is based on a simple Galois LFSR, with the "camera age" (in seconds) as the input.
  • The app creates a new profile and:
    • Stores the Camera Advertised Name and Authentication Token. The Camera's BLE MAC address is not used.
    • Reads and stores the Camera’s Unique Number (trailer of the USB Serial Number).
    • Reads and stores the Camera Name, which can be changed on both the Camera and the app side. This name is used for the UI and as the Wi-Fi AP SSID. The FUJIFILM prefix of the name cannot be changed through the UI, but a non-native app can set any name.
  • The XApp does not create a new profile if the Camera Unique Number matches a value stored in any existing profile; instead, it updates the existing profile.
  • The Camera creates a new profile and:
    • Stores the Authentication Token. The phone's BLE MAC is not used.
    • Newer cameras remember which application (Camera Remote or XApp) paired
    • Stores the app name for UI purposes.
    • Makes the newly created profile the active one, which can be selected in the camera menu.
    • Supports up to 7 profiles, deleting the oldest profile when an 8th profile is created.

Paired Connection Establishment and Authentication

  • When BLE is enabled on the Camera and an "pairing destination" profile is selected, the Camera continuously advertises the Advertisement Name and the paired application UUID from the selected profile.
  • The app listens for advertisements filtered by its UUID and with an Advertisement Name matching the one in the profile.
  • Upon a match, the Camera establishes a BLE connection and discovers all services/characteristics. For the complete list of services/characteristics, refer to...
  • The app reads the Camera Unique Number to check if it matches the profile and disconnects if it does not.
  • The app sends the Authentication Token to the Camera, which validates it. If the token does not match the value in the "pairing destination" profile, the Camera returns an error. Otherwise, the connection is considered successfully established.

Notes on pairing algorithm

  • The above algorithm is relatively straightforward to replicate on both the non-native app and the camera side. The later might be useful for testing and research purposes. For research purposes both are implemented as CLI Linux applications written in Python (to be published)

  • The algorithm is I think prone to several issues that might negatively impact the user experience.

    Example scenarios:

    • When a user pairs the Camera Remote with the camera, then installs the XApp (or vice versa) and pairs the camera with it, the previously paired app will stop working. Both profiles on the camera will display the same phone name without any indication of which profile corresponds to which application.

    • When a user has two devices (e.g., a phone and an iPad) or when two users are sharing the camera:

      • Pairing with one device automatically makes the other device "inactive." The user must manually switch the active device on the camera before it can be used, or as a workaround always activate pairing mode on the camera, which creates a new record on camera that is automatically activated.
      • If the app is running (e.g., in the background) on a device that is not selected as the "pairing destination" on the camera, it will continuously attempt to connect. Since the app cannot determine from the advertisement data whether it is the correct instance, it will go through a lengthy service discovery process (lasting more than 10 seconds on newer cameras). It only realizes that it’s not the intended device when it sends the wrong authentication token and receives an error. During this time, the camera stops advertising, making it harder for the intended app to discover it. Worse, the app continues trying to connect after the failure, leading to unnecessary battery drain on the camera.

Protocol details

See files at https://github.com/tiredboffin/fffw/tree/main/ffbt