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); }
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); }
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); }
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); }
uint8_t *AddStatusMessageToResponse(uint8_t *ptr, const StatusMessage *message) { ptr = PushUInt16(ptr, message->sub_device); *ptr++ = message->status_type; ptr = PushUInt16(ptr, message->message_id); ptr = PushUInt16(ptr, message->data_value1); ptr = PushUInt16(ptr, message->data_value2); return ptr; }
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); }
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); }
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); }
// 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_GetPresetStatus(const RDMHeader *header, UNUSED const uint8_t *param_data) { const uint16_t scene_index = ExtractUInt16(¶m_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); }
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; }
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); }
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); }