## Audio Switch

As users increasingly utilize multiple audio source devices to perform their
daily tasks, there's growing demand for a simpler solution to manage headset
use across devices. Audio switch seamlessly transitions headset connections
between devices based on user activity (e.g. starting a movie) and prioritized
events (e.g. an incoming call).

### UX Principles

1. Connection switching should be fast and based on user action.
2. Connection switching should be transparent to users, allowing users to control/revert if the switching is undesirable.
3. Switching should respect user privacy.

### Roles

*Audio Switch Seeker*: The Seeker is an audio source device (for example, a
phone or tablet), looking for a nearby headset to connect with when applicable.

*Audio Switch Provider*: The Provider is normally a headset advertising its
presence and connection status for Seekers to make switching decisions.

### Requirements Overview

To achieve smart switching, Providers must adhere to the following requirements:

| Name | Description | Requirements | Mandatory? |
|---|---|---|---|
| Page Scan | To accept a new connection request from another Seeker when there is an existing connection. For single-point Providers: - The original source device will automatically pause its audio playback when the Provider is disconnecting. For multipoint Providers: - If there is still an available connection, it will accept the connection request. - If the connection bandwidth is full, disconnect the least recently used connection (e.g. no audio event for a long time), and accept the new incoming request. | Low latency page scan mode (scan interval should be no larger than 640 ms) is required to improve the performance. To make a trade-off between battery life and switching performance, the Provider can have a default page scan mode for most cases (low-power mode, scan interval should be no larger than 1280 ms). But low latency mode must be used in following situations: - First 30 seconds of power on - First 30 seconds of no connection or paging - First 30 seconds of device idle | Mandatory |
| Connection history | To switch back to the previous connection and resume playing if applicable. Switching back will be triggered by communications via Message Stream APIs. The pausing audio event should be included in the record to resume playing if applicable. | Maintain connection history and implement Message Stream APIs. | Mandatory |
| Connection status | For Seekers to do the connection switching judgment.The connection status includes: - Connection state - Audio type of the active connection - Account information of the active connection - Connected device(s) | Include connection status in BLE Advertisement and Message Stream. | Mandatory |
| Runtime capabilities change | Audio switch can be enabled by upgrading firmware on the Provider, so the capabilities need to be synchronized between Seeker and Provider at runtime. | Implement Message Stream APIs to access runtime capabilities. | Mandatory |
| Configurable switching rules | Let Seeker configure the priority between existing active audio streaming and new audio streaming requests via user preference settings. For example, the audio switch Seeker may provide UI settings to let users enable/disable automatic switching between media streaming and calling. Audio switch Seeker will set and get the switching rule via Message Stream. | Multipoint Providers only. Implement Message Stream APIs to make switching rules between connected devices configurable. | Optional |
| Active device switching | Let Audio switch Seeker simulate Audio switching between connected devices. On the Audio switch Seeker side, there may be a UI for users to easily switch between connected devices. | Multipoint Providers only. Implement Message Stream APIs for Audio switch Seeker to determine the active audio source between connected devices. | Mandatory |
| Multipoint switching notification | Let the Audio switch Seeker show the switching notification. | Multipoint Providers only. Implement Message Stream APIs to notify connected Audio switch Seekers when a multipoint switching is taking place. | Mandatory |

### Advertising payload

