Bool callback function crashes, but int and float work! Confused [SOLVED]

I’m currently working on a library to integrate with a home automation platform, revolving around Cloud APIs and Webhooks.

As part of this, my library provides for the library user to create devices and nodes that will register on the Home Automation platform. When the Home Automation platform requests to GET or SET a value (e.g. onoff or room temp or thermostat mode) from the Particle device the library calls a user provided callback function.

I’m trying my best to keep things OOP and DRY… I’m not a great programmer, so bear with me please…

During Setup() the library is initialised and device/node capabilities are setup. Callbacks are attached. As I need to support callbacks to deal with bool, int and float I am overloading the methods in my intermediate class.
The code work fine with int and float callbacks, I can call my Cloud Function and the callbacks GET and SET perfectly, and my reports are published to my event stream. All good. But if I try to SET a bool callback, my photon blinks red and dies.

It could be a dumb error, but I can’t see it… So… here’s the code, it’s long so I’m just showing pertinent bits in the hope someone will know why bool callbacks might be different.


 class AthomGetSetObject: public AthomBaseObject {
    // Extends AthomBaseObject to support Get Set and Callbacks
    AthomGetSetObject(const String myName); // Constructor override
    int setSetCallback( int (*yourFunc)(int) ); // callback func for set
    int setSetCallback( float (*yourFunc)(float) ); // callback func for set
    int setSetCallback( bool (*yourFunc)(bool) ); // callback func for set
    int setGetCallback( int (*yourFunc)() ); // callback func for get
    int setGetCallback( float (*yourFunc)() ); // callback func for get
    int setGetCallback( bool (*yourFunc)() ); // callback func for get
    int doSet(const int myValue);
    float doSet(const float myValue);
    bool doSet(const bool myValue);
    int doGet(const int myValue);
    int doGetInt();
    float doGet(const float myValue);
    float doGetFloat();
    bool doGet(const bool myValue);
    bool doGetBool();
    bool isGetable();
    bool isSetable();
    bool isInt();
    bool isFloat();
    bool isBool();
    String getType(); // String representation of type

    bool _isSetable;     // true when callback attached
    bool _isGetable;     // true when callback attached
    bool _isInt;
    bool _isFloat;
    bool _isBool;
    int (*_setCallbacki)(int);   // set callback function
    float (*_setCallbackf)(float);   // set callback function
    bool (*_setCallbackb)(bool);   // set callback function
    int (*_getCallbacki)();   // get callback function
    float (*_getCallbackf)();   // get callback function
    bool (*_getCallbackb)();   // get callback function


 int AthomGetSetObject::doSet(const int myValue) {
   if (_isInt && _isSetable) {
     return _setCallbacki(myValue);             // THIS WORKS FINE :)
   } else {
     return -1;

 float AthomGetSetObject::doSet(const float myValue) {
   if (_isFloat && _isSetable) {
     return _setCallbackf(myValue);            // THIS WORKS FINE :)
   } else {
     return -1;

 bool AthomGetSetObject::doSet(const bool myValue) {
   debug("doSet bool Called: " + String(myValue));
   if (_isBool && _isSetable && _getCallbackb!=nullptr) {
     debug("doSet bool calling callback");
     bool result = _setCallbackb(myValue);        // DEBUGS CONFIRM THIS IS WHERE IT DIES
     debug("Got result on bool set callback");
     return result;
   } else {
     return false;

For reference, here is how I set the the callback:

 int AthomGetSetObject::setSetCallback( bool (*yourFunc)(bool) ) {
   if (yourFunc==nullptr || (_isGetable && (_isFloat || _isInt))) {
     // Get and set type must match
     return -1;
   _setCallbackb = yourFunc;
   _setCallbackf = nullptr;
   _setCallbackb = nullptr;
   _isInt = false;
   _isFloat = false;
   _isBool = true;
   _isSetable = true;
   return 0;

I’m not including anything higher in the class/object hierarchy for brevity.

However, these are my test functions that I’m attaching from my test ino

int TestSetCallBackInt(int myVal) {
  debug("Int Test Set Callback Called OK - returning: " + String(myVal));
  return myVal;

float TestSetCallBackFloat(float myVal) {
  debug("Float Test Set Callback Called OK - returning: " + String(myVal));
  return myVal;

bool TestSetCallBackBool(bool myVal) {
  debug("Bool Test Set Callback Called OK - returning same bool" + String(myVal));
  return myVal;

The delays are just there to ensure I see the debug output.

My callbacks are set as so:


These calls overload as follows:

template <class FuncType>
void AthomDevice::setCapabilitySetCallback(const int nodeId, const String myCapability, FuncType (*yourFunc)(FuncType) ) {
  // TODO Add return values
  int myCapId = findCapabilityByName(nodeId, myCapability);
  if (myCapId > 0) {
    getCapability(nodeId, myCapId)->setSetCallback(yourFunc);
template void AthomDevice::setCapabilitySetCallback<int>(const int nodeId, const String myCapability, int (*yourFunc)(int) );
template void AthomDevice::setCapabilitySetCallback<float>(const int nodeId, const String myCapability, float (*yourFunc)(float) );
template void AthomDevice::setCapabilitySetCallback<bool>(const int nodeId, const String myCapability, bool (*yourFunc)(bool) );

Debug output shows I can get and set my ints and my float fine, but when I try to SET a value associated with a boolean callback, the Photon dies (Red LED and restart) when I call the bool callback function

 bool result = _setCallbackb(myValue);

Anyone any idea why a bool callback function would behave differently?

Complete code here:

Just curious. Does it fail if you declare the bool before asigning the value through a function return? I.e.:

bool result;
result = _setCallbackb(myValue);

No, no difference if the bool is declared first. Originally I was just using

return _setCallbackb(myValue);

but split it down to help with debugging.

OK. Sorry all who waded through that… copy and paste errors have been located.
If anyone cares, the problem was two-fold, I was validating incorrectly

if (_isBool && _isSetable && _getCallbackb!=nullptr) {
should have been
if (_isBool && _isSetable && _setCallbackb!=nullptr) {

Which then exposed the issue was actually in the setup of the callback, meaning I was calling nullptr!

The setup was incorrect because

   _setCallbackb = yourFunc;
   _setCallbackf = nullptr;
   _setCallbackb = nullptr;

should have been

   _setCallbackb = yourFunc;
   _setCallbackf = nullptr;
   _setCallbacki = nullptr;

I set and then accidentally cleared the callback pointer.

Clear light of day and all that. Wood for trees etc…