Bluetooth Filter Driver for DS3-compatibility - research notes
-
PSMs shall be odd and the least significant bit of the most significant byte shall be zero, hence the following ranges do not contain valid PSMs: 0x0100-0x01FF, 0x0300-0x03FF, 0x0500-0x05FF, 0x0700-0x07FF, 0x0900-0x09FF, 0x0B00-0x0BFF, 0x0D00-0x0DFF, 0x0F00-0x0FFF. All even values are also not valid as PSMs.
-
Really interesting, keep up the good work!
Am I right in assuming these are research notes for an Airbender successor?
-
@414n not quite, this is already a successor successor
The AirBender successor is code-named WireShock and already exists in the lab, has working support for fake DS3s and doesn't require additional software to function (AirBender needs Shibari to actually function).
However, WireShock is - like AirBender - a USB function driver, which means it needs to replace the entire default Windows Bluetooth driver which means your Bluetooth host gets unusable for anything else that is not a DualShock. That's the same technique ScpToolkit used.
This research is my attempt to discover "the holy grail"; a solution which keeps the existing Bluetooth drivers in place so headsets, keyboards etc. keep working but allows transparent co-existence with DualShock/Nav/Move 3 devices.
-
Right, now that we've gotten so far to send back a connection response, the second channel pops up and requires a "proxy-PSM" as well:
UrbFunctionBulkInTransferCompleted 2019/01/05-18:11:16.983 TRACE_LEVEL_INFORMATION >> L2CAP_Connection_Request UrbFunctionBulkInTransferCompleted 2019/01/05-18:11:16.983 TRACE_LEVEL_INFORMATION ++ PSM: 0x13
May I just add that writing a Bluetooth Profile Driver takes forever even if you can steal big chunks of code from the Windows driver samples
-
Oh yeah, registering a proxy PSM for
PSM_HID_INTERRUPT
as well shoots us even further forward:UrbFunctionInterruptInTransferCompleted 2019/01/05-21:13:01.717 TRACE_LEVEL_INFORMATION HCI_Connection_Complete_EV UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.742 TRACE_LEVEL_VERBOSE UrbFunctionBulkInTransferCompleted Entry UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.742 TRACE_LEVEL_INFORMATION >> L2CAP_Connection_Request UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.742 TRACE_LEVEL_INFORMATION ++ PSM: 0x11 UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.742 TRACE_LEVEL_INFORMATION ++ Patching PSM to 0x5053 UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.763 TRACE_LEVEL_VERBOSE UrbFunctionBulkInTransferCompleted Entry UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.763 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Request UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.765 TRACE_LEVEL_VERBOSE UrbFunctionBulkInTransferCompleted Entry UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.765 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Response UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.771 TRACE_LEVEL_VERBOSE UrbFunctionBulkInTransferCompleted Entry UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.771 TRACE_LEVEL_INFORMATION >> L2CAP_Connection_Request UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.771 TRACE_LEVEL_INFORMATION ++ PSM: 0x13 UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.771 TRACE_LEVEL_INFORMATION ++ Patching PSM to 0x5055 UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.781 TRACE_LEVEL_VERBOSE UrbFunctionBulkInTransferCompleted Entry UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.781 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Request UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.783 TRACE_LEVEL_VERBOSE UrbFunctionBulkInTransferCompleted Entry UrbFunctionBulkInTransferCompleted 2019/01/05-21:13:01.783 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Response
Which generates some more noise in the profile driver:
2019/01/05-21:13:01.379 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Entry 2019/01/05-21:13:01.379 TRACE_LEVEL_INFORMATION BthPS3IndicationCallback ++ IndicationRemoteConnect 2019/01/05-21:13:01.379 TRACE_LEVEL_VERBOSE BthPS3SendConnectResponse Entry 2019/01/05-21:13:01.379 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Entry 2019/01/05-21:13:01.379 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Exit 2019/01/05-21:13:01.379 TRACE_LEVEL_VERBOSE BthPS3SendConnectResponse Exit (STATUS_SUCCESS (0x00000000)) 2019/01/05-21:13:01.379 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Exit 2019/01/05-21:13:01.389 TRACE_LEVEL_VERBOSE BthPS3RemoteConnectResponseCompletion Entry 2019/01/05-21:13:01.389 TRACE_LEVEL_INFORMATION Connection completion, status: STATUS_SUCCESS (0x00000000) 2019/01/05-21:13:01.389 TRACE_LEVEL_INFORMATION Connection established with client 2019/01/05-21:13:01.389 TRACE_LEVEL_INFORMATION Connection completed, connection: 0xFFFFFA80089CC0C0 2019/01/05-21:13:01.389 TRACE_LEVEL_VERBOSE BthPS3RemoteConnectResponseCompletion Exit 2019/01/05-21:13:01.395 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Entry 2019/01/05-21:13:01.395 TRACE_LEVEL_INFORMATION BthPS3IndicationCallback ++ IndicationRemoteConnect 2019/01/05-21:13:01.395 TRACE_LEVEL_VERBOSE BthPS3SendConnectResponse Entry 2019/01/05-21:13:01.395 TRACE_LEVEL_VERBOSE BthPS3SendConnectResponse Exit (STATUS_SUCCESS (0x00000000)) 2019/01/05-21:13:01.395 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Exit 2019/01/05-21:13:01.395 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Entry 2019/01/05-21:13:01.395 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Exit 2019/01/05-21:13:01.413 TRACE_LEVEL_VERBOSE BthPS3RemoteConnectResponseCompletion Entry 2019/01/05-21:13:01.413 TRACE_LEVEL_INFORMATION Connection completion, status: STATUS_DEVICE_NOT_CONNECTED (0xC000009D) 2019/01/05-21:13:01.413 TRACE_LEVEL_VERBOSE BthPS3RemoteConnectResponseCompletion Exit
Now ofc. the state machine I ripped off the
bthecho
sample driver goes crazy here and the connection drops but both channels connection requests actually bubble up to our driver, that's good news -
Btw. if you attempt to register one of the "forbidden" PSMs within your profile driver like so:
DevCtx->Header.ProfileDrvInterface.BthReuseBrb( &(DevCtx->RegisterUnregisterBrb), BRB_REGISTER_PSM ); brb = (struct _BRB_PSM *) &(DevCtx->RegisterUnregisterBrb); brb->Psm = PSM_HID_CONTROL; // LOL, nope status = BthPS3SendBrbSynchronously( DevCtx->Header.IoTarget, DevCtx->Header.Request, (PBRB)brb, sizeof(*brb) );
the system crashes
no NT_STATUS failure code, you'll be sent straight to hell. So, uh, don't do that
-
This is how the profile driver could look like, notice the original host driver still being in place:
The Hardware ID would be
BTHENUM\{CUSTOM_SERVICE_GUID}
where in my lab example I simply recycled the onebthecho
uses:The service GUID I registered with a WinAPI call to BluetoothSetLocalServiceInfo:
DWORD SetBthServiceInfo( BOOLEAN bEnabled ) { DWORD err = ERROR_SUCCESS; BLUETOOTH_LOCAL_SERVICE_INFO SvcInfo = {0}; SvcInfo.Enabled = bEnabled; if (FAILED(StringCbCopyW(SvcInfo.szName, sizeof(SvcInfo.szName), BthEchoSampleSvcName))) { printf("Copying svc name failed\n"); goto exit; } if (ERROR_SUCCESS != (err = BluetoothSetLocalServiceInfo( NULL, //callee would select the first found radio &BTHECHOSAMPLE_SVC_GUID, 0, &SvcInfo ))) { printf("BluetoothSetLocalServiceInfo failed, err = %d\n", err); goto exit; } exit: return err; }
Again, simply taken from the Microsoft sample. I also noticed, that the
bthsrvinst
project links againstBluetoothApis.lib
, which bombs on Windows 7. Link againstBthprops.lib
instead and it will work.Supported in Windows 8 and later versions of Windows.
-
2019/01/08-18:50:55.893 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Entry 2019/01/08-18:50:55.893 TRACE_LEVEL_INFORMATION New connection for 5053 from AC7A4D2819AC arrived 2019/01/08-18:50:55.893 TRACE_LEVEL_VERBOSE L2CAP_PS3_SendConnectResponse Entry 2019/01/08-18:50:55.893 TRACE_LEVEL_VERBOSE L2CAP_PS3_ConnectResponsePendingCompleted Entry 2019/01/08-18:50:55.893 TRACE_LEVEL_INFORMATION Connection PENDING completed with status: STATUS_SUCCESS (0x00000000) 2019/01/08-18:50:55.893 TRACE_LEVEL_VERBOSE L2CAP_PS3_ConnectResponsePendingCompleted Exit 2019/01/08-18:50:55.893 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Entry 2019/01/08-18:50:55.893 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Exit 2019/01/08-18:50:55.893 TRACE_LEVEL_VERBOSE L2CAP_PS3_SendConnectResponse Exit (STATUS_SUCCESS (0x00000000)) 2019/01/08-18:50:55.893 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Exit 2019/01/08-18:50:55.904 TRACE_LEVEL_VERBOSE BthPS3RemoteConnectResponseCompletion Entry 2019/01/08-18:50:55.904 TRACE_LEVEL_INFORMATION Connection completion, status: STATUS_SUCCESS (0x00000000) 2019/01/08-18:50:55.904 TRACE_LEVEL_INFORMATION Connection established with client 2019/01/08-18:50:55.904 TRACE_LEVEL_INFORMATION Connection completed, connection: 0xFFFFFA8009F6C480 2019/01/08-18:50:55.904 TRACE_LEVEL_VERBOSE BthPS3RemoteConnectResponseCompletion Exit 2019/01/08-18:50:55.911 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Entry 2019/01/08-18:50:55.911 TRACE_LEVEL_INFORMATION New connection for 5055 from AC7A4D2819AC arrived 2019/01/08-18:50:55.911 TRACE_LEVEL_VERBOSE L2CAP_PS3_SendConnectResponse Entry 2019/01/08-18:50:55.911 TRACE_LEVEL_VERBOSE L2CAP_PS3_SendConnectResponse Exit (STATUS_SUCCESS (0x00000000)) 2019/01/08-18:50:55.911 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Exit 2019/01/08-18:50:55.911 TRACE_LEVEL_VERBOSE L2CAP_PS3_ConnectResponsePendingCompleted Entry 2019/01/08-18:50:55.911 TRACE_LEVEL_INFORMATION Connection PENDING completed with status: STATUS_SUCCESS (0x00000000) 2019/01/08-18:50:55.911 TRACE_LEVEL_VERBOSE L2CAP_PS3_ConnectResponsePendingCompleted Exit 2019/01/08-18:50:55.911 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Entry 2019/01/08-18:50:55.911 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Exit 2019/01/08-18:50:55.927 TRACE_LEVEL_VERBOSE BthPS3RemoteConnectResponseCompletion Entry
Right, so the connection handshake works for both Control and Interrupt channel, now I need to copypasta a ton of code to send and respond to the configuration requests. And extend the state machine to handle two channels instead of one like the example code intended. Oh dear
-
Nope, wrong assumption. The profile driver doesn't craft configuration requests, the parent driver does.
Sniff-log from under
BTHUSB
:2019/01/08-19:06:14.202 TRACE_LEVEL_INFORMATION >> L2CAP_Connection_Request 2019/01/08-19:06:14.233 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response (Response: 01) 2019/01/08-19:06:14.233 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response (Response: 01) 2019/01/08-19:06:14.233 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response (Response: 00) 2019/01/08-19:06:14.233 TRACE_LEVEL_INFORMATION << L2CAP_Configuration_Request 2019/01/08-19:06:14.245 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Request 2019/01/08-19:06:14.245 TRACE_LEVEL_INFORMATION << L2CAP_Configuration_Response 2019/01/08-19:06:14.247 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Response 2019/01/08-19:06:14.253 TRACE_LEVEL_INFORMATION >> L2CAP_Connection_Request 2019/01/08-19:06:14.253 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response (Response: 01) 2019/01/08-19:06:14.253 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response (Response: 01) 2019/01/08-19:06:14.253 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response (Response: 00) 2019/01/08-19:06:14.253 TRACE_LEVEL_INFORMATION << L2CAP_Configuration_Request 2019/01/08-19:06:14.266 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Request 2019/01/08-19:06:14.266 TRACE_LEVEL_INFORMATION << L2CAP_Configuration_Response 2019/01/08-19:06:14.267 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Response 2019/01/08-19:06:14.275 TRACE_LEVEL_INFORMATION >> L2CAP_Disconnection_Request 2019/01/08-19:06:14.281 TRACE_LEVEL_INFORMATION >> L2CAP_Disconnection_Request
That's both cool and frightening; hopefully the host knows what it's doing
Also, why is PENDING sent twice per channel
did I do that or the host...
EDIT: I did that, no need for it, the parent driver has everything under control
-
Sniffing intensifies
2019/01/08-20:04:06.318 TRACE_LEVEL_INFORMATION >> L2CAP_Connection_Request [Code: 0x02, Identifier: 0x01, Length: 4, PSM: 0x5053, SCID: 0x1440] 2019/01/08-20:04:06.349 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x01, Length: 8, DCID: 0x0000, SCID: 0x1440, Result: 0x0001, Status: 0x0000] 2019/01/08-20:04:06.349 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x01, Length: 8, DCID: 0x0000, SCID: 0x1440, Result: 0x0001, Status: 0x0000] 2019/01/08-20:04:06.349 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x01, Length: 8, DCID: 0x0040, SCID: 0x1440, Result: 0x0000, Status: 0x0000] 2019/01/08-20:04:06.349 TRACE_LEVEL_INFORMATION << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x01, Length: 8, DCID: 0x1440, Flags: 0x0000, Options: 0x02A00201] 2019/01/08-20:04:06.360 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x02, Length: 4, DCID: 0x0040, Flags: 0x0000, Options: 0x00001000] 2019/01/08-20:04:06.361 TRACE_LEVEL_INFORMATION << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x02, Length: 6, SCID: 0x1440, Flags: 0x0000, Result: 0x0000, Options: 0x0000] 2019/01/08-20:04:06.362 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x01, Length: 6, SCID: 0x0040, Flags: 0x0000, Result: 0x0000, Options: 0x0052] 2019/01/08-20:04:06.369 TRACE_LEVEL_INFORMATION >> L2CAP_Connection_Request [Code: 0x02, Identifier: 0x03, Length: 4, PSM: 0x5055, SCID: 0x1481] 2019/01/08-20:04:06.369 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x03, Length: 8, DCID: 0x0000, SCID: 0x1481, Result: 0x0001, Status: 0x0000] 2019/01/08-20:04:06.369 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x03, Length: 8, DCID: 0x0000, SCID: 0x1481, Result: 0x0001, Status: 0x0000] 2019/01/08-20:04:06.369 TRACE_LEVEL_INFORMATION << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x03, Length: 8, DCID: 0x0041, SCID: 0x1481, Result: 0x0000, Status: 0x0000] 2019/01/08-20:04:06.369 TRACE_LEVEL_INFORMATION << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x02, Length: 8, DCID: 0x1481, Flags: 0x0000, Options: 0x02A00201] 2019/01/08-20:04:06.380 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x04, Length: 28, DCID: 0x0041, Flags: 0x0000, Options: 0x02001603] 2019/01/08-20:04:06.381 TRACE_LEVEL_INFORMATION << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x04, Length: 30, SCID: 0x1481, Flags: 0x0000, Result: 0x0001, Options: 0x1603] 2019/01/08-20:04:06.383 TRACE_LEVEL_INFORMATION >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x02, Length: 6, SCID: 0x0041, Flags: 0x0000, Result: 0x0000, Options: 0x0052] 2019/01/08-20:04:06.389 TRACE_LEVEL_INFORMATION >> L2CAP_Disconnection_Request [Code: 0x06, Identifier: 0x05, Length: 4, DCID: 0x0041, SCID: 0x1481] 2019/01/08-20:04:06.389 TRACE_LEVEL_INFORMATION << L2CAP_Disconnection_Response [Code: 0x07, Identifier: 0x05, Length: 4, DCID: 0x0041, SCID: 0x1481] 2019/01/08-20:04:06.399 TRACE_LEVEL_INFORMATION >> L2CAP_Disconnection_Request [Code: 0x06, Identifier: 0x06, Length: 4, DCID: 0x0040, SCID: 0x1440] 2019/01/08-20:04:06.399 TRACE_LEVEL_INFORMATION << L2CAP_Disconnection_Response [Code: 0x07, Identifier: 0x06, Length: 4, DCID: 0x0040, SCID: 0x1440]
-
L2CAP Channel Configuration
MTU
A successful agreement on MTU value
L2CAP_MAX_MTU
:<< L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x15, Length: 8, DCID: 0x3240, Flags: 0x0000, Options: 0xFFFF0201] >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x02, Length: 4, DCID: 0x0040, Flags: 0x0000, Options: 0x02010000] << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x02, Length: 6, SCID: 0x3240, Flags: 0x0000, Result: 0x0000, Options: 0x0000] >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x15, Length: 10, SCID: 0x0040, Flags: 0x0000, Result: 0x0000, Options: 0x0201] << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x16, Length: 8, DCID: 0x3281, Flags: 0x0000, Options: 0xFFFF0201] >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x16, Length: 10, SCID: 0x0041, Flags: 0x0000, Result: 0x0000, Options: 0x0201]
QOS
Controller and host currently can't agree on QUALITY OF SERVICE (QOS) OPTION.
Option
0x02001603
is translated to:0x03
(QoS option type) with length of 22 (0x16
) and requested option is0x0200
(0x02
= Service Type as Guaranteed,L2CAP_FLOW_SERVICE_TYPE_GUARANTEED
)>> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x04, Length: 28, DCID: 0x0041, Flags: 0x0000, Options: 0x02001603] << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x04, Length: 30, SCID: 0x3281, Flags: 0x0000, Result: 0x0001, Options: 0x1603]
-
Ladies and gentlemen, we got him
The DS3 is connected to standard Windows Bluetooth Stack
I must be dreaming
it actually works, my DS3 is connected to an USB Bluetooth dongle running the standard Windows Bluetooth Stack, the filter and the profile driver!
git commit && git push
Lower filter log
2019/01/08-21:02:33.479 >> L2CAP_Connection_Request [Code: 0x02, Identifier: 0x01, Length: 4, PSM: 0x5053, SCID: 0x42C0] 2019/01/08-21:02:33.491 << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x01, Length: 8, DCID: 0x0000, SCID: 0x42C0, Result: 0x0001, Status: 0x0000] 2019/01/08-21:02:33.491 << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x01, Length: 8, DCID: 0x0040, SCID: 0x42C0, Result: 0x0000, Status: 0x0000] 2019/01/08-21:02:33.491 << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x03, Length: 8, DCID: 0x42C0, Flags: 0x0000, Options: 0xFFFF0201] 2019/01/08-21:02:33.497 >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x02, Length: 4, DCID: 0x0040, Flags: 0x0000, Options: 0x00010004] 2019/01/08-21:02:33.497 << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x02, Length: 6, SCID: 0x42C0, Flags: 0x0000, Result: 0x0000, Options: 0x0000] 2019/01/08-21:02:33.499 >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x03, Length: 10, SCID: 0x0040, Flags: 0x0000, Result: 0x0000, Options: 0x0201] 2019/01/08-21:02:33.507 >> L2CAP_Connection_Request [Code: 0x02, Identifier: 0x03, Length: 4, PSM: 0x5055, SCID: 0x4301] 2019/01/08-21:02:33.507 << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x03, Length: 8, DCID: 0x0000, SCID: 0x4301, Result: 0x0001, Status: 0x0000] 2019/01/08-21:02:33.507 << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x03, Length: 8, DCID: 0x0041, SCID: 0x4301, Result: 0x0000, Status: 0x0000] 2019/01/08-21:02:33.507 << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x04, Length: 8, DCID: 0x4301, Flags: 0x0000, Options: 0xFFFF0201] 2019/01/08-21:02:33.516 >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x04, Length: 28, DCID: 0x0041, Flags: 0x0000, Options: 0x02001603] 2019/01/08-21:02:33.516 << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x04, Length: 6, SCID: 0x4301, Flags: 0x0000, Result: 0x0000, Options: 0x0000] 2019/01/08-21:02:33.519 >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x04, Length: 10, SCID: 0x0041, Flags: 0x0000, Result: 0x0000, Options: 0x0201]
Profile driver log
2019/01/08-21:02:33.201 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Entry 2019/01/08-21:02:33.201 TRACE_LEVEL_INFORMATION New connection for PSM 0x5053 from AC7A4D2819AC arrived 2019/01/08-21:02:33.201 TRACE_LEVEL_VERBOSE L2CAP_PS3_SendConnectResponse Entry 2019/01/08-21:02:33.201 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Entry 2019/01/08-21:02:33.201 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Exit 2019/01/08-21:02:33.201 TRACE_LEVEL_VERBOSE L2CAP_PS3_SendConnectResponse Exit (STATUS_SUCCESS (0x00000000)) 2019/01/08-21:02:33.201 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Exit 2019/01/08-21:02:33.209 TRACE_LEVEL_VERBOSE L2CAP_PS3_ConnectResponseCompleted Entry 2019/01/08-21:02:33.209 TRACE_LEVEL_INFORMATION Connection completion, status: STATUS_SUCCESS (0x00000000) 2019/01/08-21:02:33.209 TRACE_LEVEL_INFORMATION Connection established with client 2019/01/08-21:02:33.209 TRACE_LEVEL_INFORMATION Connection completed, connection: 0xFFFFFA8009A7A5E0 2019/01/08-21:02:33.209 TRACE_LEVEL_VERBOSE L2CAP_PS3_ConnectResponseCompleted Exit 2019/01/08-21:02:33.216 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Entry 2019/01/08-21:02:33.216 TRACE_LEVEL_INFORMATION New connection for PSM 0x5055 from AC7A4D2819AC arrived 2019/01/08-21:02:33.216 TRACE_LEVEL_VERBOSE L2CAP_PS3_SendConnectResponse Entry 2019/01/08-21:02:33.216 TRACE_LEVEL_VERBOSE L2CAP_PS3_SendConnectResponse Exit (STATUS_SUCCESS (0x00000000)) 2019/01/08-21:02:33.216 TRACE_LEVEL_VERBOSE BthPS3IndicationCallback Exit 2019/01/08-21:02:33.216 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Entry 2019/01/08-21:02:33.216 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Exit 2019/01/08-21:02:33.225 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Entry 2019/01/08-21:02:33.225 TRACE_LEVEL_INFORMATION BthPS3ConnectionIndicationCallback ++ IndicationRemoteConfigRequest 2019/01/08-21:02:33.225 TRACE_LEVEL_VERBOSE BthPS3ConnectionIndicationCallback Exit 2019/01/08-21:02:33.228 TRACE_LEVEL_VERBOSE L2CAP_PS3_ConnectResponseCompleted Entry 2019/01/08-21:02:33.228 TRACE_LEVEL_INFORMATION Connection completion, status: STATUS_SUCCESS (0x00000000) 2019/01/08-21:02:33.228 TRACE_LEVEL_INFORMATION Connection established with client 2019/01/08-21:02:33.228 TRACE_LEVEL_INFORMATION Connection completed, connection: 0xFFFFFA8009D890C0 2019/01/08-21:02:33.228 TRACE_LEVEL_VERBOSE L2CAP_PS3_ConnectResponseCompleted Exit
-
This is the last (still working) Chinese ripoff-DS3 I currently possess and it connects as well
2019/01/09-19:39:23.848 >> L2CAP_Connection_Request [Code: 0x02, Identifier: 0x01, Length: 4, PSM: 0x5053, SCID: 0x0040] 2019/01/09-19:39:23.858 << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x01, Length: 8, DCID: 0x0000, SCID: 0x0040, Result: 0x0001, Status: 0x0000] 2019/01/09-19:39:23.858 << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x01, Length: 8, DCID: 0x0040, SCID: 0x0040, Result: 0x0000, Status: 0x0000] 2019/01/09-19:39:23.858 << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x01, Length: 8, DCID: 0x0040, Flags: 0x0000, Options: 0xFFFF0201] 2019/01/09-19:39:23.871 >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x02, Length: 4, DCID: 0x0040, Flags: 0x0000, Options: 0x00001000] 2019/01/09-19:39:23.871 << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x02, Length: 6, SCID: 0x0040, Flags: 0x0000, Result: 0x0000, Options: 0x0000] 2019/01/09-19:39:23.873 >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x01, Length: 10, SCID: 0x0040, Flags: 0x0000, Result: 0x0000, Options: 0x0201] 2019/01/09-19:39:23.880 >> L2CAP_Connection_Request [Code: 0x02, Identifier: 0x03, Length: 4, PSM: 0x5055, SCID: 0x0041] 2019/01/09-19:39:23.880 << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x03, Length: 8, DCID: 0x0000, SCID: 0x0041, Result: 0x0001, Status: 0x0000] 2019/01/09-19:39:23.880 << L2CAP_Connection_Response [Code: 0x03, Identifier: 0x03, Length: 8, DCID: 0x0041, SCID: 0x0041, Result: 0x0000, Status: 0x0000] 2019/01/09-19:39:23.880 << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x02, Length: 8, DCID: 0x0041, Flags: 0x0000, Options: 0xFFFF0201] 2019/01/09-19:39:23.893 >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x04, Length: 4, DCID: 0x0041, Flags: 0x0000, Options: 0x00001000] 2019/01/09-19:39:23.893 << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x04, Length: 6, SCID: 0x0041, Flags: 0x0000, Result: 0x0000, Options: 0x0000] 2019/01/09-19:39:23.894 >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x02, Length: 10, SCID: 0x0041, Flags: 0x0000, Result: 0x0000, Options: 0x0201]
-
DualShock 4 (Revision 1) connection sequence
2019/01/09-21:11:02.588 << L2CAP_Connection_Request [Code: 0x02, Identifier: 0x02, Length: 4, PSM: 0x0001, SCID: 0x0040] 2019/01/09-21:11:02.597 >> L2CAP_Connection_Response [Code: 0x03, Identifier: 0x02, Length: 8, DCID: 0x0040, SCID: 0x0040, Result: 0x0001, Status: 0x0002] 2019/01/09-21:11:02.599 >> L2CAP_Connection_Response [Code: 0x03, Identifier: 0x02, Length: 8, DCID: 0x0040, SCID: 0x0040, Result: 0x0000, Status: 0x0000] 2019/01/09-21:11:02.599 << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x03, Length: 8, DCID: 0x0040, Flags: 0x0000, Options: 0x04000201] 2019/01/09-21:11:02.610 >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x03, Length: 10, SCID: 0x0040, Flags: 0x0000, Result: 0x0000, Options: 0x0201] 2019/01/09-21:11:02.612 >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x01, Length: 8, DCID: 0x0040, Flags: 0x0000, Options: 0x04000201] 2019/01/09-21:11:02.612 << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x01, Length: 6, SCID: 0x0040, Flags: 0x0000, Result: 0x0000, Options: 0x0000] 2019/01/09-21:11:02.612 << L2CAP_Disconnection_Request [Code: 0x06, Identifier: 0x00, Length: 0, DCID: 0x350F, SCID: 0x1903] 2019/01/09-21:11:02.623 << L2CAP_Disconnection_Request [Code: 0x06, Identifier: 0x00, Length: 1, DCID: 0x350F, SCID: 0x1903] 2019/01/09-21:11:04.088 << L2CAP_Disconnection_Request [Code: 0x06, Identifier: 0x00, Length: 2, DCID: 0x350F, SCID: 0x1903] 2019/01/09-21:11:04.449 << L2CAP_Disconnection_Request [Code: 0x06, Identifier: 0x00, Length: 3, DCID: 0x350F, SCID: 0x1903] 2019/01/09-21:11:04.513 << L2CAP_Disconnection_Request [Code: 0x06, Identifier: 0x00, Length: 4, DCID: 0x350F, SCID: 0x1903] 2019/01/09-21:11:04.718 << L2CAP_Disconnection_Request [Code: 0x06, Identifier: 0x00, Length: 5, DCID: 0x350F, SCID: 0x1903] 2019/01/09-21:11:05.031 << L2CAP_Connection_Request [Code: 0x02, Identifier: 0x04, Length: 4, PSM: 0x0011, SCID: 0x0041] 2019/01/09-21:11:05.069 >> L2CAP_Connection_Response [Code: 0x03, Identifier: 0x04, Length: 8, DCID: 0x0041, SCID: 0x0041, Result: 0x0001, Status: 0x0002] 2019/01/09-21:11:05.091 >> L2CAP_Connection_Response [Code: 0x03, Identifier: 0x04, Length: 8, DCID: 0x0041, SCID: 0x0041, Result: 0x0000, Status: 0x0000] 2019/01/09-21:11:05.091 << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x05, Length: 8, DCID: 0x0041, Flags: 0x0000, Options: 0x02A00201] 2019/01/09-21:11:05.135 >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x05, Length: 10, SCID: 0x0041, Flags: 0x0000, Result: 0x0000, Options: 0x0201] 2019/01/09-21:11:05.156 >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x02, Length: 8, DCID: 0x0041, Flags: 0x0000, Options: 0x02A00201] 2019/01/09-21:11:05.156 << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x02, Length: 6, SCID: 0x0041, Flags: 0x0000, Result: 0x0000, Options: 0x0000] 2019/01/09-21:11:05.156 << L2CAP_Connection_Request [Code: 0x02, Identifier: 0x06, Length: 4, PSM: 0x0013, SCID: 0x0042] 2019/01/09-21:11:05.192 >> L2CAP_Connection_Response [Code: 0x03, Identifier: 0x06, Length: 8, DCID: 0x0042, SCID: 0x0042, Result: 0x0001, Status: 0x0002] 2019/01/09-21:11:05.199 >> L2CAP_Connection_Response [Code: 0x03, Identifier: 0x06, Length: 8, DCID: 0x0042, SCID: 0x0042, Result: 0x0000, Status: 0x0000] 2019/01/09-21:11:05.199 << L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x07, Length: 8, DCID: 0x0042, Flags: 0x0000, Options: 0x02A00201] 2019/01/09-21:11:05.209 >> L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x07, Length: 10, SCID: 0x0042, Flags: 0x0000, Result: 0x0000, Options: 0x0201] 2019/01/09-21:11:05.212 >> L2CAP_Configuration_Request [Code: 0x04, Identifier: 0x03, Length: 8, DCID: 0x0042, Flags: 0x0000, Options: 0x02A00201] 2019/01/09-21:11:05.212 << L2CAP_Configuration_Response [Code: 0x05, Identifier: 0x03, Length: 6, SCID: 0x0042, Flags: 0x0000, Result: 0x0000, Options: 0x0000] 2019/01/09-21:11:07.797 << L2CAP_Disconnection_Request [Code: 0x06, Identifier: 0x08, Length: 4, DCID: 0x0040, SCID: 0x0040] 2019/01/09-21:11:07.801 >> L2CAP_Disconnection_Response [Code: 0x07, Identifier: 0x08, Length: 4, DCID: 0x0040, SCID: 0x0040]
-
-
-
-
Bloody hell, my mind was not prepared to deal with a state machine handling two L2CAP channels with all those async stuff happening and the tons of error handling required. Time for my favorite part in what I call (dramatic music playing
) poke-in-the-dark-development:
- think about the solution
- code it
- think about it again
- realize it's flawed
- revert changes
goto 1
-
Oddly enough I wasn't able to find an official way to get the remote device name from an incoming connection, just the MAC address. This isn't a showstopper but odd and annoying for device identification. Or am I missing something
-
@nefarius said in Bluetooth Filter Driver for DS3-compatibility - research notes:
Oddly enough I wasn't able to find an official way to get the remote device name from an incoming connection, just the MAC address. This isn't a showstopper but odd and annoying for device identification. Or am I missing something
Wait a minute... if I got this right, calling
IOCTL_BTH_GET_DEVICE_INFO
returns aBTH_DEVICE_INFO_LIST
containingBTH_DEVICE_INFO
which can then be matched againstaddress
and contains aname
member:Name of the remote Bluetooth device, as reported by the device, encoded in UTF8. The user may have locally provided a display name for the remote Bluetooth device; that name is overridden, and does not appear in this member; it is accessible only with a call to the BluetoothGetDeviceInfo function.
Bingo! The name isn't a 100% safe to rely on in device identification compared to the MAC address, but it's the best shot. It's important to react differently depending on the device type (DualShock 3, Navigation Controller, Motion Controller or DualShock 4 a.k.a. Wireless Controller). This is how it's currently done in WireShock:
BD_ADDR_FROM_BUFFER(clientAddr, &buffer[3]); ULONG length; // // Scan through rest of buffer until null-terminator is found // for (length = 1; buffer[length + 8] != 0x00 && (length + 8) < NumBytesTransferred; length++); // // Store remote name in device context // WireBusSetChildRemoteName( Device, &clientAddr, &buffer[9], length ); switch (buffer[9]) { case 'P': // First letter in PLAYSTATION(R)3 Controller ('P') WireBusSetChildDeviceType( Device, &clientAddr, DS_DEVICE_TYPE_PS3_DUALSHOCK ); break; case 'N': // First letter in Navigation Controller ('N') WireBusSetChildDeviceType( Device, &clientAddr, DS_DEVICE_TYPE_PS3_NAVIGATION ); break; case 'M': // First letter in Motion Controller ('M') WireBusSetChildDeviceType( Device, &clientAddr, DS_DEVICE_TYPE_PS3_MOTION ); break; case 'W': // First letter in Wireless Controller ('W') WireBusSetChildDeviceType( Device, &clientAddr, DS_DEVICE_TYPE_PS4_DUALSHOCK ); break; default: TraceEvents(TRACE_LEVEL_ERROR, TRACE_INTERRUPT, "Couldn't determine device type from remote name (%c)", buffer[9] ); break; }
I've discovered that a DS4 (Rev1) paired in PC-mode will also try to directly connect with PSM
0x11
and0x13
in addition to the correct0x01
and gets denied. It continues to work though; my best guess is that the controller simply tries if the Bluetooth host is a PS4 and changes its behavior accordingly. This is unfortunate for my profile driver, because now I need to know that it is a DS4, not a DS3, and deny the connection request because the filter will rewrite the PSMs as well. This rabbit hole...