Beispiel #1
0
        public override bool Pair(PhysicalAddress master)
        {
            var transfered = 0;
            var host       = master.GetAddressBytes();

            byte[] buffer =
            {
                0x13, host[5], host[4], host[3], host[2], host[1], host[0], 0x00, 0x00, 0x00,
                0x00,    0x00,    0x00,    0x00,    0x00,    0x00,    0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00
            };

            Buffer.BlockCopy(GlobalConfiguration.Instance.BdLink, 0, buffer, 7,
                             GlobalConfiguration.Instance.BdLink.Length);

            if (SendTransfer(UsbHidRequestType.HostToDevice, UsbHidRequest.SetReport, 0x0313, buffer, ref transfered))
            {
                HostAddress = master;

                Log.DebugFormat("++ Paired DS4 [{0}] To BTH Dongle [{1}]", DeviceAddress.AsFriendlyName(), HostAddress.AsFriendlyName());
                return(true);
            }

            Log.DebugFormat("++ Pair Failed [{0}]", DeviceAddress.AsFriendlyName());
            return(false);
        }
Beispiel #2
0
        public override bool Start()
        {
            if (!IsActive)
            {
                return(State == DsState.Connected);
            }

            State         = DsState.Connected;
            PacketCounter = 0;

            Task.Factory.StartNew(HidWorker, _hidCancellationTokenSource.Token);

            _outputReportTask = _outputReportSchedule.Subscribe(tick => Process(DateTime.Now));

            Rumble(0, 0);
            Log.DebugFormat("-- Started Device Instance [{0}] Local [{1}] Remote [{2}]", m_Instance,
                            DeviceAddress.AsFriendlyName(), HostAddress.AsFriendlyName());

            // connection sound
            if (GlobalConfiguration.Instance.IsUsbConnectSoundEnabled)
            {
                AudioPlayer.Instance.PlayCustomFile(GlobalConfiguration.Instance.UsbConnectSoundFile);
            }

            #region Request HID Report Descriptor

            // try to retrieve HID Report Descriptor
            var buffer     = new byte[512];
            var transfered = 0;

            if (SendTransfer(UsbHidRequestType.GetDescriptor, UsbHidRequest.GetDescriptor,
                             ToValue(UsbHidClassDescriptorType.Report),
                             buffer, ref transfered) && transfered > 0)
            {
                Log.DebugFormat("-- HID Report Descriptor: {0}", buffer.ToHexString(transfered));

                // store report descriptor
                ReportDescriptor.Parse(buffer);
            }

            #endregion

            return(State == DsState.Connected);
        }
Beispiel #3
0
        public override string ToString()
        {
            switch (State)
            {
            case DsState.Disconnected:
                return(string.Format("Pad {0} : Disconnected", PadId));

            case DsState.Reserved:
                return(string.Format("Pad {0} : {1} {2} - Reserved", PadId, Model, DeviceAddress.AsFriendlyName()));

            case DsState.Connected:
                return(string.Format("Pad {0} : {1} {2} - {3} {4:X8} {5}", PadId, Model,
                                     DeviceAddress.AsFriendlyName(),
                                     Connection,
                                     m_Packet,
                                     Battery));
            }

            throw new Exception();
        }
Beispiel #4
0
        public override bool Open(string devicePath)
        {
            if (base.Open(devicePath))
            {
                State = DsState.Reserved;
                GetDeviceInstance(ref m_Instance);

                var transfered = 0;

                if (SendTransfer(UsbHidRequestType.DeviceToHost, UsbHidRequest.GetReport, 0x03F5, m_Buffer,
                                 ref transfered))
                {
                    HostAddress =
                        new PhysicalAddress(new[]
                                            { m_Buffer[2], m_Buffer[3], m_Buffer[4], m_Buffer[5], m_Buffer[6], m_Buffer[7] });
                }
                else
                {
                    Log.ErrorFormat("Couldn't request Bluetooth host address for device {0}, error: {1}", devicePath,
                                    new Win32Exception(Marshal.GetLastWin32Error()));
                    State = DsState.Disconnected;
                    return(false);
                }

                if (SendTransfer(UsbHidRequestType.DeviceToHost, UsbHidRequest.GetReport, 0x03F2, m_Buffer,
                                 ref transfered))
                {
                    DeviceAddress =
                        new PhysicalAddress(new[]
                                            { m_Buffer[4], m_Buffer[5], m_Buffer[6], m_Buffer[7], m_Buffer[8], m_Buffer[9] });
                }
                else
                {
                    Log.ErrorFormat("Couldn't request Bluetooth device address for device {0}, error: {1}", devicePath,
                                    new Win32Exception(Marshal.GetLastWin32Error()));
                    State = DsState.Disconnected;
                    return(false);
                }

                Log.InfoFormat("Successfully opened device with MAC address {0}", DeviceAddress.AsFriendlyName());

                if (!IniConfig.Instance.Hci.GenuineMacAddresses.Any(m => DeviceAddress.AsFriendlyName().StartsWith(m)))
                {
                    Log.WarnFormat("Fake DualShock 3 detected [{0}]", DeviceAddress.AsFriendlyName());

                    var bthCompany = IniConfig.Instance.BthChipManufacturers.FirstOrDefault(
                        m =>
                        DeviceAddress.AsFriendlyName().StartsWith(m.PartialMacAddress.ToUpper()));

                    if (bthCompany != null && bthCompany.Name.Equals("AirohaTechnologyCorp"))
                    {
                        Log.WarnFormat("Controller uses Bluetooth chip by Airoha Technology Corp., suppressing workaround");
                        IsFake = false;
                    }
                    else
                    {
                        IsFake = true;
                    }
                }
                else
                {
                    Log.Info("Genuine Sony DualShock 3 detected");
                }
            }

            return(State == DsState.Reserved);
        }
