Bluetooth Filter Driver for DS3-compatibility - research notes

While we're already having a working code base for a dedicated Bluetooth host dongle function driver supporting genuine and fake DS3s I wanna also explore the path of a different approach: keeping the default Windows Bluetooth driver stack in place and patching it in a way that it will accept a DS3 connection transparently in parallel to other devices (keyboards, headsets etc.) via filter driver.

Analysis environment

  • Windows 7 32-Bit
  • Generic Bluetooth Radio (Cambridge Silicon Radio Ltd.)
    • Hardware ID: USB\VID_0A12&PID_0001
  • Genuine Sony DualShock 3 controller

Tools used

  • DebugView
  • RequestTrace

Analysis

On Interrupt Pipe (HCI communication) connection seems to work at least until receiving HCI_Remote_Name_Request_Complete_EV:

0_1547896876512_71f8b8f8-b2c4-4c35-a290-10d7cb3db73e-image.png

This corresponds to this

0_1547896888532_d908db13-e738-4e5c-81c0-18daef84c852-image.png

in AirBender/WireShock. The HCI_Command_Remote_Name_Request is the last HCI command which has to succeed, which looks like it does. Next is building the L2CAP connection, which seems to get initiated as well a few requests later:

0_1547896925248_38853936-6843-4d7a-b6ab-8bbec8fd2d78-image.png

As buffer[6] == 0x01 && buffer[7] == 0x00 represents the L2CAP control channel. So the L2CAP ping-pong should be looked at in greater detail and find the stage where it starts to break.

L2CAP_Connection_Request

00000181	0.82300282	** RT_CompletionRoutineUrbSubmit: Irp: 0x854DC8B8 - IOCTL_INTERNAL_USB_SUBMIT_URB - URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER - Status STATUS_SUCCESS - Buffer: 0x85703000, MDL: 0x887905F0, Length: 0x10, Pipe:0x85A2137C, Flags: 0x3.	
00000182	0.82301444	** 42 20 0C 00 08 00 01 00  02 01 04 00 11 00 40 7C  B ............@|	
00000183	0.82302463	** 42 20 0C 00 08 00 01 00  02 01 04 00 11 00 40 7C  B ............@|	
00000184	0.82304817	** Irp: 0x854DC8B8 - IOCTL_INTERNAL_USB_SUBMIT_URB - URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER. Buffer: 0x878B3000, MDL: 0x0, Length: 0x1000, Pipe:0x85A2137C, Flags: 0x3.	

This gets repeated over and over again, so either the correct answer is missing in the trace or not sent at all.

This .INF section will add driver as a lower class filter driver for the Bluetooth class (GUID: {e0cbf06c-cd8b-4647-bb8a-263b43f0f974}) and load it on every BTHUSB host device:

[Filter_Device.NT.HW]
AddReg = Filter_AddReg

[Filter_AddReg]
HKLM,SYSTEM\CurrentControlSet\Control\Class\{e0cbf06c-cd8b-4647-bb8a-263b43f0f974},LowerFilters,0x00010008,Filter

Section for uninstallation missing.

EDIT: obsolete, will do this via helper tool instead of INF file.

Gotcha! 👮

2018/12/30-22:27:05.535	TRACE_LEVEL_VERBOSE	>> IOCTL_INTERNAL_USB_SUBMIT_URB
2018/12/30-22:27:05.535	TRACE_LEVEL_VERBOSE	>> >> URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (PipeHandle: 854C164C)
2018/12/30-22:27:05.535	TRACE_LEVEL_VERBOSE	Bulk OUT transfer
2018/12/30-22:27:05.535	TRACE_LEVEL_INFORMATION	3C 00 10 00 0C 00 01 00 03 01 08 00 00 00 40 21 02 00 00 00 
2018/12/30-22:27:05.535	TRACE_LEVEL_INFORMATION	L2CAP_Connection_Response (Response: 02)

Byte 8 is L2CAP_Connection_Response from Windows Bluetooth driver, byte 16 is status:

/// <summary>
///     Connection refused – PSM not supported.
/// </summary>
L2CAP_ConnectionResponseResult_ConnectionRefusedPsmNotNupported = 0x0002

This is kinda nice to know because it's the very first L2CAP connection failing because the PSM (Protocol/Service Multiplexer) the DS3 wants to establish a channel for is forbidden in Windows. Let's patch that and see what happens 😏

Why this happens is actually documented, especially:

