relay.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. // relay.c — host→controller relay dispatch (see relay.h).
  2. //
  3. // The actual routing lives in the BT host (bt_relay), which knows what is bound
  4. // to each slot: a generic pad's rumble output, or an SC2's Valve report
  5. // characteristic. bt_relay is weak so a BT-less build still links.
  6. //
  7. // SPDX-License-Identifier: AGPL-3.0-or-later
  8. #include "puck/relay.h"
  9. // Diagnostics: how many host→controller relays we've seen, and the last report
  10. // id. Lets the panel confirm Steam is actually sending haptics/rumble.
  11. volatile uint16_t g_relay_count;
  12. volatile uint8_t g_relay_last_id;
  13. __attribute__((weak)) void bt_relay(int slot, uint8_t report_id,
  14. const uint8_t *body, uint16_t len)
  15. {
  16. (void)slot;
  17. (void)report_id;
  18. (void)body;
  19. (void)len;
  20. }
  21. void relay_enqueue(int slot, uint8_t report_id, const uint8_t *body, uint16_t len)
  22. {
  23. g_relay_count++;
  24. g_relay_last_id = report_id;
  25. bt_relay(slot, report_id, body, len);
  26. }
  27. void puck_rumble(int slot, uint16_t lo, uint16_t hi)
  28. {
  29. uint16_t inten = (lo > hi) ? lo : hi;
  30. uint8_t p[9];
  31. p[0] = inten ? 0x04 : 0x00; // HAPTIC_TYPE_RUMBLE / off
  32. p[1] = (uint8_t)(inten & 0xFF);
  33. p[2] = (uint8_t)(inten >> 8);
  34. p[3] = (uint8_t)(lo & 0xFF);
  35. p[4] = (uint8_t)(lo >> 8);
  36. p[5] = 0;
  37. p[6] = (uint8_t)(hi & 0xFF);
  38. p[7] = (uint8_t)(hi >> 8);
  39. p[8] = 0;
  40. relay_enqueue(slot, 0x80, p, 9);
  41. }