private void ParseBufferDs3()

in ScpControl/Bluetooth/BthDongle.Tasks.cs [246:511]


        private void ParseBufferDs3(BthDevice connection, L2CapDataPacket packet)
        {
            byte[] L2_DCID;
            byte[] L2_SCID;

            if (packet.IsControlChannel) // Control Channel
            {
                if (packet.IsValidSignallingCommandCode)
                {
                    var Event = packet.SignallingCommandCode;

                    switch (Event)
                    {
                            #region L2CAP_Command_Reject

                        case L2CAP.Code.L2CAP_Command_Reject:

                            Log.DebugFormat(">> {0}", Event);
                            break;

                            #endregion

                            #region L2CAP_Connection_Request

                        case L2CAP.Code.L2CAP_Connection_Request:

                            Log.DebugFormat(">> {0} with PSM [{1}] [CID: {2}]", Event,
                                packet.ProtocolServiceMultiplexer,
                                packet.ChannelId);

                            L2_SCID = packet.SourceChannelIdentifier;

                            // set HID command channel for current connection
                            L2_DCID = connection.SetConnectionType(packet.ProtocolServiceMultiplexer, L2_SCID);

                            // send response with connection pending
                            L2CAP_Connection_Response(connection.HciHandle.Bytes,
                                packet.ChannelId, L2_SCID, L2_DCID,
                                L2CAP.ConnectionResponseResult.ConnectionPending,
                                L2CAP.ConnectionResponseStatus.AuthorisationPending);

                            Log.DebugFormat("<< {0} [CID: {1}]", L2CAP.Code.L2CAP_Connection_Response,
                                packet.ChannelId);

                            // send response with connection successful
                            L2CAP_Connection_Response(connection.HciHandle.Bytes,
                                packet.ChannelId, L2_SCID, L2_DCID,
                                L2CAP.ConnectionResponseResult.ConnectionSuccessful);

                            Log.DebugFormat("<< {0} [CID: {1}]", L2CAP.Code.L2CAP_Connection_Response,
                                packet.ChannelId);

                            // send configuration request
                            L2CAP_Configuration_Request(connection.HciHandle.Bytes, _l2CapDataIdentifier++, L2_SCID);

                            Log.DebugFormat("<< {0} [CID: {1}]", L2CAP.Code.L2CAP_Configuration_Request,
                                _l2CapDataIdentifier - 1);
                            break;

                            #endregion

                            #region L2CAP_Connection_Response

                        case L2CAP.Code.L2CAP_Connection_Response:

                            Log.DebugFormat(">> {0} [Result: {1}] [CID: {2}]", Event, packet.Result, packet.ChannelId);

                            var result = packet.Result;

                            L2_SCID = packet.SourceChannelIdentifier;
                            Log.DebugFormat("-- L2_SCID = [{0:X2}, {1:X2}]", L2_SCID[0], L2_SCID[1]);

                            L2_DCID = packet.DestinationChannelIdentifier;
                            Log.DebugFormat("-- L2_DCID = [{0:X2}, {1:X2}]", L2_DCID[0], L2_DCID[1]);

                            // interpret result
                            switch ((L2CAP.ConnectionResponseResult) result)
                            {
                                case L2CAP.ConnectionResponseResult.ConnectionSuccessful:

                                    // destination channel identifier
                                    var DCID = packet.DestinationChannelIdentifierUInt16;
                                    Log.DebugFormat("-- DCID (shifted) = {0:X4}", DCID);

                                    // set HID service channel for current connection
                                    connection.SetConnectionType(L2CAP.PSM.HID_Service, L2_SCID[0], L2_SCID[1], DCID);

                                    // send configuration request
                                    L2CAP_Configuration_Request(connection.HciHandle.Bytes, _l2CapDataIdentifier++,
                                        L2_SCID);

                                    Log.DebugFormat("<< {0} [CID: {1}]",
                                        L2CAP.Code.L2CAP_Configuration_Request,
                                        packet.ChannelId);
                                    break;
                                case L2CAP.ConnectionResponseResult.ConnectionPending:

                                    Log.DebugFormat("-- Connection pending for pad {0}",
                                        connection.PadId.ToString().ToLower());
                                    break;
                                case L2CAP.ConnectionResponseResult.ConnectionRefusedPsmNotNupported:

                                    Log.ErrorFormat(
                                        "Requested Protocol Service Multiplexer not supported on device {0}",
                                        connection.HostAddress);
                                    break;
                                case L2CAP.ConnectionResponseResult.ConnectionRefusedSecurityBlock:

                                    Log.ErrorFormat("Connection refused for security reasons on device {0}",
                                        connection.HostAddress);
                                    break;
                                case L2CAP.ConnectionResponseResult.ConnectionRefusedNoResourcesAvailable:

                                    Log.ErrorFormat("Connection failed for device {0}: no resources available",
                                        connection.HostAddress);
                                    break;

                                default:
                                    Log.WarnFormat("Unknown result: {0}", result);
                                    break;
                            }

                            break;

                            #endregion

                            #region L2CAP_Configuration_Request

                        case L2CAP.Code.L2CAP_Configuration_Request:

                            Log.DebugFormat(">> {0} [CID: {1}]", Event, packet.ChannelId);

                            L2_SCID = connection.Get_SCID(packet.SourceChannelIdentifier);

                            L2CAP_Configuration_Response(connection.HciHandle.Bytes,
                                packet.ChannelId, L2_SCID);
                            Log.DebugFormat("<< {0} [CID: {1}]", L2CAP.Code.L2CAP_Configuration_Response,
                                packet.ChannelId);

                            if (connection.IsServiceStarted)
                            {
                                connection.CanStartHid = true;
                                connection.InitHidReport(packet.RawBytes);
                            }
                            break;

                            #endregion

                            #region L2CAP_Configuration_Response

                        case L2CAP.Code.L2CAP_Configuration_Response:

                            Log.DebugFormat(">> {0} [CID: {1}]", Event, packet.ChannelId);

                            Log.DebugFormat("-- MTU = {0}", packet.MaximumTransmissionUnit);

                            if (connection.CanStartService)
                            {
                                L2_DCID = L2CapDataPacket.UInt16ToBytes(BthConnection.Dcid++);

                                if (!connection.IsFake)
                                {
                                    L2CAP_Connection_Request(connection.HciHandle.Bytes, _l2CapDataIdentifier++, L2_DCID,
                                        L2CAP.PSM.HID_Service);
                                    Log.DebugFormat("<< {0} with PSM [{1}] [CID: {2}]",
                                        L2CAP.Code.L2CAP_Connection_Request,
                                        L2CAP.PSM.HID_Service,
                                        _l2CapDataIdentifier - 1);
                                }
                                else
                                {
                                    connection.SetConnectionType(L2CAP.PSM.HID_Service, L2_DCID);
                                    connection.CanStartService = false;
                                    OnInitialised(connection);
                                }
                            }
                            break;

                            #endregion

                            #region L2CAP_Disconnection_Request

                        case L2CAP.Code.L2CAP_Disconnection_Request:

                            Log.DebugFormat(">> {0} Handle [{1}]", Event, packet.SourceChannelIdentifier);

                            L2_SCID = packet.SourceChannelIdentifier;

                            L2CAP_Disconnection_Response(connection.HciHandle.Bytes,
                                packet.ChannelId, L2_SCID, L2_SCID);

                            Log.DebugFormat("<< {0}", L2CAP.Code.L2CAP_Disconnection_Response);
                            break;

                            #endregion

                            #region L2CAP_Disconnection_Response

                        case L2CAP.Code.L2CAP_Disconnection_Response:

                            Log.DebugFormat(">> {0}", Event);

                            if (connection.CanStartHid)
                            {
                                connection.IsServiceStarted = false;
                                OnInitialised(connection);
                            }
                            break;

                            #endregion

                            #region L2CAP_Echo_Request

                        case L2CAP.Code.L2CAP_Echo_Request:

                            Log.DebugFormat(">> {0}", Event);
                            break;

                            #endregion

                            #region L2CAP_Echo_Response

                        case L2CAP.Code.L2CAP_Echo_Response:

                            Log.DebugFormat(">> {0}", Event);
                            break;

                            #endregion

                            #region L2CAP_Information_Request

                        case L2CAP.Code.L2CAP_Information_Request:

                            Log.DebugFormat(">> {0}", Event);
                            break;

                            #endregion

                            #region L2CAP_Information_Response

                        case L2CAP.Code.L2CAP_Information_Response:

                            Log.DebugFormat(">> {0}", Event);
                            break;

                            #endregion
                    }
                }
            }
            else if (packet.IsHidInputReport)
            {
                // HID report received, parse content and extract gamepad data
                connection.ParseHidReport(packet.RawBytes);
            }
            else if (connection.InitHidReport(packet.RawBytes))
            {
                connection.CanStartHid = true;

                L2_DCID = connection.Get_DCID(L2CAP.PSM.HID_Service);
                L2_SCID = connection.Get_SCID(L2CAP.PSM.HID_Service);

                L2CAP_Disconnection_Request(connection.HciHandle.Bytes, _l2CapDataIdentifier++, L2_SCID, L2_DCID);

                Log.DebugFormat("<< {0}", L2CAP.Code.L2CAP_Disconnection_Request);
            }
        }