Bluetooth Driver services: Difference between revisions
No edit summary |
|||
(74 intermediate revisions by 5 users not shown) | |||
Line 215: | Line 215: | ||
|- | |- | ||
| 100 || [12.0.0+] [[#IsBluetoothEnabled]] | | 100 || [12.0.0+] [[#IsBluetoothEnabled]] | ||
|- | |||
| 101 || [15.0.0+] ForceEnableBluetooth | |||
|- | |||
| 102 || [15.0.0+] EnableBluetoothStub | |||
|- | |- | ||
| 128 || [12.0.0+] [[#AcquireAudioEvent]] | | 128 || [12.0.0+] [[#AcquireAudioEvent]] | ||
Line 248: | Line 252: | ||
| 143 || [12.0.0+] [[#GetAudioControlInputState]] | | 143 || [12.0.0+] [[#GetAudioControlInputState]] | ||
|- | |- | ||
| 144 || [12.0.0+] [[# | | 144 || [12.0.0-13.2.1] [[#AcquireAudioConnectionStateChangedEvent]] | ||
|- | |||
| 145 || [12.0.0-13.2.1] [[#GetConnectedAudioDevice]] | |||
|- | |||
| 146 || [13.0.0+] [[#CloseAudioControlInput]] | |||
|- | |||
| 147 || [13.0.0+] [[#RegisterAudioControlNotification]] | |||
|- | |||
| 148 || [13.0.0+] [[#SendAudioControlPassthroughCommand]] | |||
|- | |||
| 149 || [13.0.0+] [[#SendAudioControlSetAbsoluteVolumeCommand]] | |||
|- | |- | ||
| | | 150 || [14.0.0+] AcquireAudioSinkVolumeLocallyChangedEvent | ||
|- | |||
| 151 || [14.0.0+] AcquireAudioSinkVolumeUpdateRequestCompletedEvent | |||
|- | |||
| 152 || [14.0.0+] GetAudioSinkVolume | |||
|- | |||
| 153 || [14.0.0+] RequestUpdateAudioSinkVolume | |||
|- | |||
| 154 || [14.0.0+] IsAudioSinkVolumeSupported | |||
|- | |||
| 155 || [15.0.0+] IsAudioSinkVolumeSupported2 | |||
|- | |- | ||
| 256 || [5.0.0+] [[#IsManufacturingMode]] | | 256 || [5.0.0+] [[#IsManufacturingMode]] | ||
Line 275: | Line 299: | ||
This is used by [[BTM_services|btm]], this should not be used by other processes. | This is used by [[BTM_services|btm]], this should not be used by other processes. | ||
This first initializes the funcptr table interfaces to the defaults (same as [[#DisableBluetooth]]). [[Settings_services#GetConfigurationId1|GetConfigurationId1]] is used, an error is thrown if the output string is empty, or if it matches "SDEV_00_01_00". | [1.0.0-11.0.1] This first initializes the funcptr table interfaces to the defaults (same as [[#DisableBluetooth]]). [[Settings_services#GetConfigurationId1|GetConfigurationId1]] is used, an error is thrown if the output string is empty, or if it matches "SDEV_00_01_00". | ||
If the flag for [[#IsManufacturingMode]] is 0, or if this cmd was already used where that flag was 1, an interface funcptr is called. This is passed a ptr to a table of funcptrs. The ret is converted to a Result and returned if needed. | If the flag for [[#IsManufacturingMode]] is 0, or if this cmd was already used where that flag was 1, an interface funcptr is called. This is passed a ptr to a table of funcptrs. The ret is converted to a Result and returned if needed. [12.0.0+] A normal func is called instead, with no params/ret. This cmd always returns 0. | ||
The | The above called func does the following: | ||
* A func is called, which copies the input funcptr table into global state. These are used for writing events into [[#EventInfo]]. | * [1.0.0-11.0.1] A func is called, which copies the input funcptr table into global state. These are used for writing events into [[#EventInfo]]. | ||
* A func is called 5 times with input param = [1-5]. This initializes the specified nn::bluetooth::CircularBuffer (sharedmem and internal). | * A func is called 5 times with input param = [1-5]. This initializes the specified nn::bluetooth::CircularBuffer (sharedmem and internal). [12.0.0+] This functionality is now inlined. | ||
* A func is called for creating the "nn.bluetooth.HidMessageHandler" thread. | * A func is called for creating the "nn.bluetooth.HidMessageHandler" thread. [12.0.0+] This functionality is now inlined. | ||
Lastly, the Event is created and returned (which global state the Event is stored in depends on whether the code-path which calls the above funcptr was used). | Lastly, the Event is ([1.0.0-11.0.1] created and) returned (which global state the Event is stored in depends on whether the code-path which calls the above funcptr was used). | ||
== EnableBluetooth == | == EnableBluetooth == | ||
Line 291: | Line 315: | ||
This is used by [[BTM_services|btm]]. | This is used by [[BTM_services|btm]]. | ||
This first calls an interface funcptr, on failure 0xCA71 is returned. | [1.0.0-11.0.1] This first calls an interface funcptr, on failure 0xCA71 is returned. | ||
A global fixed [[#Address]] is copied to stack, this stack data is then overwritten with the output from [[Settings_services|GetBluetoothBdAddress]]. If GetBluetoothBdAddress fails, this will Abort. Then the same funcptr used by [[#SetAdapterProperty]] is called with this stack data, with [[#BluetoothPropertyType|type2]]. A converted error is returned if needed. | [1.0.0-11.0.1] A global fixed [[#Address]] is copied to stack, this stack data is then overwritten with the output from [[Settings_services|GetBluetoothBdAddress]]. If GetBluetoothBdAddress fails, this will Abort. Then the same funcptr used by [[#SetAdapterProperty]] is called with this stack data, with [[#BluetoothPropertyType|type2]]. A converted error is returned if needed. | ||
The last two bytes of the stack [[#Address]] are inverted (byteval = ~byteval), then the above funcptr is called with this for [[#BluetoothPropertyType|type3]]. Error conversion is handled if needed, then this returns 0. | [1.0.0-11.0.1] The last two bytes of the stack [[#Address]] are inverted (byteval = ~byteval), then the above funcptr is called with this for [[#BluetoothPropertyType|type3]]. Error conversion is handled if needed, then this returns 0. | ||
The first funcptr called above does the following: | The first funcptr called above does the following ([12.0.0+] this code is now inlined): | ||
* Calls a GPIO func with param=0, [[SVC|sleeps]] for 10000000 nanoseconds, then calls the GPIO func again with param=1. | * Calls a GPIO func with param=0, [[SVC|sleeps]] for 10000000 nanoseconds, then calls the GPIO func again with param=1. | ||
* [12.0.0+] Calls a func to update an interface object ptr to use the enabled-object. A vfunc for various interface objects are called, with Result 0xCA71 being returned if the ret is non-zero (failure after the first interface object will trigger an Abort). | |||
* [12.0.0+] [[Settings_services|GetBluetoothBdAddress]] is used, on failure this will Abort. Then the same vfunc used by [[#SetAdapterProperty]] is called with the output from GetBluetoothBdAddress, with [[#AdapterPropertyType|type0]]. This will Abort on failure. | |||
* [12.0.0+] The last two bytes of the stack [[#Address]] are inverted (byteval = ~byteval), then the above vfunc is called with this for [[#AdapterPropertyType|type3]]. This will Abort on failure, otherwise 0 is returned. | |||
* [12.0.0+] Various code described below was moved into the above vfunc(s), etc. | |||
* Calls a func for initializing the paired-devices table (empty). | * Calls a func for initializing the paired-devices table (empty). | ||
* Calls a modified version of BSA_Boot, which handles BSA server initialization. | * Calls a modified version of BSA_Boot, which handles BSA server initialization. | ||
Line 314: | Line 342: | ||
* Uses SetValue with the param which was passed to this func. | * Uses SetValue with the param which was passed to this func. | ||
* Does cleanup for the session object and exits the service. | * Does cleanup for the session object and exits the service. | ||
[12.0.0+] The Enable vfunc called above for Audio does the following: | |||
* Calls a func which does the following: | |||
** Uses BSA to enable AV. Besides the callback, the only field in the passed struct which is set is <code>features</code>. This is ORRed to set bit0 for "remote control target", which with [13.0.0+] is only done if [[System_Settings|system-setting]] <code>bluetooth_debug!is_av_rc_tg</code> is set to true. With [14.0.0+] this is also ORRed with value 0xA (bit1/bit3) when [[System_Settings|system-setting]] <code>bluetooth_debug!is_av_rc_ct</code> is set to true (which is the case for [14.0.0+]). | |||
** Error handling + state setup is done. | |||
** Uses BSA to register AV twice, with the default input struct. | |||
** Error handling + state setup is done. | |||
* If an error occurred in a certain range, a [[#FatalReason|fatal]] is triggered and 0 is returned. | |||
* Otherwise when successful, state init is done then 0 is returned. | |||
== DisableBluetooth == | == DisableBluetooth == | ||
Line 320: | Line 357: | ||
This is used by [[BTM_services|btm]]. | This is used by [[BTM_services|btm]]. | ||
This calls an interface funcptr. On success, the funcs for updating the interface funcptr tables are called (same as [[#InitializeBluetooth]]). Then the converted ret is returned as needed. | [1.0.0-11.0.1] This calls an interface funcptr. On success, the funcs for updating the interface funcptr tables are called (same as [[#InitializeBluetooth]]). Then the converted ret is returned as needed. | ||
* [12.0.0+] Vfuncs for various interface objects are called, with failure triggering an Abort in some cases. | |||
* [12.0.0+] Calls funcs to update interfaces object ptrs to use the disabled-object. | |||
* [12.0.0+] Calls the same GPIO func as [[#EnableBluetooth]] with param=0, then 0 is returned. | |||
* [12.0.0+] Various code described below was moved into the above vfunc(s), etc. | |||
When bluetooth is already disabled, that funcptr just returns 0. Otherwise when it's already enabled, it does the following: | When bluetooth is already disabled, that funcptr just returns 0. Otherwise when it's already enabled, it does the following: | ||
Line 492: | Line 534: | ||
== TriggerConnection == | == TriggerConnection == | ||
Takes an input [[#Address]] and | Takes an input [[#Address]] and a u16 timeout, no output. | ||
This is used by [[BTM_services|btm]]. | This is used by [[BTM_services|btm]]. | ||
Line 499: | Line 541: | ||
The funcptr does the following: | The funcptr does the following: | ||
* Calls a func, returning the ret on failure. This uses a BSA extension (message 0x8CE), with the | * Calls a func, returning the ret on failure. This uses a BSA extension (message 0x8CE), with the u16 timeout being used with this. | ||
* Then another func is called, with the input [[#Address]], with the ret from here being returned. This throws an error if the device isn't paired. This opens a HID-Host connection to the specified [[#Address]]. The passed sec_mask is 0x12 (Inbound/outbound authentication required), and brcm_mask is set for enabling TBFC Page. | * Then another func is called, with the input [[#Address]], with the ret from here being returned. This throws an error if the device isn't paired. This opens a HID-Host connection to the specified [[#Address]]. The passed sec_mask is 0x12 (Inbound/outbound authentication required), and brcm_mask is set for enabling TBFC Page. | ||
The handler for the above message with the used bit flag does the following: | The handler for the above message with the used bit flag does the following: | ||
* Uses HCI vendor command 0xFCC2 with param_len=0xE. Param data: | * Uses HCI vendor command 0xFCC2 (TBFC Write Parameters) with param_len=0xE. Param data: u16 timeout value is inserted into the following tAPP_TM_TBFC_PARAM structure initialized with default values. The default host trigger timeout used elsewhere is 0x1800. | ||
{| class="wikitable" border="1" | |||
== AddPairedDeviceInfo == | |- | ||
Takes a type-0x19 input buffer containing [[Settings_services#BluetoothDevicesSettings|BluetoothDevicesSettings]], no output. | ! Offset | ||
! Size | |||
This is used by [[BTM_services|btm]]. | ! Description | ||
! Value | |||
|- | |||
| 0x0 | |||
| 0x1 | |||
| BfcEnable | |||
| 0x1 | |||
|- | |||
| 0x1 | |||
| 0x1 | |||
| Frequency1 | |||
| 0x0 | |||
|- | |||
| 0x2 | |||
| 0x1 | |||
| Frequency2 | |||
| 0x18 | |||
|- | |||
| 0x3 | |||
| 0x1 | |||
| Frequency3 | |||
| 0x4E | |||
|- | |||
| 0x4 | |||
| 0x1 | |||
| AccessCodeLength | |||
| 0x20 | |||
|- | |||
| 0x5 | |||
| 0x2 | |||
| HostScanInterval | |||
| 0x200 | |||
|- | |||
| 0x7 | |||
| 0x2 | |||
| HostTriggerTimeout | |||
| timeout | |||
|- | |||
| 0x9 | |||
| 0x2 | |||
| HidScanInterval | |||
| 0x200 | |||
|- | |||
| 0xB | |||
| 0x1 | |||
| HidScanRetry | |||
| 0x3 | |||
|- | |||
| 0xC | |||
| 0x1 | |||
| DontDisturb | |||
| 0x0 | |||
|- | |||
| 0xD | |||
| 0x1 | |||
| WakeUpMask | |||
| 0x0 | |||
|} | |||
== AddPairedDeviceInfo == | |||
Takes a type-0x19 input buffer containing [[Settings_services#BluetoothDevicesSettings|BluetoothDevicesSettings]], no output. | |||
This is used by [[BTM_services|btm]]. | |||
[12.0.0+] If [[Settings_services#BluetoothDevicesSettings|TrustedServices]] is 0, value 0x100000 is used. When bit20 is set, HID is initialized for this device, otherwise when bitmask 0xC0000 is set (<code>if((TrustedServices & 0xC0000) != 0)</code>) [[#OpenAudioConnection|audio]] is initialized for this device. | |||
== GetPairedDeviceInfo == | == GetPairedDeviceInfo == | ||
Takes an input [[#Address]] and a type-0x1A output buffer containing [[Settings_services#BluetoothDevicesSettings|BluetoothDevicesSettings]]. | Takes an input [[#Address]] and a type-0x1A output buffer containing [[Settings_services#BluetoothDevicesSettings|BluetoothDevicesSettings]]. | ||
Line 767: | Line 873: | ||
== ConnectGattServer == | == ConnectGattServer == | ||
Takes an input u8, an [[#Address]], a bool, an [[Applet_Manager_services#AppletResourceUserId|AppletResourceUserId]], no output. | Takes an input u8 client_if, an [[#Address]], a bool, an [[Applet_Manager_services#AppletResourceUserId|AppletResourceUserId]], no output. | ||
This is used by [[BTM_services|btm]]. | This is used by [[BTM_services|btm]]. | ||
The input bool and AppletResourceUserId are unused. | |||
The is_direct field passed to BSA is value 1. | |||
== CancelConnectGattServer == | == CancelConnectGattServer == | ||
Line 920: | Line 1,030: | ||
== SetBleScanParameter == | == SetBleScanParameter == | ||
Takes two input u16s, no output. | Takes two input u16s, no output. | ||
The first u16 is scan_interval, the second u16 is scan_window. | |||
This is used by [[BTM_services|btm]]. | This is used by [[BTM_services|btm]]. | ||
Line 937: | Line 1,049: | ||
sdknso uses an user-specified EventClearMode. | sdknso uses an user-specified EventClearMode. | ||
This just gets a previously-initialized Event from global state, [[#IsManufacturingMode]] is used to select which Event to use. | |||
== GetAudioEventInfo == | == GetAudioEventInfo == | ||
Takes a type-0xA output buffer, returns an output [[#AudioEventType]]. | Takes a type-0xA output buffer, returns an output [[#AudioEventType]]. | ||
This is essentially the same as the other [12.0.0+] Get*EventInfo cmds, however in this case the output type is set to value 0 when no event is available. | |||
See [[#AudioEventInfo]]. | |||
== OpenAudioConnection == | == OpenAudioConnection == | ||
Takes an input [[#Address]], no output. | Takes an input [[#Address]], no output. | ||
This goes through state and eventually uses BSA to open an AV connection. The input struct has the RC flag set to true. sec_mask is set to require authentication and encryption. | |||
== CloseAudioConnection == | == CloseAudioConnection == | ||
Takes an input [[#Address]], no output. | Takes an input [[#Address]], no output. | ||
This goes through state and eventually uses BSA to close an AV connection. | |||
== OpenAudioOut == | == OpenAudioOut == | ||
Takes an input [[#Address]], returns an output u32. | Takes an input [[#Address]], returns an output u32 audio_handle. | ||
== CloseAudioOut == | == CloseAudioOut == | ||
Takes an input u32, no output. | Takes an input u32 [[#OpenAudioOut|audio_handle]], no output. | ||
== AcquireAudioOutStateChangedEvent == | == AcquireAudioOutStateChangedEvent == | ||
Takes an input u32, returns an output Event handle. | Takes an input u32 [[#OpenAudioOut|audio_handle]], returns an output Event handle. | ||
sdknso uses an user-specified EventClearMode. | sdknso uses an user-specified EventClearMode. | ||
== StartAudioOut == | == StartAudioOut == | ||
Takes an input u32, a [[#PcmParameter]], a nn::TimeSpan, returns an output nn::TimeSpan and u64. | Takes an input u32 [[#OpenAudioOut|audio_handle]], a [[#PcmParameter]], a nn::TimeSpan latency, returns an output nn::TimeSpan latency and u64. | ||
This eventually uses BSA to start an AV stream. The codec is "Raw PCM". Synchronous feeding mode is used. | |||
== StopAudioOut == | == StopAudioOut == | ||
Takes an input u32, no output. | Takes an input u32 [[#OpenAudioOut|audio_handle]], no output. | ||
This eventually uses BSA to stop an AV stream. The pause flag is set to false. | |||
== GetAudioOutState == | == GetAudioOutState == | ||
Takes an input u32, returns an output [[#AudioOutState]]. | Takes an input u32 [[#OpenAudioOut|audio_handle]], returns an output [[#AudioOutState]]. | ||
== GetAudioOutFeedingCodec == | == GetAudioOutFeedingCodec == | ||
Takes an input u32, returns an output [[#AudioCodec]]. | Takes an input u32 [[#OpenAudioOut|audio_handle]], returns an output [[#AudioCodec]]. | ||
== GetAudioOutFeedingParameter == | == GetAudioOutFeedingParameter == | ||
Takes an input u32, returns an output [[#PcmParameter]]. | Takes an input u32 [[#OpenAudioOut|audio_handle]], returns an output [[#PcmParameter]]. | ||
== AcquireAudioOutBufferAvailableEvent == | == AcquireAudioOutBufferAvailableEvent == | ||
Takes an input u32, returns an output Event handle. | Takes an input u32 [[#OpenAudioOut|audio_handle]], returns an output Event handle. | ||
sdknso uses an user-specified EventClearMode. | sdknso uses an user-specified EventClearMode. | ||
This gets an Event which was previously initialized. | |||
== SendAudioData == | == SendAudioData == | ||
Takes an input u32, a type-0x9 input buffer, returns an output u64. | Takes an input u32 [[#OpenAudioOut|audio_handle]], a type-0x9 input buffer, returns an output u64 transferred_size. | ||
This eventually uses BSA to send the specified buffer to the required UIPC channel. If transferred_size doesn't match the buffer size, error 0x177A71 is returned. transferred_size is always either 0 (error occured) or the buffer size. | |||
== AcquireAudioControlInputStateChangedEvent == | == AcquireAudioControlInputStateChangedEvent == | ||
Line 985: | Line 1,115: | ||
sdknso uses an user-specified EventClearMode. | sdknso uses an user-specified EventClearMode. | ||
This gets an Event which was previously initialized. | |||
== GetAudioControlInputState == | == GetAudioControlInputState == | ||
Takes a type-0xA output buffer containing an array of [[#AudioControlButtonState]], returns an output s32. | Takes a type-0xA output buffer containing an array of [[#AudioControlButtonState]], returns an output s32 total_out. | ||
A maximum of 0xF entries can be returned. | |||
== AcquireAudioConnectionStateChangedEvent == | == AcquireAudioConnectionStateChangedEvent == | ||
Line 993: | Line 1,127: | ||
sdknso uses an user-specified EventClearMode. | sdknso uses an user-specified EventClearMode. | ||
This gets an Event which was previously initialized. | |||
== GetConnectedAudioDevice == | == GetConnectedAudioDevice == | ||
Takes a type-0xA output buffer containing an array of [[#Address]], returns an output s32. | Takes a type-0xA output buffer containing an array of [[#Address]], returns an output s32 total_out. | ||
A maximum of 0x8 entries can be returned. | |||
== CloseAudioControlInput == | |||
Takes an input [[#Address]], no output. | |||
This uses the BSA AV API to close the AVRCP connection. | |||
== RegisterAudioControlNotification == | |||
Takes an input [[#Address]] and an u32 [[#AvrcEventType]], no output. | |||
This uses the BSA AV API to send a vendor control command: ctype=0x3, label={counter which is incremented}, length=0x9, data=[0x31, 0x00, 0x00, 0x05, {u8 [[#AvrcEventType]]}, {rest is zeros}]. | |||
This does nothing since BSA requires [[#EnableBluetooth|features]] bit1 and bit3 to be set in order to use this. | |||
== SendAudioControlPassthroughCommand == | |||
Takes an input [[#Address]], an u32 [[#AvrcOperationId]], an u32 [[#AvrcStateType]], no output. | |||
This uses the BSA AV API to send a remote control command: label={counter which is incremented}, rc_id=[[#AvrcOperationId]], key_state=[[#AvrcStateType]]. | |||
This does nothing since BSA requires [[#EnableBluetooth|features]] bit1 to be set in order to use this. | |||
== SendAudioControlSetAbsoluteVolumeCommand == | |||
Takes an input [[#Address]] and a s32, no output. | |||
This uses the BSA AV API to send a vendor control command: ctype=0x0, label={counter which is incremented}, length=0x5, data=[0x50, 0x00, 0x00, 0x01, {input s32 value written as an u8}]. | |||
See [[#RegisterAudioControlNotification]] regarding the usage requirement. | |||
== IsManufacturingMode == | == IsManufacturingMode == | ||
Line 1,128: | Line 1,292: | ||
This is u32 enum "nn::bluetooth::hal::AdapterPropertyType". | This is u32 enum "nn::bluetooth::hal::AdapterPropertyType". | ||
The sysmodule will Abort if the input type is unavailable / not recognized. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! Value | ! Value | ||
! Description | ! Description | ||
! Data contents | |||
|- | |- | ||
| [1.0.0-11.0.1] 0 || || The funcptr which writes the data into state for this event is not called (only checked on [10.0.0]). | | 0 || Address || [[#Address]] | ||
|- | |||
| 1 || Name || String, max length 0xF8 excluding NUL-terminator. | |||
|- | |||
| 2 || || 3-bytes, Class of Device. | |||
|- | |||
| 3 || || Only available with [[#SetAdapterProperty]]. Same as [[#BluetoothPropertyType]] type3. | |||
|} | |||
= TransportType = | |||
This is u32 enum "nn::bluetooth::TransportType". | |||
= BluetoothSspVariant = | |||
This is u8 enum "nn::bluetooth::BluetoothSspVariant". [12.0.0+] This is u32 enum "nn::bluetooth::hal::BluetoothSspVariant". | |||
= EventType = | |||
This is u32 enum "nn::bluetooth::EventType". | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value | |||
! Name | |||
! Description | |||
|- | |||
| [1.0.0-11.0.1] 0 || || The funcptr which writes the data into state for this event is not called (only checked on [10.0.0]). | |||
|- | |- | ||
| 0 ([1.0.0-11.0.1] 3) || || New device found during Inquiry. | | 0 ([1.0.0-11.0.1] 3) || || New device found during Inquiry. | ||
Line 1,247: | Line 1,428: | ||
|- | |- | ||
| 7 || Only for [[#EventInfo]]: triggered after enabling bluetooth, when a global state field is value 4 or 2. | | 7 || Only for [[#EventInfo]]: triggered after enabling bluetooth, when a global state field is value 4 or 2. | ||
|- | |||
| 9 || [12.0.0+] Only for [[#EventInfo]]: triggered when bluetooth errors occur in a certain range, with various Audio interface vfuncs. | |||
|} | |} | ||
Line 1,269: | Line 1,452: | ||
[12.0.0+]: | [12.0.0+]: | ||
{. | {| class="wikitable" border="1" | ||
|- | |||
= AdapterPropertySet = | ! Offset | ||
This is "nn::bluetooth::hal::AdapterPropertySet". This is a 0x102-byte struct. | ! Size | ||
! Description | |||
|- | |||
| 0x0 || 0x1 || [[#AdapterPropertyType]] | |||
|- | |||
| 0x1 || 0x1 || Data size | |||
|- | |||
| 0x2 || {Above size} || Data, as specified by the type. | |||
|} | |||
= AdapterPropertySet = | |||
This is "nn::bluetooth::hal::AdapterPropertySet". This is a 0x102-byte struct. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x6 || Same as the data for [[#AdapterPropertyType]] type0. | |||
|- | |||
| 0x6 || 0x3 || Same as the data for [[#AdapterPropertyType]] type2. | |||
|- | |||
| 0x9 || 0xF9 || Same as the data for [[#AdapterPropertyType]] type1. | |||
|} | |||
= Address = | = Address = | ||
Line 1,422: | Line 1,629: | ||
|} | |} | ||
[1.0.0- | [1.0.0-8.1.1] [[#EventType|Type7]]: | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,429: | Line 1,636: | ||
! Size | ! Size | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || | | 0x0 || 0x6 || Device [[#Address|address]]. | ||
|- | |- | ||
| | | 0x6 || 0x2 || Padding | ||
|- | |- | ||
| | | 0x8 || 0x4 || Status, always 0 except with [[#ConnectionEventType|event0]]: 2 = ACL Link is now Resumed (BSA_SEC_RESUMED_EVT), 9 = connection failed (pairing/authentication failed, or opening the hid connection failed). | ||
|- | |- | ||
| 0xC || 0x4 || [[#ConnectionEventType]] | | 0xC || 0x4 || [[#ConnectionEventType]] | ||
|} | |} | ||
[ | [9.0.0-11.0.1] [[#EventType|Type7]]: | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,447: | Line 1,655: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x4 || [[#ConnectionEventType]] | | 0x0 || 0x4 || Status, always 0 except with [[#ConnectionEventType|event0]]: 2 = ACL Link is now Resumed (BSA_SEC_RESUMED_EVT), 9 = connection failed (pairing/authentication failed, or opening the hid connection failed). | ||
|- | |||
| 0x4 || 0x6 || Device [[#Address|address]]. | |||
|- | |||
| 0xA || 0x2 || Padding | |||
|- | |||
| 0xC || 0x4 || [[#ConnectionEventType]] | |||
|} | |||
[12.0.0+] [[#EventType|Type4]]: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || [[#ConnectionEventType]] | |||
|- | |- | ||
| 0x4 || 0x6 || Device [[#Address|address]]. | | 0x4 || 0x6 || Device [[#Address|address]]. | ||
Line 1,545: | Line 1,770: | ||
[[#HidEventType|Type0]], for [[#GetHidEventInfo]]: | [[#HidEventType|Type0]], for [[#GetHidEventInfo]]: | ||
[1.0.0-11.0.1] | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 1,555: | Line 1,781: | ||
| 0x6 || 0x2 || Padding | | 0x6 || 0x2 || Padding | ||
|- | |- | ||
| 0x8 || 0x4 || Status: | | 0x8 || 0x4 || Status: 0 = hid connection opened, 2 = hid connection closed, 8 = failed to open hid connection. | ||
|} | |||
[12.0.0+] 0 = hid connection closed, 1 = hid connection opened, 2 = failed to open hid connection. | [12.0.0+] | ||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || Status: 0 = hid connection closed, 1 = hid connection opened, 2 = failed to open hid connection. | |||
|- | |||
| 0x4 || 0x6 || Device [[#Address|address]]. | |||
|} | |} | ||
Line 1,689: | Line 1,924: | ||
This is "nn::bluetooth::BleAdvertiseFilter". This is a 0x3E-byte struct. | This is "nn::bluetooth::BleAdvertiseFilter". This is a 0x3E-byte struct. | ||
{| class="wikitable" border="1" | |||
|- | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | ! Offset | ||
! Size | ! Size | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x1 || | | 0x0 || 0x1 || FilterId | ||
|- | |||
| 0x1 || 0x1 || CondDataSize. Only used with CondType Manu. | |||
|- | |- | ||
| | | 0x2 || 0x1 || CondType | ||
|- | |- | ||
| | | 0x3 || 0x1D || CondData, content depends on CondType. | ||
|- | |- | ||
| | | 0x20 || 0x1D || Mask. Only used with CondType Manu. +0 = u16 CompanyIdMask, then {pattern mask}. | ||
|- | |- | ||
| | | 0x3D || 0x1 || MaskSize. Only used with CondType Manu. | ||
|} | |} | ||
CondType: | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! | ! Value | ||
! | ! Name | ||
! Description | ! Description | ||
|- | |- | ||
| | | 2-3 || || ServiceUuid16. CondData = 16bit UUID which is byteswapped. | ||
|- | |- | ||
| | | 4-5 || || ServiceUuid32. CondData = 32bit UUID which is byteswapped. | ||
|- | |- | ||
| | | 6-7 || || ServiceUuid128. CondData = 128bit UUID which is copied raw into the param struct. | ||
|- | |- | ||
| 255 || || Manu. CondData: u16 CompanyId, then {pattern data}. | |||
|} | |} | ||
= | To pass filtering, the BLE advert data should be: data & Mask == CondData (following the type field in the advert entry with the matching type). | ||
This is "nn::bluetooth:: | |||
= BleAdvertisePacketParameter = | |||
This is "nn::bluetooth::BleAdvertisePacketParameter". This is a 8-byte struct with 1-byte alignment. | |||
[[BTM_services#StartBleScanForGeneral|StartBleScanForGeneral]] generates a [[#BleAdvertiseFilter]] from this. CondType = Manu, CondDataSize = 0xA. CondData: +0 = u16 CompanyId, u8 +2 = 0x1, +3 = {data copied from PatternData, then an u8 with value 0x0}. MaskSize = 0x9, Mask = {all 0xFF}. | |||
[[BTM_services#StartBleScanForPaired|StartBleScanForPaired]] generates a [[#BleAdvertiseFilter]] from this, similar to the above. CondType = Manu, CondDataSize = 0x11. CondData: +0 = u16 CompanyId, u8 +2 = 0x1, +3 = {data copied from PatternData, then an u8 with value 0x0, then {6-byte system btaddr}}. MaskSize = 0x10, Mask = {all 0xFF except u8 +0x9 which is 0x0}. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,738: | Line 1,974: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || | | 0x0 || 0x2 || CompanyId | ||
|- | |- | ||
| | | 0x2 || 0x6 || PatternData | ||
|} | |} | ||
= | = BleScanResult = | ||
This is "nn::bluetooth:: | This is "nn::bluetooth::BleScanResult". This is a 0x148-byte struct. | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,752: | Line 1,988: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x1 || | | 0x0 || 0x1 || | ||
|- | |||
| 0x1 || 0x6 || [[#Address]] | |||
|- | |||
| 0x7 || || Array of entries where each entry is 0x1F-bytes. hid compares +1 with 0xFF and +0x2 with the cached output from [[#BTM_services#GetBleScanParameterGeneral|GetBleScanParameterGeneral]] (entry+0x4 is skipped over). | |||
|- | |- | ||
| | | 0x140 || 0x4 || s32 Total entries in the array at 0x8. | ||
|- | |- | ||
| | | 0x144 || 0x4 || s32 | ||
|} | |} | ||
= | = BleConnectionInfo = | ||
This is a | This is "nn::bluetooth::BleConnectionInfo". This is a 0xC-byte struct. | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,768: | Line 2,008: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x4 || | | 0x0 || 0x4 || ConnectionHandle, 0xFFFFFFFF ([5.0.0-5.0.2] 0xFFFF) is invalid. | ||
|- | |- | ||
| 0x4 || | | 0x4 || 0x6 || [[#Address]] | ||
|- | |- | ||
| | | 0xA || 0x2 || Padding | ||
|- | |- | ||
|} | |} | ||
= | = GattAttributeUuid = | ||
This is "nn::bluetooth:: | This is "nn::bluetooth::GattAttributeUuid". This is a 0x14-byte struct with 4-byte alignment. | ||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || [[#BleGattUuid]] size. Must be 0x2, 0x4, or 0x10. | |||
|- | |||
| 0x4 || 0x10 || [[#BleGattUuid]] with the above size. | |||
|} | |||
= GattId = | |||
This is "nn::bluetooth::GattId". This is a 0x18-byte struct with 4-byte alignment. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,796: | Line 2,039: | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || 0x1 || | | 0x0 || 0x1 || InstanceId | ||
|- | |- | ||
| 0x1 || 0x3 || Padding | | 0x1 || 0x3 || Padding | ||
|- | |- | ||
| 0x4 || | | 0x4 || 0x14 || [[#GattAttributeUuid]] | ||
|} | |||
= BleGattUuid = | |||
This is an enum of u16, u32 and u128 values. | |||
{| class="wikitable" border="1" | |||
|- | |- | ||
! Value | |||
! Description | |||
|- | |- | ||
| | | 0x2902 || ClientConfigUuid16 | ||
|- | |- | ||
| | | 0x2908 || ReportReferenceUuid16 | ||
|- | |- | ||
| | | 0x1B666C080A578E83994EA7F7BF50DDA3 || PalmaOtafuControlPointUuid128 | ||
|- | |- | ||
| | | 0x26FE2EE709244FB7914061D97A6CE8A2 || PalmaOtafuDataUuid128 | ||
|- | |- | ||
| | | 0x45CEF889AF8E0784664404737C7FBE2B || NbatUuid128 | ||
|- | |- | ||
| 0x50 || {above size} || Same as [[#LeEventInfo]]+0x4A. | | 0x46CEF889AF8E0784664404737C7FBE2B || BatteryLevelUuid128 | ||
|} | |- | ||
| 0x47CEF889AF8E0784664404737C7FBE2B || BatteryStateUuid128 | |||
= AudioEventType = | |- | ||
This is "nn::bluetooth::hal::AudioEventType". This is an u32 enum. | | 0xD88B7646729DBDA17A4425F4101126C7 || PalmaOtafuUuid128 | ||
|- | |||
= PcmParameter = | | 0xE5237AE2516B55BB67456DF36CE17566 || NhogUuid128 | ||
This is "nn::bluetooth::system::PcmParameter". This is a 0xC-byte struct with 4-byte alignment. | |- | ||
| 0xE6237AE2516B55BB67456DF36CE17566 || InputReportUuid128 | |||
= AudioOutState = | |- | ||
This is "nn::bluetooth::system::AudioOutState". This is an u32 enum. | | 0xE7237AE2516B55BB67456DF36CE17566 || OutputCommandUuid128 | ||
|- | |||
= AudioCodec = | | 0xE8237AE2516B55BB67456DF36CE17566 || CommandResponseUuid128 | ||
This is "nn::bluetooth::system::AudioCodec". This is an u32 enum. | |} | ||
= AudioControlButtonState = | = BleClientGattOperationStatus = | ||
This is "nn::bluetooth::system::AudioControlButtonState". This is a 0x10-byte struct. | This is an u8 enum. This is converted from the [[#LeEventInfo]] status field. | ||
= Notes = | {| class="wikitable" border="1" | ||
The output from <code>sudo hcitool info {BDADDR}</code> is identical for [1.0.0-11.0.0]: | |- | ||
! Value | |||
BD Address: {BDADDR} | ! Name | ||
OUI Company: Nintendo Co.,Ltd (98-B6-E9) | ! Description | ||
Device Name: Nintendo Switch | |- | ||
LMP Version: 4.2 (0x8) LMP Subversion: 0x2409 | | 0 || || Same as [[#LeEventInfo]] status 0. | ||
Manufacturer: Broadcom Corporation (15) | |- | ||
Features page 0: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87 | | 1 || || Same as [[#LeEventInfo]] status 55. | ||
<3-slot packets> <5-slot packets> <encryption> <slot offset> | |- | ||
<timing accuracy> <role switch> <sniff mode> <RSSI> | | 2 || || Same as [[#LeEventInfo]] status 25, 52. | ||
<channel quality> <SCO link> <HV2 packets> <HV3 packets> | |- | ||
<u-law log> <A-law log> <CVSD> <paging scheme> <power control> | | 3 || || Same as [[#LeEventInfo]] status 4, 16, 21, 50. | ||
<transparent SCO> <broadcast encrypt> <EDR ACL 2 Mbps> | |- | ||
<EDR ACL 3 Mbps> <enhanced iscan> <interlaced iscan> | | 4 || || Same as [[#LeEventInfo]] status 5. | ||
|- | |||
| 5 || || Same as [[#LeEventInfo]] status 6. | |||
|- | |||
| 6 || || Same as [[#LeEventInfo]] status 7. | |||
|- | |||
| 7 || || Same as [[#LeEventInfo]] status 9. | |||
|- | |||
| 8 || || Same as [[#LeEventInfo]] status 13. | |||
|- | |||
| 9 || || Used as the default case when the [[#LeEventInfo]] status is unrecognized. | |||
|- | |||
| 10 || || Same as [[#LeEventInfo]] status 35. | |||
|} | |||
= LeEventInfo = | |||
This is a 0x400-byte struct. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || Status. 0 = success, non-zero = error. | |||
|- | |||
| 0x4 || 0x4 || ConnectionId | |||
|- | |||
| 0x8 || 0x1 || Flags. Bit0 = IsWrite, bit1 = IsDescriptor, bit2 = IsNotify. | |||
When bit2 is set, bit0 = IsIndication. | |||
|- | |||
| 0x9 || 0x3 || Padding | |||
|- | |||
| 0xC || 0x14 || Service [[#GattAttributeUuid]] | |||
|- | |||
| 0x20 || 0x14 || Characteristic [[#GattAttributeUuid]] | |||
|- | |||
| 0x34 || 0x14 || Descriptor [[#GattAttributeUuid]] | |||
|- | |||
| 0x48 || 0x2 || Size of the below data. | |||
|- | |||
| 0x4A || 0x200 || Data with the above size. | |||
|} | |||
= BleClientGattOperationInfo = | |||
This is "nn::bluetooth::BleClientGattOperationInfo". This is converted from [[#LeEventInfo]]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x1 || [[#BleClientGattOperationStatus]] | |||
|- | |||
| 0x1 || 0x3 || Padding | |||
|- | |||
| 0x4 || 0x4 || Same as [[#LeEventInfo]]+0x4. | |||
|- | |||
| 0x8 || 0x1 || Same as [[#LeEventInfo]]+0x8. | |||
|- | |||
| 0x9 || 0x3 || Padding | |||
|- | |||
| 0xC || 0x14 || Same as [[#LeEventInfo]]+0xC. | |||
|- | |||
| 0x20 || 0x14 || Same as [[#LeEventInfo]]+0x20. | |||
|- | |||
| 0x34 || 0x14 || Same as [[#LeEventInfo]]+0x34. | |||
|- | |||
| 0x48 || 0x8 || Same as [[#LeEventInfo]]+0x48. | |||
|- | |||
| 0x50 || {above size} || Same as [[#LeEventInfo]]+0x4A. | |||
|} | |||
= AudioEventType = | |||
This is "nn::bluetooth::hal::AudioEventType". This is an u32 enum. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value | |||
! Name | |||
! Description | |||
|- | |||
| 0 || || None | |||
|- | |||
| 1 || || Connection | |||
|} | |||
= AudioEventInfo = | |||
This is the output buffer for [[#GetAudioEventInfo]]. The data stored here depends on the [[#AudioEventType]]. | |||
[[#AudioEventType|Type1]]: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || Status: 0 = AV connection closed, 1 = AV connection opened, 2 = failed to open AV connection. | |||
|- | |||
| 0x4 || 0x6 || Device [[#Address|address]]. | |||
|- | |||
| 0xA || 0x2 || Padding | |||
|} | |||
= PcmParameter = | |||
This is "nn::bluetooth::system::PcmParameter". This is a 0xC-byte struct with 4-byte alignment. | |||
The sysmodule will Abort if any of these fields are invalid. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 0x0 || 0x4 || Must be 0-3. Controls number of channels: 0 = mono, non-zero = stereo. | |||
|- | |||
| 0x4 || 0x4 || s32 SampleRate. Must be one of the following: 16000, 32000, 44100, 48000. | |||
|- | |||
| 0x8 || 0x4 || Bits per sample. Must be 8 or 16. | |||
|} | |||
= AudioOutState = | |||
This is "nn::bluetooth::system::AudioOutState". This is an u32 enum. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value | |||
! Description | |||
|- | |||
| 0 || Stopped | |||
|- | |||
| 1 || Started | |||
|} | |||
= AudioCodec = | |||
This is "nn::bluetooth::system::AudioCodec". This is an u32 enum. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value | |||
! Description | |||
|- | |||
| 0 || Raw PCM | |||
|} | |||
= AudioControlButtonState = | |||
This is "nn::bluetooth::system::AudioControlButtonState". This is a 0x10-byte struct. | |||
= AvrcEventType = | |||
This is "nn::bluetooth::hal::AvrcEventType". | |||
= AvrcOperationId = | |||
This is "nn::bluetooth::hal::AvrcOperationId". This is the same as tBSA_AV_RC. | |||
= AvrcStateType = | |||
This is "nn::bluetooth::hal::AvrcStateType". This is the same as tBSA_AV_STATE. | |||
= Notes = | |||
The output from <code>sudo hcitool info {BDADDR}</code> is identical for [1.0.0-11.0.0]: | |||
BD Address: {BDADDR} | |||
OUI Company: Nintendo Co.,Ltd (98-B6-E9) | |||
Device Name: Nintendo Switch | |||
LMP Version: 4.2 (0x8) LMP Subversion: 0x2409 | |||
Manufacturer: Broadcom Corporation (15) | |||
Features page 0: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87 | |||
<3-slot packets> <5-slot packets> <encryption> <slot offset> | |||
<timing accuracy> <role switch> <sniff mode> <RSSI> | |||
<channel quality> <SCO link> <HV2 packets> <HV3 packets> | |||
<u-law log> <A-law log> <CVSD> <paging scheme> <power control> | |||
<transparent SCO> <broadcast encrypt> <EDR ACL 2 Mbps> | |||
<EDR ACL 3 Mbps> <enhanced iscan> <interlaced iscan> | |||
<interlaced pscan> <inquiry with RSSI> <extended SCO> | <interlaced pscan> <inquiry with RSSI> <extended SCO> | ||
<EV4 packets> <EV5 packets> <AFH cap. slave> | <EV4 packets> <EV5 packets> <AFH cap. slave> | ||
Line 1,863: | Line 2,287: | ||
The bluetooth stack is Broadcom/Cypress brcm BSA (for example, see [https://github.com/hardkernel/buildroot_linux_amlogic_brcm-bsa here]). | The bluetooth stack is Broadcom/Cypress brcm BSA (for example, see [https://github.com/hardkernel/buildroot_linux_amlogic_brcm-bsa here]). | ||
Various btdrv service commands use a custom BSA extension (message-ids based at 0x8CA/2250), this is referred to as "robson". | Various btdrv service commands use a custom BSA extension (message-ids based at 0x8CA/2250), this is referred to as "robson". The following BSA modules are supported by the BSA server task thread (including the aforementioned robson): sys, dm, disc, sec, hh, [12.0.0+] av, dg, tm, ble. | ||
The following L2CAP services are registered (dynamic channels): SDP, ATT (GATT), RFCOMM, HID (PSMs: 0x11, 0x13, 0x8001, 0x8003). | The following L2CAP services are registered (dynamic channels): SDP, ATT (GATT), RFCOMM, HID (PSMs: 0x11, 0x13, 0x8001, 0x8003), [12.0.0+] AVCTP/AVCTP_Browsing (only when the features bitfield passed to BSA_AvEnable by [[#EnableBluetooth]] has bit0 ("remote control target") or bit1 set), [12.0.0+] AVDTP. | ||
<code>l2cu_send_peer_echo_rsp</code> is called with p_data=NULL and data_len=0, therefore no data is returned in the L2CAP ECHO response. | <code>l2cu_send_peer_echo_rsp</code> is called with p_data=NULL and data_len=0, therefore no data is returned in the L2CAP ECHO response. | ||
Line 1,930: | Line 2,354: | ||
| CYW4356A3_001.004.009.0092.0095 | | CYW4356A3_001.004.009.0092.0095 | ||
|- | |- | ||
| [12.0.0] | | [12.0.0-14.1.2] | ||
| BSA0106_01.60.00_ | | BSA0106_01.60.00_ | ||
| Hayward_T3_RC_20210224 | | Hayward_T3_RC_20210224 | ||
| CYW4356A3_001.004.009.0092.0095 | | CYW4356A3_001.004.009.0092.0095 | ||
|- | |||
| [15.0.0-20.1.0] | |||
| BSA0106_01.60.00_ | |||
| Hayward_T3_RC_20210224 | |||
| BCM4356A3 UART 37.4 MHz wlbga_bu | |||
|} | |} | ||
<code>bsa_sv_tm_read_version_excback</code> copies bsa_version_string and concats with bsa_version_info_string to generate <code>tBSA_TM_READ_VERSION.bsa_server_version</code>. | <code>bsa_sv_tm_read_version_excback</code> copies bsa_version_string and concats with bsa_version_info_string to generate <code>tBSA_TM_READ_VERSION.bsa_server_version</code>. | ||
* [15.0.0]: In the HCI memwrite data, only config data was changed, no code changes. | |||
[[Category:Services]] | [[Category:Services]] |