Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve uvc with import/export of config parameters #64

Merged
merged 3 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions include/usbg/function/uvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ extern "C" {
struct usbg_f_uvc;
typedef struct usbg_f_uvc usbg_f_uvc;

struct usbg_f_uvc_config_attrs
{
int streaming_maxburst;
int streaming_maxpacket;
int streaming_interval;
const char *function_name;
};

struct usbg_f_uvc_frame_attrs
{
int bFrameIndex;
Expand Down Expand Up @@ -52,6 +60,15 @@ struct usbg_f_uvc_attrs
struct usbg_f_uvc_format_attrs **formats;
};

enum usbg_f_uvc_config_attr {
USBG_F_UVC_CONFIG_ATTR_MIN = 0,
USBG_F_UVC_CONFIG_MAXBURST = USBG_F_UVC_CONFIG_ATTR_MIN,
USBG_F_UVC_CONFIG_MAXPACKET,
USBG_F_UVC_CONFIG_INTERVAL,
USBG_F_UVC_CONFIG_FUNCTION_NAME,
USBG_F_UVC_CONFIG_ATTR_MAX
};

enum usbg_f_uvc_frame_attr {
USBG_F_UVC_FRAME_ATTR_MIN = 0,
USBG_F_UVC_FRAME_INDEX = USBG_F_UVC_FRAME_ATTR_MIN,
Expand All @@ -77,6 +94,12 @@ enum usbg_f_uvc_format_attr {
USBG_F_UVC_FORMAT_ATTR_MAX
};

union usbg_f_uvc_config_attr_val {
int streaming_maxburst;
int streaming_maxpacket;
int streaming_interval;
const char *function_name;
};

union usbg_f_uvc_frame_attr_val {
int bmCapabilities;
Expand Down
177 changes: 175 additions & 2 deletions src/function/uvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,42 @@ struct usbg_f_uvc
bool formats_initiated;
};

#define UVC_DEC_ATTR(_name) \
{ \
.name = #_name, \
.offset = offsetof(struct usbg_f_uvc_config_attrs, _name), \
.get = usbg_get_dec, \
.set = usbg_set_dec, \
.import = usbg_get_config_node_int, \
.export = usbg_set_config_node_int, \
}

#define UVC_STRING_ATTR(_name) \
{ \
.name = #_name, \
.offset = offsetof(struct usbg_f_uvc_config_attrs, _name), \
.get = usbg_get_string, \
.set = usbg_set_string, \
.export = usbg_set_config_node_string, \
.import = usbg_get_config_node_string, \
}

struct {
const char *name;
size_t offset;
usbg_attr_get_func get;
usbg_attr_set_func set;
usbg_import_node_func import;
usbg_export_node_func export;
} uvc_config_attr[USBG_F_UVC_CONFIG_ATTR_MAX] = {
[USBG_F_UVC_CONFIG_MAXBURST] = UVC_DEC_ATTR(streaming_maxburst),
[USBG_F_UVC_CONFIG_MAXPACKET] = UVC_DEC_ATTR(streaming_maxpacket),
[USBG_F_UVC_CONFIG_INTERVAL] = UVC_DEC_ATTR(streaming_interval),
[USBG_F_UVC_CONFIG_FUNCTION_NAME] = UVC_STRING_ATTR(function_name),
};

#undef UVC_DEC_ATTR

#define UVC_DEC_ATTR(_name) \
{ \
.name = #_name, \
Expand Down Expand Up @@ -173,8 +209,8 @@ int init_frames(struct usbg_f_uvc *uvc, int j)
return ret;
}

ret = scandir(fpath, &dent, frame_select, frame_sort);
if (ret < 0) {
nmb = scandir(fpath, &dent, frame_select, frame_sort);
if (nmb < 0) {
ret = usbg_translate_error(errno);
return ret;
}
Expand Down Expand Up @@ -250,6 +286,71 @@ static void uvc_cleanup_attrs(struct usbg_function *f, void *f_attrs)
return usbg_f_uvc_cleanup_attrs(f_attrs);
}

int usbg_f_uvc_get_config_attr_val(usbg_f_uvc *uvcf, enum usbg_f_uvc_config_attr iattr,
union usbg_f_uvc_config_attr_val *val)
{
char ipath[USBG_MAX_PATH_LENGTH];
int nmb;

nmb = snprintf(ipath, sizeof(ipath), "%s/%s/",
uvcf->func.path, uvcf->func.name);
if (nmb >= sizeof(ipath))
return USBG_ERROR_PATH_TOO_LONG;


return uvc_config_attr[iattr].get(ipath, "",
uvc_config_attr[iattr].name, val);
}

int usbg_f_uvc_set_config_attr_val(usbg_f_uvc *uvcf, enum usbg_f_uvc_config_attr iattr,
union usbg_f_uvc_config_attr_val val)
{
char ipath[USBG_MAX_PATH_LENGTH];
int nmb;

nmb = snprintf(ipath, sizeof(ipath), "%s/%s/",
uvcf->func.path, uvcf->func.name);
if (nmb >= sizeof(ipath))
return USBG_ERROR_PATH_TOO_LONG;

return uvc_config_attr[iattr].set(ipath, "",
uvc_config_attr[iattr].name, &val);
}

int usbg_f_uvc_get_config_attrs(usbg_f_uvc *uvcf, struct usbg_f_uvc_config_attrs *iattrs)
{
int i;
int ret = 0;

for (i = USBG_F_UVC_CONFIG_ATTR_MIN; i < USBG_F_UVC_CONFIG_ATTR_MAX; ++i) {
ret = usbg_f_uvc_get_config_attr_val(uvcf, i,
(union usbg_f_uvc_config_attr_val *)
((char *)iattrs
+ uvc_config_attr[i].offset));
if (ret)
break;
}

return ret;
}

int usbg_f_uvc_set_config_attrs(usbg_f_uvc *uvcf, const struct usbg_f_uvc_config_attrs *iattrs)
{
int i;
int ret = 0;

for (i = USBG_F_UVC_FRAME_ATTR_MIN; i < USBG_F_UVC_FRAME_ATTR_MAX; ++i) {
ret = usbg_f_uvc_set_config_attr_val(uvcf, i,
*(union usbg_f_uvc_config_attr_val *)
((char *)iattrs
+ uvc_config_attr[i].offset));
if (ret)
break;
}

return ret;
}

int usbg_f_uvc_get_frame_attr_val(usbg_f_uvc *uvcf, const char* format, int frame_id,
enum usbg_f_uvc_frame_attr fattr,
union usbg_f_uvc_frame_attr_val *val)
Expand Down Expand Up @@ -646,6 +747,41 @@ static int uvc_import_format(struct usbg_f_uvc *uvcf, const char *format, bool *
return ret;
};

static int uvc_import_config(struct usbg_f_uvc *uvcf, config_setting_t *root)
{
union usbg_f_uvc_config_attr_val val;
config_setting_t *config_node;
int ret = 0;
int i;

config_node = config_setting_get_member(root, "config");
if (!config_node) {
ret = USBG_ERROR_INVALID_PARAM;
return ret;
}

if (!config_setting_is_group(config_node)) {
ret = USBG_ERROR_INVALID_TYPE;
return ret;
}

for (i = USBG_F_UVC_CONFIG_ATTR_MIN; i < USBG_F_UVC_CONFIG_ATTR_MAX; ++i) {
ret = uvc_config_attr[i].import(config_node, uvc_config_attr[i].name, &val);
/* node not found */
if (ret == 0)
continue;
/* error */
if (ret < 0)
break;

ret = usbg_f_uvc_set_config_attr_val(uvcf, i, val);
if (ret)
break;
}

return ret;
}

static int uvc_libconfig_import(struct usbg_function *f, config_setting_t *root)
{
struct usbg_f_uvc *uvcf = usbg_to_uvc_function(f);
Expand Down Expand Up @@ -695,6 +831,10 @@ static int uvc_libconfig_import(struct usbg_function *f, config_setting_t *root)
goto out;
}

ret = uvc_import_config(uvcf, root);
if (ret != USBG_SUCCESS)
return ret;

ret = uvc_set_class(uvcf, UVC_PATH_CONTROL);
if (ret != USBG_SUCCESS)
return ret;
Expand All @@ -708,6 +848,31 @@ static int uvc_libconfig_import(struct usbg_function *f, config_setting_t *root)

}

static int uvc_export_config(struct usbg_f_uvc *uvcf, config_setting_t *root)
{
config_setting_t *config_node;
union usbg_f_uvc_config_attr_val val;
int i;
int ret = 0;

config_node = config_setting_add(root, "config", CONFIG_TYPE_GROUP);
if (!config_node)
goto out;

for (i = USBG_F_UVC_CONFIG_ATTR_MIN; i < USBG_F_UVC_CONFIG_ATTR_MAX; ++i) {
ret = usbg_f_uvc_get_config_attr_val(uvcf, i, &val);
if (ret)
break;

ret = uvc_config_attr[i].export(config_node, uvc_config_attr[i].name, &val);
if (ret)
break;
}

out:
return ret;
};

static int uvc_export_format_attrs(struct usbg_f_uvc *uvcf, const char *format,
config_setting_t *root)
{
Expand All @@ -725,6 +890,9 @@ static int uvc_export_format_attrs(struct usbg_f_uvc *uvcf, const char *format,
break;
}

if (ret == USBG_ERROR_NOT_FOUND)
ret = 0;

return ret;
}

Expand All @@ -745,6 +913,9 @@ static int uvc_export_frame_attrs(struct usbg_f_uvc *uvcf, const char *format,
break;
}

if (ret == USBG_ERROR_NOT_FOUND)
ret = 0;

return ret;
}

Expand Down Expand Up @@ -813,6 +984,8 @@ static int uvc_libconfig_export(struct usbg_function *f, config_setting_t *root)
goto out;
}

ret = uvc_export_config(uvcf, root);

out:
return ret;
}
Expand Down