int DimmerModel_SetIdentifyMode(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } uint8_t mode = param_data[0]; if (mode != IDENTIFY_MODE_QUIET && mode != IDENTIFY_MODE_LOUD) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_active_device->identify_mode = mode; return RDMResponder_BuildSetAck(header); }
int DimmerModel_SetOutputResponseTime(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } 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); } g_active_device->output_response_time = setting; return RDMResponder_BuildSetAck(header); }
int DimmerModel_SetModulationFrequency(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint8_t setting = param_data[0]; if (setting == 0u || setting > NUMBER_OF_MODULATION_FREQUENCIES) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_active_device->modulation_frequency = setting; return RDMResponder_BuildSetAck(header); }
int MovingLightModel_ResetDevice(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } if (param_data[0] != 0x01) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } // warm reset g_responder->is_muted = false; return RDMResponder_BuildSetAck(header); }
int DimmerModel_SetPresetMergeMode(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint16_t merge_mode = param_data[0]; if (merge_mode > MERGE_MODE_DMX_ONLY) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_root_device.merge_mode = merge_mode; return RDMResponder_BuildSetAck(header); }
int MovingLightModel_SetPowerState(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } if (param_data[0] > POWER_STATE_NORMAL) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } if (g_moving_light.power_state != param_data[0]) { g_moving_light.using_factory_defaults = false; } g_moving_light.power_state = param_data[0]; return RDMResponder_BuildSetAck(header); }
int MovingLightModel_SetDisplayInvert(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } if (param_data[0] > DISPLAY_INVERT_AUTO) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } if (g_moving_light.display_invert != param_data[0]) { g_moving_light.using_factory_defaults = false; } g_moving_light.display_invert = param_data[0]; return RDMResponder_BuildSetAck(header); }
int MovingLightModel_SetLampOnMode(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } if (param_data[0] > LAMP_ON_MODE_ON_AFTER_CAL) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } if (g_moving_light.lamp_on_mode != param_data[0]) { g_moving_light.using_factory_defaults = false; } g_moving_light.lamp_on_mode = param_data[0]; return RDMResponder_BuildSetAck(header); }
// Child PID Handlers // ---------------------------------------------------------------------------- int ProxyModelChild_GetQueuedMessage(const RDMHeader *header, UNUSED const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } uint8_t status_type = param_data[0]; if (status_type == STATUS_NONE || status_type > STATUS_ERROR) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } RDMResponder_BuildHeader(header, ACK, GET_COMMAND_RESPONSE, PID_STATUS_MESSAGES, sizeof(RDMHeader)); return RDMUtil_AppendChecksum(g_rdm_buffer); }
int DimmerModel_SetSubDeviceReportingThreshold(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } uint8_t threshold = param_data[0]; if (threshold != STATUS_NONE && threshold != STATUS_ADVISORY && threshold != STATUS_WARNING && threshold != STATUS_ERROR) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_active_device->sd_report_threshold = threshold; return RDMResponder_BuildSetAck(header); }
int DimmerModel_SetLockState(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint16_t) + sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint16_t pin = ExtractUInt16(param_data); const uint8_t lock_state = param_data[2]; if (pin != g_root_device.pin_code || lock_state >= NUMBER_OF_LOCK_STATES) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_root_device.lock_state = lock_state; return RDMResponder_BuildSetAck(header); }
int DimmerModel_SetPresetPlayback(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint16_t) + sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint16_t playback_mode = ExtractUInt16(param_data); if (playback_mode > NUMBER_OF_SCENES && playback_mode != PRESET_PLAYBACK_ALL) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_root_device.playback_mode = playback_mode; g_root_device.playback_level = param_data[2]; return RDMResponder_BuildSetAck(header); }
int DimmerModel_SetDMXBlockAddress(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint16_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } uint16_t start_address = ExtractUInt16(param_data); if (start_address == 0u || start_address > MAX_DMX_START_ADDRESS) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } bool ok = ResetToBlockAddress(start_address); if (ok) { return RDMResponder_BuildSetAck(header); } else { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } }
int DimmerModel_SetLockPin(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != 2u * sizeof(uint16_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint16_t new_pin = ExtractUInt16(param_data); const uint16_t old_pin = ExtractUInt16(¶m_data[2]); if (new_pin > MAX_PIN_CODE) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } if (old_pin != g_root_device.pin_code) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_root_device.pin_code = new_pin; return RDMResponder_BuildSetAck(header); }
int DimmerModel_SetMinimumLevel(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != 2u * sizeof(uint16_t) + sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint16_t min_level_increasing = ExtractUInt16(¶m_data[0]); const uint16_t min_level_decreasing = ExtractUInt16(¶m_data[2]); const uint8_t on_below_min = param_data[4]; if (on_below_min > 1) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_active_device->min_level_increasing = min_level_increasing; g_active_device->min_level_decreasing = min_level_decreasing; g_active_device->on_below_min = on_below_min; return RDMResponder_BuildSetAck(header); }
int MovingLightModel_SetFactoryDefaults(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != 0u) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } MovingLightModel_ResetToFactoryDefaults(); RDMResponder_ResetToFactoryDefaults(); return RDMResponder_BuildSetAck(header); }
int DimmerModel_SetCurve(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint8_t curve = param_data[0]; if (curve == 0u || curve > NUMBER_OF_CURVES) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } // To make it interesting, not every sub-device supports each curve type. if (curve % 2 && g_active_device->index % 2 == 0) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_active_device->curve = curve; return RDMResponder_BuildSetAck(header); }
int DimmerModel_SetDMXStartupMode(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != 3u * sizeof(uint16_t) + sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint16_t scene_index = ExtractUInt16(param_data); const uint16_t loss_of_signal_delay = ExtractUInt16(¶m_data[2]); const uint16_t hold_time = ExtractUInt16(¶m_data[4]); if (scene_index > NUMBER_OF_SCENES && scene_index != PRESET_PLAYBACK_ALL) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } g_root_device.startup_scene = scene_index; g_root_device.startup_delay = loss_of_signal_delay; g_root_device.startup_hold = hold_time; g_root_device.startup_level = param_data[6]; return RDMResponder_BuildSetAck(header); }
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); }
int MovingLightModel_SetLampState(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } if (param_data[0] > LAMP_STRIKE) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } if (g_moving_light.lamp_state == LAMP_OFF && param_data[0] == LAMP_ON) { g_moving_light.lamp_strikes++; } if (g_moving_light.lamp_state != param_data[0]) { g_moving_light.using_factory_defaults = false; } g_moving_light.lamp_state = param_data[0]; if (g_moving_light.lamp_state == LAMP_STRIKE) { g_moving_light.lamp_strike_time = CoarseTimer_GetTime(); } return RDMResponder_BuildSetAck(header); }
int MovingLightModel_SetLanguage(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != RDM_LANGUAGE_STRING_SIZE) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const char *new_lang = (const char*) param_data; bool matched = false; unsigned int i = 0; for (; i < NUMBER_OF_LANGUAGES; i++) { if (memcmp(LANGUAGES[i], new_lang, RDM_LANGUAGE_STRING_SIZE) == 0) { g_moving_light.language_index = i; matched = true; break; } } if (!matched) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } return RDMResponder_BuildSetAck(header); }
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); }
int DimmerModel_SetPresetStatus(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != 4u * sizeof(uint16_t) + sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint16_t scene_index = ExtractUInt16(¶m_data[0]); const uint16_t up_fade_time = ExtractUInt16(¶m_data[2]); const uint16_t down_fade_time = ExtractUInt16(¶m_data[4]); const uint16_t wait_time = ExtractUInt16(¶m_data[6]); const uint8_t clear_preset = param_data[8]; 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]; if (scene->programmed_state == PRESET_PROGRAMMED_READ_ONLY) { return RDMResponder_BuildNack(header, NR_WRITE_PROTECT); } if (clear_preset > 1u) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } if (clear_preset == 1u) { scene->up_fade_time = 0u; scene->down_fade_time = 0u; scene->wait_time = 0u; scene->programmed_state = PRESET_NOT_PROGRAMMED; } else { // don't change the state here, if we haven't been programmed, just update // the timing params scene->up_fade_time = up_fade_time; scene->down_fade_time = down_fade_time; scene->wait_time = wait_time; } return RDMResponder_BuildSetAck(header); }
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); }
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); }
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); }
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); }
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); }
int DimmerModel_PerformSelfTest(const RDMHeader *header, const uint8_t *param_data) { if (header->param_data_length != sizeof(uint8_t)) { return RDMResponder_BuildNack(header, NR_FORMAT_ERROR); } const uint8_t self_test_id = param_data[0]; // We don't allow cancelling self-tests if (self_test_id > NUMBER_OF_SELF_TESTS) { return RDMResponder_BuildNack(header, NR_DATA_OUT_OF_RANGE); } if (self_test_id == SELF_TEST_OFF) { g_root_device.running_self_test = SELF_TEST_OFF; } else { if (g_root_device.running_self_test) { return RDMResponder_BuildNack(header, NR_ACTION_NOT_SUPPORTED); } g_root_device.running_self_test = self_test_id; g_root_device.self_test_timer = CoarseTimer_GetTime(); } return RDMResponder_BuildSetAck(header); }
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); }