|
@@ -1,318 +1,181 @@
|
|
|
#include <MiLightClient.h>
|
|
#include <MiLightClient.h>
|
|
|
#include <MiLightRadioConfig.h>
|
|
#include <MiLightRadioConfig.h>
|
|
|
|
|
+#include <Arduino.h>
|
|
|
|
|
|
|
|
-MiLightRadio* MiLightClient::getRadio(const MiLightRadioType type) {
|
|
|
|
|
- MiLightRadioStack* stack = NULL;
|
|
|
|
|
|
|
+MiLightRadio* MiLightClient::switchRadio(const MiLightRadioType type) {
|
|
|
|
|
+ RadioStack* stack = NULL;
|
|
|
|
|
|
|
|
- if (type == RGBW) {
|
|
|
|
|
- stack = rgbwRadio;
|
|
|
|
|
- } else if (type == CCT) {
|
|
|
|
|
- stack = cctRadio;
|
|
|
|
|
- } else if (type == RGB_CCT) {
|
|
|
|
|
- stack = rgbCctRadio;
|
|
|
|
|
|
|
+ for (int i = 0; i < numRadios; i++) {
|
|
|
|
|
+ if (radios[i]->config.type == type) {
|
|
|
|
|
+ stack = radios[i];
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (stack != NULL) {
|
|
if (stack != NULL) {
|
|
|
MiLightRadio *radio = stack->getRadio();
|
|
MiLightRadio *radio = stack->getRadio();
|
|
|
|
|
|
|
|
- if (currentRadio != stack->type) {
|
|
|
|
|
|
|
+ if (currentRadio->config.type != stack->config.type) {
|
|
|
radio->configure();
|
|
radio->configure();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- currentRadio = stack->type;
|
|
|
|
|
|
|
+ currentRadio = stack;
|
|
|
|
|
+ formatter = stack->config.packetFormatter;
|
|
|
return radio;
|
|
return radio;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Serial.print("MiLightClient - tried to get radio for unknown type: ");
|
|
|
|
|
+ Serial.println(type);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::setResendCount(const unsigned int resendCount) {
|
|
|
|
|
- this->resendCount = resendCount;
|
|
|
|
|
|
|
+void MiLightClient::prepare(MiLightRadioConfig& config,
|
|
|
|
|
+ const uint16_t deviceId,
|
|
|
|
|
+ const uint8_t groupId) {
|
|
|
|
|
+
|
|
|
|
|
+ switchRadio(config.type);
|
|
|
|
|
+
|
|
|
|
|
+ if (deviceId >= 0 && groupId >= 0) {
|
|
|
|
|
+ formatter->prepare(deviceId, groupId);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-uint8_t MiLightClient::nextSequenceNum() {
|
|
|
|
|
- return sequenceNum++;
|
|
|
|
|
|
|
+void MiLightClient::setResendCount(const unsigned int resendCount) {
|
|
|
|
|
+ this->resendCount = resendCount;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-bool MiLightClient::available(const MiLightRadioType radioType) {
|
|
|
|
|
- MiLightRadio* radio = getRadio(radioType);
|
|
|
|
|
-
|
|
|
|
|
- if (radio == NULL) {
|
|
|
|
|
|
|
+bool MiLightClient::available() {
|
|
|
|
|
+ if (currentRadio == NULL) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return radio->available();
|
|
|
|
|
|
|
+ return currentRadio->getRadio()->available();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::read(const MiLightRadioType radioType, uint8_t packet[]) {
|
|
|
|
|
- MiLightRadio* radio = getRadio(radioType);
|
|
|
|
|
-
|
|
|
|
|
- if (radio == NULL) {
|
|
|
|
|
|
|
+void MiLightClient::read(uint8_t packet[]) {
|
|
|
|
|
+ if (currentRadio == NULL) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
size_t length;
|
|
size_t length;
|
|
|
- radio->read(packet, length);
|
|
|
|
|
|
|
+ currentRadio->getRadio()->read(packet, length);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::write(const MiLightRadioType radioType,
|
|
|
|
|
- uint8_t packet[]) {
|
|
|
|
|
-
|
|
|
|
|
- MiLightRadio* radio = getRadio(radioType);
|
|
|
|
|
-
|
|
|
|
|
- if (radio == NULL) {
|
|
|
|
|
|
|
+void MiLightClient::write(uint8_t packet[]) {
|
|
|
|
|
+ if (currentRadio == NULL) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+#ifdef DEBUG_PRINTF
|
|
|
|
|
+ printf("Sending packet: ");
|
|
|
|
|
+ for (int i = 0; i < currentRadio->config.getPacketLength(); i++) {
|
|
|
|
|
+ printf("%02X", packet[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+ printf("\n");
|
|
|
|
|
+#endif
|
|
|
|
|
+
|
|
|
for (int i = 0; i < this->resendCount; i++) {
|
|
for (int i = 0; i < this->resendCount; i++) {
|
|
|
- radio->write(packet, MILIGHT_PACKET_LENGTH);
|
|
|
|
|
|
|
+ currentRadio->getRadio()->write(packet, currentRadio->config.getPacketLength());
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+void MiLightClient::updateColorRaw(const uint8_t color) {
|
|
|
|
|
+ formatter->updateColorRaw(color);
|
|
|
|
|
+ flushPacket();
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-void MiLightClient::writeRgbw(
|
|
|
|
|
- const uint16_t deviceId,
|
|
|
|
|
- const uint8_t color,
|
|
|
|
|
- const uint8_t brightness,
|
|
|
|
|
- const uint8_t groupId,
|
|
|
|
|
- const uint8_t button) {
|
|
|
|
|
-
|
|
|
|
|
- uint8_t packet[MilightRgbwConfig.packetLength];
|
|
|
|
|
- size_t packetPtr = 0;
|
|
|
|
|
-
|
|
|
|
|
- packet[packetPtr++] = RGBW;
|
|
|
|
|
- packet[packetPtr++] = deviceId >> 8;
|
|
|
|
|
- packet[packetPtr++] = deviceId & 0xFF;
|
|
|
|
|
- packet[packetPtr++] = color;
|
|
|
|
|
- packet[packetPtr++] = (brightness << 3) | (groupId & 0x07);
|
|
|
|
|
- packet[packetPtr++] = button;
|
|
|
|
|
- packet[packetPtr++] = nextSequenceNum();
|
|
|
|
|
-
|
|
|
|
|
- write(RGBW, packet);
|
|
|
|
|
|
|
+void MiLightClient::updateHue(const uint16_t hue) {
|
|
|
|
|
+ formatter->updateHue(hue);
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::writeCct(const uint16_t deviceId,
|
|
|
|
|
- const uint8_t groupId,
|
|
|
|
|
- const uint8_t button) {
|
|
|
|
|
-
|
|
|
|
|
- uint8_t packet[MilightRgbwConfig.packetLength];
|
|
|
|
|
- uint8_t sequenceNum = nextSequenceNum();
|
|
|
|
|
- size_t packetPtr = 0;
|
|
|
|
|
-
|
|
|
|
|
- packet[packetPtr++] = CCT;
|
|
|
|
|
- packet[packetPtr++] = deviceId >> 8;
|
|
|
|
|
- packet[packetPtr++] = deviceId & 0xFF;
|
|
|
|
|
- packet[packetPtr++] = groupId;
|
|
|
|
|
- packet[packetPtr++] = button;
|
|
|
|
|
- packet[packetPtr++] = sequenceNum;
|
|
|
|
|
- packet[packetPtr++] = sequenceNum;
|
|
|
|
|
-
|
|
|
|
|
- write(CCT, packet);
|
|
|
|
|
|
|
+void MiLightClient::updateBrightness(const uint8_t brightness) {
|
|
|
|
|
+ formatter->updateBrightness(brightness);
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::updateColorRaw(const uint16_t deviceId, const uint8_t groupId, const uint16_t color) {
|
|
|
|
|
- writeRgbw(deviceId, color, 0, groupId, RGBW_COLOR);
|
|
|
|
|
|
|
+void MiLightClient::updateStatus(MiLightStatus status, uint8_t groupId) {
|
|
|
|
|
+ formatter->updateStatus(status, groupId);
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::updateHue(const uint16_t deviceId, const uint8_t groupId, const uint16_t hue) {
|
|
|
|
|
- // Map color as a Hue value in [0, 359] to [0, 255]. The protocol also has
|
|
|
|
|
- // 0 being roughly magenta (#FF00FF)
|
|
|
|
|
- const int16_t remappedColor = (hue + 40) % 360;
|
|
|
|
|
- const uint8_t adjustedColor = round(remappedColor * (255 / 360.0));
|
|
|
|
|
-
|
|
|
|
|
- writeRgbw(deviceId, adjustedColor, 0, groupId, RGBW_COLOR);
|
|
|
|
|
|
|
+void MiLightClient::updateStatus(MiLightStatus status) {
|
|
|
|
|
+ formatter->updateStatus(status);
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::updateBrightness(const uint16_t deviceId, const uint8_t groupId, const uint8_t brightness) {
|
|
|
|
|
- // Expect an input value in [0, 100]. Map it down to [0, 25].
|
|
|
|
|
- const uint8_t adjustedBrightness = round(brightness * (25 / 100.0));
|
|
|
|
|
-
|
|
|
|
|
- // The actual protocol uses a bizarre range where min is 16, max is 23:
|
|
|
|
|
- // [16, 15, ..., 0, 31, ..., 23]
|
|
|
|
|
- const uint8_t packetBrightnessValue = (
|
|
|
|
|
- ((31 - adjustedBrightness) + 17) % 32
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- writeRgbw(deviceId, 0, packetBrightnessValue, groupId, RGBW_BRIGHTNESS);
|
|
|
|
|
|
|
+void MiLightClient::updateSaturation(const uint8_t value) {
|
|
|
|
|
+ formatter->updateSaturation(value);
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::updateStatus(const MiLightRadioType type, const uint16_t deviceId, const uint8_t groupId, MiLightStatus status) {
|
|
|
|
|
- if (type == RGBW) {
|
|
|
|
|
- uint8_t button = RGBW_GROUP_1_ON + ((groupId - 1)*2) + status;
|
|
|
|
|
- writeRgbw(deviceId, 0, 0, groupId, button);
|
|
|
|
|
- } else {
|
|
|
|
|
- writeCct(deviceId, groupId, getCctStatusButton(groupId, status));
|
|
|
|
|
- }
|
|
|
|
|
|
|
+void MiLightClient::updateColorWhite() {
|
|
|
|
|
+ formatter->updateColorWhite();
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::updateColorWhite(const uint16_t deviceId, const uint8_t groupId) {
|
|
|
|
|
- uint8_t button = RGBW_GROUP_1_MAX_LEVEL + ((groupId - 1)*2);
|
|
|
|
|
- pressButton(RGBW, deviceId, groupId, button);
|
|
|
|
|
|
|
+void MiLightClient::pair() {
|
|
|
|
|
+ formatter->pair();
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::pair(const MiLightRadioType type, const uint16_t deviceId, const uint8_t groupId) {
|
|
|
|
|
- updateStatus(type, deviceId, groupId, ON);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void MiLightClient::unpair(const MiLightRadioType type, const uint16_t deviceId, const uint8_t groupId) {
|
|
|
|
|
- if (type == RGBW) {
|
|
|
|
|
- updateStatus(RGBW, deviceId, groupId, ON);
|
|
|
|
|
- delay(1);
|
|
|
|
|
- updateColorWhite(deviceId, groupId);
|
|
|
|
|
- } else if (type == CCT) {
|
|
|
|
|
- for (int i = 0; i < 5; i++) {
|
|
|
|
|
- updateStatus(CCT, deviceId, groupId, ON);
|
|
|
|
|
- delay(1);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+void MiLightClient::unpair() {
|
|
|
|
|
+ formatter->unpair();
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::pressButton(const MiLightRadioType type, const uint16_t deviceId, const uint8_t groupId, const uint8_t button) {
|
|
|
|
|
- if (type == RGBW) {
|
|
|
|
|
- writeRgbw(deviceId, 0, 0, groupId, button);
|
|
|
|
|
- } else if (type == CCT) {
|
|
|
|
|
- writeCct(deviceId, groupId, button);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+void MiLightClient::increaseBrightness() {
|
|
|
|
|
+ formatter->increaseBrightness();
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::allOn(const MiLightRadioType type, const uint16_t deviceId) {
|
|
|
|
|
- if (type == RGBW) {
|
|
|
|
|
- writeRgbw(deviceId, 0, 0, 0, RGBW_ALL_ON);
|
|
|
|
|
- } else if (type == CCT) {
|
|
|
|
|
- writeCct(deviceId, 0, CCT_ALL_ON);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+void MiLightClient::decreaseBrightness() {
|
|
|
|
|
+ formatter->decreaseBrightness();
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::allOff(const MiLightRadioType type, const uint16_t deviceId) {
|
|
|
|
|
- if (type == RGBW) {
|
|
|
|
|
- writeRgbw(deviceId, 0, 0, 0, RGBW_ALL_OFF);
|
|
|
|
|
- } else if (type == CCT) {
|
|
|
|
|
- writeCct(deviceId, 0, CCT_ALL_OFF);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+void MiLightClient::increaseTemperature() {
|
|
|
|
|
+ formatter->increaseTemperature();
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::increaseCctBrightness(const uint16_t deviceId, const uint8_t groupId) {
|
|
|
|
|
- writeCct(deviceId, groupId, CCT_BRIGHTNESS_UP);
|
|
|
|
|
|
|
+void MiLightClient::decreaseTemperature() {
|
|
|
|
|
+ formatter->decreaseTemperature();
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::decreaseCctBrightness(const uint16_t deviceId, const uint8_t groupId) {
|
|
|
|
|
- writeCct(deviceId, groupId, CCT_BRIGHTNESS_DOWN);
|
|
|
|
|
|
|
+void MiLightClient::updateTemperature(const uint8_t temperature) {
|
|
|
|
|
+ formatter->updateTemperature(temperature);
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::updateCctBrightness(const uint16_t deviceId, const uint8_t groupId, const uint8_t brightness) {
|
|
|
|
|
- for (int i = 0; i < MILIGHT_CCT_INTERVALS; i++) {
|
|
|
|
|
- decreaseCctBrightness(deviceId, groupId);
|
|
|
|
|
- }
|
|
|
|
|
- for (int i = 0; i < brightness/10; i++) {
|
|
|
|
|
- increaseCctBrightness(deviceId, groupId);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+void MiLightClient::command(uint8_t command, uint8_t arg) {
|
|
|
|
|
+ formatter->command(command, arg);
|
|
|
|
|
+ flushPacket();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void MiLightClient::increaseTemperature(const uint16_t deviceId, const uint8_t groupId) {
|
|
|
|
|
- writeCct(deviceId, groupId, CCT_TEMPERATURE_UP);
|
|
|
|
|
|
|
+void MiLightClient::formatPacket(uint8_t* packet, char* buffer) {
|
|
|
|
|
+ formatter->format(packet, buffer);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
-void MiLightClient::decreaseTemperature(const uint16_t deviceId, const uint8_t groupId) {
|
|
|
|
|
- writeCct(deviceId, groupId, CCT_TEMPERATURE_DOWN);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void MiLightClient::updateTemperature(const uint16_t deviceId, const uint8_t groupId, const uint8_t temperature) {
|
|
|
|
|
- for (int i = 0; i < MILIGHT_CCT_INTERVALS; i++) {
|
|
|
|
|
- decreaseTemperature(deviceId, groupId);
|
|
|
|
|
- }
|
|
|
|
|
- for (int i = 0; i < temperature; i++) {
|
|
|
|
|
- increaseTemperature(deviceId, groupId);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-uint8_t MiLightClient::getCctStatusButton(uint8_t groupId, MiLightStatus status) {
|
|
|
|
|
- uint8_t button = 0;
|
|
|
|
|
|
|
+
|
|
|
|
|
+void MiLightClient::flushPacket() {
|
|
|
|
|
+ PacketStream& stream = formatter->buildPackets();
|
|
|
|
|
+ const size_t prevNumRepeats = this->resendCount;
|
|
|
|
|
|
|
|
- if (status == ON) {
|
|
|
|
|
- switch(groupId) {
|
|
|
|
|
- case 1:
|
|
|
|
|
- button = CCT_GROUP_1_ON;
|
|
|
|
|
- break;
|
|
|
|
|
- case 2:
|
|
|
|
|
- button = CCT_GROUP_2_ON;
|
|
|
|
|
- break;
|
|
|
|
|
- case 3:
|
|
|
|
|
- button = CCT_GROUP_3_ON;
|
|
|
|
|
- break;
|
|
|
|
|
- case 4:
|
|
|
|
|
- button = CCT_GROUP_4_ON;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- switch(groupId) {
|
|
|
|
|
- case 1:
|
|
|
|
|
- button = CCT_GROUP_1_OFF;
|
|
|
|
|
- break;
|
|
|
|
|
- case 2:
|
|
|
|
|
- button = CCT_GROUP_2_OFF;
|
|
|
|
|
- break;
|
|
|
|
|
- case 3:
|
|
|
|
|
- button = CCT_GROUP_3_OFF;
|
|
|
|
|
- break;
|
|
|
|
|
- case 4:
|
|
|
|
|
- button = CCT_GROUP_4_OFF;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // When sending multiple packets, normalize the number of repeats
|
|
|
|
|
+ if (stream.numPackets > 1) {
|
|
|
|
|
+ setResendCount(MILIGHT_DEFAULT_RESEND_COUNT);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return button;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-MiLightRadioType MiLightClient::getRadioType(const String& typeName) {
|
|
|
|
|
- if (typeName.equalsIgnoreCase("rgbw")) {
|
|
|
|
|
- return RGBW;
|
|
|
|
|
- } else if (typeName.equalsIgnoreCase("cct")) {
|
|
|
|
|
- return CCT;
|
|
|
|
|
- } else if (typeName.equalsIgnoreCase("rgb_cct")) {
|
|
|
|
|
- return RGB_CCT;
|
|
|
|
|
- } else {
|
|
|
|
|
- return UNKNOWN;
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const MiLightRadioConfig& MiLightClient::getRadioConfig(const String& typeName) {
|
|
|
|
|
- switch (getRadioType(typeName)) {
|
|
|
|
|
- case RGBW:
|
|
|
|
|
- return MilightRgbwConfig;
|
|
|
|
|
- case CCT:
|
|
|
|
|
- return MilightCctConfig;
|
|
|
|
|
- case RGB_CCT:
|
|
|
|
|
- return MilightRgbCctConfig;
|
|
|
|
|
- default:
|
|
|
|
|
- Serial.print("Unknown radio type: ");
|
|
|
|
|
- Serial.println(typeName);
|
|
|
|
|
- return MilightRgbwConfig;
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
|
|
+ while (stream.hasNext()) {
|
|
|
|
|
+ write(stream.next());
|
|
|
|
|
|
|
|
-void MiLightClient::formatPacket(MiLightRadioConfig& config, uint8_t* packet, char* buffer) {
|
|
|
|
|
- if (config.type == RGBW || config.type == CCT) {
|
|
|
|
|
- String format = String("Request type : %02X\n")
|
|
|
|
|
- + "Device ID : %02X%02X\n"
|
|
|
|
|
- + "b1 : %02X\n"
|
|
|
|
|
- + "b2 : %02X\n"
|
|
|
|
|
- + "b3 : %02X\n"
|
|
|
|
|
- + "Sequence Num. : %02X";
|
|
|
|
|
-
|
|
|
|
|
- sprintf(
|
|
|
|
|
- buffer,
|
|
|
|
|
- format.c_str(),
|
|
|
|
|
- packet[0],
|
|
|
|
|
- packet[1], packet[2],
|
|
|
|
|
- packet[3],
|
|
|
|
|
- packet[4],
|
|
|
|
|
- packet[5],
|
|
|
|
|
- packet[6]
|
|
|
|
|
- );
|
|
|
|
|
- } else {
|
|
|
|
|
- for (int i = 0; i < config.packetLength; i++) {
|
|
|
|
|
- sprintf(buffer, "%02X ", packet[i]);
|
|
|
|
|
- buffer += 3;
|
|
|
|
|
|
|
+ if (stream.hasNext()) {
|
|
|
|
|
+ delay(10);
|
|
|
}
|
|
}
|
|
|
- sprintf(buffer, "\n\n");
|
|
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
+
|
|
|
|
|
+ setResendCount(prevNumRepeats);
|
|
|
|
|
+ formatter->reset();
|
|
|
|
|
+}
|