Kaynağa Gözat

Fix crash when sending group 0 commands (#349) (#350)

Add null checks to prevent crash for group 0 commands
Chris Mullins 7 yıl önce
ebeveyn
işleme
8ce5bf8d61

+ 17 - 9
lib/MiLight/FUT089PacketFormatter.cpp

@@ -35,18 +35,22 @@ void FUT089PacketFormatter::updateColorRaw(uint8_t value) {
 void FUT089PacketFormatter::updateTemperature(uint8_t value) {
   // look up our current mode 
   const GroupState* ourState = this->stateStore->get(this->deviceId, this->groupId, REMOTE_TYPE_FUT089);
-  BulbMode originalBulbMode = ourState->getBulbMode();
-
-  // are we already in white?  If not, change to white
-  if (originalBulbMode != BulbMode::BULB_MODE_WHITE) {
-    updateColorWhite();
+  BulbMode originalBulbMode;
+  
+  if (ourState != NULL) {
+    originalBulbMode = ourState->getBulbMode();
+
+    // are we already in white?  If not, change to white
+    if (originalBulbMode != BulbMode::BULB_MODE_WHITE) {
+      updateColorWhite();
+    }
   }
 
   // now make the temperature change
   command(FUT089_KELVIN, 100 - value);
 
   // and return to our original mode
-  if ((settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_WHITE)) {
+  if (ourState != NULL && (settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_WHITE)) {
     switchMode(*ourState, originalBulbMode);
   }
 }
@@ -58,10 +62,14 @@ void FUT089PacketFormatter::updateTemperature(uint8_t value) {
 void FUT089PacketFormatter::updateSaturation(uint8_t value) {
   // look up our current mode 
   const GroupState* ourState = this->stateStore->get(this->deviceId, this->groupId, REMOTE_TYPE_FUT089);
-  BulbMode originalBulbMode = ourState->getBulbMode();
+  BulbMode originalBulbMode;
+  
+  if (ourState != NULL) {
+    originalBulbMode = ourState->getBulbMode();
+  }
 
   // are we already in color?  If not, we need to flip modes
-  if ((settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_COLOR)) {
+  if (ourState != NULL && (settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_COLOR)) {
     updateHue(ourState->getHue());
   }
 
@@ -69,7 +77,7 @@ void FUT089PacketFormatter::updateSaturation(uint8_t value) {
   command(FUT089_SATURATION, 100 - value);
 
   // and revert back if necessary
-  if ((settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_COLOR)) {
+  if (ourState != NULL && (settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_COLOR)) {
     switchMode(*ourState, originalBulbMode);
   }
 }

+ 23 - 11
lib/MiLight/RgbCctPacketFormatter.cpp

@@ -47,14 +47,17 @@ void RgbCctPacketFormatter::updateTemperature(uint8_t value) {
   // is lost.  So lookup our current bulb mode, and if needed, reset the hue/mode after
   // changing the temperature
   const GroupState* ourState = this->stateStore->get(this->deviceId, this->groupId, REMOTE_TYPE_RGB_CCT);
-  BulbMode originalBulbMode = ourState->getBulbMode();
 
   // now make the temperature change
   command(RGB_CCT_KELVIN, cmdValue);
 
   // and return to our original mode
-  if ((settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_WHITE)) {
-    switchMode(*ourState, originalBulbMode);
+  if (ourState != NULL) {
+    BulbMode originalBulbMode = ourState->getBulbMode();
+
+    if ((settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_WHITE)) {
+      switchMode(*ourState, originalBulbMode);
+    }
   }
 }
 
@@ -63,19 +66,25 @@ void RgbCctPacketFormatter::updateTemperature(uint8_t value) {
 void RgbCctPacketFormatter::updateSaturation(uint8_t value) {
    // look up our current mode 
   const GroupState* ourState = this->stateStore->get(this->deviceId, this->groupId, REMOTE_TYPE_RGB_CCT);
-  BulbMode originalBulbMode = ourState->getBulbMode();
-
-  // are we already in white?  If not, change to white
-  if ((settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_COLOR)) {
-    updateHue(ourState->getHue());
+  BulbMode originalBulbMode;
+  
+  if (ourState != NULL) {
+    originalBulbMode = ourState->getBulbMode();
+
+    // are we already in white?  If not, change to white
+    if ((settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_COLOR)) {
+      updateHue(ourState->getHue());
+    }
   }
 
   // now make the saturation change
   uint8_t remapped = value + RGB_CCT_SATURATION_OFFSET;
   command(RGB_CCT_SATURATION, remapped);
 
-  if ((settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_COLOR)) {
-    switchMode(*ourState, originalBulbMode);
+  if (ourState != NULL) {
+    if ((settings->enableAutomaticModeSwitching) && (originalBulbMode != BulbMode::BULB_MODE_COLOR)) {
+      switchMode(*ourState, originalBulbMode);
+    }
   }
 }
 
@@ -83,7 +92,10 @@ void RgbCctPacketFormatter::updateColorWhite() {
   // there is no direct white command, so let's look up our prior temperature and set that, which
   // causes the bulb to go white 
   const GroupState* ourState = this->stateStore->get(this->deviceId, this->groupId, REMOTE_TYPE_RGB_CCT);
-  uint8_t value = V2PacketFormatter::tov2scale(ourState->getKelvin(), RGB_CCT_KELVIN_REMOTE_END, 2);
+  uint8_t value = 
+    ourState == NULL 
+      ? 0 
+      : V2PacketFormatter::tov2scale(ourState->getKelvin(), RGB_CCT_KELVIN_REMOTE_END, 2);
 
   // issue command to set kelvin to prior value, which will drive to white
   command(RGB_CCT_KELVIN, value);

+ 1 - 1
lib/MiLight/RgbPacketFormatter.cpp

@@ -48,7 +48,7 @@ void RgbPacketFormatter::updateColorRaw(uint8_t value) {
 
 void RgbPacketFormatter::updateBrightness(uint8_t value) {
   const GroupState* state = this->stateStore->get(deviceId, groupId, MiLightRemoteType::REMOTE_TYPE_RGB);
-  int8_t knownValue = state->isSetBrightness() ? state->getBrightness() : -1;
+  int8_t knownValue = (state != NULL && state->isSetBrightness()) ? state->getBrightness() : -1;
 
   valueByStepFunction(
     &PacketFormatter::increaseBrightness,

+ 1 - 1
lib/MiLight/RgbwPacketFormatter.cpp

@@ -44,7 +44,7 @@ void RgbwPacketFormatter::previousMode() {
 
 uint8_t RgbwPacketFormatter::currentMode() {
   const GroupState* state = stateStore->get(deviceId, groupId, REMOTE_TYPE_RGBW);
-  return state->getMode();
+  return state != NULL ? state->getMode() : 0;
 }
 
 void RgbwPacketFormatter::updateMode(uint8_t mode) {