You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
4.3 KiB

  1. /* Copyright (C) 2014 Kristian Lauszus, TKJ Electronics. All rights reserved.
  2. This software may be distributed and modified under the terms of the GNU
  3. General Public License version 2 (GPL2) as published by the Free Software
  4. Foundation and appearing in the file GPL2.TXT included in the packaging of
  5. this file. Please note that GPL2 Section 2[b] requires that all works based
  6. on this software must also be made publicly available under the terms of
  7. the GPL2 ("Copyleft").
  8. Contact information
  9. -------------------
  10. Kristian Lauszus, TKJ Electronics
  11. Web : http://www.tkjelectronics.com
  12. e-mail : kristianl@tkjelectronics.com
  13. */
  14. #ifndef _ps4bt_h_
  15. #define _ps4bt_h_
  16. #include "BTHID.h"
  17. #include "PS4Parser.h"
  18. /**
  19. * This class implements support for the PS4 controller via Bluetooth.
  20. * It uses the BTHID class for all the Bluetooth communication.
  21. */
  22. class PS4BT : public BTHID, public PS4Parser {
  23. public:
  24. /**
  25. * Constructor for the PS4BT class.
  26. * @param p Pointer to the BTD class instance.
  27. * @param pair Set this to true in order to pair with the device. If the argument is omitted then it will not pair with it. One can use ::PAIR to set it to true.
  28. * @param pin Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used.
  29. */
  30. PS4BT(BTD *p, bool pair = false, const char *pin = "0000") :
  31. BTHID(p, pair, pin) {
  32. PS4Parser::Reset();
  33. };
  34. /**
  35. * Used to check if a PS4 controller is connected.
  36. * @return Returns true if it is connected.
  37. */
  38. bool connected() {
  39. return BTHID::connected;
  40. };
  41. protected:
  42. /** @name BTHID implementation */
  43. /**
  44. * Used to parse Bluetooth HID data.
  45. * @param len The length of the incoming data.
  46. * @param buf Pointer to the data buffer.
  47. */
  48. virtual void ParseBTHIDData(uint8_t len, uint8_t *buf) {
  49. PS4Parser::Parse(len, buf);
  50. };
  51. /**
  52. * Called when a device is successfully initialized.
  53. * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
  54. * This is useful for instance if you want to set the LEDs in a specific way.
  55. */
  56. virtual void OnInitBTHID() {
  57. PS4Parser::Reset();
  58. enable_sixaxis(); // Make the controller send out the entire output report
  59. if (pFuncOnInit)
  60. pFuncOnInit(); // Call the user function
  61. else
  62. setLed(Blue);
  63. };
  64. /** Used to reset the different buffers to there default values */
  65. virtual void ResetBTHID() {
  66. PS4Parser::Reset();
  67. };
  68. /**@}*/
  69. /** @name PS4Parser implementation */
  70. virtual void sendOutputReport(PS4Output *output) { // Source: https://github.com/chrippa/ds4drv
  71. uint8_t buf[79];
  72. memset(buf, 0, sizeof(buf));
  73. buf[0] = 0x52; // HID BT Set_report (0x50) | Report Type (Output 0x02)
  74. buf[1] = 0x11; // Report ID
  75. buf[2] = 0x80;
  76. buf[4]= 0xFF;
  77. buf[7] = output->smallRumble; // Small Rumble
  78. buf[8] = output->bigRumble; // Big rumble
  79. buf[9] = output->r; // Red
  80. buf[10] = output->g; // Green
  81. buf[11] = output->b; // Blue
  82. buf[12] = output->flashOn; // Time to flash bright (255 = 2.5 seconds)
  83. buf[13] = output->flashOff; // Time to flash dark (255 = 2.5 seconds)
  84. output->reportChanged = false;
  85. // The PS4 console actually set the four last bytes to a CRC32 checksum, but it seems like it is actually not needed
  86. HID_Command(buf, sizeof(buf));
  87. };
  88. /**@}*/
  89. private:
  90. void enable_sixaxis() { // Command used to make the PS4 controller send out the entire output report
  91. uint8_t buf[2];
  92. buf[0] = 0x43; // HID BT Get_report (0x40) | Report Type (Feature 0x03)
  93. buf[1] = 0x02; // Report ID
  94. HID_Command(buf, 2);
  95. };
  96. void HID_Command(uint8_t *data, uint8_t nbytes) {
  97. pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
  98. };
  99. };
  100. #endif