int DimmerModel_GetDMXBlockAddress(const RDMHeader *header,
                                   UNUSED const uint8_t *param_data) {
  uint16_t total_footprint = 0u;
  uint16_t expected_start_address = 0u;
  bool is_contiguous = true;
  unsigned int i = 0u;
  for (; i < NUMBER_OF_SUB_DEVICES; i++) {
    RDMResponder *responder = &g_subdevices[i].responder;
    uint16_t sub_device_footprint = responder->def
        ->personalities[responder->current_personality - 1u].slot_count;
    total_footprint += sub_device_footprint;
    if (expected_start_address &&
        expected_start_address != responder->dmx_start_address) {
      is_contiguous = false;
    } else if (expected_start_address) {
      expected_start_address += sub_device_footprint;
    } else {
      expected_start_address = responder->dmx_start_address +
                               sub_device_footprint;
    }
  }

  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr = PushUInt16(ptr, total_footprint);
  ptr = PushUInt16(
      ptr,
      is_contiguous ? g_subdevices[0].responder.dmx_start_address :
          INVALID_DMX_START_ADDRESS);
  return RDMResponder_AddHeaderAndChecksum(header, ACK,
                                           ptr - g_rdm_buffer);
}
static int GetModelList(const RDMHeader *header) {
  uint8_t our_uid[UID_LENGTH];
  RDMHandler_GetUID(our_uid);

  if (RDMUtil_UIDCompare(our_uid, header->dest_uid)) {
    return RDM_RESPONDER_NO_RESPONSE;
  }

  uint16_t sub_device = ntohs(header->sub_device);
  // No subdevice support for now.
  if (sub_device != SUBDEVICE_ROOT) {
    return RDMResponder_BuildNack(header, NR_SUB_DEVICE_OUT_OF_RANGE);
  }

  if (header->command_class != GET_COMMAND) {
    return RDMResponder_BuildNack(header, NR_UNSUPPORTED_COMMAND_CLASS);
  }

  if (header->param_data_length) {
    return RDMResponder_BuildNack(header, NR_FORMAT_ERROR);
  }

  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  unsigned int i = 0u;
  for (; i < MAX_RDM_MODELS; i++) {
    if (g_models[i].model_id != NULL_MODEL_ID) {
      ptr = PushUInt16(ptr, g_models[i].model_id);
    }
  }

  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
int DimmerModel_GetCurve(const RDMHeader *header,
                         UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = g_active_device->curve;
  *ptr++ = NUMBER_OF_CURVES;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
int DimmerModel_GetOutputResponseTime(const RDMHeader *header,
                                      UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = g_active_device->output_response_time;
  *ptr++ = NUMBER_OF_OUTPUT_RESPONSE_TIMES;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
int DimmerModel_GetModulationFrequency(const RDMHeader *header,
                                       UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = g_active_device->modulation_frequency;
  *ptr++ = NUMBER_OF_MODULATION_FREQUENCIES;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
int DimmerModel_GetPresetPlayback(const RDMHeader *header,
                                  UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr = PushUInt16(ptr, g_root_device.playback_mode);
  *ptr++ = g_root_device.playback_level;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#7
0
// Proxy PID Handlers
// ----------------------------------------------------------------------------
int ProxyModel_GetProxiedDeviceCount(const RDMHeader *header,
                                     UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr = PushUInt16(ptr, NUMBER_OF_CHILDREN);
  *ptr++ = 0;  // list change
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
int DimmerModel_GetLockState(const RDMHeader *header,
                             UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = g_root_device.lock_state;
  // We don't include the unlocked state.
  *ptr++ = NUMBER_OF_LOCK_STATES - 1u;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
int DimmerModel_GetMinimumLevel(const RDMHeader *header,
                                UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr = PushUInt16(ptr, g_active_device->min_level_increasing);
  ptr = PushUInt16(ptr, g_active_device->min_level_decreasing);
  *ptr++ = g_active_device->on_below_min;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#10
0
int MovingLightModel_GetLanguage(const RDMHeader *header,
                                 UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr += RDMUtil_StringCopy((char*) ptr, RDM_LANGUAGE_STRING_SIZE,
                            LANGUAGES[g_moving_light.language_index],
                            RDM_LANGUAGE_STRING_SIZE);
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#11
0
int DimmerModel_GetDMXFailMode(const RDMHeader *header,
                               UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr = PushUInt16(ptr, g_root_device.fail_scene);
  ptr = PushUInt16(ptr, g_root_device.fail_loss_of_signal_delay);
  ptr = PushUInt16(ptr, g_root_device.fail_hold_time);
  *ptr++ = g_root_device.fail_level;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#12
0
int DimmerModel_GetDMXStartupMode(const RDMHeader *header,
                                  UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr = PushUInt16(ptr, g_root_device.startup_scene);
  ptr = PushUInt16(ptr, g_root_device.startup_delay);
  ptr = PushUInt16(ptr, g_root_device.startup_hold);
  *ptr++ = g_root_device.startup_level;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
static int GetSetModelId(const RDMHeader *header,
                         const uint8_t *param_data) {
  uint8_t our_uid[UID_LENGTH];
  RDMHandler_GetUID(our_uid);

  if (!RDMUtil_RequiresAction(our_uid, header->dest_uid)) {
    return RDM_RESPONDER_NO_RESPONSE;
  }

  uint16_t sub_device = ntohs(header->sub_device);
  // No subdevice support for now.
  if (sub_device != SUBDEVICE_ROOT && sub_device != SUBDEVICE_ALL) {
    return RDMResponder_BuildNack(header, NR_SUB_DEVICE_OUT_OF_RANGE);
  } else if (sub_device == SUBDEVICE_ALL &&
             header->command_class == GET_COMMAND) {
    return RDMResponder_BuildNack(header, NR_SUB_DEVICE_OUT_OF_RANGE);
  }

  if (header->command_class == GET_COMMAND) {
    if (header->param_data_length) {
      return RDMResponder_BuildNack(header, NR_FORMAT_ERROR);
    }

    if (RDMUtil_UIDCompare(our_uid, header->dest_uid)) {
      return RDM_RESPONDER_NO_RESPONSE;
    }

    uint16_t model_id = NULL_MODEL_ID;
    if (g_rdm_handler.active_model) {
      model_id = g_rdm_handler.active_model->model_id;
    }

    uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
    ptr = PushUInt16(ptr, model_id);
    return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
  } else if (header->command_class == SET_COMMAND) {
    if (header->param_data_length != sizeof(uint16_t)) {
      return RDMResponder_BuildNack(header, NR_FORMAT_ERROR);
    }

    // take action
    uint16_t new_model = JoinShort(param_data[0], param_data[1]);
    bool ok = RDMHandler_SetActiveModel(new_model);

    if (RDMUtil_UIDCompare(our_uid, header->dest_uid)) {
      return RDM_RESPONDER_NO_RESPONSE;
    }

    if (!ok) {
      return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
    }

    return RDMResponder_BuildSetAck(header);
  }
  return RDM_RESPONDER_NO_RESPONSE;
}
示例#14
0
// PID Handlers
// ----------------------------------------------------------------------------
int MovingLightModel_GetLanguageCapabilities(const RDMHeader *header,
                                            UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  unsigned int i = 0;
  for (; i < NUMBER_OF_LANGUAGES; i++) {
    ptr += RDMUtil_StringCopy((char*) ptr, RDM_LANGUAGE_STRING_SIZE,
                              LANGUAGES[i], RDM_LANGUAGE_STRING_SIZE);
  }
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#15
0
int ProxyModel_GetProxiedDevices(const RDMHeader *header,
                                 UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  unsigned int i = 0u;
  for (; i < NUMBER_OF_CHILDREN; i++) {
    memcpy(ptr, g_children[i].responder.uid, UID_LENGTH);
    ptr += UID_LENGTH;
  }
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#16
0
int MovingLightModel_GetClock(const RDMHeader *header,
                              UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr = PushUInt16(ptr, g_moving_light.year);
  *ptr++ = g_moving_light.month;
  *ptr++ = g_moving_light.day;
  *ptr++ = g_moving_light.hour;
  *ptr++ = g_moving_light.minute;
  *ptr++ = g_moving_light.second;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#17
0
int DimmerModel_GetDimmerInfo(const RDMHeader *header,
                              UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr = PushUInt16(ptr, 0u);  // min level lower
  ptr = PushUInt16(ptr, 0xfffe);  // min level upper
  ptr = PushUInt16(ptr, 0u);  // max level lower
  ptr = PushUInt16(ptr, 0xfffe);  // max level upper
  *ptr++ = NUMBER_OF_CURVES;
  *ptr++ = 8u;  // level resolution
  *ptr++ = 1u;  // split levels supported
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#18
0
int DimmerModel_GetStatusIdDescription(const RDMHeader *header,
                                       UNUSED const uint8_t *param_data) {
  const uint16_t status_id = ExtractUInt16(param_data);
  if (status_id != STS_OLP_TESTING) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }

  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr += RDMUtil_StringCopy((char*) ptr, RDM_DEFAULT_STRING_SIZE,
                            STS_OLP_TESTING_DESCRIPTION,
                            RDM_DEFAULT_STRING_SIZE);
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#19
0
int DimmerModel_GetOutputResponseDescription(const RDMHeader *header,
                                             UNUSED const uint8_t *param_data) {
  const uint8_t setting = param_data[0];
  if (setting == 0u || setting > NUMBER_OF_OUTPUT_RESPONSE_TIMES) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }

  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = setting;
  ptr += RDMUtil_StringCopy((char*) ptr, RDM_DEFAULT_STRING_SIZE,
                            OUTPUT_RESPONSE_TIMES[setting - 1],
                            RDM_DEFAULT_STRING_SIZE);
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#20
0
int DimmerModel_GetCurveDescription(const RDMHeader *header,
                                    UNUSED const uint8_t *param_data) {
  const uint8_t curve = param_data[0];
  if (curve == 0u || curve > NUMBER_OF_CURVES) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }

  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = curve;
  ptr += RDMUtil_StringCopy((char*) ptr, RDM_DEFAULT_STRING_SIZE,
                            DIMMER_CURVES[curve - 1],
                            RDM_DEFAULT_STRING_SIZE);
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#21
0
int DimmerModel_GetLockStateDescription(const RDMHeader *header,
                                        const uint8_t *param_data) {
  const uint8_t lock_state = param_data[0];
  if (lock_state == 0u || lock_state >= NUMBER_OF_LOCK_STATES) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }

  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = lock_state;
  ptr += RDMUtil_StringCopy((char*) ptr, RDM_DEFAULT_STRING_SIZE,
                            LOCK_STATES[lock_state],
                            RDM_DEFAULT_STRING_SIZE);
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#22
0
int DimmerModel_GetSelfTestDescription(const RDMHeader *header,
                                       UNUSED const uint8_t *param_data) {
  const uint8_t self_test_id = param_data[0];
  if (self_test_id == SELF_TEST_OFF || self_test_id > NUMBER_OF_SELF_TESTS) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }

  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = self_test_id;
  ptr += RDMUtil_StringCopy((char*) ptr, RDM_DEFAULT_STRING_SIZE,
                            SELF_TESTS[self_test_id - 1].description,
                            RDM_DEFAULT_STRING_SIZE);
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#23
0
int DimmerModel_GetModulationFrequencyDescription(
    const RDMHeader *header,
    UNUSED const uint8_t *param_data) {
  const uint8_t setting = param_data[0];
  if (setting == 0u || setting > NUMBER_OF_MODULATION_FREQUENCIES) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }

  const ModulationFrequency *frequency = &MODULATION_FREQUENCY[setting - 1];
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = setting;
  ptr = PushUInt32(ptr, frequency->frequency);
  ptr += RDMUtil_StringCopy((char*) ptr, RDM_DEFAULT_STRING_SIZE,
                            frequency->description,
                            RDM_DEFAULT_STRING_SIZE);
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#24
0
int DimmerModel_GetPresetStatus(const RDMHeader *header,
                                UNUSED const uint8_t *param_data) {
  const uint16_t scene_index = ExtractUInt16(&param_data[0]);

  if (scene_index == 0u || scene_index > NUMBER_OF_SCENES) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }

  Scene *scene = &g_root_device.scenes[scene_index - 1u];

  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  ptr = PushUInt16(ptr, scene_index);
  ptr = PushUInt16(ptr, scene->up_fade_time);
  ptr = PushUInt16(ptr, scene->down_fade_time);
  ptr = PushUInt16(ptr, scene->wait_time);
  *ptr++ = scene->programmed_state;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#25
0
// Root PID Handlers
// ----------------------------------------------------------------------------
int DimmerModel_GetStatusMessages(const RDMHeader *header,
                                  UNUSED const uint8_t *param_data) {
  uint8_t threshold = param_data[0];

  if (threshold > STATUS_ERROR) {
    return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE);
  }

  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);

  if (threshold == STATUS_GET_LAST_MESSAGE) {
    // Return the last set of messages.
    unsigned int i = 0u;
    for (; i < g_status_messages.count; i++) {
      ptr = AddStatusMessageToResponse(ptr, &g_status_messages.last[i]);
    }
  } else {
    // Build the list of status messages.
    g_status_messages.count = 0u;

    // Check the root
    if (g_root_device.status_message.is_active &&
        MaybeDequeueStatusMessage(&g_root_device.status_message, threshold)) {
      ptr = AddStatusMessageToResponse(
                ptr, &g_status_messages.last[g_status_messages.count]);
      g_status_messages.count++;
    }

    // Check the sub devices.
    unsigned int i = 0u;
    for (; i < NUMBER_OF_SUB_DEVICES &&
           g_status_messages.count < STATUS_MESSAGE_QUEUE_SIZE; i++) {
      DimmerSubDevice *subdevice = &g_subdevices[i];

      if (MaybeDequeueStatusMessage(&subdevice->status_message, threshold)) {
        ptr = AddStatusMessageToResponse(
                  ptr, &g_status_messages.last[g_status_messages.count]);
        g_status_messages.count++;
      }
    }
  }

  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#26
0
int DimmerModel_GetPresetInfo(const RDMHeader *header,
                              UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = true;  // level supported
  *ptr++ = true;  // sequence supported
  *ptr++ = true;  // split times supported
  *ptr++ = true;  // fail infinite delay supported
  *ptr++ = true;  // fail infinite hold supported
  *ptr++ = true;  // startup infinite hold supported
  ptr = PushUInt16(ptr, NUMBER_OF_SCENES);
  ptr = PushUInt16(ptr, 0u);  // min fade time
  ptr = PushUInt16(ptr, 0xfffe);  // max fade time
  ptr = PushUInt16(ptr, 0u);  // min wait time
  ptr = PushUInt16(ptr, 0xfffe);  // max wait time
  ptr = PushUInt16(ptr, 0u);  // min fail delay time
  ptr = PushUInt16(ptr, 0xfffe);  // max fail delay time
  ptr = PushUInt16(ptr, 0u);  // min fail hold time
  ptr = PushUInt16(ptr, 0xfffe);  // max fail hold time
  ptr = PushUInt16(ptr, 0u);  // min startup delay time
  ptr = PushUInt16(ptr, 0xfffe);  // max startup delay time
  ptr = PushUInt16(ptr, 0u);  // min startup hold time
  ptr = PushUInt16(ptr, 0xfffe);  // max startup hold time
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}
示例#27
0
int DimmerModel_GetSelfTest(const RDMHeader *header,
                            UNUSED const uint8_t *param_data) {
  uint8_t *ptr = g_rdm_buffer + sizeof(RDMHeader);
  *ptr++ = g_root_device.running_self_test ? true : false;
  return RDMResponder_AddHeaderAndChecksum(header, ACK, ptr - g_rdm_buffer);
}