gstreamer/subprojects/gst-plugins-bad/sys/uvcgadget/gstuvcsink.h
Michael Grzeschik 3b345568bc uvcsink: Respond to control requests with proper error handling
The complete handling on the control interface is currently dead.
We return with EOPNOTSUPP for the caller to know that a response
to such requests is not valid. The host however may ask
control interface why these control requests were not available.

For this the UVC_VC_REQUEST_ERROR_CODE_CONTROL is used. As an overall
exception for the control interface we just always return 0x06 as
an response which is representing "not implemented".

This patch is a necessary feature to properly pass the UVC Functionality
Test of the USB3CV Compliance Software.

Fixes: 69c1746139 ('uvcgadget: Properly implement GET_INFO control responses')
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7524>
2025-04-01 15:57:20 +00:00

84 lines
1.8 KiB
C

/*
* SPDX-License-Identifier: LGPL-2.0-or-later
*
* Copyright (C) 2023 Pengutronix e.K. - www.pengutronix.de
*
*/
#pragma once
#include "linux/usb/g_uvc.h"
#include "linux/usb/video.h"
#include "linux/videodev2.h"
#include <gst/gst.h>
#include "configfs.h"
G_BEGIN_DECLS GST_DEBUG_CATEGORY_EXTERN (uvcsink_debug);
#define REQUEST_ERROR_CODE_NO_ERROR 0x0
#define REQUEST_ERROR_CODE_INVALID_REQUEST 0x6
#define GST_TYPE_UVCSINK (gst_uvc_sink_get_type())
G_DECLARE_FINAL_TYPE (GstUvcSink, gst_uvc_sink, GST, UVCSINK, GstBin)
GST_ELEMENT_REGISTER_DECLARE (uvcsink);
struct _GstUvcSink
{
GstBin bin;
GstElement *fakesink;
GstElement *v4l2sink;
GstPad *sinkpad;
GstPad *fakesinkpad;
GstPad *v4l2sinkpad;
/* streaming status */
gboolean streaming;
GstCaps *probed_caps;
GstCaps *cur_caps;
/* a poll for video_fd */
GstPoll *poll;
GstPollFD pollfd;
struct uvc_function_config *fc;
struct {
int bFrameIndex;
int bFormatIndex;
unsigned int dwFrameInterval;
} cur;
struct uvc_streaming_control probe;
struct uvc_streaming_control commit;
int control;
int request_error_code;
/* probes */
int buffer_peer_probe_id;
int idle_probe_id;
GstClock *v4l2_clock;
int caps_changed;
int streamon;
int streamoff;
};
#define UVCSINK_MSG_LOCK(v) g_mutex_lock(&(v)->msg_lock)
#define UVCSINK_MSG_UNLOCK(v) g_mutex_unlock(&(v)->msg_lock)
int uvc_events_process_data(GstUvcSink * self,
const struct uvc_request_data *data);
int uvc_events_process_setup(GstUvcSink * self,
const struct usb_ctrlrequest *ctrl,
struct uvc_request_data *resp);
int uvc_fill_streaming_control(GstUvcSink * self,
struct uvc_streaming_control *ctrl,
int iframe, int iformat, unsigned int dwival);
G_END_DECLS