Skip to content

Commit

Permalink
fix: rainmaker device callback not getting invoked (espressif#8249)
Browse files Browse the repository at this point in the history
This PR fixes an issue of multiple device callbacks (one callback per device) were not getting registered and invoked.
Consider an example where I create two devices, a switch and a fan; each of them having their own write callbacks. On controlling either switch/fan through Rainmaker app, the callback that got registered at last gets invoked. This is also seen in the issue reported in espressif#8231
  • Loading branch information
sanketwadekar authored May 31, 2023
1 parent 82227e6 commit 2c4dead
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 19 deletions.
26 changes: 15 additions & 11 deletions libraries/RainMaker/src/RMakerDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,31 @@
static esp_err_t err;
typedef void (*deviceWriteCb)(Device*, Param*, const param_val_t val, void *priv_data, write_ctx_t *ctx);
typedef void (*deviceReadCb)(Device*, Param*, void *priv_data, read_ctx_t *ctx);

void (*write_cb)(Device*, Param*, param_val_t, void*, write_ctx_t*);
void (*read_cb)(Device*, Param*, void*, read_ctx_t*);
Device device;
Param param;
typedef struct {
void *priv_data;
deviceWriteCb write_cb;
deviceReadCb read_cb;
} RMakerDevicePrivT;

static esp_err_t write_callback(const device_handle_t *dev_handle, const param_handle_t *par_handle, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
Device device;
Param param;
device.setDeviceHandle(dev_handle);
param.setParamHandle(par_handle);

write_cb(&device, &param, val, priv_data, ctx);
deviceWriteCb cb = ((RMakerDevicePrivT *)priv_data)->write_cb;
cb(&device, &param, val, ((RMakerDevicePrivT *)priv_data)->priv_data, ctx);
return ESP_OK;
}

static esp_err_t read_callback(const device_handle_t *dev_handle, const param_handle_t *par_handle, void *priv_data, read_ctx_t *ctx)
{
Device device;
Param param;
device.setDeviceHandle(dev_handle);
param.setParamHandle(par_handle);

read_cb(&device, &param, priv_data, ctx);
deviceReadCb cb = ((RMakerDevicePrivT *)priv_data)->read_cb;
cb(&device, &param, ((RMakerDevicePrivT *)priv_data)->priv_data, ctx);
return ESP_OK;
}

Expand All @@ -41,8 +45,8 @@ esp_err_t Device::deleteDevice()

void Device::addCb(deviceWriteCb writeCb, deviceReadCb readCb)
{
write_cb = writeCb;
read_cb = readCb;
this->private_data.write_cb = writeCb;
this->private_data.read_cb = readCb;
err = esp_rmaker_device_add_cb(getDeviceHandle(), write_callback, read_callback);
if(err != ESP_OK) {
log_e("Failed to register callback");
Expand Down
41 changes: 33 additions & 8 deletions libraries/RainMaker/src/RMakerDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,42 @@

class Device
{
public:
typedef void (*deviceWriteCb)(Device*, Param*, const param_val_t val, void *priv_data, write_ctx_t *ctx);
typedef void (*deviceReadCb)(Device*, Param*, void *priv_data, read_ctx_t *ctx);
typedef struct {
void *priv_data;
deviceWriteCb write_cb;
deviceReadCb read_cb;
} RMakerDevicePrivT;
private:
const device_handle_t *device_handle;
RMakerDevicePrivT private_data;

protected:
void setPrivateData(void *priv_data) {
this->private_data.priv_data = priv_data;
}

const RMakerDevicePrivT* getDevicePrivateData()
{
return &this->private_data;
}
public:
Device()
{
device_handle = NULL;
}
this->private_data.priv_data = NULL;
this->private_data.write_cb = NULL;
this->private_data.read_cb = NULL;
}

Device(const char *dev_name, const char *dev_type = NULL, void *priv_data = NULL)
{
device_handle = esp_rmaker_device_create(dev_name, dev_type, priv_data);
this->private_data.priv_data = priv_data;
this->private_data.write_cb = NULL;
this->private_data.read_cb = NULL;
device_handle = esp_rmaker_device_create(dev_name, dev_type, &this->private_data);
if(device_handle == NULL){
log_e("Device create error");
}
Expand All @@ -48,9 +73,6 @@ class Device
{
return device_handle;
}

typedef void (*deviceWriteCb)(Device*, Param*, const param_val_t val, void *priv_data, write_ctx_t *ctx);
typedef void (*deviceReadCb)(Device*, Param*, void *priv_data, read_ctx_t *ctx);

esp_err_t deleteDevice();
void addCb(deviceWriteCb write_cb, deviceReadCb read_cb = NULL);
Expand Down Expand Up @@ -94,7 +116,8 @@ class Switch : public Device
}
void standardSwitchDevice(const char *dev_name, void *priv_data, bool power)
{
esp_rmaker_device_t *dev_handle = esp_rmaker_switch_device_create(dev_name, priv_data, power);
this->setPrivateData(priv_data);
esp_rmaker_device_t *dev_handle = esp_rmaker_switch_device_create(dev_name, (void *)this->getDevicePrivateData(), power);
setDeviceHandle(dev_handle);
if(dev_handle == NULL){
log_e("Switch device not created");
Expand All @@ -115,7 +138,8 @@ class LightBulb : public Device
}
void standardLightBulbDevice(const char *dev_name, void *priv_data, bool power)
{
esp_rmaker_device_t *dev_handle = esp_rmaker_lightbulb_device_create(dev_name, priv_data, power);
this->setPrivateData(priv_data);
esp_rmaker_device_t *dev_handle = esp_rmaker_lightbulb_device_create(dev_name, (void *)this->getDevicePrivateData(), power);
setDeviceHandle(dev_handle);
if(dev_handle == NULL){
log_e("Light device not created");
Expand Down Expand Up @@ -157,7 +181,8 @@ class TemperatureSensor : public Device
}
void standardTemperatureSensorDevice(const char *dev_name, void *priv_data, float temp)
{
esp_rmaker_device_t *dev_handle = esp_rmaker_temp_sensor_device_create(dev_name, priv_data, temp);
this->setPrivateData(priv_data);
esp_rmaker_device_t *dev_handle = esp_rmaker_temp_sensor_device_create(dev_name, (void *)this->getDevicePrivateData(), temp);
setDeviceHandle(dev_handle);
if(dev_handle == NULL){
log_e("Temperature Sensor device not created");
Expand Down

0 comments on commit 2c4dead

Please sign in to comment.