Difference between revisions of "Bluetooth Driver services"
(→btdrv) |
|||
Line 218: | Line 218: | ||
| 100 || [12.0.0+] [[#IsBluetoothEnabled]] | | 100 || [12.0.0+] [[#IsBluetoothEnabled]] | ||
|- | |- | ||
− | | 128 || [12.0.0+] AcquireAudioEvent | + | | 128 || [12.0.0+] [[#AcquireAudioEvent]] |
|- | |- | ||
− | | 129 || [12.0.0+] GetAudioEventInfo | + | | 129 || [12.0.0+] [[#GetAudioEventInfo]] |
|- | |- | ||
− | | 130 || [12.0.0+] OpenAudioConnection | + | | 130 || [12.0.0+] [[#OpenAudioConnection]] |
|- | |- | ||
− | | 131 || [12.0.0+] CloseAudioConnection | + | | 131 || [12.0.0+] [[#CloseAudioConnection]] |
|- | |- | ||
− | | 132 || [12.0.0+] OpenAudioOut | + | | 132 || [12.0.0+] [[#OpenAudioOut]] |
|- | |- | ||
− | | 133 || [12.0.0+] CloseAudioOut | + | | 133 || [12.0.0+] [[#CloseAudioOut]] |
|- | |- | ||
− | | 134 || [12.0.0+] AcquireAudioOutStateChangedEvent | + | | 134 || [12.0.0+] [[#AcquireAudioOutStateChangedEvent]] |
|- | |- | ||
− | | 135 || [12.0.0+] StartAudioOut | + | | 135 || [12.0.0+] [[#StartAudioOut]] |
|- | |- | ||
− | | 136 || [12.0.0+] StopAudioOut | + | | 136 || [12.0.0+] [[#StopAudioOut]] |
|- | |- | ||
− | | 137 || [12.0.0+] GetAudioOutState | + | | 137 || [12.0.0+] [[#GetAudioOutState]] |
|- | |- | ||
− | | 138 || [12.0.0+] GetAudioOutFeedingCodec | + | | 138 || [12.0.0+] [[#GetAudioOutFeedingCodec]] |
|- | |- | ||
− | | 139 || [12.0.0+] GetAudioOutFeedingParameter | + | | 139 || [12.0.0+] [[#GetAudioOutFeedingParameter]] |
|- | |- | ||
− | | 140 || [12.0.0+] AcquireAudioOutBufferAvailableEvent | + | | 140 || [12.0.0+] [[#AcquireAudioOutBufferAvailableEvent]] |
|- | |- | ||
− | | 141 || [12.0.0+] SendAudioData | + | | 141 || [12.0.0+] [[#SendAudioData]] |
|- | |- | ||
− | | 142 || [12.0.0+] AcquireAudioControlInputStateChangedEvent | + | | 142 || [12.0.0+] [[#AcquireAudioControlInputStateChangedEvent]] |
|- | |- | ||
− | | 143 || [12.0.0+] GetAudioControlInputState | + | | 143 || [12.0.0+] [[#GetAudioControlInputState]] |
|- | |- | ||
− | | 144 || [12.0.0+] AcquireAudioConnectionStateChangedEvent | + | | 144 || [12.0.0+] [[#AcquireAudioConnectionStateChangedEvent]] |
|- | |- | ||
− | | 145 || [12.0.0+] GetConnectedAudioDevice | + | | 145 || [12.0.0+] [[#GetConnectedAudioDevice]] |
|- | |- | ||
| 256 || [5.0.0+] [[#IsManufacturingMode]] | | 256 || [5.0.0+] [[#IsManufacturingMode]] | ||
Line 925: | Line 925: | ||
This uses a BSA extension (message 0x8D0). | This uses a BSA extension (message 0x8D0). | ||
+ | |||
+ | == IsBluetoothEnabled == | ||
+ | No input, returns an output bool. | ||
+ | |||
+ | == AcquireAudioEvent == | ||
+ | No input, returns an output Event handle. | ||
+ | |||
+ | sdknso uses an user-specified EventClearMode. | ||
+ | |||
+ | == GetAudioEventInfo == | ||
+ | Takes a type-0xA output buffer, returns an output [[#AudioEventType]]. | ||
+ | |||
+ | == OpenAudioConnection == | ||
+ | Takes an input [[#Address]], no output. | ||
+ | |||
+ | == CloseAudioConnection == | ||
+ | Takes an input [[#Address]], no output. | ||
+ | |||
+ | == OpenAudioOut == | ||
+ | Takes an input [[#Address]], returns an output u32. | ||
+ | |||
+ | == CloseAudioOut == | ||
+ | Takes an input u32, no output. | ||
+ | |||
+ | == AcquireAudioOutStateChangedEvent == | ||
+ | Takes an input u32, returns an output Event handle. | ||
+ | |||
+ | sdknso uses an user-specified EventClearMode. | ||
+ | |||
+ | == StartAudioOut == | ||
+ | |||
+ | == StopAudioOut == | ||
+ | |||
+ | == GetAudioOutState == | ||
+ | |||
+ | == GetAudioOutFeedingCodec == | ||
+ | |||
+ | == GetAudioOutFeedingParameter == | ||
+ | |||
+ | == AcquireAudioOutBufferAvailableEvent == | ||
+ | |||
+ | == SendAudioData == | ||
+ | |||
+ | == AcquireAudioControlInputStateChangedEvent == | ||
+ | |||
+ | == GetAudioControlInputState == | ||
+ | |||
+ | == AcquireAudioConnectionStateChangedEvent == | ||
+ | |||
+ | == GetConnectedAudioDevice == | ||
== IsManufacturingMode == | == IsManufacturingMode == | ||
Line 946: | Line 996: | ||
[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. | ||
− | |||
− | |||
− | |||
= bt = | = bt = |
Revision as of 18:30, 7 April 2021
btdrv
This is "nn::bluetooth::IBluetoothDriver".
Support for "nn::bluetooth::*" was added to sdknso with 6.x.
btdrv appears to be designed to only be used by the two sysmodules which use it, hid and btm. This service uses global state, nothing service-session-specific.
This has max_sessions 30. IPC handling is done by the main-thread.
As of 10.x these services only support using Hid and BLE devices, other devices such as audio are not usable.
[11.0.0+] sdknso moved various functions/etc from "nn::bluetooth::" into "nn::bluetooth::hal::". This includes all functions exposing btdrv. These btdrv functions now automatically initialize the service if needed, the dedicated initialization function is now a stub since calling it is no longer needed. The internal "nn::bluetooth::user::" functions implementing #bt were moved to "nn::bluetooth::hal::user::", these are called by the the user-facing "nn::bluetooth::" functions.
Cmds 46-83 were added with [4.0.0+].
Various cmds were moved/etc starting with #InitializeBle with [5.0.0+].
InitializeBluetoothDriver
No input/output.
[1.0.0-10.2.0] This is the first cmd used during service init.
This just returns 0.
InitializeBluetooth
No input, returns an output Event handle with EventClearMode=1.
This is used by btm, this should not be used by other processes.
This first initializes the funcptr table interfaces to the defaults (same as #DisableBluetooth). 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.
The funcptr does the following:
- 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 for creating the "nn.bluetooth.HidMessageHandler" thread.
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).
EnableBluetooth
No input/output.
This is used by btm.
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 GetBluetoothBdAddress. If GetBluetoothBdAddress fails, this will Abort. Then the same funcptr used by #SetAdapterProperty is called with this stack data, with 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 type3. Error conversion is handled if needed, then this returns 0.
The first funcptr called above does the following:
- Calls a GPIO func with param=0, sleeps for 10000000 nanoseconds, then calls the GPIO func again with param=1.
- Calls a func for initializing the paired-devices table (empty).
- Calls a modified version of BSA_Boot, which handles BSA server initialization.
- Calls a func which uses
nn::os::InitializeEvent
andnn::os::InitializeMutex
with global state. - Calls a func which handles BSA client initialization. This also sends a message to the "nn.bluetooth.HidMessageHandler" thread for enabling bluetooth (which updates the interface funcptr tables, etc).
- Calls a func which enables HID-Host with BSA, and opens the UIPC channel where the registered funcptr is used for writing HID DATA reports which were received.
- Calls a func which initializes global state and uses BSA for initializing Security.
- If the output flag from GetBluetoothBoostEnableFlag is set, a func is called.
- If the output flag from GetBluetoothAfhEnableFlag is not set, a func is called.
The GPIO func does the following:
- Initializes the gpio service.
- Uses OpenSession with value 0x03 (BtRst).
- Uses SetDirection with value 0x1.
- Uses SetValue with the param which was passed to this func.
- Does cleanup for the session object and exits the service.
DisableBluetooth
No input/output.
This is used by 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.
When bluetooth is already disabled, that funcptr just returns 0. Otherwise when it's already enabled, it does the following:
- Calls a func which closes the HID-Host UIPC channel, and uses BSA for disabling HID-Host.
- Calls a func which uses
nn::os::FinalizeMutex
andnn::os::FinalizeEvent
with global state. - Uses
nn::os::InitializeEvent
,nn::os::InitializeTimerEvent
, with a ptr for the former Event being written into global state. - Uses BTA_DisableBluetooth.
- Uses
nn::os::StartOneShotTimerEvent
with a value of 5 seconds. - Waits for either of the above to trigger using
nn::os::TryWaitEvent
andnn::os::TryWaitTimerEvent
, with each loop iteration sleeping for 5000000 nanoseconds.- The Event is signaled when disabling bluetooth finishes.
- Cleanup for the above Event/TimerEvent is done.
- Calls a func which handles BSA client cleanup.
- Calls a func which does the following:
- Calls a func which tells the "nn.bluetooth.TimerThread" to exit, then destroys that thread (GKI timer thread).
- Calls a func which just returns.
- Calls a func which handles GKI cleanup (including destroying the task threads).
- Calls a func which waits for the UIPC threads to exit + destroys the threads and handles cleanup.
- Calls the same GPIO func as #EnableBluetooth with param=0.
- Sends a message to the "nn.bluetooth.HidMessageHandler" thread for disabling bluetooth (which updates the interface funcptr tables, etc).
FinalizeBluetooth
No input/output.
Not used by btm, other processes should not use this.
Calls an interface funcptr, the ret is ignored. The Event setup by #InitializeBluetooth is closed. Lastly, the same funcs used by #InitializeBluetooth are called for initializing the interface funcptr tables to the defaults, then 0 is returned.
The above interface funcptr does the following (regardless of whether bluetooth is disabled/enabled):
- Calls a func which: uses
nn::os::SignalLightEvent
to tell the "nn.bluetooth.HidMessageHandler" thread to exit, then waits for the thread to exit and destroys the thread. - Calls the same func as #InitializeBluetooth for setting event funcptrs in global state, except in this case the content of the input table is all NULL.
- Calls a func 5 times with param=[1-5]. This is the cleanup version of the nn::bluetooth::CircularBuffer setup func used by #InitializeBluetooth.
GetAdapterProperties
Takes a type-0x1A output buffer containing an #AdapterProperty.
[12.0.0+] Takes a type-0x1A output buffer containing an #AdapterPropertySet.
This is used by btm.
GetAdapterProperty
Takes an input #BluetoothPropertyType and a type-0xA output buffer.
[12.0.0+] Takes an input #AdapterPropertyType and a type-0x1A output buffer containing an #AdapterProperty.
SetAdapterProperty
Takes an input #BluetoothPropertyType and a type-0x9 input buffer.
[12.0.0+] Takes a type-0x19 input buffer containing an #AdapterProperty, no output.
StartInquiry
No input/output.
[12.0.0+] Takes an input BitFlagSet 32bit service_mask and s64 nanoseconds_duration, no output.
This is used by btm.
This starts Inquiry, the output data will be available via #GetEventInfo. Inquiry will automatically stop in 10.24 seconds ([12.0.0+] calculated from the input duration instead).
[12.0.0+] When service_mask is -1 the original defaults from pre-12.0.0 are used (besides duration). Otherwise, service_mask is written into the parameter struct (masked with the all-allowed-BSA-services value), and the EventInfo for discovered devices are triggered when inquiry finishes instead of immediately.
StopInquiry
No input/output.
This is used by btm.
This stops Inquiry which was started by #StartInquiry, if it's still active.
CreateBond
Takes an input #Address and a type-0x19 input buffer containing a #TransportType, no output.
[9.0.0+] Now only takes an #Address and a #TransportType without a buffer, no output.
The #TransportType is unused.
This is used by btm.
RemoveBond
Takes an input #Address, no output.
This is used by btm.
CancelBond
Takes an input #Address, no output.
This is used by btm.
RespondToPinRequest
Takes an input #Address, a bool, an u8, a #BluetoothPinCode, no output.
[12.0.0+] Takes an input #Address, a #PinCode, no output.
sdknso uses an user-specified s32 for the u8.
The sysmodule impl for the funcptr used with this cmd only uses the #Address - this and hard-coded PIN "0000" are written into the parameter struct (and a size field for the PIN).
[12.0.0+] The input #PinCode is now actually used and passed to BSA, instead of hard-coding the PIN.
RespondToSspRequest
Takes an input #Address, a #BluetoothSspVariant, a bool, an u32, no output.
[12.0.0+] Takes an input #Address, a bool, a #BluetoothSspVariant, an u32, no output.
This is used by btm.
The sysmodule impl for the funcptr/vfunc used with this cmd only uses the #Address and bool - the parameter struct size is only 0x7-bytes. The bool indicates whether the request is accepted.
GetEventInfo
Takes a type-0xA output buffer and returns an output #EventType.
This copies 0x400-bytes from state to the output buffer, copies the #EventType from state to output, and signals an event.
This is used by btm.
See #EventInfo.
InitializeHid
Takes an input u16, returns an output Event with EventClearMode=1.
Originally sdknso used an user-specified value for the u16, however with [9.0.0+] it uses hard-coded value 0x1 instead.
This is used by btm, this should not be used by other processes.
OpenHidConnection
Takes an input #Address, no output.
This just returns 0.
This is used by btm.
CloseHidConnection
Takes an input #Address, no output.
This is used by btm.
HidSendData
Takes an input #Address and a type-0x19 input buffer containing a #HidData, no output.
WriteHidData
Takes an input #Address and a type-0x19 input buffer containing a #HidReport, no output.
This is used by hid.
This sends a HID DATA transaction packet with report-type Output.
WriteHidData2
Takes an input #Address and a type-0x9 input buffer, no output.
This is internally the same as #WriteHidData, with the input buffer being directly passed to the funcptr instead of a tmp copy of the input #HidReport.
HidSetReport
Takes an input #Address, a #BluetoothHhReportType, a type-0x19 input buffer containing a #HidData, no output.
SetHidReport
Takes an input #Address, a #BluetoothHhReportType, a type-0x19 input buffer containing a #HidReport, no output.
This is used by hid.
This sends a HID SET_REPORT transaction packet.
GetHidReport
Takes an input #Address, an u8 report_id, a #BluetoothHhReportType, no output.
This is used by hid.
This sends a HID GET_REPORT transaction packet. The report_id is sent in the packet for the Report Id, when non-zero.
HidWakeController
Takes an input #Address, no output.
TriggerConnection
Takes an input #Address and an u16, no output.
This is used by btm.
This calls an interface funcptr, then returns the converted ret as needed.
The funcptr does the following:
- Calls a func, returning the ret on failure. This uses a BSA extension (message 0x8CE), with the input u16 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.
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: u32 +0 = 0x14E18, u16 +4 = 0x20, u8 +6 = 0x2, u16 +7 = {input u16 message param value} (written via u8 writes), u32 +9 = 0x30200, u8 +0xD = 0.
AddPairedDeviceInfo
Takes a type-0x19 input buffer containing BluetoothDevicesSettings, no output.
This is used by btm.
GetPairedDeviceInfo
Takes an input #Address and a type-0x1A output buffer containing BluetoothDevicesSettings.
This is used by btm.
FinalizeHid
No input/output.
Not used by btm, other processes should not use this.
GetHidEventInfo
Takes a type-0xA output buffer, returns an output #HidEventType.
This copies 0x480-bytes from state to the output buffer. #HidEventType is set to: stateval!=0 ? 7 : 0. Once finished, this signals an event.
This is used by btm.
SetTsi
Takes an input #Address and an u8 Tsi, no output.
This is used by btm.
The response will be available via #GetHidEventInfo.
This uses a BSA extension.
Tsi: non-value-0xFF to Set (BSA message 0x8CA), value 0xFF to Exit (BSA message 0x8CB).
Set: this uses command HCI_Set_MWS_Signaling with data determined using the input u8. Then this uses Broadcom HCI vendor command 0xFD95 with param_len=0x2: param +0x0 = 0x1, +0x1 = {Tsi value}. When this vendor command is successful, it then uses command HCI_Sniff_Mode with data selected using the Tsi value as the array-index. If the remote device doesn't support this (status indicating error with Mode Change Event for the response to HCI_Sniff_Mode), an error will be thrown via the EventInfo. That error can be resolved if the remote device uses the HCI_Sniff_Mode command prior to the Switch doing so.
Exit: this uses command HCI_Exit_Sniff_Mode.
EnableBurstMode
Takes an input #Address and a bool, no output.
This is used by btm.
The response will be available via #GetHidEventInfo.
This uses a BSA extension.
bool flag: true = Set (BSA message 0x8CC), false = Exit (BSA message 0x8CD).
SetZeroRetransmission
Takes an input #Address and a type-0x9 input buffer containing an array of u8s, no output.
The entry-count is clamped to a maximum of 5, the count can be 0. This buffer contains ReportIds.
This is used by btm.
The response will be available via #GetHidEventInfo.
This uses a BSA extension (message 0x8CF).
EnableMcMode
Takes an input bool, no output.
This is used by btm.
This uses a BSA extension (message 0x8CE).
EnableLlrScan
No input/output.
This is used by btm.
This uses a BSA extension (message 0x8CE).
DisableLlrScan
No input/output.
This is used by btm.
This uses a BSA extension (message 0x8CE).
EnableRadio
Takes an input bool, no output.
This is used by btm.
This uses a BSA extension (message 0x8CE).
The message is handled by using HCI vendor command 0xFC34 with param_len=0x1: param +0 = {input bool}.
SetVisibility
Takes two input bools, no output.
The first bool controls Inquiry Scan, whether the device can be discovered during Inquiry. The second bool controls Page Scan, whether the device accepts connections.
This is used by btm.
EnableTbfcScan
Takes an input bool, no output.
This is used by btm.
RegisterHidReportEvent
No input, returns an output Event handle with EventClearMode=1.
This gets the Event handle for a previously created Event.
This is used by hid.
The Event is signaled when data is available with #GetHidReportEventInfo.
GetHidReportEventInfo
No input, takes a type-0xA output buffer and returns a #HidEventType.
[7.0.0+] No longer takes a buffer or returns output, now returns an output sharedmem handle. sdknso maps this with size=0x3000 and permissions=RW-.
Originally this was used in a dedicated sdknso func, with [7.0.0+] this is now used at the start of the sdknso impl for #RegisterHidReportEvent if the above sharedmem was not mapped yet.
The [7.0.0+] GetHidReportEventInfo sdknso func loads data using the above sharedmem.
This is used by hid.
GetLatestPlr
Takes a type-0x16 output buffer containing a #PlrList ([1.0.0-8.1.1] #PlrStatistics).
[12.0.0+] Takes a type-0xA output buffer containing an array of #PacketLostRate, returns an output s32.
This calls an interface funcptr then returns 0.
The interface funcptr impl will Abort if the output struct ptr is NULL. Then data is copied from global state to output, doing double->u32 conversion as needed.
GetPendingConnections
No input/output.
This is used by btm.
The output data will be available via #GetHidEventInfo.
GetChannelMap
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 #Channel and bit-count=79.
This calls an interface funcptr then returns 0.
EnableTxPowerBoostSetting
Takes an input bool, no output.
sdknso ignores errors from this. sdknso exposes this under "nn::bluetooth::debug::".
IsTxPowerBoostSettingEnabled
No input, returns an output bool.
sdknso sets the tmpout_bool to 1, and uses that with the cmd. The sdknso func directly returns tmpout_bool, errors from the cmd are ignored.
sdknso exposes this under "nn::bluetooth::debug::".
EnableAfhSetting
Takes an input bool, no output.
sdknso ignores errors from this. sdknso exposes this under "nn::bluetooth::debug::".
IsAfhSettingEnabled
sdknso sets the tmpout_bool to 1, and uses that with the cmd. The sdknso func directly returns tmpout_bool, errors from the cmd are ignored.
sdknso exposes this under "nn::bluetooth::debug::".
InitializeBle
No input, returns an output Event handle with EventClearMode=1.
This is used by btm.
EnableBle
No input/output.
This is used by btm.
DisableBle
No input/output.
This is used by btm.
FinalizeBle
No input/output.
SetBleVisibility
Takes two input bools, no output.
First bool: whether the BLE device is discoverable. Second bool: whether the BLE device is connectable.
SetLeConnectionParameter
Takes a #LeConnectionParams, no output.
SetBleConnectionParameter
Takes an input #Address, a bool, a #BleConnectionParameter, no output.
This is used by btm.
SetLeDefaultConnectionParameter
Takes a #LeConnectionParams, no output.
SetBleDefaultConnectionParameter
Takes a #BleConnectionParameter, no output.
This is used by btm.
SetBleAdvertiseData
Takes a type-0x19 input buffer containing a #BleAdvertisePacketData, no output.
SetBleAdvertiseParameter
Takes an input #Address, two u16s, no output.
StartBleScan
No input/output.
This is used by btm.
StopBleScan
No input/output.
This is used by btm.
AddBleScanFilterCondition
Takes a type-0x19 input buffer containing a #BleAdvertiseFilter, no output.
This is used by btm.
DeleteBleScanFilterCondition
Takes a type-0x19 input buffer containing a #BleAdvertiseFilter, no output.
This is used by btm.
DeleteBleScanFilter
Takes an input u8, no output.
Originally the sdknso func used an u8 for the user-specified param, with [9.0.0+] it's a s32.
ClearBleScanFilters
No input/output.
This is used by btm.
EnableBleScanFilter
Takes an input bool, no output.
This is used by btm.
RegisterGattClient
Takes an input #GattAttributeUuid, no output.
This is used by btm.
UnregisterGattClient
Takes an input u8, no output.
UnregisterAllGattClients
No input/output.
ConnectGattServer
Takes an input u8, an #Address, a bool, an AppletResourceUserId, no output.
This is used by btm.
CancelConnectGattServer
Takes an input u8, an #Address, a bool, no output.
This is used by btm.
DisconnectGattServer
Takes an input u32, no output.
This is used by btm.
GetGattAttribute
Takes an #Address and an u32, no output.
[9.0.0+] Now takes an input u32, no output.
GetGattService
Takes an input u32 and a #GattAttributeUuid, no output.
ConfigureAttMtu
Takes an input u16 and u32, no output.
This is used by btm.
RegisterGattServer
Takes an input #GattAttributeUuid, no output.
UnregisterGattServer
Takes an input u8, no output.
ConnectGattClient
Takes an input u8, an #Address, a bool, no output.
LeServerDisconnect
Takes an input u8, an #Address, no output.
DisconnectGattClient
Takes an input u8, no output.
AddGattService
Takes an input u8, an u8, a bool, a #GattAttributeUuid, no output.
Originally sdknso used an user-specified u8 for the second u8, with [9.0.0+] that func param is now a s32.
EnableGattService
Takes an input u8, a #GattAttributeUuid, no output.
AddGattCharacteristic
Takes an input u8, an u8, an u16, a #GattAttributeUuid, a #GattAttributeUuid, no output.
AddGattDescriptor
Takes an input u8, an u16, a #GattAttributeUuid, a #GattAttributeUuid, no output.
GetBleManagedEventInfo
Takes a type-0xA output buffer, returns an output #BleEventType.
This copies 0x400-bytes from state to the output buffer, and copies the #BleEventType from state to output.
This is used by btm.
GetGattFirstCharacteristic
Takes an input bool, an u32, a #GattId, a #GattAttributeUuid, returns an output u8 Property and CharacteristicId.
GetGattNextCharacteristic
Takes an input bool, an u32, a #GattId, a #GattId, a #GattAttributeUuid, returns an output u8 Property and CharacteristicId.
GetGattFirstDescriptor
Takes an input bool, an u32, a #GattId, a #GattId, a #GattAttributeUuid, returns an output DescriptorId.
GetGattNextDescriptor
Takes an input bool, an u32, a #GattId, a #GattId, a #GattId, a #GattAttributeUuid, returns an output DescriptorId.
RegisterGattManagedDataPath
Takes an input #GattAttributeUuid, no output.
This is used by btm.
UnregisterGattManagedDataPath
Takes an input #GattAttributeUuid, no output.
RegisterGattHidDataPath
Takes an input #GattAttributeUuid, no output.
This is used by btm.
UnregisterGattHidDataPath
Takes an input #GattAttributeUuid, no output.
This is used by btm.
RegisterGattDataPath
Takes an input #GattAttributeUuid, no output.
This is used by btm.
UnregisterGattDataPath
Takes an input #GattAttributeUuid, no output.
This is used by btm.
ReadGattCharacteristic
Takes an input bool PrimaryService, an u8, an u32 ConnectionHandle, a #GattId, a #GattId, no output.
ReadGattDescriptor
Takes an input bool PrimaryService, an u8, an u32 ConnectionHandle, a #GattId, a #GattId, a #GattId, no output.
This is used by hid.
WriteGattCharacteristic
Takes a type-0x9 input buffer, a bool PrimaryService, an u8, a bool, an u32 ConnectionHandle, a #GattId, a #GattId, no output.
The buffer size must be <=0x258.
WriteGattDescriptor
Takes a type-0x9 input buffer, a bool PrimaryService, an u8, an u32 ConnectionHandle, a #GattId, a #GattId, a #GattId, no output.
The buffer size must be <=0x258.
RegisterGattNotification
Takes an input bool, an u32 ConnectionHandle, a #GattId, a #GattId, no output.
UnregisterGattNotification
Takes an input bool, an u32 ConnectionHandle, a #GattId, a #GattId, no output.
This is used by hid.
GetLeHidEventInfo
Takes a type-0xA output buffer, returns an output #BleEventType.
This copies 0x400-bytes from state to the output buffer, and copies the #BleEventType from state to output. This also resets the state which was used for the outbuf-copy. Once finished, this signals an event.
This is used by hid.
See #LeEventInfo for the output buffer.
RegisterBleHidEvent
No input, returns an output Event handle with EventClearMode=1.
This is used by hid.
SetBleScanParameter
Takes two input u16s, no output.
This is used by btm.
MoveToSecondaryPiconet
Takes an input #Address, no output.
The response will be available via #GetHidEventInfo.
This uses a BSA extension (message 0x8D0).
IsBluetoothEnabled
No input, returns an output bool.
AcquireAudioEvent
No input, returns an output Event handle.
sdknso uses an user-specified EventClearMode.
GetAudioEventInfo
Takes a type-0xA output buffer, returns an output #AudioEventType.
OpenAudioConnection
Takes an input #Address, no output.
CloseAudioConnection
Takes an input #Address, no output.
OpenAudioOut
Takes an input #Address, returns an output u32.
CloseAudioOut
Takes an input u32, no output.
AcquireAudioOutStateChangedEvent
Takes an input u32, returns an output Event handle.
sdknso uses an user-specified EventClearMode.
StartAudioOut
StopAudioOut
GetAudioOutState
GetAudioOutFeedingCodec
GetAudioOutFeedingParameter
AcquireAudioOutBufferAvailableEvent
SendAudioData
AcquireAudioControlInputStateChangedEvent
GetAudioControlInputState
AcquireAudioConnectionStateChangedEvent
GetConnectedAudioDevice
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-setting "bluetooth_debug!skip_boot". The first func is the same as the second one, except it writes the bool into global state.
This is used by 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.
bt
This is "nn::bluetooth::IBluetoothUser".
This has max_sessions 30. IPC handling is done by the main-thread.
LeClientReadCharacteristic
Takes a PID, a bool, an u8, an u32, a #GattId, a #GattId, an AppletResourceUserId, no output.
This is essentially the same as #ReadGattCharacteristic, the AppletResourceUserId is unused.
LeClientReadDescriptor
Takes a PID, a bool, an u8, an u32, a #GattId, a #GattId, a #GattId, an AppletResourceUserId, no output.
This is essentially the same as #ReadGattDescriptor, the AppletResourceUserId is unused.
LeClientWriteCharacteristic
Takes a PID, a type-0x9 input buffer, a bool, an u8, a bool, an u32, a #GattId, a #GattId, an AppletResourceUserId, no output.
This is essentially the same as #WriteGattCharacteristic, the AppletResourceUserId is unused.
LeClientWriteDescriptor
Takes a PID, a type-0x9 input buffer, a bool, an u8, an u32, a #GattId, a #GattId, a #GattId, an AppletResourceUserId, no output.
This is essentially the same as #WriteGattDescriptor, the AppletResourceUserId is unused.
LeClientRegisterNotification
Takes a PID, an input bool, an u32, a #GattId, a #GattId, an AppletResourceUserId, no output.
This is essentially the same as #RegisterGattNotification, the AppletResourceUserId is unused.
LeClientDeregisterNotification
Takes a PID, an input bool, an u32, a #GattId, a #GattId, an AppletResourceUserId, no output.
This is essentially the same as #UnregisterGattNotification, the AppletResourceUserId is unused.
SetLeResponse
Takes a PID, a type-0x9 input buffer, an u8, a #GattAttributeUuid, a #GattAttributeUuid, an AppletResourceUserId, no output.
The AppletResourceUserId is unused.
The buffer size must be <=0x258.
LeSendIndication
Takes a PID, a type-0x9 input buffer, an u8, a bool, a #GattAttributeUuid, a #GattAttributeUuid, an AppletResourceUserId, no output.
The AppletResourceUserId is unused.
The buffer size used internally is clamped to max size 0x258.
GetLeEventInfo
Takes a PID, a type-0xA output buffer, an AppletResourceUserId, returns an output #BleEventType.
This is identical to #GetLeHidEventInfo except different state is used. The AppletResourceUserId is unused. See #LeEventInfo for the output buffer.
RegisterBleEvent
Takes a PID, an AppletResourceUserId, returns an output Event handle with EventClearMode=1.
This is identical to #RegisterBleHidEvent except different Event state is used. The AppletResourceUserId is unused.
BluetoothPropertyType
This is u32 enum "nn::bluetooth::BluetoothPropertyType".
The sysmodule will Abort if the input type is unavailable / not recognized.
Value | Description | Buffer contents |
---|---|---|
1 | Name | String, max length 0xF8 excluding NUL-terminator. |
2 | Address | #Address |
3 | Only available with #SetAdapterProperty. Unknown, #Address. The default is the same as type2, with the last two bytes inverted.
This uses a BSA extension (message 0x8CE), the message handler which is used here uses HCI vendor command 0xFD98 with param_len=0x7: u8 param+0 = {whether the #Address is non-zero}, +1 6-bytes = {#Address with byte-order swapped}. | |
5 | 3-bytes, Class of Device. | |
6 | 1-byte, FeatureSet. The default is value 0x68. |
AdapterPropertyType
This is u32 enum "nn::bluetooth::hal::AdapterPropertyType".
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".
Value | Name | Description |
---|---|---|
0 | The funcptr which writes the data into state for this event is not called (only checked on [10.0.0]). | |
3 | New device found during Inquiry. | |
4 | Inquiry status changed. | |
5 | Triggered by BSA_SEC_PIN_REQ_EVT: PIN code request for pairing. | |
6 | Triggered by BSA_SEC_SP_CFM_REQ_EVT/BSA_SEC_SP_KEY_NOTIF_EVT: SSP confirm request / SSP passkey notification. | |
7 | Connection | |
13 | BluetoothCrash. Triggered by #EmulateBluetoothCrash and BSA_MGT_DISCONNECT_EVT. |
ConnectionEventType
This is the event value in #EventInfo when #EventType is type7.
Value | Name | Description |
---|---|---|
0 | Connection status. | |
1 | Triggered by BSA_SEC_SP_CFM_REQ_EVT: SSP confirm request. | |
2 | Triggered by BSA_SEC_SUSPENDED_EVT: ACL Link is now Suspended. |
BluetoothHhReportType
This is u32 enum "nn::bluetooth::BluetoothHhReportType".
Bit0-1 directly control the HID bluetooth transaction report-type value. Bit2-3: these directly control the Parameter Reserved field for SetReport, for GetReport these control the Parameter Reserved and Size bits.
Value | Description |
---|---|
0 | Other |
1 | Input |
2 | Output |
3 | Feature |
HidEventType
This is u32 enum "nn::bluetooth::HidEventType".
Value | Name | Description |
---|---|---|
0 | Connection. Only used with #GetHidEventInfo. | |
4 | DATA report on the Interrupt channel. | |
7 | Response for extensions. Only used with #GetHidEventInfo. | |
8 | Response to SET_REPORT. | |
9 | Response to GET_REPORT. |
BleEventType
This is u32 enum "nn::bluetooth::BleEventType".
FatalReason
This is u32 enum "nn::bluetooth::FatalReason".
This determines the u16 data to write into the CircularBuffer. #EmulateBluetoothCrash handles values outside of 1-2 the same as value 3.
Value | Description |
---|---|
0 | Only for #EventInfo: invalid. |
1 | u16 data = 0x850. Can only be triggered by #EmulateBluetoothCrash, not triggered by the sysmodule otherwise. |
2 | u16 data = 0x851. HCI command timeout. |
3 | u16 data = 0x852. HCI event HCI_Hardware_Error occurred. |
7 | Only for #EventInfo: triggered after enabling bluetooth, when a global state field is value 4 or 2. |
AdapterProperty
This is "nn::bluetooth::AdapterProperty" ([12.0.0+] "nn::bluetooth::hal::AdapterProperty"). This is a 0x103-byte ([12.0.0+] 0x102-byte) struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x6 | Same as the data for #BluetoothPropertyType type2. |
0x6 | 0x3 | Same as the data for #BluetoothPropertyType type5. |
0x9 | 0xF9 | Same as the data for #BluetoothPropertyType type1 (last byte is not initialized). |
0x102 | 0x1 | Set to hard-coded value 0x68 (same as the data for #BluetoothPropertyType type6). |
[12.0.0+]:
{...}
AdapterPropertySet
This is "nn::bluetooth::hal::AdapterPropertySet". This is a 0x102-byte struct.
Address
This is "nn::bluetooth::Address". This is a 0x6-byte struct with 1-byte alignment.
EventInfo
This is the output buffer for #GetEventInfo. The data stored here depends on the #EventType.
Offset | Size | Description |
---|---|---|
0x0 | 0x4 |
Offset | Size | Description |
---|---|---|
0x0 | 0xF9 | Device name, NUL-terminated string. |
0xF9 | 0x6 | Device address. |
0xFF | 0x10 | Reserved |
0x10F | 0x3 | Class of Device. |
0x112 | 0x4 | Set to fixed value u32 0x1. |
0x116 | 0xFA | Reserved |
0x210 | 0x5C | Reserved |
0x26C | 0xF9 | Device name, NUL-terminated string. Same as name above, except starting at index 1. |
0x365 | 0x4 | s32 RSSI |
0x369 | 0x4 | Two bytes which are the same as name[11-12]. |
0x36D | 0x10 | Reserved |
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Status: 0 = stopped, 1 = started. |
Offset | Size | Description |
---|---|---|
0x0 | 0x6 | Device address. |
0x6 | 0xF9 | Device name, NUL-terminated string. |
0xFF | 0x3 | Class of Device. |
Offset | Size | Description |
---|---|---|
0x0 | 0x6 | Device address. |
0x6 | 0xF9 | Device name, NUL-terminated string. |
0xFF | 0x3 | Class of Device. |
0x102 | 0x2 | Padding |
0x104 | 0x4 | 0 = SSP confirm request, 3 = SSP passkey notification. |
0x108 | 0x4 | s32 Passkey, only set when the above field is value 3. |
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Status, always 0 except with 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. |
0xA | 0x2 | Padding |
0xC | 0x4 | #ConnectionEventType |
Offset | Size | Description |
---|---|---|
0x0 | 0x2 | #FatalReason |
BluetoothPinCode
This is "nn::bluetooth::BluetoothPinCode". This is a 0x10-byte struct with 1-byte alignment.
PinCode
This is "nn::bluetooth::hal::PinCode". This is a 0x11-byte struct with 1-byte alignment.
Offset | Size | Description |
---|---|---|
0x0 | 0xF | PinCode |
0xF | 0x1 | PinCode length, must be 0x1-0xF otherwise the sysmodule will Abort. |
ServiceFlag
This is "nn::bluetooth::hal::ServiceFlag". This is the same as the BSA service-mask.
HidData
This is "nn::bluetooth::HidData". This is a 0x282-byte struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x2 | Size of the following data. |
0x2 | 0x280 | Data |
HidReport
This is "nn::bluetooth::HidReport". This is a 0x2BE-byte struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x2 | Size of the following data. |
0x2 | 0x2BC | Data |
PlrStatistics
This is "nn::bluetooth::PlrStatistics". This is a 0x84-byte struct.
PlrList
This is "nn::bluetooth::PlrList". This is a 0xA4-byte struct.
PacketLostRate
This is "nn::bluetooth::hal::PacketLostRate".
ChannelMapList
This is "nn::bluetooth::ChannelMapList". This is a 0x88-byte struct.
Channel
This is "nn::bluetooth::hal::Channel".
LeChannel
This is "nn::bluetooth::hal::LeChannel".
LeConnectionParams
This is "nn::bluetooth::LeConnectionParams". This is a 0x14-byte struct with 2-byte alignment.
BleConnectionParameter
This is "nn::bluetooth::BleConnectionParameter". This is a 0xC-byte struct with 2-byte alignment.
BleAdvertisePacketData
This is "nn::bluetooth::BleAdvertisePacketData" ([5.0.0-8.1.1] "nn::bluetooth::LeAdvertiseData"). This is a 0xCC-byte struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | |
0x4 | 0x1 | |
0x5 | 0x1 | Size of the data at +0x6. |
0x6 | 0x1F | |
0x25 | 0x3 | Padding |
0x28 | 0x1 | Total array entries for the below array, can be 0. |
0x29 | 0x7 | Padding |
0x30 | count*0x14 | Array entries, see below. |
0xA4 | 0x1 | Size of the data at +0xA8. |
0xA5 | 0x1 | |
0xA6 | 0x2 | Padding |
0xA8 | 0x1F | |
0xC7 | 0x1 | |
0xC8 | 0x1 | |
0xC9 | 0x3 | Padding |
Array entry:
Offset | Size | Description |
---|---|---|
0x0 | 0x2 | |
0x2 | 0x12 | Unused |
BleAdvertiseFilter
This is "nn::bluetooth::BleAdvertiseFilter". This is a 0x3E-byte struct.
BleAdvertisePacketParameter
This is "nn::bluetooth::BleAdvertisePacketParameter". This is a 8-byte struct with 1-byte alignment.
BleScanResult
This is "nn::bluetooth::BleScanResult". This is a 0x148-byte struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | |
0x1 | 0x6 | #Address |
0x7 | 0x139 | |
0x140 | 0x4 | s32 |
0x144 | 0x4 | s32 |
BleConnectionInfo
This is "nn::bluetooth::BleConnectionInfo". This is a 0xC-byte struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | ConnectionHandle, 0xFFFFFFFF ([5.0.0-5.0.2] 0xFFFF) is invalid. |
0x4 | 0x6 | #Address |
0xA | 0x2 | Padding |
GattAttributeUuid
This is "nn::bluetooth::GattAttributeUuid". This is a 0x14-byte struct with 4-byte alignment.
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | UUID size, must be 0x2, 0x4, or 0x10. |
0x4 | 0x10 | UUID with the above size. |
GattId
This is "nn::bluetooth::GattId". This is a 0x18-byte struct with 4-byte alignment.
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | InstanceId |
0x1 | 0x3 | Padding |
0x4 | 0x14 | #GattAttributeUuid |
LeEventInfo
This is a 0x400-byte struct.
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | |
0x4 | 0x4 | |
0x8 | 0x1 | |
0x9 | 0x3 | Padding |
0xC | 0x14 | #GattAttributeUuid |
0x20 | 0x14 | #GattAttributeUuid |
0x34 | 0x14 | #GattAttributeUuid |
0x48 | 0x2 | Size of the below data. |
0x4A | {above size} | Data. |
BleClientGattOperationInfo
This is "nn::bluetooth::BleClientGattOperationInfo". This is converted from #LeEventInfo.
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Converted from #LeEventInfo+0x0. |
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. |
Notes
The output from sudo hcitool info {BDADDR}
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> <EV4 packets> <EV5 packets> <AFH cap. slave> <AFH class. slave> <LE support> <3-slot EDR ACL> <5-slot EDR ACL> <sniff subrating> <pause encryption> <AFH cap. master> <AFH class. master> <EDR eSCO 2 Mbps> <EDR eSCO 3 Mbps> <3-slot EDR eSCO> <extended inquiry> <LE and BR/EDR> <simple pairing> <encapsulated PDU> <err. data report> <non-flush flag> <LSTO> <inquiry TX power> <EPC> <extended features> Features page 1: 0x0f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 Features page 2: 0x7f 0x0b 0x00 0x00 0x00 0x00 0x00 0x00
The bluetooth driver implements the bluetooth protocol over h4/uart. It interfaces with the uart service to actually talk with the bluetooth hardware.
The bluetooth stack is Broadcom/Cypress brcm BSA (for example, see here).
Various btdrv service commands use a custom BSA extension (message-ids based at 0x8CA/2250), this is referred to as "robson".
The following L2CAP services are registered (dynamic channels): SDP, ATT (GATT), RFCOMM, HID (PSMs: 0x11, 0x13, 0x8001, 0x8003).
l2cu_send_peer_echo_rsp
is called with p_data=NULL and data_len=0, therefore no data is returned in the L2CAP ECHO response.
The following HID transaction types are supported (by hidh_l2cif_data_ind
): HANDSHAKE, CONTROL (only param VIRTUAL_CABLE_UNPLUG is supported), DATA, DATAC.
- DATAC is not actually supported, since the callback function (
bta_hh_cback
) just frees the message and returns.
Versions
System Version | bsa_version_string | bsa_version_info_string | Config string |
---|---|---|---|
[1.0.0] | BSA0106_01.60.00_ | Hayward_J3_Patch_20161118 | BCM4356A3_001.004.009.0045.0000 |
[2.0.0] | BSA0106_01.60.00_ | Hayward_J5_RC_20161227 | BCM4356A3_001.004.009.0047.0049 |
[3.0.0-3.0.1] | BSA0106_01.60.00_ | Hayward_K4_RC_20170504 | BCM4356A3_001.004.009.0054.0056 |
[4.0.0] | BSA0106_01.60.00_ | Hayward_L4_RC_20170815 | CYW4356A3_001.004.009.0057.0059 |
[5.0.0] | BSA0106_01.60.00_ | Hayward_M2_RC_20180109 | CYW4356A3_001.004.009.0059.0061 |
[5.1.0] | BSA0106_01.60.00_ | Hayward_N1_RC_20180226 | CYW4356A3_001.004.009.0062.0064 |
[6.0.0-6.2.0] | BSA0106_01.60.00_ | Hayward_N3_RC_20180612 | CYW4356A3_001.004.009.0062.0064 |
[7.0.0] | BSA0106_01.60.00_ | Hayward_O1_RC_20180829 | CYW4356A3_001.004.009.0076.0077 |
[8.0.0-9.0.0] | BSA0106_01.60.00_ | Hayward_P1_RC_20190121 | CYW4356A3_001.004.009.0076.0077 |
[10.0.0-11.0.0] | BSA0106_01.60.00_ | Hayward_R2_RC_20191119 | CYW4356A3_001.004.009.0092.0095 |
[12.0.0] | BSA0106_01.60.00_ | Hayward_T3_RC_20210224 | CYW4356A3_001.004.009.0092.0095 |
bsa_sv_tm_read_version_excback
copies bsa_version_string and concats with bsa_version_info_string to generate tBSA_TM_READ_VERSION.bsa_server_version
.