xinput_auth_platform.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #include "xinput_auth.h"
  2. #include "src/libxsm3/xsm3.h"
  3. #include <Arduino.h>
  4. #include <stdio.h>
  5. static TaskHandle_t g_authWorker;
  6. uint32_t xinputAuthLock()
  7. {
  8. uint32_t mask = __get_PRIMASK();
  9. __disable_irq();
  10. return mask;
  11. }
  12. void xinputAuthUnlock(uint32_t mask)
  13. {
  14. __set_PRIMASK(mask);
  15. }
  16. void xinputAuthBoardSerial(char serial[13])
  17. {
  18. snprintf(serial, 13, "%04lX%08lX",
  19. (unsigned long)(NRF_FICR->DEVICEID[1] & 0xFFFF),
  20. (unsigned long)NRF_FICR->DEVICEID[0]);
  21. }
  22. static void authWorker(void *)
  23. {
  24. for (;;) {
  25. ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
  26. xinputAuthProcess();
  27. }
  28. }
  29. bool xinputAuthStartWorker()
  30. {
  31. if (g_authWorker)
  32. return true;
  33. // Adafruit's USB task has only 200 words of stack. Crypto gets its own
  34. // stack below the RF loop's priority, leaving USB polling responsive.
  35. return xTaskCreate(authWorker, "xsm3", 2048, nullptr, tskIDLE_PRIORITY,
  36. &g_authWorker) == pdPASS;
  37. }
  38. void xinputAuthNotify()
  39. {
  40. if (g_authWorker)
  41. xTaskNotifyGive(g_authWorker);
  42. }
  43. void xinputAuthYield()
  44. {
  45. // taskYIELD() cannot schedule below the continuously runnable RF loop.
  46. // Lend the worker one tick between polls, never inside an RF RX window.
  47. if (xinputAuthBusy())
  48. delay(1);
  49. }
  50. extern "C" bool xsm3_random_bytes(uint8_t *buffer, size_t length)
  51. {
  52. // OpenPuck uses the radio directly, without enabling the SoftDevice;
  53. // no other firmware subsystem owns RNG. Do not use Arduino random().
  54. NRF_RNG->CONFIG = RNG_CONFIG_DERCEN_Enabled << RNG_CONFIG_DERCEN_Pos;
  55. NRF_RNG->EVENTS_VALRDY = 0;
  56. NRF_RNG->TASKS_START = 1;
  57. unsigned long started = millis();
  58. for (size_t i = 0; i < length;) {
  59. if (NRF_RNG->EVENTS_VALRDY) {
  60. buffer[i++] = (uint8_t)NRF_RNG->VALUE;
  61. NRF_RNG->EVENTS_VALRDY = 0;
  62. } else if (millis() - started > 100) {
  63. NRF_RNG->TASKS_STOP = 1;
  64. return false;
  65. }
  66. }
  67. NRF_RNG->TASKS_STOP = 1;
  68. return true;
  69. }