Bluetooth Classic Accessory Interface Specification


Overview

The Bluetooth Classic Accessory Interface Specification defines how a mobile device (such as Android phone) communicates with a BlueParrott headset using Bluetooth Classic through an AT‑command–based interface. At the core of the interface is a structured set of AT commands exchanged over the Classic Bluetooth link. This design uses standardized and vendor‑specific AT command prefixes to organize functional areas, with each command representing a specific feature or data channel. AT commands define what the headset exposes such as button events, mode changes, logs, sensor values, or model information, and specify whether the application can query, configure, or receive event notifications through the Bluetooth Classic connection.

Read Commands

Command Description Command Definition Response Definition
INIT Sent to headset to request Init Response AT+ANDROID: BP, INIT AT+ANDROID=BP, MODE, mode
AT+ANDROID=BP, BONDABLE, bondable
AT+ANDROID=BP, SPEEDDIAL, speed dial #
AT+ANDROID=BP, APPNAME, app name
AT+ANDROID=BP, APPKEY, app key
AT+ANDROID=BP, MODEL, model
AT+ANDROID=BP, PBVERSION, pb version
AT+ANDROID=BP, FWVERSION, fw version
AT+ANDROID=BP, CMFBVERSION, cmfb version
AT+ANDROID=BP, S1STATE, sensor state
AT+ANDROID=BP, S2STATE, sensor state
AT+ANDROID=BP, S3STATE, sensor state
AT+ANDROID=BP, VERBOSITY, verbosity
AT+ANDROID=BP, TXNR, tx noise reduction mode
AT+ANDROID=BP, TXGAIN, tx gain mode
AT+ANDROID=BP, TEMPERATURE, temperature value in °C
AT+ANDROID=BP, ENDINIT
AT+ANDROID=BP, ENTKEY1, Enterprise Key 1
AT+ANDROID=BP, ENTKEY2, Enterprise Key 2
AT+ANDROID=BP, ENTKEY3, Enterprise Key 3
AT+ANDROID=BP, ENDENTINIT
STATE Sent to headset to request State Response AT+ANDROID: BP, STATE AT+ANDROID=BP, MODE, mode
AT+ANDROID=BP, BONDABLE, bondable
AT+ANDROID=BP, SPEEDDIAL, speed dial #
AT+ANDROID=BP, APPNAME, app name
AT+ANDROID=BP, APPKEY, app key
AT+ANDROID=BP, MODEL, model
AT+ANDROID=BP, PBVERSION, pb version
AT+ANDROID=BP, FWVERSION, fw version
AT+ANDROID=BP, CMFBVERSION, cmfb version
AT+ANDROID=BP, S1STATE, sensor state
AT+ANDROID=BP, S2STATE, sensor state
AT+ANDROID=BP, S3STATE, sensor state
AT+ANDROID=BP, VERBOSITY, verbosity
AT+ANDROID=BP, TXNR, tx noise reduction mode
AT+ANDROID=BP, TXGAIN, tx gain mode
AT+ANDROID=BP, TEMPERATURE, temperature value in °C
AT+ANDROID=BP, ENDSTATE
AT+ANDROID=BP, ENTKEY1, Enterprise Key 1
AT+ANDROID=BP, ENTKEY2, Enterprise Key 2
AT+ANDROID=BP, ENTKEY3, Enterprise Key 3
AT+ANDROID=BP, ENDENTSTATE

Write Commands