Beispiel #5
0
        public override bool Start()
        {
            Model = DsModel.DS3;

            if (IsActive)
            {
                var transfered = 0;

                if (SendTransfer(UsbHidRequestType.HostToDevice, UsbHidRequest.SetReport, 0x03F4, _hidCommandEnable, ref transfered))
                {
                    base.Start();
                }
                else
                {
                    Log.ErrorFormat("Couldn't send control request to device {0}, error: {1}", DeviceAddress.AsFriendlyName(),
                                    new Win32Exception(Marshal.GetLastWin32Error()));
                    return(false);
                }
            }

            return(State == DsState.Connected);
        }
Beispiel #6
0
        public override bool Start()
        {
            Model = DsModel.DS4;

            // skip repairing if disabled in global configuration
            if (!GlobalConfiguration.Instance.Repair)
            {
                return(base.Start());
            }

            var transfered = 0;

            var hostMac = HostAddress.GetAddressBytes();

            byte[] buffer =
            {
                0x13, hostMac[5], hostMac[4], hostMac[3], hostMac[2], hostMac[1], hostMac[0],
                0x00,       0x00,       0x00,       0x00,       0x00,       0x00,       0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
            };

            Buffer.BlockCopy(GlobalConfiguration.Instance.BdLink, 0, buffer, 7,
                             GlobalConfiguration.Instance.BdLink.Length);

            if (SendTransfer(UsbHidRequestType.HostToDevice, UsbHidRequest.SetReport, 0x0313, buffer, ref transfered))
            {
                Log.DebugFormat("++ Repaired DS4 [{0}] Link Key For BTH Dongle [{1}]", DeviceAddress.AsFriendlyName(), HostAddress.AsFriendlyName());
            }
            else
            {
                Log.DebugFormat("++ Repair DS4 [{0}] Link Key For BTH Dongle [{1}] Failed!", DeviceAddress.AsFriendlyName(), HostAddress.AsFriendlyName());
            }

            return(base.Start());
        }
