int STDCALL memory_object_descriptor_imp::start_operation_cmd(void * notification_id, uint16_t operation_type)
{
    struct jdksavdecc_frame cmd_frame;
    struct jdksavdecc_aem_command_start_operation aem_cmd_start_operation;
    memset(&aem_cmd_start_operation, 0, sizeof(aem_cmd_start_operation));

    if (operation_type > JDKSAVDECC_MEMORY_OBJECT_OPERATION_UPLOAD)
    {
        log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, " Invalid operation type %x on memory object\n", operation_type);
        return -1;
    }

    aem_cmd_start_operation.aem_header.aecpdu_header.controller_entity_id = base_end_station_imp_ref->get_adp()->get_controller_entity_id();
    aem_cmd_start_operation.aem_header.command_type = JDKSAVDECC_AEM_COMMAND_START_OPERATION;

    aem_cmd_start_operation.descriptor_type = descriptor_type();
    aem_cmd_start_operation.descriptor_index = descriptor_index();
    aem_cmd_start_operation.operation_id = 0;
    aem_cmd_start_operation.operation_type = operation_type;

    aecp_controller_state_machine_ref->ether_frame_init(base_end_station_imp_ref->mac(), &cmd_frame,
                                                        ETHER_HDR_SIZE + JDKSAVDECC_AEM_COMMAND_START_OPERATION_COMMAND_LEN);
    ssize_t aem_cmd_start_operation_returned = jdksavdecc_aem_command_start_operation_write(&aem_cmd_start_operation,
                                                                                            cmd_frame.payload,
                                                                                            ETHER_HDR_SIZE,
                                                                                            sizeof(cmd_frame.payload));

    if (aem_cmd_start_operation_returned < 0)
    {
        log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "aem_command_start_operation_write error\n");
        return -1;
    }

    aecp_controller_state_machine_ref->common_hdr_init(JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_COMMAND,
                                                       &cmd_frame,
                                                       base_end_station_imp_ref->entity_id(),
                                                       JDKSAVDECC_AEM_COMMAND_START_OPERATION_COMMAND_LEN -
                                                           JDKSAVDECC_COMMON_CONTROL_HEADER_LEN);
    system_queue_tx(notification_id, CMD_WITH_NOTIFICATION, cmd_frame.payload, cmd_frame.length);

    return 0;
}
int STDCALL clock_domain_descriptor_imp::send_set_clock_source_cmd(void * notification_id, uint16_t new_clk_src_index)
{
    struct jdksavdecc_frame cmd_frame;
    struct jdksavdecc_aem_command_set_clock_source aem_cmd_set_clk_src;
    ssize_t aem_cmd_set_clk_src_returned;
    memset(&aem_cmd_set_clk_src, 0, sizeof(aem_cmd_set_clk_src));

    /***************************************** AECP Common Data ******************************************/
    aem_cmd_set_clk_src.aem_header.aecpdu_header.controller_entity_id = base_end_station_imp_ref->get_adp()->get_controller_entity_id();
    // Fill aem_cmd_set_clk_src.sequence_id in AEM Controller State Machine
    aem_cmd_set_clk_src.aem_header.command_type = JDKSAVDECC_AEM_COMMAND_SET_CLOCK_SOURCE;

    /***************** AECP Message Specific Data ****************/
    aem_cmd_set_clk_src.descriptor_type = descriptor_type();
    aem_cmd_set_clk_src.descriptor_index = descriptor_index();
    aem_cmd_set_clk_src.clock_source_index = new_clk_src_index;

    /*************************** Fill frame payload with AECP data and send the frame ***********************/
    aecp_controller_state_machine_ref->ether_frame_init(base_end_station_imp_ref->mac(), &cmd_frame,
                                                        ETHER_HDR_SIZE + JDKSAVDECC_AEM_COMMAND_SET_CLOCK_SOURCE_COMMAND_LEN);
    aem_cmd_set_clk_src_returned = jdksavdecc_aem_command_set_clock_source_write(&aem_cmd_set_clk_src,
                                                                                 cmd_frame.payload,
                                                                                 ETHER_HDR_SIZE,
                                                                                 sizeof(cmd_frame.payload));

    if (aem_cmd_set_clk_src_returned < 0)
    {
        log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "aem_cmd_set_clk_src_write error\n");
        assert(aem_cmd_set_clk_src_returned >= 0);
        return -1;
    }

    aecp_controller_state_machine_ref->common_hdr_init(JDKSAVDECC_AECP_MESSAGE_TYPE_AEM_COMMAND,
                                                       &cmd_frame,
                                                       base_end_station_imp_ref->entity_id(),
                                                       JDKSAVDECC_AEM_COMMAND_SET_CLOCK_SOURCE_COMMAND_LEN -
                                                           JDKSAVDECC_COMMON_CONTROL_HEADER_LEN);
    system_queue_tx(notification_id, CMD_WITH_NOTIFICATION, cmd_frame.payload, cmd_frame.length);

    return 0;
}
    int STDCALL stream_input_descriptor_imp::send_get_rx_state_cmd(void *notification_id)
    {
        struct jdksavdecc_frame *cmd_frame;
        struct jdksavdecc_acmpdu acmp_cmd_get_rx_state;
        int acmp_cmd_get_rx_state_returned;
        uint64_t listener_guid = base_end_station_imp_ref->get_entity_desc_by_index(0)->entity_id();

        cmd_frame = (struct jdksavdecc_frame *)malloc(sizeof(struct jdksavdecc_frame));

        /******************************************* ACMP Common Data ******************************************/
        acmp_cmd_get_rx_state.controller_entity_id = base_end_station_imp_ref->get_adp()->get_controller_guid();
        jdksavdecc_eui64_init(&acmp_cmd_get_rx_state.talker_entity_id);
        jdksavdecc_uint64_write(listener_guid, &acmp_cmd_get_rx_state.listener_entity_id, 0, sizeof(uint64_t));
        acmp_cmd_get_rx_state.talker_unique_id = 0;
        acmp_cmd_get_rx_state.listener_unique_id = descriptor_index();
        jdksavdecc_eui48_init(&acmp_cmd_get_rx_state.stream_dest_mac);
        acmp_cmd_get_rx_state.connection_count = 0;
        // Fill acmp_cmd_get_rx_state.sequence_id in AEM Controller State Machine
        acmp_cmd_get_rx_state.flags = 0;
        acmp_cmd_get_rx_state.stream_vlan_id = 0;

        /*************** Fill frame payload with AECP data and send the frame ***************/
        acmp_controller_state_machine_ref->ether_frame_init(cmd_frame);
        acmp_cmd_get_rx_state_returned = jdksavdecc_acmpdu_write(&acmp_cmd_get_rx_state,
                                                                 cmd_frame->payload,
                                                                 ETHER_HDR_SIZE,
                                                                 sizeof(cmd_frame->payload));

        if(acmp_cmd_get_rx_state_returned < 0)
        {
            log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "cmd_get_rx_state_write error\n");
            assert(acmp_cmd_get_rx_state_returned >= 0);
            return -1;
        }

        acmp_controller_state_machine_ref->common_hdr_init(JDKSAVDECC_ACMP_MESSAGE_TYPE_GET_RX_STATE_COMMAND, cmd_frame);
        system_queue_tx(notification_id, CMD_WITH_NOTIFICATION, cmd_frame->payload, cmd_frame->length);

        free(cmd_frame);
        return 0;
    }