The Provider shall include its current connection status in the advertisement,
built on top of the Fast Pair Account data described in
[Advertising: When not discoverable](https://developers.google.com/nearby/fast-pair/specifications/service/provider#AdvertisingWhenNotDiscoverable "Advertizing when not discoverable").

Note that the version of [table 4.2](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#table4.2) is 0x1.

#### Connection Status Field

| Octet | Data type | Description | Value | Mandatory? |
|---|---|---|---|---|
| 0 | `uint8` | Field length and type 0bLLLLTTTT - L = length of connection status in bytes - T = type | 0bLLLL0101 - length: *varies* - type = 0b0101 | Mandatory |
| 1 | `uint8` | Connection state 0bHAFRSSSS - H = on head detection - A = connection availability - F = focus mode - R = auto-reconnected - S = connection state | 0bHAFRSSSS - for 0bHAFR, see [Connection Flags](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassConnectionFlags) - for 0bSSSS, see [connection state](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassConnectionState) | Mandatory |
| 2 | `uint8` | Custom data Currently, it only contains content type which is used to describe the usage of current audio streaming. The Seeker will send it to the Provider. | The value is sent from the Seeker of current active streaming to the Provider via message stream. 0 if the current active streaming is not from Seeker. | Mandatory |
| 3 - *var* |   | Connected devices bitmap A bitmap to show which devices are currently connected to the Provider. All bonded devices are arranged in order, one bit for one bonded device. The length will depend on how many bonded devices of the Provider there are. | The mapped bit set to 1 if the device is currently connected to the Provider, 0 otherwise. See [Connected Device Bitmap](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassConnectedDeviceBitmap) for details | Optional |

***Table 4.1:** Connection status field raw data*

##### Connection Flags

- 0bH = on head detection

  - 1, on head now
  - 0, otherwise, not on head or there is no OHD sensor
- 0bA = connection availability

  - 1, there is an available connection
  - 0, otherwise
- 0bF = focus mode

  - 1, in focused mode now, connection switching is not allowed for media usage, i.e. no A2DP to A2DP switching
  - 0, otherwise
- 0bR = auto-reconnected

  - 1, if the current connection is auto-reconnected by the Provider, meaning it is not connected by users (for multipoint, if one of the existing connections is auto-reconnected, it should be set to 1)
  - 0, otherwise

##### Connection state

- 0x0: no connection
- 0x1: paging
- 0x2: connected but no data transferring
- 0x3: Non-audio data transferring (only when switchable, if not, using 0xF)
- 0x4: A2DP streaming, AVRCP not applicable
- 0x5: A2DP streaming and AVRCP playing
- 0x6: HFP (phone/voip call) streaming, including inband and non-inband ringtone
- 0x7: LE audio - media streaming without control
- 0x8: LE audio - media streaming with control
- 0x9: LE audio - call streaming
- 0xA: LE audio - broadcast
- 0xF: Disable connection switch temporarily (e.g. firmware update)

##### LE Audio Context Type and Connection state

Recommend the LE Audio Provider should handle all of the context types specified
in [Assigned Numbers 6.12.3](https://www.bluetooth.com/specifications/assigned-numbers/)
(unless the Provider explicitly does not support a given context type) and map
the context type to the connection state as below.

- Conversational: 0x9
- Media: 0x8
- Game: 0x7
- Instructional: 0x7
- Voice Assistants: 0x9
- Live: 0x9
- Sound Effects: 0x2
- Notifications: 0x2
- Ringtone: 0x9
- Alerts: 0x7
- Emergency Alarm: 0x9

For the mixed LE Audio context type scenario such as playing media during the
call, Provider shall use the connection state with highest priority, i.e. use
0x9 (call) for above scenario instead of 0x8 (media).

##### Connected Device Bitmap

To avoid undesired connection switching, the Seeker may need to know which
device(s) the headset is currently connected to. For example, when the headset
is connected to the phone, the user doesn't want to be interrupted by the
connection switching when one of their family members starts YouTube on the
tablet.

Note that this bitmap is anonymous, the Seeker is unable to know what other
devices are bonded with the Provider. For example, take 5 bonded devices:

- 0: laptop (0bx0000000)
- 1: phoneA (0b0x000000)
- 2: phoneB (0b00x00000)
- 3: tablet (0b000x0000)
- 4: TV (0b0000x000)

If the current connected devices are a laptop and a tablet, the value of the
bitmap will be 0b10010000. The order change is acceptable if it is unavoidable,
e.g. when users factory reset the headset or when the bonded device count
reaches the upper limit.

#### Random Resolvable Advertisement

> [!NOTE]
> **Note:** Google recommends implementing the [Cryptographic Test Cases](https://developers.google.com/nearby/fast-pair/specifications/appendix/cryptotestcases "Link to the Cryptographic Test Cases.") to ease verification of these requirements.

To avoid tracking and respect user privacy, the Provider should rotate and
encrypt the field by the account key using AES-CTR:

     encrypted_connection_status_field = connection_status_raw_data ^ AES(Key, IV)

where

1. Key is derived from the [in use account key](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassInUseAccountKey), which
   is defined in the next section.

   - Key is generated by the HKDF function, IETF RFC 5869, using the SHA-256
     hash function.

           Key = HKDF(account_key, NULL, UTF8("SASS-RRD-KEY"),16)

   - Provider shall use the original account key here, i.e. the first byte
     of the key is 0x04, not included in use pattern.

2. IV (initial vector) is the 2-byte salt of Account Key Data with zero
   padding, i.e. IV is concat(salt, 14-byte ZEROs).

3. Connection status raw data is defined in [table 4.1](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#table4.1), if the
   connection status changes, the salt and RPA should be regenerated at the
   same advertising time frame.

This makes the encrypted connection status field rotate at the same time as the
Account Key Data rotates.

The BLE advertisement will be structured as below:

| Octet | Data type | Description | Value | Mandatory? |
|---|---|---|---|---|
| 0 | `uint8` | Version and flags | 0x10 | Mandatory |
| 1 - *t* |   | Account Key Data | *varies* | Mandatory |
| *t+1* - *s* |   | Battery Data | *varies* | Optional |
| *s+1* - *var* |   | Random Resolvable Data | *varies* | Mandatory if the Account Key List is not empty, otherwise Excluded. |

***Table 4.2:** BLE advertisement with Random Resolvable Data*

Random Resolvable Data contains:

| Octet | Data type | Description | Value | Mandatory? |
|---|---|---|---|---|
| 0 | `uint8` | Field length and type 0bLLLLTTTT - L = length of encrypted data - T = type | 0bLLLL0110 - length: *varies* - type = 0b0110 | Mandatory |
| 1 - *var* |   | Encrypted data | *varies* | Mandatory |

***Table 4.2.1:** Random Resolvable Data*

As an example, if the Random Resolvable Data contains an encrypted connection
status field, the decrypted result will be the
[connection status field](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassConnectionStatusField).

To prevent tampering, the Account Key Data above should be slightly modified
when the Random Resolvable Data is included in the advertisement. Normally, when
building the account key filter, a value V is produced by combining the account
key filter with a salt. Instead, when Random Resolvable Data is also being
advertised, the value V should be constructed as:

     V = concat(account_key, salt, random_resolvable_data)

If both Battery Data and Random Resolvable Data are being advertised, V should
be constructed as:

     V = concat(account_key, salt, battery_data, random_resolvable_data)

#### In Use Account Key

The connection switching is account-based, so the Provider should include the
account information of the current connection in the BLE advertisement. If the
current connected device is a Audio switch Seeker, the Provider should be able
to get the account key associated with this Seeker, and use this account key to
encrypt the connection status field. If the connected audio source is non-Audio
switch Seeker, the Provider should use the most recently used account key.

Before computing the [account key filter](https://developers.google.com/nearby/fast-pair/specifications/service/provider#AccountKeyFilter "Account Key Filter"), the Provider should modify the first
byte of the account keys to include one of the following in use patterns:

1. 0b00000100  
   This account key is not in use.  
   This is the default one (see [Account key](https://developers.google.com/nearby/fast-pair/specifications/characteristics#AccountKey "Account Key")).
2. 0b00000101  
   This account key is the most recently used account key.  
   The connection status field is encrypted by this account key. There is no account key information of the current connection state, it could mean no devices connected or the connected device is not an Audio switch Seeker.
3. 0b00000110  
   This account key is the in use account key.  
   The connection status field is encrypted by this account key, and the current connected device is associated with this account key.

> [!NOTE]
> **Note:** the in use pattern is only for computing the account key filter, and should not be stored back. The stored account key should be the original one which is assigned at pairing.

#### Schematic for Audio switch payload

The figure below shows the schematic for Audio switch payload.
![](https://developers.google.com/nearby/fast-pair/images/SASS-ble-payload-schematic.png)

### Messages

When connected, Seeker and Provider can use the [Message stream](https://developers.google.com/nearby/fast-pair/specifications/extensions/messagestream#MessageStream "Message Stream") to sync Audio
switch capability, trigger a connection switch, set and get the switching
preference, notify connection status and so on. We create a message group and
message codes specific for Audio switch as below.

| Message Group Name | Value |
|---|---|
| Audio switch | 0x07 |

Additional details for each message code are included in the following sections.

| Message Code Name | Value | Multipoint only | Sender | Responder | Encrypt | MAC | ACK |
|---|---|---|---|---|---|---|---|
| [Get capability of Audio switch](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#GetCapabilityOfSass) | 0x10 | N | Both | Both, via code 0x11 | N | N | N |
| [Notify capability of Audio switch](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#NotifyCapabilityOfSass) | 0x11 | N | Both | Both | N | Y | Y |
| [Set multipoint state](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SetMultipointState) | 0x12 | Y | Seeker | Provider | N | Y | Y |
| [Set switching preference](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SetSwitchingPreference) | 0x20 | Y | Seeker | Provider | N | Y | Y |
| [Get switching preference](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#GetSwitchingPreference) | 0x21 | Y | Seeker | Provider, via code 0x22 | N | N | N |
| [Notify switching preference](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#NotifySwitchingPreference) | 0x22 | Y | Provider | Seeker | N | N | N |
| [Switch active audio source(to connected device)](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SwitchActiveAudioSource) | 0x30 | Y | Seeker | Provider | N | Y | Y |
| [Switch back](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SwitchBack) | 0x31 | N | Seeker | Provider | N | Y | Y |
| [Notify multipoint-switch event](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#NotifyMultipointSwitchEvent) | 0x32 | Y | Provider | Seeker | N | N | N |
| [Get connection status](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#GetConnectionStatus) | 0x33 | Y | Seeker | Provider, via code 0x34 | N | N | N |
| [Notify connection status](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#NotifyConnectionStatus) | 0x34 | Y | Provider | Seeker | Y | N | N |
| [Notify Audio switch initiated connection](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#NotifySassInitiatedConnection) | 0x40 | N | Seeker | Provider | N | Y | Y |
| [Indicate in use account key](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#IndicateInUseAccountKey) | 0x41 | N | Seeker | Provider | N | Y | Y |
| [Send custom data](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SendCustomData) | 0x42 | N | Seeker | Provider | N | Y | Y |
| [Set drop connection target](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SetDropConnectionTarget) | 0x43 | Y | Seeker | Provider | N | Y | Y |

***Table 4.3:** Audio switch messages*

#### MAC of Audio switch Messages

To provide message authentication, all Audio switch messages with additional
data sent from Seeker to Provider require a [Message Authentication Code](https://developers.google.com/nearby/fast-pair/specifications/extensions/mac#MacOfMessageStream "MAC"). When
a message with MAC is received, it should be [acknowledged](https://developers.google.com/nearby/fast-pair/specifications/extensions/acknowledgement#MessageStreamAcknowledgements "Message Stream Acknowledgements") so that the Seeker
knows whether or not the Provider has reacted to the message.

If message authentication succeeds, the Provider shall send the ACK for the
message:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Acknowledgement | 0xFF |
| 1 | uint8 | ACK | 0x01 |
| 2 - 3 | uint16 | Additional data length | *varies* |
| 4 | uint8 | Audio switch | 0x07 |
| 5 | uint8 | Audio switch message code | *varies* |
| 6 - *s* |   | Additional data | *varies* |

If it fails, the Provider shall send the NAK for the message:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Acknowledgement | 0xFF |
| 1 | uint8 | NAK | 0x02 |
| 2 - 3 | uint16 | Additional data length | 0x0003 |
| 4 | uint8 | Error reason | *varies* |
| 5 | uint8 | Audio switch | 0x07 |
| 6 | uint8 | Audio switch message code | *varies* |

Note that, if the Provider is the sender, MAC is not required.

#### Get capability of Audio switch

Both the Audio switch Provider and Seeker can check if the connected Fast Pair
Seeker/Provider supports Audio switch or not by using the below message:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Get capability of Audio switch | 0x10 |
| 2 - 3 | uint16 | Additional data length | 0 |

***Table 4.3.1.0:** Get capability of Audio switch*

#### Notify capability of Audio switch

Upon receiving [get capability of Audio switch](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#GetCapabilityOfSass) message
code, the Audio switch Seeker/Provider will respond with one of the following
flags:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Notify capability of Audio switch | 0x11 |
| 2 - 3 | uint16 | Additional data length | 20 if this is sent by Seeker 4 if this is sent by Provider |
| 4 - 5 | uint16 | Audio switch version code | A non-zero value means it supports Audio switch. Current version (with the security enhancement) code is 0x0102. 0x0000 or no response in 1 second means Audio switch is not supported on this device |
| 6 - 7 | flags | Audio switch capability flags of the Provider If this is sent by Seeker, these two bytes should be ignored. | *varies* See [Audio switch capability flags](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassCapabilityFlags) |
| 8 - 15 |   | Message nonce Only required when this is sent by Seeker | *varies* |
| 16 - 23 |   | Message authentication code Only required when this is sent by Seeker | *varies* |

***Table 4.3.1.1:** Notify capability of Audio switch*

##### Audio switch capability flags

1. Bit 0 (octet 6, MSB): Audio switch state

   - 1, if Audio switch state is on
   - 0, otherwise
2. Bit 1: multipoint configurability

   - 1, if the device supports multipoint and it can be switched between on and off
   - 0, otherwise (does not support multipoint or multipoint is always on)
3. Bit 2: multipoint current state

   - 1, if multipoint is on
   - 0, otherwise
4. Bit 3: on-head detection

   - 1, if this device supports on-head detection (even if on-head detection is turned off now)
   - 0, otherwise
5. Bit 4: on-head detection current state

   - 1, if on-head detection is turned on
   - 0, otherwise (does not support on-head detection or on-head detection is disabled)
6. All the other bits are reserved, default 0.

#### Set multipoint state

On Audio switch Seekers, we may provide the setting for users to turn on/off
multipoint functionality. The Seeker will set the multipoint state to the
Provider using the below message:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Set multipoint state | 0x12 |
| 2 - 3 | uint16 | Additional data length | 17 |
| 4 | uint8 | Multipoint state | 0: switch off multipoint 1: switch on multipoint |
| 5 - 12 |   | Message nonce | *varies* |
| 13 - 20 |   | Message authentication code | *varies* |

***Table 4.3.1.2:** Set multipoint state*

#### Set switching preference

Audio switch Seekers may modify the switching preference of multipoint and set
it to the Provider using the below message:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Set switching preference | 0x20 |
| 2 - 3 | uint16 | Additional data length | 18 |
| 4 | flags | Switching preference | *varies* See [multipoint switching preference flag](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#MultipointSwitchingPreferenceFlag) |
| 5 |   | Advanced switching settings This byte is reserved, default value is 0 | *varies* |
| 6 - 13 |   | Message nonce | *varies* |
| 14 - 21 |   | Message authentication code | *varies* |

***Table 4.3.2.0:** Set switching preference*

##### Multipoint switching preference flag

- Bit 0 (MSB): A2DP vs A2DP (default 0)
- Bit 1: HFP vs HFP (default 0)
- Bit 2: A2DP vs HFP (default 0)
- Bit 3: HFP vs A2DP (default 1)
- Bit 4 - 7: reserved
- Above represents as "new profile request" vs "current active profile"
  - 0 for not switching
  - 1 for switching

#### Get switching preference

Audio switch Seekers can query the switching preference of multipoint from the
Provider using the below message:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Get switching configuration | 0x21 |
| 2 - 3 | uint16 | Additional data length | 0 |

***Table 4.3.2.1:** Get switching preference*

#### Notify switching preference

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Notify switching preference | 0x22 |
| 2 - 3 | uint16 | Additional data length | 2 |
| 4 | flags | Switching preference flags | *varies* See [multipoint switching preference flag](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#MultipointSwitchingPreferenceFlag) |
| 5 |   | Advanced switching settings This byte is reserved, default value should be 0 | *varies* |

***Table 4.3.2.2:** Notify switching preference*

#### Switch active audio source (to connected device)

Audio switch Seekers can request the multipoint Provider to switch the active
audio source between connected devices using the below message:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Switch active audio source (to connected device) | 0x30 |
| 2 - 3 | uint16 | Additional data length | 17 |
| 4 | flags | Switching active audio source event flags | *varies* See [switching active audio source event](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SwitchingActiveAudioSourceEvent) |
| 5 - 12 |   | Message nonce | *varies* |
| 13 - 20 |   | Message authentication code | *varies* |

***Table 4.3.3.0:** Switch active audio source (to connected device)*

##### Switching active audio source event

- Bit 0 (MSB): 1 switch to this device, 0 switch to second connected device
- Bit 1: 1 resume playing on switch to device after switching, 0 otherwise. Resuming playing means the Provider sends a PLAY notification to the Seeker through AVRCP profile. If the previous state (before switched away) was not PLAY, the Provider should ignore this flag.
- Bit 2: 1 reject SCO on switched away device, 0 otherwise
- Bit 3: 1 disconnect Bluetooth on switch away device, 0 otherwise.
- Bit 4 - 7: reserved.

Audio switch Seekers may not always know their state correctly, so it's possible
for the Provider to receive a "switch to this device" message when the Seeker is
already the active device. In this case, to show the correct UI on Seeker, the
Provider can send a NAK with the error reason, 0x4 - Redundant device action.

For a LE Audio Provider who has more than one set member, the Provider should
disconnect all the members from the Seeker, otherwise the bluetooth stack of the
Seeker would reconnect to the Provider.

#### Switch back (to disconnected device)

If the connection switching is unwanted, users can revert the switching, and in
certain scenarios, it makes sense to restore the audio connection to minimize
disruption. The Seeker will use the below message to trigger switching back:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Switch back (to disconnected device) | 0x31 |
| 2 - 3 | uint16 | Additional data length | 17 |
| 4 | uint8 | Switch back event | *varies* 0x01: switch back 0x02: switch back and resume playing |
| 5 - 12 |   | Message nonce | *varies* |
| 13 - 20 |   | Message authentication code | *varies* |

***Table 4.3.3.1:** Switch back (to disconnected device)*

For multipoint Providers, to do a connection switch, a Provider may drop the
connection with one audio source device and pause the audio session on the other
audio source. For example, assume the multipoint headset is connected to a
tablet and a 3rd supported Audio switch device. The user is watching video on
the tablet when there is an incoming call on their phone. The phone will trigger
a connection switch on the headset, which needs to drop the 3rd device's
connection in order to connect to the phone, while also pausing the media
session on the tablet to get the ringtone from the phone. If the user declines
the call, the phone may ask the headset to "switch back and resume playing".
Upon receiving this request, the headset must reconnect to the 3rd device, and
resume playing of the paused video on the tablet.

> [!NOTE]
> **Note:** Provider can ignore the back message if the last disconnection happened more than 3 minutes ago.

#### Notify multipoint-switch event

To make users aware of a multipoint-switch event taking place, the Audio switch
Seeker may show a notification to users. The Provider should notify connected
Audio switch Seekers about the switching event.

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Notify multipoint-switch event Provider should send it on every switch, including Audio switch Seeker to non-Audio switch Seeker, non-Audio switch Seeker to Audio switch Seeker and Audio switch Seeker to Audio switch Seeker | 0x32 |
| 2 - 3 | uint16 | Additional data length | *varies* |
| 4 | uint8 | Switching reason This value should be determined based on [Connection state](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassConnectionState). For LE Audio use-cases, looking into the mapping between [LE Audio Context Type and Connection state](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#LeaContextTypeAndSassConnectionState) may be useful. For example, the connection state corresponding to Voice Assistants is 0x9(LE audio - call streaming). So, the switching reason for a switch initiated by Voice Assistants should be 0x02. | *varies* 0x00: Unspecified 0x01: Media (e.g. A2DP streaming, LEA media streaming) 0x02: Call (e.g. HFP streaming, LEA call streaming) |
| 5 | uint8 | Target device | *varies* 0x01: this device 0x02: another connected device |
| 6 - n | utf8 | Target device name if the target device is Audio switch Seeker, using the name the Seeker sent to, otherwise using the BT name, if not applicable, using last 2 bytes of its address | *varies* |

***Table 4.3.3.2:** Notify multipoint-switch event*

#### Get connection status

The Seeker can get the current connection status from the Provider:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Get connection status | 0x33 |
| 2 - 3 | uint16 | Additional data length | 0 |

***Table 4.3.3.3:** Get connection status*

Upon receiving this message, the Provider shall respond by the message code
0x34, [notify connection status](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#NotifyConnectionStatus).

#### Notify connection status

As defined in BLE [advertising payload](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassConnectionStatusField), for
multipoint Providers, if the connection status changes, except for changing
advertising packet, the Provider should also notify the connected Seekers which
are using the same account key about the change. If the Provider is connected
with an Audio switch Seeker and a non-Audio switch Seeker, if the non-Audio
switch Seeker is active, the Provider should also notify the connected Audio
switch Seeker about the connection status (using the Seeker's account key).

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Notify connection status | 0x34 |
| 2 - 3 | uint16 | Additional data length | *varies* |
| 4 | uint8 | Active device flag | *varies* 0x00: this Seeker is passive, and the active device is using the same account key 0x01: this Seeker is the active device 0x02: this Seeker is passive, and the active device is non-Audio switch Seeker. |
| 5 - n |   | [Encrypted connection status](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#EncryptedConnectionStatusMessage) | *varies* |
| n+1 - n+8 |   | Message nonce | *varies* |

***Table 4.3.3.4:** Notify connection status*

#### Encrypted connection status message

     encrypted_connection_status = connection_status_raw_data ^ AES(Key, IV)

where:

- Key is derived from the in use account key, see
  [Random Resolvable Advertisement](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassRandomResolvableAdvertisement).

       Key = HKDF(account_key, NULL, UTF8("SASS-RRD-KEY"),16)

- IV is concat(Session_nonce, Message_nonce)

- connection_status_raw_data = concat(connection_state, custom_data,
  connected_devices) which is defined in BLE
  [advertising payload](https://developers.google.com/nearby/fast-pair/specifications/extensions/sass#SassConnectionStatusField)
  Note that the byte for field length and type should not be included since
  we have message code and data length here.

#### Notify Audio switch initiated connection

Audio switch Providers may need to know if the connection switching is triggered
by Audio switch to have different reactions, e.g. disable earcons for Audio
switch events. The Seeker sends a message to notify the Provider that this
connection was an Audio switch initiated connection.

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Notify Audio switch initiated connection | 0x40 |
| 2 - 3 | uint16 | Additional data length | 17 |
| 4 | uint8 | Audio switch initiated connection indication | *varies* 0: this connection was not triggered by Audio switch 1: this was an Audio switch initiated connection |
| 5 - 12 |   | Message nonce | *varies* |
| 13 - 20 |   | Message authentication code | *varies* |

***Table 4.3.4.0:** Notify Audio switch initiated connection*

#### Indicate in use account key

If multiple account keys on the Seeker (e.g. multi-users) are associated with
the Provider, the Seeker will use the below message to indicate which account
key is in use.

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Indicate in use account key | 0x41 |
| 2 - 3 | uint16 | Additional data length | 22 |
| 4 - 9 | utf8 | In use string | UTF8 ("in-use") |
| 10 - 17 |   | Message nonce | *varies* |
| 18 - 25 |   | Message authentication code | *varies* |

***Table 4.3.4.1:** Indicate in use account key*

Upon receiving this message, the Provider can know which account key is in use
by verifying the message authentication code.

#### Send custom data

The active Audio switch Seeker can encapsulate the information (e.g. audio
usage) of audio stream in custom data byte, and send it to the Provider by using
the below message:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Send custom data | 0x42 |
| 2 - 3 | uint16 | Additional data length | 17 |
| 4 | uint8 | Custom data | *varies* |
| 5 - 12 |   | Message nonce | *varies* |
| 13 - 20 |   | Message authentication code | *varies* |

***Table 4.3.4.2:** Send custom data*

Upon receiving the custom data, the Provider will update the advertising packet
to include the custom data. For a multipoint Provider, it should also notify the
connection status change to another connected Seeker using the same account key.

#### Set drop connection target

On multipoint headsets, if the preferred connection to be dropped is not the
least recently used one, Audio switch Seekers can tell the Provider which device
to drop using the below message:

| Octet | Data Type | Description | Value |
|---|---|---|---|
| 0 | uint8 | Audio switch | 0x07 |
| 1 | uint8 | Set drop connection target | 0x43 |
| 2 - 3 | uint16 | Additional data length | 17 |
| 4 | uint8 | Target connected device to be dropped | *varies* 1: this device |
| 5 - 12 |   | Message nonce | *varies* |
| 13 - 20 |   | Message authentication code | *varies* |

***Table 4.3.4.3:** Set drop connection target*