Beispiel #7
0
        public override bool Open(string devicePath)
        {
            if (base.Open(devicePath))
            {
                State = DsState.Reserved;
                GetDeviceInstance(ref m_Instance);

                var transfered = 0;

                if (SendTransfer(UsbHidRequestType.DeviceToHost, UsbHidRequest.GetReport, 0x03F5, m_Buffer,
                                 ref transfered))
                {
                    HostAddress =
                        new PhysicalAddress(new[]
                                            { m_Buffer[2], m_Buffer[3], m_Buffer[4], m_Buffer[5], m_Buffer[6], m_Buffer[7] });
                }
                else
                {
                    Log.ErrorFormat("Couldn't request Bluetooth host address for device {0}, error: {1}", devicePath,
                                    new Win32Exception(Marshal.GetLastWin32Error()));
                    State = DsState.Disconnected;
                    return(false);
                }

                if (SendTransfer(UsbHidRequestType.DeviceToHost, UsbHidRequest.GetReport, 0x03F2, m_Buffer,
                                 ref transfered))
                {
                    DeviceAddress =
                        new PhysicalAddress(new[]
                                            { m_Buffer[4], m_Buffer[5], m_Buffer[6], m_Buffer[7], m_Buffer[8], m_Buffer[9] });
                }
                else
                {
                    Log.ErrorFormat("Couldn't request Bluetooth device address for device {0}, error: {1}", devicePath,
                                    new Win32Exception(Marshal.GetLastWin32Error()));
                    State = DsState.Disconnected;
                    return(false);
                }

                Log.InfoFormat("Successfully opened device with MAC address {0}", DeviceAddress.AsFriendlyName());

                if (!IniConfig.Instance.Hci.GenuineMacAddresses.Any(m => DeviceAddress.AsFriendlyName().StartsWith(m)))
                {
                    Log.WarnFormat("Fake DualShock 3 detected [{0}]", DeviceAddress.AsFriendlyName());

                    var bthCompany = IniConfig.Instance.BthChipManufacturers.FirstOrDefault(
                        m =>
                        DeviceAddress.AsFriendlyName().StartsWith(m.PartialMacAddress.ToUpper()));

                    if (bthCompany != null && bthCompany.Name.Equals("AirohaTechnologyCorp"))
                    {
                        Log.WarnFormat("Controller uses Bluetooth chip by Airoha Technology Corp., suppressing workaround");
                        IsFake = false;
                    }
                    else
                    {
                        IsFake = true;
                    }
                }
                else
                {
                    Log.Info("Genuine Sony DualShock 3 detected");

                    //Switch to initial read (for eeprom and version)
                    if (SendTransfer(UsbHidRequestType.HostToDevice, UsbHidRequest.SetReport, 0x03EF, _eepromSetReport, ref transfered))
                    {
                        //read EEPROM
                        var buffer = new byte[64];                         //maybe this should be 49 as well, we only use first 49 bytes max
                        transfered = buffer.Length;
                        if (SendTransfer(UsbHidRequestType.DeviceToHost, UsbHidRequest.GetReport, 0x03EF, buffer, ref transfered) && transfered >= 49)
                        {
                            _cal = new DS3CalInstance(DeviceAddress, buffer);
                            var eepromBuffer = buffer;

                            //read version
                            buffer     = new byte[49];
                            transfered = buffer.Length;
                            if (SendTransfer(UsbHidRequestType.DeviceToHost, UsbHidRequest.GetReport, 0x0301, buffer, ref transfered) && transfered >= 49)
                            {
                                _cal.InitialCal(buffer);
                                var statusBuffer = buffer;

                                var totalBuffer = new byte[49 + 49];
                                Array.Copy(eepromBuffer, 0, totalBuffer, 0, Math.Min(eepromBuffer.Length, 49));
                                Array.Copy(statusBuffer, 0, totalBuffer, 49, Math.Min(statusBuffer.Length, 49));

                                using (var db = new ScpDb())
                                {
                                    using (var tran = db.Engine.GetTransaction())
                                    {
                                        tran.Insert(ScpDb.TableDS3Data, DeviceAddress.GetAddressBytes(), totalBuffer);
                                        tran.Commit();
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(State == DsState.Reserved);
        }
Beispiel #8
0
        public override bool Start()
        {
            Model = DsModel.DS3;

            if (IsActive)
            {
                var transfered = 0;

                if (_cal != null)
                {
                    //send initial cal value
                    var outBuffer = new byte[48];
                    outBuffer[9] = 0xFF;
                    _cal.ApplyCalToOutReport(outBuffer);

                    if (SendTransfer(UsbHidRequestType.HostToDevice, UsbHidRequest.SetReport,
                                     ToValue(UsbHidReportRequestType.Output, UsbHidReportRequestId.One),
                                     outBuffer, ref transfered) == false)
                    {
                        Log.ErrorFormat("Couldn't send cal control request to device {0}, error: {1}", DeviceAddress.AsFriendlyName(),
                                        new Win32Exception(Marshal.GetLastWin32Error()));
                        return(false);
                    }
                }

                if (SendTransfer(UsbHidRequestType.HostToDevice, UsbHidRequest.SetReport, 0x03F4, _hidCommandEnable, ref transfered))
                {
                    base.Start();
                }
                else
                {
                    Log.ErrorFormat("Couldn't send control request to device {0}, error: {1}", DeviceAddress.AsFriendlyName(),
                                    new Win32Exception(Marshal.GetLastWin32Error()));
                    return(false);
                }
            }

            return(State == DsState.Connected);
        }
Beispiel #9
0
 public override string ToString()
 {
     return(string.Format("{0} - {1}", DeviceAddress.AsFriendlyName(), _remoteName));
 }
Beispiel #10
0
        public override bool Start()
        {
            CanStartHid = false;
            State       = DsState.Connected;

            byte[] eepromContents = null, statusContents = null;
            using (var db = new ScpDb())
            {
                using (var tran = db.Engine.GetTransaction())
                {
                    var row = tran.Select <byte[], byte[]>(ScpDb.TableDS3Data, DeviceAddress.GetAddressBytes());
                    if (row.Exists)
                    {
                        eepromContents = new byte[49];
                        statusContents = new byte[49];

                        var rowData = row.Value;
                        Array.Copy(rowData, 0, eepromContents, 0, eepromContents.Length);
                        Array.Copy(rowData, eepromContents.Length, statusContents, 0, statusContents.Length);
                    }
                }
            }

            if (eepromContents != null && statusContents != null)
            {
                _cal = new DS3CalInstance(DeviceAddress, eepromContents);
                _cal.InitialCal(statusContents);
            }

            if (!IsFake && _cal == null)
            {
                Log.WarnFormat("EEPROM data for DS3 controller {0} not present, please connect it via USB first!", DeviceAddress.AsFriendlyName());
            }

            m_Queued  = 1;
            m_Blocked = true;
            m_Last    = DateTime.Now;
            BluetoothDevice.HID_Command(HciHandle.Bytes, Get_SCID(L2CAP.PSM.HID_Command), _hidCommandEnable);

            return(base.Start());
        }