Navigation

    ViGEm Forums

    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • Twitter
    • GitHub
    • Discord

    Bluetooth Filter Driver for DS3-compatibility - research notes

    Research and Development
    35
    251
    34336
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • 414n
      414n last edited by

      Really interesting, keep up the good work!

      Am I right in assuming these are research notes for an Airbender successor?

      nefarius 1 Reply Last reply Reply Quote 0
      • nefarius
        nefarius @414n last edited by

        @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.

        1 Reply Last reply Reply Quote 0
        • nefarius
          nefarius last edited by

          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 😵

          1 Reply Last reply Reply Quote 0
          • nefarius
            nefarius last edited by

            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 🙂

            1 Reply Last reply Reply Quote 0
            • nefarius
              nefarius last edited by nefarius

              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 🙃

              1 Reply Last reply Reply Quote 0
              • nefarius
                nefarius last edited by

                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.

                1 Reply Last reply Reply Quote 0
                • nefarius
                  nefarius last edited by

                  😲

                  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 👀

                  1 Reply Last reply Reply Quote 0
                  • nefarius
                    nefarius last edited by nefarius

                    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 😏

                    1 Reply Last reply Reply Quote 0
                    • nefarius
                      nefarius last edited by

                      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]
                      
                      1 Reply Last reply Reply Quote 0
                      • nefarius
                        nefarius last edited by nefarius

                        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]
                        
                        1 Reply Last reply Reply Quote 0
                        • nefarius
                          nefarius last edited by

                          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
                          
                          1 Reply Last reply Reply Quote 0
                          • nefarius
                            nefarius last edited by

                            This is the last (still working) Chinese ripoff-DS3 I currently possess and it connects as well 🤠

                            0_1547059434312_8b7e4079-2500-48e1-a869-73ab9d6f16a8-image.png

                            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]
                            
                            1 Reply Last reply Reply Quote 0
                            • nefarius
                              nefarius last edited by nefarius

                              DualShock 4 (Revision 1) connection sequence

                              0_1547064933258_759bd2c1-8fe3-4260-8dc5-5170dcfdb563-image.png

                              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]
                              
                              1 Reply Last reply Reply Quote 0
                              • nefarius
                                nefarius last edited by

                                Oof, code base growing rapidly 😲

                                0_1547249461104_4e064261-c7a3-4eb8-8a13-c1fcfbd06181-image.png

                                From top to bottom:

                                • Profile driver
                                • Filter driver
                                • Driver installation utility
                                1 Reply Last reply Reply Quote 0
                                • nefarius
                                  nefarius last edited by nefarius

                                  Enum BTH - Microsoft Bluetooth Enumerator

                                  0_1547251444420_ca5c635d-2be8-4358-b4d9-1849473af9f5-image.png

                                  0_1547251423220_6ea3077d-93fc-4f16-8ddc-efe543a129cb-image.png

                                  Enum USB - Generic Bluetooth Radio

                                  0_1547251570723_d1de37d7-b6da-4a75-9dae-7595f9a13709-image.png

                                  0_1547251746992_c6667e68-8eb4-4317-b746-8c8c579df759-image.png

                                  PlayStation 3 Peripherals Filter Driver

                                  0_1547252006112_97dc8e2f-53ec-42f6-882b-13a725649c6b-image.png

                                  0_1547252022063_82276012-0158-4d9d-a71e-34ca738b432e-image.png

                                  How the Heck do I get rid of the Advanced tab 🤔

                                  0_1547289468275_c76cdce4-f691-4fb5-90c8-6cfe38bd12cb-image.png

                                  1 Reply Last reply Reply Quote 0
                                  • nefarius
                                    nefarius last edited by nefarius

                                    Working on BthPS3Util

                                    Creating a small command line utility for abstracting away the mess of creating filter device node, installing filter driver, enabling the filter and registering the service profile.

                                    0_1547897266264_3235ea5f-c436-4f3f-8969-a3b90a480c5c-image.png

                                    0_1547308197893_3fe40c51-c0ad-4bfa-98ae-0863ad41b749-image.png

                                    0_1547897296398_9b5bed5d-d8cf-4311-8149-26726d846457-image.png

                                    1 Reply Last reply Reply Quote 0
                                    • nefarius
                                      nefarius last edited by

                                      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:

                                      1. think about the solution
                                      2. code it
                                      3. think about it again
                                      4. realize it's flawed
                                      5. revert changes
                                      6. goto 1

                                      🤦‍♂️

                                      1 Reply Last reply Reply Quote 0
                                      • nefarius
                                        nefarius last edited by

                                        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 1 Reply Last reply Reply Quote 0
                                        • nefarius
                                          nefarius @nefarius last edited by nefarius

                                          @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 a BTH_DEVICE_INFO_LIST containing BTH_DEVICE_INFO which can then be matched against address and contains a name 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 and 0x13 in addition to the correct 0x01 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... 😵

                                          1 Reply Last reply Reply Quote 0
                                          • Daltz333
                                            Daltz333 last edited by Daltz333

                                            Quite interesting research. So putting this into simple terms, the filter driver will pickup the DS4 and will interpret it's requests instead? Which is bad because the DS4 has bluetooth support already.

                                            nefarius 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post