Tesla Developer API Guide: BLE Key Pair — Auth and Vehicle Commands (Part 3)

Shankar Kumarasamy
6 min readJan 29, 2024

Tesla provides 2 ways of communication with the car. One is over the internet using the APIs and the other is using a BLE connection. BLE connection helps in one of the most crucial parts of locking and unlocking the car, even without having a network connection in the car and on the phone or any other BLE compatible key fobs. This helps in 2 major use cases, even in scenarios where the internet is very intermittent.

  1. Lock the car as you walk away from the car
  2. Unlock the car as you walk closer to the car

The use case for Bluetooth Low Energy (BLE) in cars is not limited to just locking and unlocking the vehicle. Most of the other commands can also be directly sent to the car over BLE, without having to take the full internet-based routing of commands. However, one thing to consider is the range of operating BLE from within a distance of the car.

Code repository for the BLE functionality can be found here — https://github.com/teslamotors/vehicle-command.git

We must utilize the code in the path — vehicle-command/cmd/tesla-control.
I used VS code editor as the IDE and cloned the project from the GitHub repository.

Check out the Tesla Vehicle Command code from GitHub

Navigate to tesla-control in the terminal and run 'go build'

Build ‘tesla-control’

BLE Pairing and issuing vehicle commands -

To send commands to a vehicle, it is crucial to ensure that the channel used is secure. Tesla uses the public-private key pair model to establish this security over Bluetooth Low Energy (BLE). The private key, which is securely stored, is sent with the vehicle command whenever it is issued. The public key generated is added to the vehicle. Steps 1 and 2 of the process below explain how to create the public and private keys.

High-level architecture of Tesla BLE authentication and vehicle command

Step 1 :: Generate the private key
openssl ecparam -genkey -name prime256v1 -noout > private.pem

Step 2 :: Generate the public key
openssl ec -in private.pem -pubout > public.pem

Step 3 :: Add the public key with the car
./tesla-control -vin {VIN} -ble add-key-request {path_to_the_public_key_along_with_the_public_key_file_name} {ROLE} {FORM_FACTOR}

VIN — Vehicle Identification Number
ROLE — One of: owner, driver
FORM_FACTOR — One of: nfc_card, ios_device, android_device, cloud_key

A sample command to add a BLE key looks like the below -
./tesla-control -vin 7ABCGDEE123ABC555 -ble add-key-request public.pem owner cloud_key

When the command is issued, a successful request will return the following response.
Sent add-key request to 7ABCGDEE123ABC555. Confirm by tapping NFC card on center console.

When an NFC card is tapped on the center console of a Tesla vehicle, a message will appear on the car display console.

Tesla touchscreen is displaying a confirmation button to add a public key to the car

After adding the key, it will appear in the key list and a notification will be sent if you have the Tesla app installed on your phone.

Tesla App notification showing a key is added to the vehicle

It is possible to add additional keys by passing the private key from a previously registered key using 'add-key' command for other use cases.

Step 4 :: Test by issuing the commands
./tesla-control -ble -vin {VIN} -key-name {private_key_file_name} -key-file {path_to_the_private_key_along_with_the_public_key_file_name} {COMMAND}

VIN — Vehicle Identification Number
COMMAND — Instruction issued to the vehicle

A sample command to unlock the car looks like the below -
./tesla-control -ble -vin 7ABCGDEE123ABC555 -key-name private.pem -key-file private.pem unlock

Common errors when working with BLE include being out of range or not adding the key.
1. You must provide a private key with -key-name or -key-file to execute this command
2. Error: failed to find BLE beacon for 7ABCGDEE123ABC555 (Sdt5t1fdd18c17644C): can't scan: context deadline exceeded

Implementing the BLE key on a mobile app

The complete set of commands required to set up the BLE connection for Tesla

Below are the commands that can currently be issued via BLE, as per the current code at the time of writing this blog post:

List of commands that can be issued to the Tesla Vehicle in a secure way over BLE commands

To remove a previously added key from the car, follow the steps below.
1. On the touchscreen, touch Controls > Locks.
2. In the key list, find the key you want to delete and touch its associated trash icon.

List of Keys as displayed on the touchscreen

3. When prompted, scan an authenticated key on the card reader to confirm the deletion.

To authenticate and remove the key, simply tap the NFC card

4. After the deletion process, the removed key will no longer appear in the key list. Additionally, if the Tesla app is installed on your phone, you will receive a notification informing you of the deletion.

Tesla App notification showing a key is removed from the vehicle

Implementing the BLE key on a mobile app

BLE pairing can be used as mobile keys to connect to a car. It is important to understand the permissions that need to be granted in the Android and iOS platforms for the mobile app.

Android (All versions):

  • BLUETOOTH: Grants basic access to Bluetooth hardware for any functionality (connect, scan, advertise).
  • BLUETOOTH_SCAN: Introduced in Android 12 (API 31), allows scanning for devices without needing location permission. You can still choose to declare ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION for better filtering based on distance.
  • ACCESS_FINE_LOCATION (Android 6–11): Required for BLE scans due to potential for inferring user location, even if your app doesn’t explicitly use location data.
  • ACCESS_COARSE_LOCATION (Android 12+): Optional for most cases, but recommended for better filtering by distance if you also have ACCESS_FINE_LOCATION.

iOS:

  • NSBluetoothPeripheralUsageDescription: This key in your Info.plist file describes the purpose of using Bluetooth Low Energy for background scanning. Be clear and specific about why your app needs to scan in the background.
  • Background Modes: Enable the “Core Bluetooth LE Scan” background mode in your project’s Capabilities tab. This informs the OS that your app needs to perform BLE scans while in the background, and allows users to approve this functionality explicitly.

Additional Considerations:

  • Android 11: Apps targeting Android 11 can no longer obtain “Allow All the Time” permission for Location or BLE scanning directly. Users need to manually enable background access through Settings after granting initial permission.
  • Battery usage: Background scanning can drain battery significantly. Make sure your app uses efficient scanning techniques and only scans when necessary.
  • User privacy: Be transparent about the purpose of background scanning and clearly explain the benefits to users. Consider providing ways for users to control background scanning behavior within your app.

Share your thoughts on the Tesla BLE setup and how it can be implemented in practical use cases.
Happy learning!

Originally published at http://shankarkumarasamy.blog on January 29, 2024.

--

--

Shankar Kumarasamy

Mobile application and connected-devices development consultant. Enthusiastic and excited about digital transformation era.