Command Description Values Command Definition
MODE Sent to headset to write the button Mode key, see VXI_BUTTON_MODE, mode is the string representation of a decimal number 0: Mute
2: SDK Mode
7: Voice Control
12: Check Battery
41: Second MFB
46: Answer/End Calls
AT+ANDROID: BP, MODE, mode
BONDABLE Sent to headset to write the Bondable key, see VXI_BONDABLE, bondable is the string representation of a decimal number 0: not bondable
1: bondable
AT+ANDROID: BP, BONDABLE, bondable
SPEEDDIAL deprecated deprecated deprecated
APPNAME Sent to headset to write the App Name key, see VXI_APPNAME, app name is the application name as a string, maximum of 22 characters. Note that strings must be packed into / unpacked from the memory location. Chip memory is 16 bits wide, so 2 chars / WORD AT+ANDROID: BP, APPNAME, app name
APPKEY Sent to headset to write the App ID key, see VXI_APPID, is a string representing the application type (kdk, esc), maximum of 22 characters. Note that strings must be packed into / unpacked from the memory location. Chip memory is 16 bits wide, so 2 chars / WORD AT+ANDROID: BP, APPKEY, app key
ENTKEY1 Sent to headset to write Enterprise Key 1, see BP_ENT_1, Enterprise Key 1 is a 16 bit decimal value AT+ANDROID: BP, ENTKEY1, Enterprise Key 1
ENTKEY2 Sent to headset to write Enterprise Key 2, see BP_ENT_2, Enterprise Key 2 is a 16 bit decimal value AT+ANDROID: BP, ENTKEY2, Enterprise Key 2
ENTKEY3 Sent to headset to write Enterprise Key 3, see BP_ENT_3, Enterprise Key 3 is a 16 bit decimal value AT+ANDROID: BP, ENTKEY3, Enterprise Key 3
VERBOSITY Sent to headset to set the verbosity level AT+ANDROID:BP, VERBOSITY, level
BLE_ADVERTISE_ON Sent to headset to enable/disable BLE advertisement AT+ANDROID: BP, BLE_ADVERTISE_ON, boolean
CLASSIC_PTT_ON Sent to headset to enable/disable Classic PTT AT+ANDROID: BP, CLASSIC_PTT_ON, boolean
PTTOC_ON Sent to headset to enable/disable Push-to-Talk over Cellular AT+ANDROID: BP, PPTOC_ON, boolean
SHARED_DEVICE_MODE Sent to the headset to enable/disable shared device mode AT+ANDROID: BP, SHARED_DEVICE_MODE, boolean
QR_CODE_SCAN_MODE Sent to the headset to enable/disable QR Code mode AT+ANDROID: BP, QR_CODE_SCAN_MODE, boolean
TX_DSP_MODE Set microphone noise suppression mode 0: High
1: Medium (Default)
2: Off
AT+ANDROID=BP,TXNR, mode
TX_GAIN_MODE Set microphone gain mode 0: -5dB
1: -4dB
2: -3dB
3: -2dB
4: -1dB
5: 0dB
6: 1dB
7: 2dB
8: 3dB
9: 4dB
10: 5dB
255: AGC (Auto Gain Control)
AT+ANDROID=BP,TXGAIN, mode

Notify Commands

Command Description Values Payload
TEMPERATURE Send notification to client when the temperature changes its value +/-1 deg C° AT+ANDROID=BP, TEMPERATURE, temperature value in °C

Message Complete

Command Description Response Definition
ENDINIT Sent from headset to indicate end of Init Response AT+ANDROID=BP, ENDINIT
ENDSTATE Sent from headset to indicate end of State Response AT+ANDROID=BP, ENDSTATE
ENDENTINIT Sent from headset to indicate end of Enterprise Init Response AT+ANDROID=BP, ENDENTINIT
ENDENTSTATE Sent from headset to indicate end of Enterprise State Response AT+ANDROID=BP, ENDENTSTATE

Button Events

Command Description Response Definition
PTT,P When the Parrott button is pressed AT+ANDROID=BP, PTT,P
PTT,R When the Parrott button is released AT+ANDROID=BP, PTT,R
PTT,T When the Parrott button is single tapped AT+ANDROID=BP, PTT,T
PTT,D When the Parrott button is double tapped AT+ANDROID=BP, PTT,D
PTT,L When the Parrott button is long pressed AT+ANDROID=BP, PTT,L
PTT,P When the Parrott button is pressed AT+ANDROID=BP, PTT,P

Log Events

