Bluetooth Driver services: Difference between revisions
No edit summary |
|||
(63 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 321: | Line 345: | ||
[12.0.0+] The Enable vfunc called above for Audio does the following: | [12.0.0+] The Enable vfunc called above for Audio does the following: | ||
* Calls a func which 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 set for "remote control target". | ** 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. | ** Error handling + state setup is done. | ||
** Uses BSA to register AV twice, with the default input struct. | ** Uses BSA to register AV twice, with the default input struct. | ||
Line 510: | 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 517: | 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" | |||
|- | |||
! Offset | |||
! Size | |||
! 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 == | == AddPairedDeviceInfo == | ||
Line 527: | Line 613: | ||
This is used by [[BTM_services|btm]]. | 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 == | ||
Line 785: | 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 938: | 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 960: | Line 1,054: | ||
== 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 1,005: | 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 1,013: | 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 | 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. | |||
== GetBleChannelMap == | This uses the BSA AV API to send a remote control command: label={counter which is incremented}, rc_id=[[#AvrcOperationId]], key_state=[[#AvrcStateType]]. | ||
Takes a type-0x16 output buffer containing a [[#ChannelMapList]]. | |||
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 == | |||
No input, returns an output bool. | |||
sdknso will Abort if this fails, the bool is returned instead of a Result. sdknso exposes this under "nn::bluetooth::debug::". | |||
This calls the same two funcs as various other cmds etc. This writes the bool returned by the second func to output, then returns 0. The second func loads the bool from [[System_Settings|system-setting]] "bluetooth_debug!skip_boot". The first func is the same as the second one, except it writes the bool into global state. [12.0.0+] These two funcs now additionally load [[System_Settings|system-setting]] "bluetooth_config!skip_boot", which is ORRed with the first setting, then that's used for storing in state / returning the value. | |||
This is used by [[BTM_services|btm]]. | |||
== EmulateBluetoothCrash == | |||
Takes an input [[#FatalReason]], no output. | |||
sdknso masks the FatalReason with an u16-mask before passing it to the cmd. sdknso exposes this under "nn::bluetooth::debug::". | |||
This writes data into a CircularBuffer (seperate from sharedmem) with type=0x29, where the data is an u16 determined using the input [[#FatalReason]]. This is only done if a state field is value 0x3, after calling the func for this the field is set to value 0. The thread handling that sent message then converts the u16 back into a [[#FatalReason]] for writing into [[#EventInfo]]. | |||
== GetBleChannelMap == | |||
Takes a type-0x16 output buffer containing a [[#ChannelMapList]]. | |||
[12.0.0+] Takes two type-0xA output buffers, returns an output s32. The first buffer contains an array of [[#Address]], the second buffer contains an array of BitFlagSet with [[#LeChannel]] and bit-count=40. | [12.0.0+] Takes two type-0xA output buffers, returns an output s32. The first buffer contains an array of [[#Address]], the second buffer contains an array of BitFlagSet with [[#LeChannel]] and bit-count=40. | ||
Line 1,485: | Line 1,629: | ||
|} | |} | ||
[1.0.0- | [1.0.0-8.1.1] [[#EventType|Type7]]: | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 1,492: | Line 1,636: | ||
! Size | ! Size | ||
! Description | ! Description | ||
|- | |- | ||
| 0x0 || | | 0x0 || 0x6 || Device [[#Address|address]]. | ||
|- | |- | ||
| | | 0x6 || 0x2 || Padding | ||
|- | |- | ||
| 0xA || 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]] | |||
|} | |||
[9.0.0-11.0.1] [[#EventType|Type7]]: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset | |||
! Size | |||
! Description | |||
|- | |||
| 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]] | | 0xC || 0x4 || [[#ConnectionEventType]] | ||
Line 1,608: | 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,618: | 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,752: | 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,801: | 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,815: | 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,831: | 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,859: | 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,926: | 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,993: | 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]] |