Some PSMs are reserved for use by Windows:
SDP: 0x01
RFCOMM: 0x03
HID Control: 0x11
HID Data: 0x13
BNEP: 0x0F

It is well-known that the DS3 establishes communication channels via PSM 0x11 and 0x13, which works fine on the PS3 (custom Bluetooth stack firmware) and Linux (no such reservations/limitations). On Windows however this is a pretty big deal and the showstopper for an out-of-the-box working connection of a DS3 with standard Windows Bluetooth stack.

A pretty neat hack around this limitation was discovered a few years back, but API hooking or binary patches in kernel space are strictly forbidden (mainly for stability and security reasons, even Anti-Virus vendors had to back down from this approach starting with the Vista kernel) so while having this info as a fallback, it's not something we can use in production and therefore a KMDF Bluetooth Profile Driver won't be helpful here.

Will further go down and explore the lower BTHUSB filter route 😉

Hm, even if nothing of this works in the end: I've now accidentally created a Bluetooth sniffer which is nice 😅

0_1546343450556_4a15c70c-bf43-4bcf-bd12-2593eed2be29-image.png

I abandoned the Bluetooth Profile Driver idea to soon; let's see what this skeleton can do for me 🤔

0_1546352012177_9a0cde3c-1002-4d22-baf5-c52f9f1aba30-image.png

Oh my! 😲 This actually worked 👀

I've currently set up a BTHUSB lower filter driver simply looking for an incoming L2CAP connection request with the dredded PSM 0x11 and patching it to an artificial fixed value (currently 0x5053)

UrbFunctionBulkInTransferCompleted	2019/01/01-15:26:42.733	TRACE_LEVEL_VERBOSE	UrbFunctionBulkInTransferCompleted Entry
UrbFunctionBulkInTransferCompleted	2019/01/01-15:26:42.733	TRACE_LEVEL_INFORMATION	>> L2CAP_Connection_Request
UrbFunctionBulkInTransferCompleted	2019/01/01-15:26:42.733	TRACE_LEVEL_INFORMATION	++ PSM: 0x11
UrbFunctionBulkInTransferCompleted	2019/01/01-15:26:42.733	TRACE_LEVEL_INFORMATION	++ Patching PSM to 0x5053

This grants us a way around bthport.sys!BthIsSystemPSM denying the connection right away, so far so good! But that's not enough; how should the Bluetooth stack now know what to do with a non-existent PSM? Well, we need to register a custom Profile Driver for it, of course! 😆

2019/01/01-15:26:31.001	TRACE_LEVEL_INFORMATION	++ Trying to register PSM 0x5053
2019/01/01-15:26:31.001	TRACE_LEVEL_INFORMATION	++ Got PSM 0x5053
2019/01/01-15:26:31.001	TRACE_LEVEL_VERBOSE	BthPS3RegisterPSM Exit
2019/01/01-15:26:31.001	TRACE_LEVEL_VERBOSE	BthPS3RegisterL2CAPServer Entry
2019/01/01-15:26:31.001	TRACE_LEVEL_VERBOSE	BthPS3IndicationCallback Entry
2019/01/01-15:26:31.001	TRACE_LEVEL_VERBOSE	BthPS3IndicationCallback Exit
2019/01/01-15:26:31.001	TRACE_LEVEL_VERBOSE	BthPS3RegisterL2CAPServer Exit
2019/01/01-15:26:42.763	TRACE_LEVEL_VERBOSE	BthPS3IndicationCallback Entry
2019/01/01-15:26:42.763	TRACE_LEVEL_INFORMATION	BthPS3IndicationCallback ++ IndicationRemoteConnect
2019/01/01-15:26:42.763	TRACE_LEVEL_VERBOSE	BthPS3IndicationCallback Exit

And we actually receive the connection request in our own profile driver now 😳

That is... very interesting! Let's see where the road leads me from here on.

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:

0_1546968648339_773f36f0-6910-4c26-9450-888fe4875590-image.png

The Hardware ID would be BTHENUM\{CUSTOM_SERVICE_GUID} where in my lab example I simply recycled the one bthecho uses:

0_1546968684938_a1661077-ee57-467e-af06-1f96fd6e12e1-image.png

0_1546968857025_ba14d738-13b0-4557-b1ff-52e792f9f6a3-image.png

0_1546968889258_43c9e941-7715-4309-9141-334c11c140f1-image.png

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 against BluetoothApis.lib, which bombs on Windows 7. Link against Bthprops.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 is 0x0200 (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