int STDCALL stream_input_descriptor_imp::send_disconnect_rx_cmd(void * notification_id, uint64_t talker_entity_id, uint16_t talker_unique_id)
{
    entity_descriptor_response * entity_resp_ref = base_end_station_imp_ref->get_entity_desc_by_index(0)->get_entity_response();
    struct jdksavdecc_frame cmd_frame;
    struct jdksavdecc_acmpdu acmp_cmd_disconnect_rx;
    ssize_t acmp_cmd_disconnect_rx_returned;
    uint64_t listener_entity_id = entity_resp_ref->entity_id();

    /******************************************* ACMP Common Data *******************************************/
    acmp_cmd_disconnect_rx.controller_entity_id = base_end_station_imp_ref->get_adp()->get_controller_entity_id();
    jdksavdecc_uint64_write(talker_entity_id, &acmp_cmd_disconnect_rx.talker_entity_id, 0, sizeof(uint64_t));
    jdksavdecc_uint64_write(listener_entity_id, &acmp_cmd_disconnect_rx.listener_entity_id, 0, sizeof(uint64_t));
    acmp_cmd_disconnect_rx.talker_unique_id = talker_unique_id;
    acmp_cmd_disconnect_rx.listener_unique_id = descriptor_index();
    jdksavdecc_eui48_init(&acmp_cmd_disconnect_rx.stream_dest_mac);
    acmp_cmd_disconnect_rx.connection_count = 0;
    // Fill acmp_cmd_disconnect_rx.sequence_id in AEM Controller State Machine
    acmp_cmd_disconnect_rx.flags = 0;
    acmp_cmd_disconnect_rx.stream_vlan_id = 0;

    /**************** Fill frame payload with AECP data and send the frame ***************/
    acmp_controller_state_machine_ref->ether_frame_init(&cmd_frame);
    acmp_cmd_disconnect_rx_returned = jdksavdecc_acmpdu_write(&acmp_cmd_disconnect_rx,
                                                              cmd_frame.payload,
                                                              ETHER_HDR_SIZE,
                                                              sizeof(cmd_frame.payload));

    if (acmp_cmd_disconnect_rx_returned < 0)
    {
        log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "cmd_disconnect_rx_write error\n");
        assert(acmp_cmd_disconnect_rx_returned >= 0);
        return -1;
    }

    acmp_controller_state_machine_ref->common_hdr_init(JDKSAVDECC_ACMP_MESSAGE_TYPE_DISCONNECT_RX_COMMAND, &cmd_frame);
    system_queue_tx(notification_id, CMD_WITH_NOTIFICATION, cmd_frame.payload, cmd_frame.length);

    delete entity_resp_ref;
    return 0;
}
    int STDCALL stream_input_descriptor_imp::send_set_stream_format_cmd(void *notification_id, uint64_t new_stream_format)
    {
        struct jdksavdecc_frame *cmd_frame;
        struct jdksavdecc_aem_command_set_stream_format aem_cmd_set_stream_format;
        int aem_cmd_set_stream_format_returned;
        cmd_frame = (struct jdksavdecc_frame *)malloc(sizeof(struct jdksavdecc_frame));

        /******************************************** AECP Common Data *********************************************/
        aem_cmd_set_stream_format.controller_entity_id = base_end_station_imp_ref->get_adp()->get_controller_guid();
        // Fill aem_cmd_set_stream_format.sequence_id in AEM Controller State Machine
        aem_cmd_set_stream_format.command_type = JDKSAVDECC_AEM_COMMAND_SET_STREAM_FORMAT;

        /**************************************** AECP Message Specific Data *************************************/
        aem_cmd_set_stream_format.descriptor_type = descriptor_type();
        aem_cmd_set_stream_format.descriptor_index = descriptor_index();
        jdksavdecc_uint64_write(new_stream_format, &aem_cmd_set_stream_format.stream_format, 0, sizeof(uint64_t));

        /******************************** Fill frame payload with AECP data and send the frame ***************************/
        aem_controller_state_machine_ref->ether_frame_init(base_end_station_imp_ref->mac(), cmd_frame);
        aem_cmd_set_stream_format_returned = jdksavdecc_aem_command_set_stream_format_write(&aem_cmd_set_stream_format,
                                                                                            cmd_frame->payload,
                                                                                            ETHER_HDR_SIZE,
                                                                                            sizeof(cmd_frame->payload));

        if(aem_cmd_set_stream_format_returned < 0)
        {
            log_imp_ref->post_log_msg(LOGGING_LEVEL_ERROR, "aem_cmd_set_stream_format_write error\n");
            assert(aem_cmd_set_stream_format_returned >= 0);
            return -1;
        }

        aem_controller_state_machine_ref->common_hdr_init(cmd_frame, base_end_station_imp_ref->guid());
        system_queue_tx(notification_id, CMD_WITH_NOTIFICATION, cmd_frame->payload, cmd_frame->length);

        free(cmd_frame);
        return 0;
    }