static int HandleRequest(const RDMHeader *header, const uint8_t *param_data) {
  if (header->command_class == DISCOVERY_COMMAND) {
    return RDMResponder_HandleDiscovery(header, param_data);
  }

  if (ntohs(header->sub_device) != SUBDEVICE_ROOT) {
    return RDMResponder_BuildNack(header, NR_SUB_DEVICE_OUT_OF_RANGE);
  }

  return RDMResponder_DispatchPID(header, param_data);
}
Example #2
0
static int MovingLightModel_HandleRequest(const RDMHeader *header,
                                          const uint8_t *param_data) {
  if (!RDMUtil_RequiresAction(g_responder->uid, header->dest_uid)) {
    return RDM_RESPONDER_NO_RESPONSE;
  }

  if (header->command_class == DISCOVERY_COMMAND) {
    return RDMResponder_HandleDiscovery(header, param_data);
  }

  uint16_t sub_device = ntohs(header->sub_device);

  // No subdevices.
  if (sub_device != SUBDEVICE_ROOT && sub_device != SUBDEVICE_ALL) {
    return RDMResponder_BuildNack(header, NR_SUB_DEVICE_OUT_OF_RANGE);
  }

  // This model has no sub devices.
  if (header->command_class == GET_COMMAND && sub_device == SUBDEVICE_ALL) {
    return RDMResponder_BuildNack(header, NR_SUB_DEVICE_OUT_OF_RANGE);
  }

  return RDMResponder_DispatchPID(header, param_data);
}
static int DimmerModel_HandleRequest(const RDMHeader *header,
                                     const uint8_t *param_data) {
  if (!RDMUtil_RequiresAction(g_responder->uid, header->dest_uid)) {
    return RDM_RESPONDER_NO_RESPONSE;
  }

  // The standard isn't at all clear how a responder is supposed to behave if
  // it receives discovery commands with a non-0 subdevice. For now we just
  // ignore the sub-device field.
  if (header->command_class == DISCOVERY_COMMAND) {
    return RDMResponder_HandleDiscovery(header, param_data);
  }

  const uint16_t sub_device = ntohs(header->sub_device);

  // GETs to all subdevices are invalid.
  if (header->command_class == GET_COMMAND && sub_device == SUBDEVICE_ALL) {
    return RDMResponder_BuildNack(header, NR_SUB_DEVICE_OUT_OF_RANGE);
  }

  // Check if we're locked
  bool locked = false;
  if (header->command_class == SET_COMMAND) {
    if (g_root_device.lock_state == LOCK_STATE_ALL_LOCKED ||
        (g_root_device.lock_state == LOCK_STATE_SUBDEVICES_LOCKED &&
         sub_device != SUBDEVICE_ROOT)) {
      locked = true;
    }
  }

  if (sub_device == SUBDEVICE_ROOT) {
    if (locked) {
      return RDMResponder_BuildNack(header, NR_WRITE_PROTECT);
    } else {
      return RDMResponder_DispatchPID(header, param_data);
    }
  }

  unsigned int i = 0u;
  bool handled = false;
  int response_size = RDM_RESPONDER_NO_RESPONSE;
  for (; i < NUMBER_OF_SUB_DEVICES; i++) {
    if (sub_device == g_subdevices[i].index || sub_device == SUBDEVICE_ALL) {
      if (!locked) {
        g_active_device = &g_subdevices[i];
        RDMResponder_SwitchResponder(&g_subdevices[i].responder);
        response_size = RDMResponder_DispatchPID(header, param_data);
      }
      handled = true;
    }
  }

  RDMResponder_RestoreResponder();

  if (!handled) {
    return RDMResponder_BuildNack(header, NR_SUB_DEVICE_OUT_OF_RANGE);
  }

  if (locked) {
    return RDMResponder_BuildNack(header, NR_WRITE_PROTECT);
  }

  // If it was an all-subdevices call, it's not really clear how to handle the
  // response, in this case we return the last one.
  return response_size;
}