PacketSender.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <PacketSender.h>
  2. #include <MiLightRadioConfig.h>
  3. PacketSender::PacketSender(
  4. RadioSwitchboard& radioSwitchboard,
  5. Settings& settings,
  6. PacketSentHandler packetSentHandler
  7. ) : radioSwitchboard(radioSwitchboard)
  8. , settings(settings)
  9. , stateStore(stateStore)
  10. , currentPacket(nullptr)
  11. , packetRepeatsRemaining(0)
  12. , packetSentHandler(packetSentHandler)
  13. , lastSend(0)
  14. , currentResendCount(settings.packetRepeats)
  15. , throttleMultiplier(
  16. std::ceil(
  17. (settings.packetRepeatThrottleSensitivity / 1000.0) * settings.packetRepeats
  18. )
  19. )
  20. { }
  21. void PacketSender::enqueue(uint8_t* packet, const MiLightRemoteConfig* remoteConfig, const size_t repeatsOverride) {
  22. #ifdef DEBUG_PRINTF
  23. Serial.println("Enqueuing packet");
  24. #endif
  25. size_t repeats = repeatsOverride == DEFAULT_PACKET_SENDS_VALUE
  26. ? this->currentResendCount
  27. : repeatsOverride;
  28. queue.push(packet, remoteConfig, repeats);
  29. }
  30. void PacketSender::loop() {
  31. // Switch to the next packet if we're done with the current one
  32. if (packetRepeatsRemaining == 0 && !queue.isEmpty()) {
  33. nextPacket();
  34. }
  35. // If there's a packet we're handling, deal with it
  36. if (currentPacket != nullptr && packetRepeatsRemaining > 0) {
  37. handleCurrentPacket();
  38. }
  39. }
  40. bool PacketSender::isSending() {
  41. return packetRepeatsRemaining > 0 || !queue.isEmpty();
  42. }
  43. void PacketSender::nextPacket() {
  44. #ifdef DEBUG_PRINTF
  45. Serial.printf("Switching to next packet, %d packets in queue\n", queue.size());
  46. #endif
  47. currentPacket = queue.pop();
  48. if (currentPacket->repeatsOverride > 0) {
  49. packetRepeatsRemaining = currentPacket->repeatsOverride;
  50. } else {
  51. packetRepeatsRemaining = settings.packetRepeats;
  52. }
  53. // Adjust resend count according to throttling rules
  54. updateResendCount();
  55. }
  56. void PacketSender::handleCurrentPacket() {
  57. // Always switch radio. could've been listening in another context
  58. radioSwitchboard.switchRadio(currentPacket->remoteConfig);
  59. size_t numToSend = std::min(packetRepeatsRemaining, settings.packetRepeatsPerLoop);
  60. sendRepeats(numToSend);
  61. packetRepeatsRemaining -= numToSend;
  62. // If we're done sending this packet, fire the sent packet callback
  63. if (packetRepeatsRemaining == 0 && packetSentHandler != nullptr) {
  64. packetSentHandler(currentPacket->packet, *currentPacket->remoteConfig);
  65. }
  66. }
  67. void PacketSender::sendRepeats(size_t num) {
  68. size_t len = currentPacket->remoteConfig->packetFormatter->getPacketLength();
  69. #ifdef DEBUG_PRINTF
  70. Serial.printf_P(PSTR("Sending packet (%d repeats): \n"), num);
  71. for (size_t i = 0; i < len; i++) {
  72. Serial.printf_P(PSTR("%02X "), currentPacket->packet[i]);
  73. }
  74. Serial.println();
  75. int iStart = millis();
  76. #endif
  77. for (size_t i = 0; i < num; ++i) {
  78. radioSwitchboard.write(currentPacket->packet, len);
  79. }
  80. #ifdef DEBUG_PRINTF
  81. int iElapsed = millis() - iStart;
  82. Serial.print("Elapsed: ");
  83. Serial.println(iElapsed);
  84. #endif
  85. }
  86. void PacketSender::updateResendCount() {
  87. unsigned long now = millis();
  88. long millisSinceLastSend = now - lastSend;
  89. long x = (millisSinceLastSend - settings.packetRepeatThrottleThreshold);
  90. long delta = x * throttleMultiplier;
  91. int signedResends = static_cast<int>(this->currentResendCount) + delta;
  92. if (signedResends < static_cast<int>(settings.packetRepeatMinimum)) {
  93. signedResends = settings.packetRepeatMinimum;
  94. } else if (signedResends > static_cast<int>(settings.packetRepeats)) {
  95. signedResends = settings.packetRepeats;
  96. }
  97. this->currentResendCount = signedResends;
  98. this->lastSend = now;
  99. }