Command Description Response Definition
BP_LOG Logging message from the headset AT+ANDROID=BP,BP_LOG,key:value


Monitor and Parse AT Commands from Headset [Code Sample]


The following example monitors Broadcast Receiver class Intents sent when the OS receive an AT Command over SPP. Prior to subscribing to the intent, use the filter to select the category(ies) and Action(s) that are needed – in the below example the usage it to monitor Jabra/Blueparrott events which uses Google’s Assigned number (+ANDROID) and Plantronics' Assigned number to monitor KODIAK events. It also listens to actions such as HEADSET_EVENT along with ACL_DISCONNECTED. The section pertaining to the parsing of the command and the action corresponding to each can be customized to fit the supported use cases and needs.



@SuppressLint("MissingPermission")
private void registerClassicReceivers() {
    IntentFilter btIntentFilter = new IntentFilter();
    Log.e(TAG, "registerClassicReceivers");
    /*
    Jabra / BlueParrott AT events uses +ANDROID (GOOGLE) suffix
    EXAMPLE: AT+ANDROID BP, PTT, P
    */
    btIntentFilter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "." + BluetoothAssignedNumbers.GOOGLE);
    /*
    OPTIONAL: The usage of PLANTRONICS is to monitor Kodiak AT commands
    */
    btIntentFilter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "." + BluetoothAssignedNumbers.PLANTRONICS);
    btIntentFilter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);
    btIntentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
    m_context.registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT.equals(action)) {
                Bundle eventExtras = intent.getExtras();
                if(eventExtras == null) {
                    return;
                }
                //get the arguments that the headset sent
                Object[] args = (Object[]) eventExtras.get(BluetoothHeadset.EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS);
                if (args == null) {
                    Log.e(TAG, "Null args for vendor specific event");
                    return;
                }
                String qualifier = (args.length >= 1) ? "" + args[0] : "";
                String eventName = (args.length >= 2) ? "" + args[1] : "";
                String data = (args.length >= 3) ? "" + args[2] : "";
                if (args.length == 3) {
                    Log.e(TAG, "[R]: " + qualifier + "," + eventName + "," + data);
                } else {
                    Log.e(TAG, "[R]: " + qualifier + "," + eventName);
                }
                data = data.toLowerCase();
                if (eventName.equals("PTT")) {
                    //PB EVENTS
                    if (data.equals("p")) {
                        handleButtonEvent(PB_BUTTON_DOWN);
                    } else if (data.equals("r")) {
                        handleButtonEvent(PB_BUTTON_UP);
                    } else if (data.equals("d")) {
                        handleButtonEvent(PB_BUTTON_DOUBLE_TAP);
                    } else if (data.equals("l")) {
                        handleButtonEvent(PB_BUTTON_LONG_PRESS);
                    } else if (data.equals("t")) {
                        handleButtonEvent(PB_BUTTON_TAP);
                    }
                }
            } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
                Log.e(TAG, "Headset got disconnected");
            }
        }
    }, btIntentFilter);
}
        

Send AT Commands to Headset [Code Sample]


private BluetoothHeadset mBluetoothHeadset = null; //init onServiceConnected
private BluetoothDevice mHfpDevice = null; // init based on adapter.getBondedDevices()
String command = "+ANDROID";
String args = agrs0 + "," + args1 + ", " + args2; //Example BP,MODE,2
When all combined:
AT+ANDROID:BP,MODE,2 → This will set the PB to a mode to send PTT events



@SuppressLint("MissingPermission")
private boolean sendVendorAT(BluetoothDevice device, String command, String args) {
    Log.d(TAG, "AT" + command + ":" + args);
    if (mHfpDevice == null ){
        Log.d(TAG, "mHfpDevice object is null");
        return false;
    }
    if (mBluetoothHeadset == null ){
        Log.d(TAG, "mBluetoothHeadset object is null");
        return false;
    }
    logStatus("AT" + command + ":" + args);
    return mBluetoothHeadset.sendVendorSpecificResultCode(device, command, args);
}