summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore29
-rw-r--r--AUTHORS2
-rw-r--r--ChangeLog7
-rw-r--r--INSTALL2
-rw-r--r--Makefile.am7
-rw-r--r--README4
-rw-r--r--configure.ac47
-rw-r--r--doc/gadget_schemes.txt301
-rw-r--r--doc/tests_guideline.txt166
-rw-r--r--doxygen.cfg (renamed from doxygen.cfg.in)9
-rw-r--r--examples/Makefile.am11
-rw-r--r--examples/gadget-acm-ecm.c25
-rw-r--r--examples/gadget-export.c81
-rw-r--r--examples/gadget-ffs.c156
-rw-r--r--examples/gadget-import.c78
-rw-r--r--examples/gadget-midi.c119
-rw-r--r--examples/gadget-ms.c161
-rw-r--r--examples/gadget-vid-pid-remove.c108
-rw-r--r--examples/show-gadgets.c139
-rw-r--r--examples/show-udcs.c61
-rw-r--r--include/usbg/usbg.h612
-rw-r--r--include/usbg/usbg_internal.h174
-rw-r--r--libusbg.pc.in (renamed from libusbgx.pc.in)4
-rw-r--r--src/Makefile.am15
-rw-r--r--src/usbg.c1984
-rw-r--r--src/usbg_schemes_libconfig.c2184
-rw-r--r--src/usbg_schemes_none.c94
-rw-r--r--tests/Makefile.am14
-rw-r--r--tests/test.c2697
-rwxr-xr-xtests/test.sh78
-rw-r--r--tests/usbg-io-wrappers.c203
-rw-r--r--tests/usbg-test.c1389
-rw-r--r--tests/usbg-test.h549
33 files changed, 457 insertions, 11053 deletions
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 7dfeaed..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,29 +0,0 @@
-/examples/*
-!/examples/*.*
-/examples/.deps
-/examples/.libs
-/src/.deps
-/src/.libs
-/tests/*
-!/tests/*.*
-/tests/.deps
-*.o
-*.lo
-*.la
-*.so
-*.so.*
-Makefile
-Makefile.in
-/configure
-/config.*
-/aclocal.m4
-/autom4te.cache
-/compile
-/depcomp
-/libtool
-/ltmain.sh
-/ar-lib
-/missing
-/install-sh
-/doxygen.cfg
-/libusbg.pc
diff --git a/AUTHORS b/AUTHORS
index 6fea705..f9b069c 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,3 +1 @@
Matt Porter <mporter@linaro.org>
-Krzysztof Opasiak <k.opasiak@samsung.com>
-
diff --git a/ChangeLog b/ChangeLog
index 63ba0f3..295762b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,2 +1,5 @@
-Tue, 22 Dec 2015 Krzysztof Opasiak <k.opasiak@samsung.com> 0.0.1
- - Initial fork from libusbg
+Mon, 20 Jan 2014 Matt Porter <mporter@linaro.org> 0.1.0
+- Rename from libgadget->libusbg
+- Update examples to use standard configfs mount point
+Wed, 04 Sep 2013 Matt Porter <mporter@linaro.org> 0.0.1
+- Initial release
diff --git a/INSTALL b/INSTALL
index 0d9d67f..786ecee 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,4 +1,4 @@
-Installing libusbgx:
+Installing libusbg:
$ autoreconf -i
$ ./configure
diff --git a/Makefile.am b/Makefile.am
index 05e1379..5fc3cd6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,13 +1,8 @@
include $(top_srcdir)/aminclude.am
SUBDIRS = src examples
-
-if BUILD_TESTS
-SUBDIRS += tests
-endif
-
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = doxygen.cfg
library_includedir=$(includedir)/usbg
library_include_HEADERS = include/usbg/usbg.h
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libusbgx.pc
+pkgconfig_DATA = libusbg.pc
diff --git a/README b/README
index 08622a3..fba9959 100644
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
-libusbg-neXt (libusbgx)
+libusbg
-------
-libusbgx is a C library encapsulating the kernel USB gadget-configfs
+libusbg is a C library encapsulating the kernel USB gadget-configfs
userspace API functionality.
It provides routines for creating and parsing USB gadget devices using
diff --git a/configure.ac b/configure.ac
index a456ba7..878c2ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,51 +1,10 @@
-AC_INIT([libusbgx], [0.0.1], [k.opasiak@samsung.com])
-AM_INIT_AUTOMAKE([1.12 -Wall -Werror foreign serial-tests])
+AC_INIT([libusbg], [0.1.0], [mporter@linaro.org])
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AM_PROG_AR
-AM_PROG_CC_C_O
AC_CONFIG_MACRO_DIR([m4])
AC_DEFINE([_GNU_SOURCE], [], [Use GNU extensions])
-
-AC_ARG_WITH([libconfig],
- AS_HELP_STRING([--without-libconfig], [build without using libconfig]),
- [with_libconfig=$withval], [with_libconfig=yes])
-
-AC_ARG_ENABLE([gadget-schemes],
- AS_HELP_STRING([--disable-gadget-schemes], [build without gadget-schemes support]),
- [enable_gadget_schemes=$enableval], [enable_gadget_schemes=yes])
-
-AC_ARG_ENABLE([tests],
- AS_HELP_STRING([--enable-tests], [build with tests]),
- [enable_tests=$enableval], [enable_tests=no])
-
-# if both tests and schemes are disabled, we do not need libconfig
-AS_IF([test "x$enable_gadget_schemes" = xno && test "x$enable_tests" = xno], [with_libconfig=no])
-
-AS_IF([test "x$with_libconfig" = xyes], [
- PKG_CHECK_MODULES([LIBCONFIG], [libconfig >= 1.4],
- [ AC_DEFINE(HAS_LIBCONFIG, 1, [detected libconfig])
- PKG_CHECK_MODULES([NEW_LIBCONFIG], [libconfig >= 1.5],
- AC_DEFINE(HAVE_LIBCONFIG_15, 1, [detected libconfig equal to or greater than 1.5]),
- AC_DEFINE(HAVE_LIBCONFIG_15, 0, []))
- ])
- CFLAGS="$CFLAGS $LIBCONFIG_CFLAGS"
- LIBS="$LIBS $LIBCONFIG_LIBS"
-], [
- enable_gadget_schemes=no
-])
-
-AS_IF([test "x$enable_tests" = xyes], [
- PKG_CHECK_MODULES([CMOCKA], [cmocka >= 1.0.0],
- AC_DEFINE(HAS_CMOCKA, 1, [detected cmocka]))
- AC_CONFIG_FILES([tests/Makefile])
-])
-AM_CONDITIONAL(BUILD_TESTS, [test "x$enable_tests" = xyes])
-
-AS_IF([test "x$enable_gadget_schemes" = xyes],
- [AC_DEFINE(HAS_GADGET_SCHEMES, 1, [gadget schemes are enables])])
-AM_CONDITIONAL(TEST_GADGET_SCHEMES, [test "x$enable_gadget_schemes" != xno])
-
LT_INIT
-AC_CONFIG_FILES([Makefile src/Makefile examples/Makefile libusbgx.pc doxygen.cfg])
+AC_CONFIG_FILES([Makefile src/Makefile examples/Makefile libusbg.pc])
DX_INIT_DOXYGEN([$PACKAGE_NAME],[doxygen.cfg])
AC_OUTPUT
diff --git a/doc/gadget_schemes.txt b/doc/gadget_schemes.txt
deleted file mode 100644
index d1d44a5..0000000
--- a/doc/gadget_schemes.txt
+++ /dev/null
@@ -1,301 +0,0 @@
-
- Gadget schemes
-
-
-Index:
-1. What are gadget schemes?
-2. Why gadget schemes?
-3. Gadget scheme syntax
- 3.1 Function scheme
- 3.2 Configuration scheme
- 3.3 Gadget scheme
-4. Conclusion
-
-
- 1. What are gadget schemes?
-
-Gadget schemes are files which contains configuration data of
-gadget/function/configuration. Those files can be generated using
-usbg_export_*() functions for whole gadget, configuration or single
-function. Library provides also set of usbg_import_*() functions which
-allows to load configuration data back to configfs.
-
-
- 2. Why gadget schemes?
-
-New kernel interface - ConfigFS which along with libcomposite allows
-to set up custom gadget. This can be achieved using simple, command
-line file system operation like mkdir, rmdir, ln -s, read and
-write. Yes, it is possible to configure usb gadget using only command
-line but each time after reboot user needs to recreate all gadgets
-once again. This means that after each reboot user needs to use about
-15 commands (depends on number and types of function). This is
-definitely not acceptable for those who used legacy gadgets and write
-only modprobe g_ether.
-
-One of first idea to solve this is to create a script and run it
-after each reboot. This approach is feasible but has many
-disadvantages. First of them is security. ConfigFS is modifiable by
-default only by root, so scripts has to be executed with root
-rights. Secondly it's really hard to modify such a script because many
-calls has hard-coded path where for example echo should be
-done. There is a lot of simple, but low level operations which can
-cause a lot of confusion for beginner.
-
-Second approach is to create executable which will create our gadget
-using base libusbg API. It is also possible but let's think for a
-moment why configfs has been introduced. It has been announced to
-separate code from configuration. Code is a piece of C code in kernel
-module which realizes usb function and configuration is understood as
-composition of those functions into a gadget as a whole. If we would
-like to create binary file for each gadget we would waste a lot of
-work which kernel contributors put to remove hard-coded gadgets from
-linux kernel. This all leads us to solution described in this document
-- gadget schemes. Light weight configuration files which describes
-composition of functions into gadget. They can be simply loaded using
-usbg_import_*() and exported using usbg_export_*(). This makes them
-easy to use equivalent of modprobe gadget_module.
-
-
- 3. Gadget scheme syntax
-
-Gadget schemes implementation uses libconfig for reading and writing
-scheme files. This means that all limitations of libconfig are also
-present in gadget schemes. More over there are additional constrains
-for scheme files. Gadget scheme is only a password and import and
-export is not limited to whole gadgets. It is possible to export all 3
-types of gadget entity: function, configuration and gadget. Please
-refer to libconfig documentation for details about syntax and rules.
-
- 3.1 Function scheme
-
-Function scheme is a file or part of file which represents single
-function.
-
-Example:
-
-instance = "my_func_instance"
-type = "ecm"
-
-attrs = {
- dev_addr = "ef:33:be:9a:90:36"
- dev_addr = "ab:63:6e:8b:10:16"
- qmult = 5
-}
-
-For functions, type is the only attribute which is always
-mandatory. Instance is mandatory only if function is part of bigger
-scheme (gadget for example). By default usbg_export_function() does
-not export instance name, because usbg_import_function() takes
-instance as one of parameters. This convention allows for simple
-function movement between gadgets without names conflict.
-
-Attrs section is optional. It may not be included, present but empty
-or present and filled with function attributes. Attribute names are
-similar as those from configfs. Each type of function has own set of
-possible attributes. It is worth to mention that some attributes are
-read only and they cannot be imported from file. To make it more
-user-friendly read-only parameters are just ignored. This allows for
-direct use of previously exported function in import. If some
-attribute has not been provided default value provided by kernel will
-be used.
-
- 3.2 Configuration scheme
-
-Configuration scheme is a file or part of file which represents single
-configuration with its attributes, strings and bindings.
-
-Simple example:
-
-id = 1
-name = "My favorite config"
-
-attrs = {
- bMaxPower = 0x40
- bmAttributes = 0x00
-}
-
-strings = (
- {
- lang = 0x409
- configuration = "My favorite string"
- }
-)
-
-functions = (
- "function_label"
-)
-
-This is example of simple configuration with some attributes values,
-strings in US English and only one function. For configurations name
-is the only field which is always mandatory. Id is mandatory only if
-this is a part of bigger structure (gadget scheme).
-
-Attrs section is optional. It may not be included, present but empty
-or present and filled with function attributes. Attribute names are
-similar as those from configfs. Currently usb configuration has only
-two attributes: bMaxPower and bmAttributes. Their meaning and set of
-allowed values can be found in usb standard.
-
-Strings section presence policy is the same as attrs section. This
-section contains a list (that's the meaning of parentheses) of strings
-with their language codes. Each group of strings has to declare their
-language using lang field. Configuration string is optional. If this
-field is not set, empty string provided by kernel will be used for
-this language. Max number of languages is defined during kernel
-compilation using MAX_USB_STRING_LANGS define.
-
-Functions section is also optional. This allows for exporting not
-fully configured configurations. This section defines bindings between
-functions and configurations. The easiest and shortest way to define a
-connection between functions and configuration is to provide list of
-comma separated functions labels. For details about function labels
-please refer to gadget schemes subsection. Bindings of function to
-given configuration could be defined in different ways which has been
-presented in featured example.
-
-Featured example:
-
-id = 1
-name = "My favorite config"
-
-attrs = {
- bMaxPower = 0x40
- bmAttributes = 0x00
-}
-
-strings = (
- {
- lang = 0x409
- configuration = "My favorite string"
- } , {
- lang = 0x415
- configuration = "Moj ulubiony napis"
- }
-)
-
-functions = (
- "function_label"
- , {
- name = "my_binding_name"
- function = "other_function_label"
- } , {
- name = "my_binding_name"
- function = {
- type = "ecm"
- instance = "my_inline_func_definition"
- attrs = {
- dev_addr = "ef:33:be:9a:90:36"
- }
- }
- }
-)
-
-First way to add function to configuration has been described along
-with simple example. Second way is to provide a group with two
-fields. First one is name and it should contain a string with binding
-name. This field is optional and can be omitted what makes this more
-verbose equivalent of previous method. Second field, named function
-is mandatory. This field should contain function label. Third way to
-add function to config is to define it inline. This method allows to
-define a brand new function instead of providing function label of
-existing one.
-
- 3.3 Gadget scheme
-
-Gadget scheme is a file which represents whole gadget with
-configurations, attributes, strings and functions.
-
-Example:
-
-attrs = {
- bcdUSB = 0x200
- bDeviceClass = 0x0
- bDeviceSubClass = 0x0
- bDeviceProtocol = 0x0
- bMaxPacketSize0 = 0x40
- idVendor = 0x1D6B
- idProduct = 0x104
- bcdDevice = 0x1
-}
-
-strings = (
- {
- lang = 0x409
- manufacturer = "Foo Inc."
- product = "Bar Gadget"
- serialnumber = "0123456789"
- }
-)
-
-functions = {
- acm_usb0 = {
- instance = "usb0"
- type = "acm"
- }
-
- my_awesome_label = {
- instance = "inst_name"
- @include "my_func_scheme.scheme"
- }
-}
-
-configs = (
- {
- id = 1
- name = "The only one"
- attrs = {
- bmAttributes = 0x80
- bMaxPower = 0x2
- }
- strings = (
- {
- lang = 0x409
- configuration = "Config id 1"
- } )
- functions = (
- {
- name = "acm.GS0"
- function = "acm_usb0"
- }
- )
- } , {
- id = 2
- @include "some_config.scheme"
- }
-)
-
-All sections in gadget scheme are optional. If attrs section has not
-been defined defaults provided by kernel are used for each attribute.
-All possible gadget attributes has been listed in above example. Their
-names are similar to those provided by usb standard and configfs.
-
-Strings section is similar to strings section from configuration
-scheme. Allowed strings are listed in example.
-
-Functions section is used to define functions which are aggregated by
-this gadget. Definition of each function begins with unique label. Any
-string which fulfills libconfig naming rules can be used as label,
-but there is one important thing - function labels are not stored in
-configfs. They are transient and are lost while executing
-usbg_cleanup(). To allow using this label after next usbg_init() there
-is a naming rule: type + "_" + instance. If label follows this
-convention it could be regenerated each time when it is
-needed. Definition of each function contains a function scheme which
-has been described in one of previous sections. It is also possible
-to use include directive of libconfig and provide only instance name
-in gadget shceme and include previously exported function scheme from
-other gadget.
-
-Configfs section contains list of configurations definitions. Each
-configuration is defined using configuration scheme described in
-previous section. Each configuration can be fully defined in gadget
-scheme file or simply included from other file just like function.
-
- 4. Conclusion
-
-Syntax of gadget scheme is based on libconfig and if any doubts appear
-don't hesitate to look into documentation of this library. There are
-also sample applications which shows how to use usbg_import_*() and
-usbg_export_*() functions in examples directory.
-
diff --git a/doc/tests_guideline.txt b/doc/tests_guideline.txt
deleted file mode 100644
index 2f5a2d8..0000000
--- a/doc/tests_guideline.txt
+++ /dev/null
@@ -1,166 +0,0 @@
-Libusbg testing guideline
--------------------------
-
-Libusbg tests use cmocka library to simulate fake configfs filesystem,
-by wrapping input/output functions.
-
-## Building and running tests
-
-# Requirements
-Building libusbg tests requires:
--CMocka unit testing framework in version >= 0.3
--libconfig in version >= 1.4
-
-# Building and running
-Before testing make sure that you have successfully built libusbg (see INSTALL for
-more details). Tests must be enabled in configuration, do it by adding proper flag
-when configuring:
-
- $ ./configure --enable-tests
-
-Then, to build and run all provided tests, run following command:
-
- $ make check
-
-This should execute testing script and produce report on standart output.
-It contains list of all test cases and its status - OK, FAILED and SKIPPED. At the
-end of report number of passed/failed tests is written and then all failed test
-cases are listed. This report is also avaible in tests/test-suite.log file.
-
-It's also possible to pass custom configuration file to testing environment.
-Currently it's used only for skipping tests. Use --generate-config and
---use-config options of test.sh to generate default config and read config
-from file. Run ./test.sh --help for more help with testing environment.
-
-# Tests skipping
-When you want to skip some test cases, use configuration files for test suite.
-To generate default config run:
-
- $ make check GENERATE_CONFIG=[file_name]
-
-It will generate tests/[file_name] file with configuration for testing. You can
-remove test cases from 'tests' list to disable them. With custom configuration file
-run:
-
- $make check USE_CONFIG=[file_name]
-
-Where file_name is name of previously generated configuration file. Test suite
-will skip tests not listed in config.
-
-
-## Writting tests
-
-Before starting your own tests implementation, become familiar with cmocka
-library (cmocka.org).
-
-test.c file contains tests implementation. Test cases are stored in
-UnitTest structures (from cmocka) and run by run_tests macro.
-
-In cmocka each test case can be composed of three parts: setup, test and
-teardown.
-
-# Setup functions
-In setup input data must be initialized and assigned to pointer given as
-argument.
-
-Libusbg requires initialized usbg_state structure for most of it's api
-functions. In most cases we define initial state in test_* strutures and
-pass it to test function, in order to run usbg_init. Each test_state
-can be defined quite simply by listing gadgets, its configs and functions
-(using gcc extenstion), e.g.:
-
- static struct test_state simple_state = {
- .path = "config",
- .gadgets = simple_gadgets,
- .udcs = simple_udcs
- };
-
-test_state structure (or other structure, if neccessary for test case)
-is casted to void * in setup function. Note, that when using test_state
-you must sort its content and fill additional fields (i.e. pathes strings).
-It can be done by calling prepare_state before test.
-
-# Test functions
-Test functions contain libusbg functions calls, preparations for them and
-checking results.
-
-When calling usbg function which operates on filesystem proper preparation
-is needed. Usbg-test framework provides functions which tell cmocka what
-operations are expected from corresponding usbg function (push_* and pull_*
-functions).
-
-E.g., in most cases you want correctly initialized usbg_state. It can be done
-by preparing filesystem by push_init and running usbg_init after that:
-
- push_init(in);
- usbg_ret = usbg_init(in->path, out);
-
-init_with_state function does that and checks results.
-
-When tested usbg function was run, you can check results by cmocka assert
-macros. Usbg-test also provides set of assert functions for usbg structures.
-
-# Teardown functions
-When test was run, you can define teardown function, which can do the cleanup.
-Argument is passed same way as before, by assigning it to cmocka state pointer
-in test function and receiving it in teardown function.
-
-In most cases you will just want to cleanup after initializing state and running
-some usbg functions. To do that teardown_state can be used as teardown function.
-You can write custom teardown for other cases.
-
-Note that in preparation for test some memory is allocated. All allocated
-pointers are stored on global stack and should be freed by calling cleanup_stack
-after test is finished (in teardown function).
-
-Remember that teardown is called also when test failed. You should assign
-something correct (NULL for example) for your teardown function to test
-argument before running functions which may fail.
-
-# Composing test cases
-All test cases are defined in list of UnitTest structures. You can define test
-case by macros provided by cmocka or by USBG_TEST or USBG_TEST_TS macro.
-
-USBG_TEST is similar to unit_test_setup_teardown from cmocka, but always uses
-the same teardown (teardown_state) and names test case with custom string.
-It combines setup function with test function, so one test function can be
-run with many different states.
-
-# Documenting test cases
-For tests documentation few doxygen macros are created.
-\usbg_test indicates that current comment block contains test case documentation.
-\test_desc{name, description, function} describe test with its name, function
-which is tested and short descripttion of what this test does.
-
-# Adding tests
-Simplest way to add more tests is defining test states and new setup functions,
-combining them with existing testing functions using USBG_TEST. You can also
-write own test function. When you have test and setup prepared, add
-
- USBG_TEST_TS("test_name", test_function, setup_function),
-or
- USBG_TEST("test_name", test_function, setup_function, teardown_function),
-
-at the end of tests[] array. Remember to add documentation to the case
-(see Documenting test cases).
-
-# Removing tests
-In order to remove test case just delete corresponding element on tests[] list
-(including documentation above it).
-
-# Modyfing tests
-When you want to change data using in test case, change corresponding test_*
-structures. Note, that single test state can be used in many test cases and
-modyfing it can effect them as well.
-You can also change test logic (by modifying test function used in case), as
-long as you know what you're doing.
-
-
-## Final notes
-
-Remember, that in test environment functions operating on files are replaced
-and operations on files cannot be performed. However, using standard input/output
-is possible.
-
-All test cases are run in single thread, so some failures on one test case
-(e.g. SIGSEGV) can cause crash on whole tests set.
diff --git a/doxygen.cfg.in b/doxygen.cfg
index d42ff83..4d7a5d8 100644
--- a/doxygen.cfg.in
+++ b/doxygen.cfg
@@ -650,8 +650,6 @@ WARN_LOGFILE =
INPUT = $(SRCDIR)/include/usbg/ $(SRCDIR)/src $(SRCDIR)/examples/
-@BUILD_TESTS_TRUE@INPUT += $(SRCDIR)/tests/
-
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
# also the default input encoding. Doxygen uses libiconv (or the iconv built
@@ -1505,7 +1503,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED = DOXYGEN
+PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
@@ -1781,8 +1779,3 @@ GENERATE_LEGEND = YES
# the various graphs.
DOT_CLEANUP = YES
-
-ALIASES += tests_start="<table> <tr> <th>Name</th> <th>Description</th> <th>Tested function</th> </tr> \n"
-ALIASES += usbg_test="\page usbg_tests"
-ALIASES += test_desc{3}="<tr> <td>\1</td> <td>\2</td> <td>\ref \3</td> </tr> \n"
-ALIASES += tests_end="</table> "
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 8c2acb2..f9f9407 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,10 +1,5 @@
-bin_PROGRAMS = show-gadgets gadget-acm-ecm gadget-vid-pid-remove gadget-ffs gadget-export gadget-import show-udcs gadget-ms gadget-midi
+bin_PROGRAMS = show-gadgets gadget-acm-ecm
gadget_acm_ecm_SOURCES = gadget-acm-ecm.c
show_gadgets_SOURCES = show-gadgets.c
-gadget_vid_pid_remove_SOURCES = gadget-vid-pid-remove.c
-gadget_ffs_SOURCES = gadget-ffs.c
-gadget_export_SOURCE = gadget-export.c
-gadget_import_SOURCE = gadget-import.c
-show_udcs_SOURCE = show-udcs.c
-AM_CPPFLAGS=-I$(top_srcdir)/include/
-AM_LDFLAGS=-L../src/ -lusbgx
+AM_CPPFLAGS=-I../include/
+AM_LDFLAGS=-L../src/ -lusbg
diff --git a/examples/gadget-acm-ecm.c b/examples/gadget-acm-ecm.c
index 65407ff..4e8010f 100644
--- a/examples/gadget-acm-ecm.c
+++ b/examples/gadget-acm-ecm.c
@@ -16,7 +16,6 @@
#include <errno.h>
#include <stdio.h>
-#include <linux/usb/ch9.h>
#include <usbg/usbg.h>
/**
@@ -38,24 +37,24 @@ int main(void)
int usbg_ret;
usbg_gadget_attrs g_attrs = {
- .bcdUSB = 0x0200,
- .bDeviceClass = USB_CLASS_PER_INTERFACE,
- .bDeviceSubClass = 0x00,
- .bDeviceProtocol = 0x00,
- .bMaxPacketSize0 = 64, /* Max allowed ep0 packet size */
- .idVendor = VENDOR,
- .idProduct = PRODUCT,
- .bcdDevice = 0x0001, /* Verson of device */
+ 0x0200, /* bcdUSB */
+ 0x00, /* Defined at interface level */
+ 0x00, /* subclass */
+ 0x00, /* device protocol */
+ 0x0040, /* Max allowed packet size */
+ VENDOR,
+ PRODUCT,
+ 0x0001, /* Verson of device */
};
usbg_gadget_strs g_strs = {
- .str_ser = "0123456789", /* Serial number */
- .str_mnf = "Foo Inc.", /* Manufacturer */
- .str_prd = "Bar Gadget" /* Product string */
+ "0123456789", /* Serial number */
+ "Foo Inc.", /* Manufacturer */
+ "Bar Gadget" /* Product string */
};
usbg_config_strs c_strs = {
- .configuration = "CDC 2xACM+ECM"
+ "CDC 2xACM+ECM"
};
usbg_ret = usbg_init("/sys/kernel/config", &s);
diff --git a/examples/gadget-export.c b/examples/gadget-export.c
deleted file mode 100644
index 9d51e9e..0000000
--- a/examples/gadget-export.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics
- *
- * Krzysztof Opasiak <k.opasiak@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/**
- * @file gadget-export.c
- * @example gadget-export.c
- * This is an example of how to export a gadget to file.
- * Common reason of doing this is to share schema of gadget
- * between different devices or preserve gadget between reboots.
- */
-
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <usbg/usbg.h>
-
-int main(int argc, char **argv)
-{
- usbg_state *s;
- usbg_gadget *g;
- int ret = -EINVAL;
- int usbg_ret;
- FILE *output;
-
- if (argc != 3) {
- fprintf(stderr, "Usage: gadget-export gadget_name file_name\n");
- return ret;
- }
-
- /* Prepare output file */
- output = fopen(argv[2], "w");
- if (!output) {
- fprintf(stderr, "Error on fopen. Error: %s\n", strerror(errno));
- goto out1;
- }
-
- /* Do gadget exporting */
- usbg_ret = usbg_init("/sys/kernel/config", &s);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB gadget init\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- g = usbg_get_gadget(s, argv[1]);
- if (!g) {
- fprintf(stderr, "Error on get gadget\n");
- goto out3;
- }
-
- usbg_ret = usbg_export_gadget(g, output);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on export gadget\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out3;
- }
-
- ret = 0;
-
-out3:
- usbg_cleanup(s);
-out2:
- fclose(output);
-out1:
- return ret;
-}
diff --git a/examples/gadget-ffs.c b/examples/gadget-ffs.c
deleted file mode 100644
index 6274c15..0000000
--- a/examples/gadget-ffs.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics
- *
- * Krzysztof Opasiak <k.opasiak@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/**
- * @file gadget-ffs.c
- * @example gadget-ffs.c
- * This is an example of how to create gadget with FunctionFS based functions
- * in two ways. After executing this program gadget will not be enabled
- * because ffs instances should be mounted and both descriptors and strings
- * should be written to ep0.
- * For more details about FunctionFS please refer to FunctionFS documentation
- * in linux kernel repository.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <linux/usb/ch9.h>
-#include <usbg/usbg.h>
-
-#define VENDOR 0x1d6b
-#define PRODUCT 0x0104
-
-int main(void)
-{
- usbg_state *s;
- usbg_gadget *g;
- usbg_config *c;
- usbg_function *f_ffs1, *f_ffs2;
- int ret = -EINVAL;
- int usbg_ret;
-
- usbg_gadget_attrs g_attrs = {
- .bcdUSB = 0x0200,
- .bDeviceClass = USB_CLASS_PER_INTERFACE,
- .bDeviceSubClass = 0x00,
- .bDeviceProtocol = 0x00,
- .bMaxPacketSize0 = 64, /* Max allowed ep0 packet size */
- .idVendor = VENDOR,
- .idProduct = PRODUCT,
- .bcdDevice = 0x0001, /* Verson of device */
- };
-
- usbg_gadget_strs g_strs = {
- .str_ser = "0123456789", /* Serial number */
- .str_mnf = "Foo Inc.", /* Manufacturer */
- .str_prd = "Bar Gadget" /* Product string */
- };
-
- usbg_config_strs c_strs = {
- .configuration = "2xFFS"
- };
-
- usbg_function_attrs f_attrs = {
- .attrs.ffs = {
- .dev_name = "my_awesome_dev_name",
- },
- };
-
- usbg_ret = usbg_init("/sys/kernel/config", &s);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB gadget init\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out1;
- }
-
- usbg_ret = usbg_create_gadget(s, "g1", &g_attrs, &g_strs, &g);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on create gadget\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_create_function(g, F_FFS, "my_dev_name", NULL, &f_ffs1);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error creating ffs1 function\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- /* When NULL is passed as instance name, dev_name take from f_attrs
- is used as instance name for this function */
- usbg_ret = usbg_create_function(g, F_FFS, NULL, &f_attrs, &f_ffs2);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error creating ffs2 function\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- /* NULL can be passed to use kernel defaults */
- usbg_ret = usbg_create_config(g, 1, "The only one", NULL, &c_strs, &c);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error creating config\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_add_config_function(c, "some_name_here", f_ffs1);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error adding ffs1\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_add_config_function(c, "some_name_here_too", f_ffs2);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error adding ffs2\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- fprintf(stdout, "2xFFS gadget has been created.\n"
- "Enable it after preparing your functions.\n");
-
- /*
- * Here we end up with two created ffs instances but they are not
- * fully operational. Now we have to do step by step:
- * 1) Mount both instances:
- * $ mount my_dev_name -t functionfs /path/to/mount/dir1
- * $ mount my_awesome_dev_name -t functionfs /path/to/mount/dir2
- *
- * 2) Run ffs daemons for both instances:
- * $ my-ffs-daemon /path/to/mount/dir1
- * $ my-ffs-daemon /path/to/mount/dir2
- *
- * 3) Enable your gadget:
- * $ echo "my_udc_name" > /sys/kernel/config/usb_gadget/g1/UDC
- */
-
- ret = 0;
-
-out2:
- usbg_cleanup(s);
-
-out1:
- return ret;
-}
diff --git a/examples/gadget-import.c b/examples/gadget-import.c
deleted file mode 100644
index e684fdb..0000000
--- a/examples/gadget-import.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics
- *
- * Krzysztof Opasiak <k.opasiak@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/**
- * @file gadget-import.c
- * @example gadget-import.c
- * This is an example of how to import a gadget from file.
- * Common reason of doing this is to create gadget base on schema
- * from other devices or resurect gadget after reboot.
- */
-
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <usbg/usbg.h>
-
-int main(int argc, char **argv)
-{
- usbg_state *s;
- int ret = -EINVAL;
- int usbg_ret;
- FILE *input;
-
- if (argc != 3) {
- fprintf(stderr, "Usage: gadget-import gadget_name file_name\n");
- return ret;
- }
-
- /* Prepare input file */
- input = fopen(argv[2], "r");
- if (!input) {
- fprintf(stderr, "Error on fopen. Error: %s\n", strerror(errno));
- goto out1;
- }
-
- /* Do gadget exporting */
- usbg_ret = usbg_init("/sys/kernel/config", &s);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB gadget init\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_import_gadget(s, input, argv[1], NULL);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on import gadget\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- if (usbg_ret == USBG_ERROR_INVALID_FORMAT)
- fprintf(stderr, "Line: %d. Error: %s\n",
- usbg_get_gadget_import_error_line(s),
- usbg_get_gadget_import_error_text(s));
- goto out3;
- }
-
- ret = 0;
-
-out3:
- usbg_cleanup(s);
-out2:
- fclose(input);
-out1:
- return ret;
-}
diff --git a/examples/gadget-midi.c b/examples/gadget-midi.c
deleted file mode 100644
index f795de1..0000000
--- a/examples/gadget-midi.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics
- *
- * Pawel Szewczyk <p.szewczyk@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <linux/usb/ch9.h>
-#include <usbg/usbg.h>
-
-#define VENDOR 0x1d6b
-#define PRODUCT 0x0104
-
-int main() {
- usbg_state *s;
- usbg_gadget *g;
- usbg_config *c;
- usbg_function *f_midi;
- int ret = -EINVAL;
- int usbg_ret;
-
- usbg_gadget_attrs g_attrs = {
- .bcdUSB = 0x0200,
- .bDeviceClass = USB_CLASS_PER_INTERFACE,
- .bDeviceSubClass = 0x00,
- .bDeviceProtocol = 0x00,
- .bMaxPacketSize0 = 64, /* Max allowed ep0 packet size */
- .idVendor = VENDOR,
- .idProduct = PRODUCT,
- .bcdDevice = 0x0001, /* Verson of device */
- };
-
- usbg_gadget_strs g_strs = {
- .str_ser = "0123456789", /* Serial number */
- .str_mnf = "Foo Inc.", /* Manufacturer */
- .str_prd = "Bar Gadget" /* Product string */
- };
-
- usbg_config_strs c_strs = {
- .configuration = "1xMIDI"
- };
-
- usbg_function_attrs f_attrs = {
- .header.attrs_type = USBG_F_ATTRS_MIDI,
- .attrs.midi = {
- .index = 0,
- .id = "usb0",
- .buflen = 128,
- .qlen = 16,
- .in_ports = 2,
- .out_ports = 3,
- },
- };
-
- usbg_ret = usbg_init("/sys/kernel/config", &s);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on usbg init\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out1;
- }
-
- usbg_ret = usbg_create_gadget(s, "g1", &g_attrs, &g_strs, &g);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error creating gadget\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
- usbg_ret = usbg_create_function(g, F_MIDI, "usb0", &f_attrs, &f_midi);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error creating function\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_create_config(g, 1, "The only one", NULL, &c_strs, &c);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error creating config\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_add_config_function(c, "some_name", f_midi);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error adding function\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_enable_gadget(g, DEFAULT_UDC);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error enabling gadget\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- ret = 0;
-out2:
- usbg_cleanup(s);
-
-out1:
- return ret;
-}
diff --git a/examples/gadget-ms.c b/examples/gadget-ms.c
deleted file mode 100644
index d6c4aaf..0000000
--- a/examples/gadget-ms.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics
- *
- * Krzysztof Opasiak <k.opasiak@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/**
- * @file gadget-ms.c
- * @example gadget-ms.c
- * This is an example of how to create gadget with mass storage function
- * with two luns.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <linux/usb/ch9.h>
-#include <usbg/usbg.h>
-
-#define VENDOR 0x1d6b
-#define PRODUCT 0x0104
-
-int main(int argc, char **argv)
-{
- usbg_state *s;
- usbg_gadget *g;
- usbg_config *c;
- usbg_function *f_ms;
- int ret = -EINVAL;
- int usbg_ret;
-
- usbg_gadget_attrs g_attrs = {
- .bcdUSB = 0x0200,
- .bDeviceClass = USB_CLASS_PER_INTERFACE,
- .bDeviceSubClass = 0x00,
- .bDeviceProtocol = 0x00,
- .bMaxPacketSize0 = 64, /* Max allowed ep0 packet size */
- .idVendor = VENDOR,
- .idProduct = PRODUCT,
- .bcdDevice = 0x0001, /* Verson of device */
- };
-
- usbg_gadget_strs g_strs = {
- .str_ser = "0123456789", /* Serial number */
- .str_mnf = "Foo Inc.", /* Manufacturer */
- .str_prd = "Bar Gadget" /* Product string */
- };
-
- usbg_f_ms_lun_attrs f_ms_luns_array[] = {
- {
- .id = -1, /* allows to place in any position */
- .cdrom = 1,
- .ro = 0,
- .nofua = 0,
- .removable = 1,
- .filename = "",
- }, {
- .id = -1, /* allows to place in any position */
- .cdrom = 0,
- .ro = 0,
- .nofua = 0,
- .removable = 1,
- .filename = argv[1],
- }
- };
-
- usbg_f_ms_lun_attrs *f_ms_luns[] = {
- /*
- * When id in lun structure is below 0 we can place it in any
- * arbitrary position
- */
- &f_ms_luns_array[1],
- &f_ms_luns_array[0],
- NULL,
- };
-
- usbg_function_attrs f_attrs = {
- .header.attrs_type = USBG_F_ATTRS_MS,
- .attrs.ms = {
- .stall = 0,
- .nluns = 2,
- .luns = f_ms_luns,
- },
- };
-
- usbg_config_strs c_strs = {
- "1xMass Storage"
- };
-
- if (argc < 2) {
- fprintf(stderr, "Usage: gadget-ms file\n");
- goto out1;
- }
-
- usbg_ret = usbg_init("/sys/kernel/config", &s);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB gadget init\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out1;
- }
-
- usbg_ret = usbg_create_gadget(s, "g1", &g_attrs, &g_strs, &g);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on create gadget\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_create_function(g, F_MASS_STORAGE, "my_reader",
- &f_attrs, &f_ms);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error creating mass storage function\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- /* NULL can be passed to use kernel defaults */
- usbg_ret = usbg_create_config(g, 1, "The only one", NULL, &c_strs, &c);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error creating config\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_add_config_function(c, "some_name_here", f_ms);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error adding ms function\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- usbg_ret = usbg_enable_gadget(g, DEFAULT_UDC);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error enabling gadget\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- ret = 0;
-
-out2:
- usbg_cleanup(s);
-
-out1:
- return ret;
-}
diff --git a/examples/gadget-vid-pid-remove.c b/examples/gadget-vid-pid-remove.c
deleted file mode 100644
index c3f9c9b..0000000
--- a/examples/gadget-vid-pid-remove.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics
- *
- * Krzysztof Opasiak <k.opasiak@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/**
- * @file gadget-vid-pid-remove.c
- * @example gadget-vid-pid-remove.c
- * This is an example of how to find and remove an gadget device with given
- * Vendor ID and product ID.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <usbg/usbg.h>
-
-#define VENDOR 0x1d6b
-#define PRODUCT 0x0104
-
-int remove_gadget(usbg_gadget *g)
-{
- int usbg_ret;
- usbg_udc *u;
-
- /* Check if gadget is enabled */
- u = usbg_get_gadget_udc(g);
-
- /* If gadget is enable we have to disable it first */
- if (u) {
- usbg_ret = usbg_disable_gadget(g);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB disable gadget udc\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out;
- }
- }
-
- /* Remove gadget with USBG_RM_RECURSE flag to remove
- * also its configurations, functions and strings */
- usbg_ret = usbg_rm_gadget(g, USBG_RM_RECURSE);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB gadget remove\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- }
-
-out:
- return usbg_ret;
-}
-
-int main(void)
-{
- int usbg_ret;
- int ret = -EINVAL;
- usbg_state *s;
- usbg_gadget *g;
- usbg_gadget_attrs g_attrs;
-
- usbg_ret = usbg_init("/sys/kernel/config", &s);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB state init\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out1;
- }
-
- g = usbg_get_first_gadget(s);
- while (g != NULL) {
- /* Get current gadget attrs to be compared */
- usbg_ret = usbg_get_gadget_attrs(g, &g_attrs);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB get gadget attrs\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out2;
- }
-
- /* Compare attrs with given values and remove if suitable */
- if (g_attrs.idVendor == VENDOR && g_attrs.idProduct == PRODUCT) {
- usbg_gadget *g_next = usbg_get_next_gadget(g);
-
- usbg_ret = remove_gadget(g);
- if (usbg_ret != USBG_SUCCESS)
- goto out2;
-
- g = g_next;
- } else {
- g = usbg_get_next_gadget(g);
- }
- }
-
-out2:
- usbg_cleanup(s);
-out1:
- return ret;
-}
diff --git a/examples/show-gadgets.c b/examples/show-gadgets.c
index d27cde5..1ae3860 100644
--- a/examples/show-gadgets.c
+++ b/examples/show-gadgets.c
@@ -29,51 +29,33 @@
void show_gadget(usbg_gadget *g)
{
- const char *name, *udc;
- usbg_udc *u;
+ char buf[USBG_MAX_STR_LENGTH];
int usbg_ret;
usbg_gadget_attrs g_attrs;
usbg_gadget_strs g_strs;
- name = usbg_get_gadget_name(g);
- if (!name) {
- fprintf(stderr, "Unable to get gadget name\n");
- return;
- }
-
+ usbg_get_gadget_name(g, buf, USBG_MAX_STR_LENGTH);
usbg_ret = usbg_get_gadget_attrs(g, &g_attrs);
if (usbg_ret != USBG_SUCCESS) {
fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
+ usbg_strerror(usbg_ret));
return;
}
fprintf(stdout, "ID %04x:%04x '%s'\n",
- g_attrs.idVendor, g_attrs.idProduct, name);
+ g_attrs.idVendor, g_attrs.idProduct, buf);
- u = usbg_get_gadget_udc(g);
- if (u)
- /* gadget is enabled */
- udc = usbg_get_udc_name(u);
- else
- /* gadget is disabled */
- udc = "\0";
-
- fprintf(stdout, " UDC\t\t\t%s\n", udc);
-
- fprintf(stdout, " bcdUSB\t\t%x.%02x\n",
- g_attrs.bcdUSB >> 8,
- g_attrs.bcdUSB & 0x00ff);
+ usbg_get_gadget_udc(g, buf, USBG_MAX_STR_LENGTH);
+ fprintf(stdout, " UDC\t\t\t%s\n", buf);
fprintf(stdout, " bDeviceClass\t\t0x%02x\n", g_attrs.bDeviceClass);
fprintf(stdout, " bDeviceSubClass\t0x%02x\n", g_attrs.bDeviceSubClass);
fprintf(stdout, " bDeviceProtocol\t0x%02x\n", g_attrs.bDeviceProtocol);
- fprintf(stdout, " bMaxPacketSize0\t%d\n", g_attrs.bMaxPacketSize0);
+ fprintf(stdout, " bMaxPacketSize0\t0x%02x\n", g_attrs.bMaxPacketSize0);
+ fprintf(stdout, " bcdDevice\t\t0x%04x\n", g_attrs.bcdDevice);
+ fprintf(stdout, " bcdUSB\t\t0x%04x\n", g_attrs.bcdUSB);
fprintf(stdout, " idVendor\t\t0x%04x\n", g_attrs.idVendor);
fprintf(stdout, " idProduct\t\t0x%04x\n", g_attrs.idProduct);
- fprintf(stdout, " bcdDevice\t\t%x.%02x\n",
- g_attrs.bcdDevice >> 8,
- g_attrs.bcdDevice & 0x00ff);
usbg_ret = usbg_get_gadget_strs(g, LANG_US_ENG, &g_strs);
if (usbg_ret != USBG_SUCCESS) {
@@ -81,24 +63,19 @@ void show_gadget(usbg_gadget *g)
usbg_strerror(usbg_ret));
return;
}
+ fprintf(stdout, " Serial Number\t\t%s\n", g_strs.str_ser);
fprintf(stdout, " Manufacturer\t\t%s\n", g_strs.str_mnf);
fprintf(stdout, " Product\t\t%s\n", g_strs.str_prd);
- fprintf(stdout, " Serial Number\t\t%s\n", g_strs.str_ser);
}
void show_function(usbg_function *f)
{
- const char *instance;
+ char instance[USBG_MAX_STR_LENGTH];
usbg_function_type type;
int usbg_ret;
usbg_function_attrs f_attrs;
- instance = usbg_get_function_instance(f);
- if (!instance) {
- fprintf(stderr, "Unable to get function instance name\n");
- return;
- }
-
+ usbg_get_function_instance(f, instance, USBG_MAX_STR_LENGTH);
type = usbg_get_function_type(f);
usbg_ret = usbg_get_function_attrs(f, &f_attrs);
if (usbg_ret != USBG_SUCCESS) {
@@ -109,90 +86,46 @@ void show_function(usbg_function *f)
fprintf(stdout, " Function, type: %s instance: %s\n",
usbg_get_function_type_str(type), instance);
-
- switch (f_attrs.header.attrs_type) {
- case USBG_F_ATTRS_SERIAL:
+ switch (type) {
+ case F_SERIAL:
+ case F_ACM:
+ case F_OBEX:
fprintf(stdout, " port_num\t\t%d\n",
- f_attrs.attrs.serial.port_num);
+ f_attrs.serial.port_num);
break;
-
- case USBG_F_ATTRS_NET:
- {
- usbg_f_net_attrs *f_net_attrs = &f_attrs.attrs.net;
-
+ case F_ECM:
+ case F_SUBSET:
+ case F_NCM:
+ case F_EEM:
+ case F_RNDIS:
fprintf(stdout, " dev_addr\t\t%s\n",
- ether_ntoa(&f_net_attrs->dev_addr));
+ ether_ntoa(&f_attrs.net.dev_addr));
fprintf(stdout, " host_addr\t\t%s\n",
- ether_ntoa(&f_net_attrs->host_addr));
- fprintf(stdout, " ifname\t\t%s\n", f_net_attrs->ifname);
- fprintf(stdout, " qmult\t\t%d\n", f_net_attrs->qmult);
+ ether_ntoa(&f_attrs.net.host_addr));
+ fprintf(stdout, " ifname\t\t%s\n", f_attrs.net.ifname);
+ fprintf(stdout, " qmult\t\t%d\n", f_attrs.net.qmult);
break;
- }
-
- case USBG_F_ATTRS_PHONET:
- fprintf(stdout, " ifname\t\t%s\n", f_attrs.attrs.phonet.ifname);
+ case F_PHONET:
+ fprintf(stdout, " ifname\t\t%s\n", f_attrs.phonet.ifname);
break;
-
- case USBG_F_ATTRS_FFS:
- fprintf(stdout, " dev_name\t\t%s\n", f_attrs.attrs.ffs.dev_name);
- break;
-
- case USBG_F_ATTRS_MS:
- {
- usbg_f_ms_attrs *attrs = &f_attrs.attrs.ms;
- int i;
-
- fprintf(stdout, " stall\t\t%d\n", attrs->stall);
- fprintf(stdout, " nluns\t\t%d\n", attrs->nluns);
- for (i = 0; i < attrs->nluns; ++i) {
- fprintf(stdout, " lun %d:\n", attrs->luns[i]->id);
- fprintf(stdout, " cdrom\t\t%d\n", attrs->luns[i]->cdrom);
- fprintf(stdout, " ro\t\t%d\n", attrs->luns[i]->ro);
- fprintf(stdout, " nofua\t\t%d\n", attrs->luns[i]->nofua);
- fprintf(stdout, " removable\t\t%d\n", attrs->luns[i]->removable);
- fprintf(stdout, " file\t\t%s\n", attrs->luns[i]->filename);
- }
- break;
- }
-
- case USBG_F_ATTRS_MIDI:
- {
- usbg_f_midi_attrs *attrs = &f_attrs.attrs.midi;
-
- fprintf(stdout, " index\t\t%d\n", attrs->index);
- fprintf(stdout, " id\t\t\t%s\n", attrs->id);
- fprintf(stdout, " in_ports\t\t%d\n", attrs->in_ports);
- fprintf(stdout, " out_ports\t\t%d\n", attrs->out_ports);
- fprintf(stdout, " buflen\t\t%d\n", attrs->buflen);
- fprintf(stdout, " qlen\t\t%d\n", attrs->qlen);
- break;
- }
-
default:
fprintf(stdout, " UNKNOWN\n");
}
-
- usbg_cleanup_function_attrs(&f_attrs);
}
void show_config(usbg_config *c)
{
usbg_binding *b;
usbg_function *f;
- const char *label, *instance, *bname;
+ char buf[USBG_MAX_STR_LENGTH], instance[USBG_MAX_STR_LENGTH];
usbg_function_type type;
usbg_config_attrs c_attrs;
usbg_config_strs c_strs;
int usbg_ret, id;
- label = usbg_get_config_label(c);
- if (!label) {
- fprintf(stderr, "Unable to get config label\n");
- return;
- }
-
+ usbg_get_config_label(c, buf, USBG_MAX_STR_LENGTH);
id = usbg_get_config_id(c);
- fprintf(stdout, " Configuration: '%s' ID: %d\n", label, id);
+ fprintf(stdout, " Configuration: '%s' ID: %d\n", buf, id);
usbg_ret = usbg_get_config_attrs(c, &c_attrs);
if (usbg_ret != USBG_SUCCESS) {
@@ -214,15 +147,11 @@ void show_config(usbg_config *c)
fprintf(stdout, " configuration\t%s\n", c_strs.configuration);
usbg_for_each_binding(b, c) {
- bname = usbg_get_binding_name(b);
+ usbg_get_binding_name(b, buf, USBG_MAX_STR_LENGTH);
f = usbg_get_binding_target(b);
- instance = usbg_get_function_instance(f);
+ usbg_get_function_instance(f, instance, USBG_MAX_STR_LENGTH);
type = usbg_get_function_type(f);
- if (!bname || !instance) {
- fprintf(stderr, "Unable to get binding details\n");
- return;
- }
- fprintf(stdout, " %s -> %s %s\n", bname,
+ fprintf(stdout, " %s -> %s %s\n", buf,
usbg_get_function_type_str(type), instance);
}
}
diff --git a/examples/show-udcs.c b/examples/show-udcs.c
deleted file mode 100644
index 66e950f..0000000
--- a/examples/show-udcs.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2014 Samsung Electronics
- *
- * Krzysztof Opasiak <k.opasiak@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-/**
- * @file show-udcs.c
- * @example show-udcs.c
- * This is an example of how to learn about UDCs available in system
- * and find out what gadget are enabled on them.
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <usbg/usbg.h>
-
-int main(void)
-{
- int usbg_ret;
- int ret = -EINVAL;
- usbg_state *s;
- usbg_gadget *g;
- usbg_udc *u;
- const char *udc_name, *gadget_name;
-
- usbg_ret = usbg_init("/sys/kernel/config", &s);
- if (usbg_ret != USBG_SUCCESS) {
- fprintf(stderr, "Error on USB state init\n");
- fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
- usbg_strerror(usbg_ret));
- goto out;
- }
-
- usbg_for_each_udc(u, s) {
- udc_name = usbg_get_udc_name(u);
- g = usbg_get_udc_gadget(u);
- if (g)
- /* some gadget is enabled */
- gadget_name = usbg_get_gadget_name(g);
- else
- gadget_name = "";
-
- fprintf(stdout, "%s <-> %s\n", udc_name, gadget_name);
- }
-
- ret = 0;
- usbg_cleanup(s);
-out:
- return ret;
-}
diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index bcf221d..1407f10 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -22,20 +22,15 @@
#include <netinet/ether.h>
#include <stdint.h>
#include <limits.h>
-#include <stdbool.h>
-#include <stdio.h> /* For FILE * */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
/**
* @file include/usbg/usbg.h
+ * @todo Add usbg_remove_[gadget|config|function|binding] APIs
* @todo Clean up static buffers in structures
*/
/**
- * @addtogroup libusbgx
+ * @addtogroup libusbg
* Public API for USB gadget-configfs library
* @{
*/
@@ -44,21 +39,9 @@ extern "C" {
#define LANG_US_ENG 0x0409
#define DEFAULT_CONFIG_LABEL "config"
-/* This one has to be at least 18 bytes to hold network address */
#define USBG_MAX_STR_LENGTH 256
#define USBG_MAX_PATH_LENGTH PATH_MAX
#define USBG_MAX_NAME_LENGTH 40
-/* Dev name for ffs is a part of function name, we subtract 4 char for "ffs." */
-#define USBG_MAX_DEV_LENGTH (USBG_MAX_NAME_LENGTH - 4)
-/* ConfigFS just like SysFS uses page size as max size of file content */
-#define USBG_MAX_FILE_SIZE 4096
-
-/**
- * @brief Additional option for usbg_rm_* functions.
- * @details This option allows to remove all content
- * of gadget/config/function recursively.
- */
-#define USBG_RM_RECURSE 1
/*
* Internal structures
@@ -68,7 +51,6 @@ struct usbg_gadget;
struct usbg_config;
struct usbg_function;
struct usbg_binding;
-struct usbg_udc;
/**
* @brief State of the gadget devices in the system
@@ -96,29 +78,6 @@ typedef struct usbg_function usbg_function;
typedef struct usbg_binding usbg_binding;
/**
- * @brief USB device controller
- */
-typedef struct usbg_udc usbg_udc;
-
-/**
- * @typedef usbg_gadget_attr
- * @brief Gadget attributes which can be set using
- * usbg_set_gadget_attr() function.
- */
-typedef enum {
- USBG_GADGET_ATTR_MIN = 0,
- BCD_USB = USBG_GADGET_ATTR_MIN,
- B_DEVICE_CLASS,
- B_DEVICE_SUB_CLASS,
- B_DEVICE_PROTOCOL,
- B_MAX_PACKET_SIZE_0,
- ID_VENDOR,
- ID_PRODUCT,
- BCD_DEVICE,
- USBG_GADGET_ATTR_MAX,
-} usbg_gadget_attr;
-
-/**
* @typedef usbg_gadget_attrs
* @brief USB gadget device attributes
*/
@@ -134,14 +93,6 @@ typedef struct
uint16_t bcdDevice;
} usbg_gadget_attrs;
-typedef enum {
- USBG_GADGET_STR_MIN = 0,
- STR_PRODUCT = USBG_GADGET_STR_MIN,
- STR_MANUFACTURER,
- STR_SERIAL_NUMBER,
- USBG_GADGET_STR_MAX,
-} usbg_gadget_str;
-
/**
* @typedef usbg_gadget_strs
* @brief USB gadget device strings
@@ -178,8 +129,7 @@ typedef struct
*/
typedef enum
{
- USBG_FUNCTION_TYPE_MIN = 0,
- F_SERIAL = USBG_FUNCTION_TYPE_MIN,
+ F_SERIAL,
F_ACM,
F_OBEX,
F_ECM,
@@ -188,11 +138,6 @@ typedef enum
F_EEM,
F_RNDIS,
F_PHONET,
- F_FFS,
- F_MASS_STORAGE,
- F_MIDI,
- F_LOOPBACK,
- USBG_FUNCTION_TYPE_MAX,
} usbg_function_type;
/**
@@ -210,7 +155,7 @@ typedef struct {
typedef struct {
struct ether_addr dev_addr;
struct ether_addr host_addr;
- const char *ifname;
+ char ifname[USBG_MAX_STR_LENGTH];
int qmult;
} usbg_f_net_attrs;
@@ -219,66 +164,10 @@ typedef struct {
* @brief Attributes for the phonet USB function
*/
typedef struct {
- const char *ifname;
+ char ifname[USBG_MAX_STR_LENGTH];
} usbg_f_phonet_attrs;
/**
- * @typedef usbg_f_ffs_attrs
- * @brief Attributes for function fs based functions
- * @details This is read only and a virtual attribute, it is non present
- * on config fs.
- */
-typedef struct {
- const char *dev_name;
-} usbg_f_ffs_attrs;
-
-/**
- * @typedef usbg_f_ms_attrs
- * @brief Attributes for mass storage functions
- */
-typedef struct usbg_f_ms_lun_attrs {
- int id;
- bool cdrom;
- bool ro;
- bool nofua;
- bool removable;
- const char *filename;
-} usbg_f_ms_lun_attrs;
-
-/**
- * @typedef usbg_f_ms_attrs
- * @brief Attributes for mass storage functions
- */
-typedef struct {
- bool stall;
- int nluns;
- usbg_f_ms_lun_attrs **luns;
-} usbg_f_ms_attrs;
-
-/**
- * @typedef usbg_f_midi_attrs
- * @brief Attributes for the MIDI function
- */
-typedef struct {
- int index;
- const char *id;
- unsigned int in_ports;
- unsigned int out_ports;
- unsigned int buflen;
- unsigned int qlen;
-} usbg_f_midi_attrs;
-
-
-/**
- * @typedef usbg_f_loopback_attrs
- * @brief Attributes for Loopback function
- */
-typedef struct {
- unsigned int buflen;
- unsigned int qlen;
-} usbg_f_loopback_attrs;
-
-/**
* @typedef attrs
* @brief Attributes for a given function type
*/
@@ -286,29 +175,6 @@ typedef union {
usbg_f_serial_attrs serial;
usbg_f_net_attrs net;
usbg_f_phonet_attrs phonet;
- usbg_f_ffs_attrs ffs;
- usbg_f_ms_attrs ms;
- usbg_f_midi_attrs midi;
- usbg_f_loopback_attrs loopback;
-} usbg_f_attrs;
-
-typedef enum {
- USBG_F_ATTRS_SERIAL = 1,
- USBG_F_ATTRS_NET,
- USBG_F_ATTRS_PHONET,
- USBG_F_ATTRS_FFS,
- USBG_F_ATTRS_MS,
- USBG_F_ATTRS_MIDI,
- USBG_F_ATTRS_LOOPBACK,
-} usbg_f_attrs_type;
-
-typedef struct {
- int attrs_type;
-} usbg_f_attrs_header;
-
-typedef struct {
- usbg_f_attrs_header header;
- usbg_f_attrs attrs;
} usbg_function_attrs;
/* Error codes */
@@ -329,22 +195,17 @@ typedef enum {
USBG_ERROR_BUSY = -8,
USBG_ERROR_NOT_SUPPORTED = -9,
USBG_ERROR_PATH_TOO_LONG = -10,
- USBG_ERROR_INVALID_FORMAT = -11,
- USBG_ERROR_MISSING_TAG = -12,
- USBG_ERROR_INVALID_TYPE = -13,
- USBG_ERROR_INVALID_VALUE = -14,
- USBG_ERROR_NOT_EMPTY = -15,
USBG_ERROR_OTHER_ERROR = -99
} usbg_error;
-/**
+/*
* @brief Get the error name as a constant string
* @param e error code
* @return Constant string with error name
*/
extern const char *usbg_error_name(usbg_error e);
-/**
+/*
* @brief Get the short description of error
* @param e error code
* @return Constant string with error description
@@ -354,30 +215,20 @@ extern const char *usbg_strerror(usbg_error e);
/* Library init and cleanup */
/**
- * @brief Initialize the libusbgx library state
+ * @brief Initialize the libusbg library state
* @param configfs_path Path to the mounted configfs filesystem
- * @param state Pointer to be filled with pointer to usbg_state
+ * @param Pointer to be filled with pointer to usbg_state
* @return 0 on success, usbg_error on error
*/
-extern int usbg_init(const char *configfs_path, usbg_state **state);
+extern int usbg_init(char *configfs_path, usbg_state **state);
/**
- * @brief Clean up the libusbgx library state
+ * @brief Clean up the libusbg library state
* @param s Pointer to state
*/
extern void usbg_cleanup(usbg_state *s);
/**
- * @brief Get ConfigFS path
- * @param s Pointer to state
- * @return Path to configfs or NULL if error occurred
- * @warning Returned buffer should not be edited!
- * Returned string is valid as long as passed usbg_state is valid.
- * For example path is valid until usbg_cleanup() call.
- */
-extern const char *usbg_get_configfs_path(usbg_state *s);
-
-/**
* @brief Get ConfigFS path length
* @param s Pointer to state
* @return Length of path or usbg_error if error occurred.
@@ -385,13 +236,13 @@ extern const char *usbg_get_configfs_path(usbg_state *s);
extern size_t usbg_get_configfs_path_len(usbg_state *s);
/**
- * @brief Copy ConfigFS path to buffer
+ * @brieg Get ConfigFS path
* @param s Pointer to state
* @param buf Buffer where path should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_cpy_configfs_path(usbg_state *s, char *buf, size_t len);
+extern int usbg_get_configfs_path(usbg_state *s, char *buf, size_t len);
/* USB gadget queries */
@@ -425,67 +276,6 @@ extern usbg_function *usbg_get_function(usbg_gadget *g,
*/
extern usbg_config *usbg_get_config(usbg_gadget *g, int id, const char *label);
-/**
- * @brief Get a udc by name
- * @param s Pointer to state
- * @param name Name of the udc
- * @return Pointer to udc or NULL if a matching udc isn't found
- */
-extern usbg_udc *usbg_get_udc(usbg_state *s, const char *name);
-
-/* USB gadget/config/function/binding removal */
-
-/**
- * @brief Remove binding between configuration and function
- * @details This function frees also the memory allocated for binding
- * @param b Binding to be removed
- * @return 0 on success, usbg_error if error occurred
- */
-extern int usbg_rm_binding(usbg_binding *b);
-
-/**
- * @brief Remove configuration
- * @details This function frees also the memory allocated for configuration
- * @param c Configuration to be removed
- * @param opts Additional options for configuration removal.
- * @return 0 on success, usbg_error if error occurred
- */
-extern int usbg_rm_config(usbg_config *c, int opts);
-
-/**
- * @brief Remove existing USB function
- * @details This function frees also the memory allocated for function
- * @param f Function to be removed
- * @param opts Additional options for configuration removal.
- * @return 0 on success, usbg_error if error occurred
- */
-extern int usbg_rm_function(usbg_function *f, int opts);
-
-/**
- * @brief Remove existing USB gadget
- * @details This function frees also the memory allocated for gadget
- * @param g Gadget to be removed
- * @param opts Additional options for configuration removal.
- * @return 0 on success, usbg_error if error occurred
- */
-extern int usbg_rm_gadget(usbg_gadget *g, int opts);
-
-/**
- * @brief Remove configuration strings for given language
- * @param c Pointer to configuration
- * @param lang Language of strings which should be deleted
- * @return 0 on success, usbg_error if error occurred
- */
-extern int usbg_rm_config_strs(usbg_config *c, int lang);
-
-/**
- * @brief Remove gadget strings for given language
- * @param g Pointer to gadget
- * @param lang Language of strings which should be deleted
- * @return 0 on success, usbg_error if error occurred
- */
-extern int usbg_rm_gadget_strs(usbg_gadget *g, int lang);
-
/* USB gadget allocation and configuration */
/**
@@ -497,7 +287,7 @@ extern int usbg_rm_gadget_strs(usbg_gadget *g, int lang);
* @param g Pointer to be filled with pointer to gadget
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_create_gadget_vid_pid(usbg_state *s, const char *name,
+extern int usbg_create_gadget_vid_pid(usbg_state *s, char *name,
uint16_t idVendor, uint16_t idProduct, usbg_gadget **g);
/**
@@ -511,60 +301,8 @@ extern int usbg_create_gadget_vid_pid(usbg_state *s, const char *name,
* @note Given strings are assumed to be in US English
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_create_gadget(usbg_state *s, const char *name,
- const usbg_gadget_attrs *g_attrs, const usbg_gadget_strs *g_strs,
- usbg_gadget **g);
-
-/**
- * @brief Get string representing selected gadget attribute
- * @param attr code of selected attribute
- * @return String suitable for given attribute or NULL if such
- * string has not been found
- */
-extern const char *usbg_get_gadget_attr_str(usbg_gadget_attr attr);
-
-/**
- * @brief Lookup attr code based on its name
- * @param name of attribute
- * @return code of suitable attribute or usbg_error
- */
-extern int usbg_lookup_gadget_attr(const char *name);
-
-/**
- * @brief Lookup str code based on its name
- * @param name of string
- * @return code of suitable string or usbg_error
- */
-extern int usbg_lookup_gadget_str(const char *name);
-
-/**
- * @brief Get name of selected gadget string
- * @param str Gadget string code
- * @return Name of string associated with this code
- */
-extern const char *usbg_get_gadget_str_name(usbg_gadget_str str);
-
-/**
- * @brief Set selected attribute to value
- * @param g Pointer to gadget
- * @param attr Code of selected attribute
- * @param val value to be set
- * @return 0 on success, usbg_error otherwise
- * @note val is of type int but value provided to this function should
- * be suitable to place it in type dedicated for selected attr (uint16 or uint8)
- */
-extern int usbg_set_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr, int val);
-
-/**
- * @brief Get value of selected attribute
- * @param g Pointer to gadget
- * @param attr Code of selected attribute
- * @return Value of selected attribute (always above zero) or
- * usbg_error if error occurred.
- * @note User should use only lowest one or two bytes as attribute value
- * depending on attribute size (see usbg_gadget_attrs for details).
- */
-extern int usbg_get_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr);
+extern int usbg_create_gadget(usbg_state *s, char *name,
+ usbg_gadget_attrs *g_attrs, usbg_gadget_strs *g_strs, usbg_gadget **g);
/**
* @brief Set the USB gadget attributes
@@ -573,7 +311,7 @@ extern int usbg_get_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr);
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_set_gadget_attrs(usbg_gadget *g,
- const usbg_gadget_attrs *g_attrs);
+ usbg_gadget_attrs *g_attrs);
/**
* @brief Get the USB gadget strings
@@ -584,16 +322,6 @@ extern int usbg_set_gadget_attrs(usbg_gadget *g,
extern int usbg_get_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs);
/**
- * @brief Get gadget name
- * @param g Pointer to gadget
- * @return Gadget name or NULL if error occurred.
- * @warning Returned buffer should not be edited!
- * Returned string is valid as long as passed usbg_gadget is valid.
- * For example gadget name is valid until someone remove gadget.
- */
-extern const char *usbg_get_gadget_name(usbg_gadget *g);
-
-/**
* @brief Get gadget name length
* @param g Gadget which name length should be returned
* @return Length of name string or usbg_error if error occurred.
@@ -601,13 +329,13 @@ extern const char *usbg_get_gadget_name(usbg_gadget *g);
extern size_t usbg_get_gadget_name_len(usbg_gadget *g);
/**
- * @brief Copy gadget name
- * @param g Pointer to gadget
+ * @brieg Get gadget name
+ * @param b Pointer to gadget
* @param buf Buffer where name should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_cpy_gadget_name(usbg_gadget *g, char *buf, size_t len);
+extern int usbg_get_gadget_name(usbg_gadget *g, char *buf, size_t len);
/**
* @brief Set the USB gadget vendor id
@@ -682,31 +410,21 @@ extern int usbg_set_gadget_device_bcd_usb(usbg_gadget *g, uint16_t bcdUSB);
* @brief Get the USB gadget strings
* @param g Pointer to gadget
* @param lang Language of strings
- * @param g_strs Structure to be filled
+ * @param g_sttrs Structure to be filled
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_get_gadget_strs(usbg_gadget *g, int lang,
usbg_gadget_strs *g_strs);
/**
- * @brief Set selected string
- * @param g Pointer to gadget
- * @param str Code of selected string
- * @param val value to be set
- * @return 0 on success, usbg_error otherwise
- */
-extern int usbg_set_gadget_str(usbg_gadget *g, usbg_gadget_str str, int lang,
- const char *val);
-
-/**
* @brief Set the USB gadget strings
* @param g Pointer to gadget
* @param lang USB language ID
- * @param g_strs Gadget attributes
+ * @param g_sttrs Gadget attributes
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_set_gadget_strs(usbg_gadget *g, int lang,
- const usbg_gadget_strs *g_strs);
+ usbg_gadget_strs *g_strs);
/**
* @brief Set the serial number for a gadget
@@ -715,8 +433,7 @@ extern int usbg_set_gadget_strs(usbg_gadget *g, int lang,
* @param ser Serial number
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_set_gadget_serial_number(usbg_gadget *g, int lang,
- const char *ser);
+extern int usbg_set_gadget_serial_number(usbg_gadget *g, int lang, char *ser);
/**
* @brief Set the manufacturer name for a gadget
@@ -725,8 +442,7 @@ extern int usbg_set_gadget_serial_number(usbg_gadget *g, int lang,
* @param mnf Manufacturer
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang,
- const char *mnf);
+extern int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang, char *mnf);
/**
* @brief Set the product name for a gadget
@@ -735,8 +451,7 @@ extern int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang,
* @param prd Product
* @return 0 on success usbg_error if error occurred
*/
-extern int usbg_set_gadget_product(usbg_gadget *g, int lang,
- const char *prd);
+extern int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd);
/* USB function allocation and configuration */
@@ -751,18 +466,7 @@ extern int usbg_set_gadget_product(usbg_gadget *g, int lang,
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_create_function(usbg_gadget *g, usbg_function_type type,
- const char *instance, const usbg_function_attrs *f_attrs,
- usbg_function **f);
-
-/**
- * @brief Get function instance name
- * @param f Pointer to function
- * @return instance name or NULL if error occurred.
- * @warning Returned buffer should not be edited!
- * Returned string is valid as long as passed usbg_function is valid.
- * For example instance name is valid until someone remove this function.
- */
-extern const char *usbg_get_function_instance(usbg_function *f);
+ char *instance, usbg_function_attrs *f_attrs, usbg_function **f);
/**
* @brief Get function instance name length
@@ -772,13 +476,13 @@ extern const char *usbg_get_function_instance(usbg_function *f);
extern size_t usbg_get_function_instance_len(usbg_function *f);
/**
- * @brief Copy function instance name
+ * @brief Get function instance name
* @param f Pointer to function
* @param buf Buffer where instance name should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_cpy_function_instance(usbg_function *f, char *buf, size_t len);
+extern int usbg_get_function_instance(usbg_function *f, char *buf, size_t len);
/**
* @brief Get function type as a string
@@ -787,30 +491,6 @@ extern int usbg_cpy_function_instance(usbg_function *f, char *buf, size_t len);
*/
extern const char *usbg_get_function_type_str(usbg_function_type type);
-/**
- * @brief Lookup function type suitable for given name
- * @param name Name of function
- * @return Function type enum or negative error code
- */
-extern int usbg_lookup_function_type(const char *name);
-
-/**
- * @brief Lookup attrs type for given type of function
- * @param f_type type of functions
- * @return Attributes type for this type of function
- */
-extern int usbg_lookup_function_attrs_type(int f_type);
-
-/**
- * @brief Cleanup content of function attributes
- * @param f_attrs function attributes which should be cleaned up.
- * @note This function should be called to free
- * additional memory allocated by usbg_get_function_attrs().
- * @warning None of attributes in passed structure should be
- * accessed after returning from this function.
- */
-extern void usbg_cleanup_function_attrs(usbg_function_attrs *f_attrs);
-
/* USB configurations allocation and configuration */
/**
@@ -825,18 +505,7 @@ extern void usbg_cleanup_function_attrs(usbg_function_attrs *f_attrs);
* @return 0 on success usbg_error if error occurred
*/
extern int usbg_create_config(usbg_gadget *g, int id, const char *label,
- const usbg_config_attrs *c_attrs, const usbg_config_strs *c_strs,
- usbg_config **c);
-
-/**
- * @brief Get config label
- * @param c Pointer to config
- * @return config label or NULL if error occurred.
- * @warning Returned buffer should not be edited!
- * Returned string is valid as long as passed usbg_config is valid.
- * For example config label is valid until someone remove this function.
- */
-extern const char *usbg_get_config_label(usbg_config *c);
+ usbg_config_attrs *c_attrs, usbg_config_strs *c_strs, usbg_config **c);
/**
* @brief Get config label length
@@ -846,16 +515,16 @@ extern const char *usbg_get_config_label(usbg_config *c);
extern size_t usbg_get_config_label_len(usbg_config *c);
/**
- * @brief Copy config label
+ * @brieg Get config label
* @param c Pointer to config
* @param buf Buffer where label should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_cpy_config_label(usbg_config *c, char *buf, size_t len);
+extern int usbg_get_config_label(usbg_config *c, char *buf, size_t len);
/**
- * @brief Get config id
+ * @brieg Get config id
* @param c Pointer to config
* @return Configuration id or usbg_error if error occurred.
*/
@@ -868,7 +537,7 @@ extern int usbg_get_config_id(usbg_config *c);
* @return 0 on success or usbg_error if error occurred.
*/
extern int usbg_set_config_attrs(usbg_config *c,
- const usbg_config_attrs *c_attrs);
+ usbg_config_attrs *c_attrs);
/**
* @brief Get the USB configuration strings
@@ -898,7 +567,7 @@ extern int usbg_set_config_bm_attrs(usbg_config *c, int bmAttributes);
* @brief Get the USB configuration strings
* @param c Pointer to configuration
* @param lang Language of strings
- * @param c_strs Structure to be filled
+ * @param c_sttrs Structure to be filled
* @return 0 on success or usbg_error if error occurred.
*/
extern int usbg_get_config_strs(usbg_config *c, int lang,
@@ -908,11 +577,11 @@ extern int usbg_get_config_strs(usbg_config *c, int lang,
* @brief Set the USB configuration strings
* @param c Pointer to configuration
* @param lang USB language ID
- * @param c_strs Configuration strings
+ * @param c_sttrs Configuration strings
* @return 0 on success, usbg_error on failure.
*/
extern int usbg_set_config_strs(usbg_config *c, int lang,
- const usbg_config_strs *c_strs);
+ usbg_config_strs *c_strs);
/**
* @brief Set the configuration string
@@ -921,7 +590,7 @@ extern int usbg_set_config_strs(usbg_config *c, int lang,
* @param string Configuration description
* @return 0 on success, usbg_error on failure.
*/
-extern int usbg_set_config_string(usbg_config *c, int lang, const char *string);
+extern int usbg_set_config_string(usbg_config *c, int lang, char *string);
/**
* @brief Add a function to a configuration
@@ -930,8 +599,7 @@ extern int usbg_set_config_string(usbg_config *c, int lang, const char *string);
* @param f Pointer to function
* @return 0 on success, usbg_error on failure.
*/
-extern int usbg_add_config_function(usbg_config *c, const char *name,
- usbg_function *f);
+extern int usbg_add_config_function(usbg_config *c, char *name, usbg_function *f);
/**
* @brief Get target function of given binding
@@ -941,16 +609,6 @@ extern int usbg_add_config_function(usbg_config *c, const char *name,
extern usbg_function *usbg_get_binding_target(usbg_binding *b);
/**
- * @brief Get binding name
- * @param b Pointer to binding
- * @return Binding name or NULL if error occurred.
- * @warning Returned buffer should not be edited!
- * Returned string is valid as long as passed usbg_binding is valid.
- * For example binding name is valid until someone remove this binding.
- */
-extern const char *usbg_get_binding_name(usbg_binding *b);
-
-/**
* @brief Get binding name length
* @param b Binding which name length should be returned
* @return Length of name string or usbg_error if error occurred.
@@ -958,24 +616,30 @@ extern const char *usbg_get_binding_name(usbg_binding *b);
extern size_t usbg_get_binding_name_len(usbg_binding *b);
/**
- * @brief Copy binding name
+ * @brief Get binding name
* @param b Pointer to binding
* @param buf Buffer where name should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_cpy_binding_name(usbg_binding *b, char *buf, size_t len);
+extern int usbg_get_binding_name(usbg_binding *b, char *buf, size_t len);
/* USB gadget setup and teardown */
/**
+ * @brief Get a list of UDC devices on the system
+ * @param udc_list Pointer to pointer to dirent pointer
+ * @return Number of UDC devices on success, usbg_error on failure
+ */
+extern int usbg_get_udcs(struct dirent ***udc_list);
+
+/**
* @brief Enable a USB gadget device
* @param g Pointer to gadget
- * @param udc where gadget should be assigned.
- * If NULL, default one (first) is used.
+ * @param udc Name of UDC to enable gadget
* @return 0 on success or usbg_error if error occurred.
*/
-extern int usbg_enable_gadget(usbg_gadget *g, usbg_udc *udc);
+extern int usbg_enable_gadget(usbg_gadget *g, char *udc);
/**
* @brief Disable a USB gadget device
@@ -985,16 +649,6 @@ extern int usbg_enable_gadget(usbg_gadget *g, usbg_udc *udc);
extern int usbg_disable_gadget(usbg_gadget *g);
/**
- * @brief Get name of udc
- * @param u Pointer to udc
- * @return UDC name or NULL if error occurred.
- * @warning Returned buffer should not be edited!
- * Returned string is valid as long as passed usbg_state is valid.
- * For example UDC name is valid until usbg_cleanup().
- */
-extern const char *usbg_get_udc_name(usbg_udc *u);
-
-/**
* @brief Get gadget name length
* @param g Gadget which name length should be returned
* @return Length of name string or usbg_error if error occurred.
@@ -1003,27 +657,14 @@ extern const char *usbg_get_udc_name(usbg_udc *u);
extern size_t usbg_get_gadget_udc_len(usbg_gadget *g);
/**
- * @brief Copy name of udc
- * @param u Pointer to udc
+ * @brieg Get name of udc to which gadget is binded
+ * @param b Pointer to gadget
* @param buf Buffer where udc name should be copied
* @param len Length of given buffer
* @return 0 on success or usbg_error if error occurred.
+ * @note If gadget isn't enabled on any udc returned string is empty.
*/
-extern int usbg_cpy_udc_name(usbg_udc *u, char *buf, size_t len);
-
-/**
- * @brief Get udc to which gadget is bound
- * @param g Pointer to gadget
- * @return Pointer to UDC or NULL if gadget is not enabled
- */
-extern usbg_udc *usbg_get_gadget_udc(usbg_gadget *g);
-
-/**
- * @brief Get gadget which is attached to this UDC
- * @param u Pointer to udc
- * @return Pointer to gadget or NULL if UDC is free
- */
-extern usbg_gadget *usbg_get_udc_gadget(usbg_udc *u);
+extern int usbg_get_gadget_udc(usbg_gadget *g, char *buf, size_t len);
/*
* USB function-specific attribute configuration
@@ -1052,8 +693,7 @@ extern int usbg_get_function_attrs(usbg_function *f,
* @param f_attrs Attributes to be set
* @return 0 on success, usbg_error if error occurred
*/
-extern int usbg_set_function_attrs(usbg_function *f,
- const usbg_function_attrs *f_attrs);
+extern int usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs);
/**
* @brief Set USB function network device address
@@ -1116,15 +756,6 @@ extern int usbg_set_net_qmult(usbg_function *f, int qmult);
b = usbg_get_next_binding(b))
/**
- * @def usbg_for_each_udc(b, c)
- * Iterates over each udc
- */
-#define usbg_for_each_udc(u, s) \
- for (u = usbg_get_first_udc(s); \
- u != NULL; \
- u = usbg_get_next_udc(u))
-
-/**
* @brief Get first gadget in gadget list
* @param s State of library
* @return Pointer to gadget or NULL if list is empty.
@@ -1150,164 +781,41 @@ extern usbg_config *usbg_get_first_config(usbg_gadget *g);
/**
* @brief Get first binding in binding list
- * @param c Pointer to configuration
+ * @param C Pointer to configuration
* @return Pointer to binding or NULL if list is empty.
* @note Bindings are sorted in strings (name) order
*/
extern usbg_binding *usbg_get_first_binding(usbg_config *c);
/**
- * @brief Get first udc in udc list
- * @param s State of library
- * @return Pointer to udc or NULL if list is empty.
- * @note UDCs are sorted in strings (name) order
- */
-extern usbg_udc *usbg_get_first_udc(usbg_state *s);
-
-/**
* @brief Get the next gadget on a list.
- * @param g Pointer to current gadget
+ * @pram g Pointer to current gadget
* @return Next gadget or NULL if end of list.
*/
extern usbg_gadget *usbg_get_next_gadget(usbg_gadget *g);
/**
* @brief Get the next function on a list.
- * @param f Pointer to current function
+ * @pram g Pointer to current function
* @return Next function or NULL if end of list.
*/
extern usbg_function *usbg_get_next_function(usbg_function *f);
/**
* @brief Get the next config on a list.
- * @param c Pointer to current config
+ * @pram g Pointer to current config
* @return Next config or NULL if end of list.
*/
extern usbg_config *usbg_get_next_config(usbg_config *c);
/**
* @brief Get the next binding on a list.
- * @param b Pointer to current binding
+ * @pram g Pointer to current binding
* @return Next binding or NULL if end of list.
*/
extern usbg_binding *usbg_get_next_binding(usbg_binding *b);
/**
- * @brief Get the next udc on a list.
- * @param u Pointer to current udc
- * @return Next udc or NULL if end of list.
- */
-extern usbg_udc *usbg_get_next_udc(usbg_udc *u);
-
-/* Import / Export API */
-
-/**
- * @brief Exports usb function to file
- * @param f Pointer to function to be exported
- * @param stream where function should be saved
- * @return 0 on success, usbg_error otherwise
- */
-extern int usbg_export_function(usbg_function *f, FILE *stream);
-
-/**
- * @brief Exports configuration to file
- * @param c Pointer to configuration to be exported
- * @param stream where configuration should be saved
- * @return 0 on success, usbg_error otherwise
- */
-extern int usbg_export_config(usbg_config *c, FILE *stream);
-
-/**
- * @brief Exports whole gadget to file
- * @param g Pointer to gadget to be exported
- * @param stream where gadget should be saved
- * @return 0 on success, usbg_error otherwise
- */
-extern int usbg_export_gadget(usbg_gadget *g, FILE *stream);
-
-/**
- * @brief Imports usb function from file and adds it to given gadget
- * @param g Gadget where function should be placed
- * @param stream from which function should be imported
- * @param instance name which should be used for new function
- * @param f place for pointer to imported function
- * if NULL this param will be ignored.
- * @return 0 on success, usbg_error otherwise
- */
-extern int usbg_import_function(usbg_gadget *g, FILE *stream,
- const char *instance, usbg_function **f);
-
-/**
- * @brief Imports usb configuration from file and adds it to given gadget
- * @param g Gadget where configuration should be placed
- * @param stream from which configuration should be imported
- * @param id which should be used for new configuration
- * @param c place for pointer to imported configuration
- * if NULL this param will be ignored.
- * @return 0 on success, usbg_error otherwise
- */
-extern int usbg_import_config(usbg_gadget *g, FILE *stream, int id,
- usbg_config **c);
-/**
- * @brief Imports usb gadget from file
- * @param s current state of library
- * @param stream from which gadget should be imported
- * @param name which should be used for new gadget
- * @param g place for pointer to imported gadget
- * if NULL this param will be ignored.
- * @return 0 on success, usbg_error otherwise
- */
-extern int usbg_import_gadget(usbg_state *s, FILE *stream,
- const char *name, usbg_gadget **g);
-
-/**
- * @brief Get text of error which occurred during last function import
- * @param g gadget where function import error occurred
- * @return Text of error or NULL if no error data
- */
-extern const char *usbg_get_func_import_error_text(usbg_gadget *g);
-
-/**
- * @brief Get line number where function import error occurred
- * @param g gadget where function import error occurred
- * @return line number or value below 0 if no error data
- */
-extern int usbg_get_func_import_error_line(usbg_gadget *g);
-
-/**
- * @brief Get text of error which occurred during last config import
- * @param g gadget where config import error occurred
- * @return Text of error or NULL if no error data
- */
-extern const char *usbg_get_config_import_error_text(usbg_gadget *g);
-
-/**
- * @brief Get line number where config import error occurred
- * @param g gadget where config import error occurred
- * @return line number or value below 0 if no error data
- */
-extern int usbg_get_config_import_error_line(usbg_gadget *g);
-
-/**
- * @brief Get text of error which occurred during last gadget import
- * @param s where gadget import error occurred
- * @return Text of error or NULL if no error data
- */
-extern const char *usbg_get_gadget_import_error_text(usbg_state *s);
-
-/**
- * @brief Get line number where gadget import error occurred
- * @param s where gadget import error occurred
- * @return line number or value below 0 if no error data
- */
-extern int usbg_get_gadget_import_error_line(usbg_state *s);
-
-/**
* @}
*/
-
-#ifdef __cplusplus
-}
-#endif
-
#endif /* __USBG_H__ */
diff --git a/include/usbg/usbg_internal.h b/include/usbg/usbg_internal.h
deleted file mode 100644
index 30d3fcf..0000000
--- a/include/usbg/usbg_internal.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- */
-
-#ifndef USBG_INTERNAL_H
-#define USBG_INTERNAL_H
-
-#include <sys/queue.h>
-#include <string.h>
-#include <usbg/usbg.h>
-
-#ifdef HAS_LIBCONFIG
-#include <libconfig.h>
-#else
- typedef struct _should_not_be_used config_t;
- void config_destroy(config_t *config);
-#endif
-
-/**
- * @file include/usbg/usbg_internal.h
- */
-
-#ifndef offsetof
-#define offsetof(type, member) __builtin_offsetof (type, member)
-#endif /* offsetof */
-
-#ifndef container_of
-#define container_of(ptr, type, field) ({ \
- const typeof(((type *)0)->field) *member = (ptr); \
- (type *)( (char *)member - offsetof(type, field) ); \
- })
-#endif /* container_of */
-
-struct usbg_state
-{
- char *path;
- char *configfs_path;
-
- TAILQ_HEAD(ghead, usbg_gadget) gadgets;
- TAILQ_HEAD(uhead, usbg_udc) udcs;
- config_t *last_failed_import;
-};
-
-struct usbg_gadget
-{
- char *name;
- char *path;
-
- TAILQ_ENTRY(usbg_gadget) gnode;
- TAILQ_HEAD(chead, usbg_config) configs;
- TAILQ_HEAD(fhead, usbg_function) functions;
- usbg_state *parent;
- config_t *last_failed_import;
- usbg_udc *udc;
-};
-
-struct usbg_config
-{
- TAILQ_ENTRY(usbg_config) cnode;
- TAILQ_HEAD(bhead, usbg_binding) bindings;
- usbg_gadget *parent;
-
- char *name;
- char *path;
- char *label;
- int id;
-};
-
-typedef int (*usbg_rm_function_callback)(usbg_function *, int);
-
-struct usbg_function
-{
- TAILQ_ENTRY(usbg_function) fnode;
- usbg_gadget *parent;
-
- char *name;
- char *path;
- char *instance;
- /* Only for internal library usage */
- char *label;
- usbg_function_type type;
- usbg_rm_function_callback rm_callback;
-};
-
-struct usbg_binding
-{
- TAILQ_ENTRY(usbg_binding) bnode;
- usbg_config *parent;
- usbg_function *target;
-
- char *name;
- char *path;
-};
-
-struct usbg_udc
-{
- TAILQ_ENTRY(usbg_udc) unode;
- usbg_state *parent;
- usbg_gadget *gadget;
-
- char *name;
-};
-
-#define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
-
-#define ARRAY_SIZE_SENTINEL(array, size) \
- static void __attribute__ ((unused)) array##_size_sentinel() \
- { \
- char array##_smaller_than_expected[ \
- (int)(ARRAY_SIZE(array) - size)] \
- __attribute__ ((unused)); \
- \
- char array##_larger_than_expected[ \
- (int)(size - ARRAY_SIZE(array))] \
- __attribute__ ((unused)); \
- }
-
-#define ERROR(msg, ...) do {\
- fprintf(stderr, "%s() "msg" \n", \
- __func__, ##__VA_ARGS__);\
- fflush(stderr);\
- } while (0)
-
-#define ERRORNO(msg, ...) do {\
- fprintf(stderr, "%s() %s: "msg" \n", \
- __func__, strerror(errno), ##__VA_ARGS__);\
- fflush(stderr);\
- } while (0)
-
-/* Insert in string order */
-#define INSERT_TAILQ_STRING_ORDER(HeadPtr, HeadType, NameField, ToInsert, NodeField) \
- do { \
- if (TAILQ_EMPTY((HeadPtr)) || \
- (strcmp((ToInsert)->NameField, TAILQ_FIRST((HeadPtr))->NameField) < 0)) \
- TAILQ_INSERT_HEAD((HeadPtr), (ToInsert), NodeField); \
- else if (strcmp((ToInsert)->NameField, TAILQ_LAST((HeadPtr), HeadType)->NameField) > 0) \
- TAILQ_INSERT_TAIL((HeadPtr), (ToInsert), NodeField); \
- else { \
- typeof(ToInsert) _cur; \
- TAILQ_FOREACH(_cur, (HeadPtr), NodeField) { \
- if (strcmp((ToInsert)->NameField, _cur->NameField) > 0) \
- continue; \
- TAILQ_INSERT_BEFORE(_cur, (ToInsert), NodeField); \
- } \
- } \
- } while (0)
-
-#define STRINGS_DIR "strings"
-#define CONFIGS_DIR "configs"
-#define FUNCTIONS_DIR "functions"
-#define GADGETS_DIR "usb_gadget"
-
-static inline int file_select(const struct dirent *dent)
-{
- if ((strcmp(dent->d_name, ".") == 0) || (strcmp(dent->d_name, "..") == 0))
- return 0;
- else
- return 1;
-}
-
-int usbg_translate_error(int error);
-
-char *usbg_ether_ntoa_r(const struct ether_addr *addr, char *buf);
-
-#endif /* USBG_INTERNAL_H */
-
diff --git a/libusbgx.pc.in b/libusbg.pc.in
index 8ea8fb5..46eb245 100644
--- a/libusbgx.pc.in
+++ b/libusbg.pc.in
@@ -3,9 +3,9 @@ exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-Name: libusbgx
+Name: libusbg
Description: USB gadget-configfs library
-Requires: libconfig
+Requires:
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lusbg
Cflags: -I${includedir}
diff --git a/src/Makefile.am b/src/Makefile.am
index b1eb951..d955a4c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,11 +1,4 @@
-lib_LTLIBRARIES = libusbgx.la
-libusbgx_la_SOURCES = usbg.c
-if TEST_GADGET_SCHEMES
-libusbgx_la_SOURCES += usbg_schemes_libconfig.c
-else
-libusbgx_la_SOURCES += usbg_schemes_none.c
-endif
-libusbgx_la_LDFLAGS = $(LIBCONFIG_LIBS)
-libusbgx_la_LDFLAGS += -version-info 0:0:0
-libusbgx_la_CFLAGS = $(LIBCONFIG_CFLAGS)
-AM_CPPFLAGS=-I$(top_srcdir)/include/
+lib_LTLIBRARIES = libusbg.la
+libusbg_la_SOURCES = usbg.c
+libusbg_la_LDFLAGS = -version-info 0:1:0
+AM_CPPFLAGS=-I../include/
diff --git a/src/usbg.c b/src/usbg.c
index b9c53e8..d73943c 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -16,7 +16,7 @@
#include <dirent.h>
#include <errno.h>
-
+#include <usbg/usbg.h>
#include <netinet/ether.h>
#include <stdio.h>
#include <stdlib.h>
@@ -26,13 +26,68 @@
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
-#include <stdbool.h>
-#include "usbg/usbg_internal.h"
+
+#define STRINGS_DIR "strings"
+#define CONFIGS_DIR "configs"
+#define FUNCTIONS_DIR "functions"
/**
* @file usbg.c
+ * @todo Handle buffer overflows
*/
+struct usbg_state
+{
+ char *path;
+
+ TAILQ_HEAD(ghead, usbg_gadget) gadgets;
+};
+
+struct usbg_gadget
+{
+ char *name;
+ char *path;
+ char udc[USBG_MAX_STR_LENGTH];
+
+ TAILQ_ENTRY(usbg_gadget) gnode;
+ TAILQ_HEAD(chead, usbg_config) configs;
+ TAILQ_HEAD(fhead, usbg_function) functions;
+ usbg_state *parent;
+};
+
+struct usbg_config
+{
+ TAILQ_ENTRY(usbg_config) cnode;
+ TAILQ_HEAD(bhead, usbg_binding) bindings;
+ usbg_gadget *parent;
+
+ char *name;
+ char *path;
+ char *label;
+ int id;
+};
+
+struct usbg_function
+{
+ TAILQ_ENTRY(usbg_function) fnode;
+ usbg_gadget *parent;
+
+ char *name;
+ char *path;
+ char *instance;
+
+ usbg_function_type type;
+};
+
+struct usbg_binding
+{
+ TAILQ_ENTRY(usbg_binding) bnode;
+ usbg_config *parent;
+ usbg_function *target;
+
+ char *name;
+ char *path;
+};
/**
* @var function_names
@@ -49,38 +104,39 @@ const char *function_names[] =
"eem",
"rndis",
"phonet",
- "ffs",
- "mass_storage",
- "midi",
- "Loopback",
-};
-
-ARRAY_SIZE_SENTINEL(function_names, USBG_FUNCTION_TYPE_MAX);
-
-const char *gadget_attr_names[] =
-{
- "bcdUSB",
- "bDeviceClass",
- "bDeviceSubClass",
- "bDeviceProtocol",
- "bMaxPacketSize0",
- "idVendor",
- "idProduct",
- "bcdDevice"
-};
-
-ARRAY_SIZE_SENTINEL(gadget_attr_names, USBG_GADGET_ATTR_MAX);
-
-const char *gadget_str_names[] =
-{
- "product",
- "manufacturer",
- "serialnumber",
};
-ARRAY_SIZE_SENTINEL(gadget_str_names, USBG_GADGET_STR_MAX);
-
-int usbg_translate_error(int error)
+#define ERROR(msg, ...) do {\
+ fprintf(stderr, "%s() "msg" \n", \
+ __func__, ##__VA_ARGS__);\
+ fflush(stderr);\
+ } while (0)
+
+#define ERRORNO(msg, ...) do {\
+ fprintf(stderr, "%s() %s: "msg" \n", \
+ __func__, strerror(errno), ##__VA_ARGS__);\
+ fflush(stderr);\
+ } while (0)
+
+/* Insert in string order */
+#define INSERT_TAILQ_STRING_ORDER(HeadPtr, HeadType, NameField, ToInsert, NodeField) \
+ do { \
+ if (TAILQ_EMPTY((HeadPtr)) || \
+ (strcmp((ToInsert)->NameField, TAILQ_FIRST((HeadPtr))->NameField) < 0)) \
+ TAILQ_INSERT_HEAD((HeadPtr), (ToInsert), NodeField); \
+ else if (strcmp((ToInsert)->NameField, TAILQ_LAST((HeadPtr), HeadType)->NameField) > 0) \
+ TAILQ_INSERT_TAIL((HeadPtr), (ToInsert), NodeField); \
+ else { \
+ typeof(ToInsert) _cur; \
+ TAILQ_FOREACH(_cur, (HeadPtr), NodeField) { \
+ if (strcmp((ToInsert)->NameField, _cur->NameField) > 0) \
+ continue; \
+ TAILQ_INSERT_BEFORE(_cur, (ToInsert), NodeField); \
+ } \
+ } \
+ } while (0)
+
+static int usbg_translate_error(int error)
{
int ret;
@@ -90,14 +146,12 @@ int usbg_translate_error(int error)
break;
case EACCES:
case EROFS:
- case EPERM:
ret = USBG_ERROR_NO_ACCESS;
break;
case ENOENT:
case ENOTDIR:
ret = USBG_ERROR_NOT_FOUND;
break;
- case ERANGE:
case EINVAL:
case USBG_ERROR_INVALID_PARAM:
ret = USBG_ERROR_INVALID_PARAM;
@@ -114,9 +168,6 @@ int usbg_translate_error(int error)
case EBUSY:
ret = USBG_ERROR_BUSY;
break;
- case ENOTEMPTY:
- ret = USBG_ERROR_NOT_EMPTY;
- break;
default:
ret = USBG_ERROR_OTHER_ERROR;
}
@@ -162,21 +213,6 @@ const char *usbg_error_name(usbg_error e)
case USBG_ERROR_PATH_TOO_LONG:
ret = "USBG_ERROR_PATH_TOO_LONG";
break;
- case USBG_ERROR_INVALID_FORMAT:
- ret = "USBG_ERROR_INVALID_FORMAT";
- break;
- case USBG_ERROR_MISSING_TAG:
- ret = "USBG_ERROR_MISSING_TAG";
- break;
- case USBG_ERROR_INVALID_TYPE:
- ret = "USBG_ERROR_INVALID_TYPE";
- break;
- case USBG_ERROR_INVALID_VALUE:
- ret = "USBG_ERROR_INVALID_VALUE";
- break;
- case USBG_ERROR_NOT_EMPTY:
- ret = "USBG_ERROR_NOT_EMPTY";
- break;
case USBG_ERROR_OTHER_ERROR:
ret = "USBG_ERROR_OTHER_ERROR";
break;
@@ -223,21 +259,6 @@ const char *usbg_strerror(usbg_error e)
case USBG_ERROR_PATH_TOO_LONG:
ret = "Created path was too long to process it.";
break;
- case USBG_ERROR_INVALID_FORMAT:
- ret = "Given file has incompatible format.";
- break;
- case USBG_ERROR_MISSING_TAG:
- ret = "One of mandatory tags is missing.";
- break;
- case USBG_ERROR_INVALID_TYPE:
- ret = "One of attributes has incompatible type.";
- break;
- case USBG_ERROR_INVALID_VALUE:
- ret = "Incorrect value provided as attribute.";
- break;
- case USBG_ERROR_NOT_EMPTY:
- ret = "Entity is not empty.";
- break;
case USBG_ERROR_OTHER_ERROR:
ret = "Other error";
break;
@@ -246,112 +267,30 @@ const char *usbg_strerror(usbg_error e)
return ret;
}
-int usbg_lookup_function_attrs_type(int f_type)
-{
- int ret;
-
- switch (f_type) {
- case F_SERIAL:
- case F_ACM:
- case F_OBEX:
- ret = USBG_F_ATTRS_SERIAL;
- break;
- case F_ECM:
- case F_SUBSET:
- case F_NCM:
- case F_EEM:
- case F_RNDIS:
- ret = USBG_F_ATTRS_NET;
- break;
- case F_PHONET:
- ret = USBG_F_ATTRS_PHONET;
- break;
- case F_FFS:
- ret = USBG_F_ATTRS_FFS;
- break;
- case F_MASS_STORAGE:
- ret = USBG_F_ATTRS_MS;
- break;
- case F_MIDI:
- ret = USBG_F_ATTRS_MIDI;
- break;
- case F_LOOPBACK:
- ret = USBG_F_ATTRS_LOOPBACK;
- break;
- default:
- ret = USBG_ERROR_NOT_SUPPORTED;
- }
-
- return ret;
-}
-
-int usbg_lookup_function_type(const char *name)
+static int usbg_lookup_function_type(char *name)
{
- int i = USBG_FUNCTION_TYPE_MIN;
+ int i = 0;
+ int max = sizeof(function_names)/sizeof(char *);
if (!name)
- return USBG_ERROR_INVALID_PARAM;
+ return -1;
do {
if (!strcmp(name, function_names[i]))
- return i;
- i++;
- } while (i != USBG_FUNCTION_TYPE_MAX);
-
- return USBG_ERROR_NOT_FOUND;
-}
-
-const char *usbg_get_function_type_str(usbg_function_type type)
-{
- return type >= USBG_FUNCTION_TYPE_MIN &&
- type < USBG_FUNCTION_TYPE_MAX ?
- function_names[type] : NULL;
-}
-
-int usbg_lookup_gadget_attr(const char *name)
-{
- int i = USBG_GADGET_ATTR_MIN;
-
- if (!name)
- return USBG_ERROR_INVALID_PARAM;
-
- do {
- if (!strcmp(name, gadget_attr_names[i]))
- return i;
- i++;
- } while (i != USBG_GADGET_ATTR_MAX);
-
- return USBG_ERROR_NOT_FOUND;
-}
-
-int usbg_lookup_gadget_str(const char *name)
-{
- int i = USBG_GADGET_STR_MIN;
-
- if (!name)
- return USBG_ERROR_INVALID_PARAM;
-
- do {
- if (!strcmp(name, gadget_str_names[i]))
- return i;
+ break;
i++;
- } while (i != USBG_GADGET_STR_MAX);
+ } while (i != max);
- return USBG_ERROR_NOT_FOUND;
-}
+ if (i == max)
+ i = -1;
-const char *usbg_get_gadget_attr_str(usbg_gadget_attr attr)
-{
- return attr >= USBG_GADGET_ATTR_MIN &&
- attr < USBG_GADGET_ATTR_MAX ?
- gadget_attr_names[attr] : NULL;
+ return i;
}
-const char *usbg_get_gadget_str_name(usbg_gadget_str str)
+const const char *usbg_get_function_type_str(usbg_function_type type)
{
- return str >= USBG_GADGET_STR_MIN &&
- str < USBG_GADGET_STR_MAX ?
- gadget_str_names[str] : NULL;
+ return type > 0 && type < sizeof(function_names)/sizeof(char *) ?
+ function_names[type] : NULL;
}
static usbg_error usbg_split_function_instance_type(const char *full_name,
@@ -429,46 +368,45 @@ static int bindings_select(const struct dirent *dent)
return 0;
}
-static int usbg_read_buf(const char *path, const char *name, const char *file,
- char *buf)
+static int file_select(const struct dirent *dent)
+{
+ if ((strcmp(dent->d_name, ".") == 0) || (strcmp(dent->d_name, "..") == 0))
+ return 0;
+ else
+ return 1;
+}
+
+static int usbg_read_buf(char *path, char *name, char *file, char *buf)
{
char p[USBG_MAX_PATH_LENGTH];
FILE *fp;
- char *ret_ptr;
int nmb;
int ret = USBG_SUCCESS;
nmb = snprintf(p, sizeof(p), "%s/%s/%s", path, name, file);
- if (nmb >= sizeof(p)) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto out;
- }
-
- fp = fopen(p, "r");
- if (!fp) {
- /* Set error correctly */
- ret = usbg_translate_error(errno);
- goto out;
- }
+ if (nmb < sizeof(p)) {
+ fp = fopen(p, "r");
+ if (fp) {
+ /* Successfully opened */
+ if (!fgets(buf, USBG_MAX_STR_LENGTH, fp)) {
+ ERROR("read error");
+ ret = USBG_ERROR_IO;
+ }
- ret_ptr = fgets(buf, USBG_MAX_STR_LENGTH, fp);
- if (!ret_ptr) {
- /* File is empty */
- if (feof(fp))
- buf[0] = '\0';
- /* Error occurred */
- else
- ret = USBG_ERROR_IO;
+ fclose(fp);
+ } else {
+ /* Set error correctly */
+ ret = usbg_translate_error(errno);
+ }
+ } else {
+ ret = USBG_ERROR_PATH_TOO_LONG;
}
- fclose(fp);
-
-out:
return ret;
}
-static int usbg_read_int(const char *path, const char *name, const char *file,
- int base, int *dest)
+static int usbg_read_int(char *path, char *name, char *file, int base,
+ int *dest)
{
char buf[USBG_MAX_STR_LENGTH];
char *pos;
@@ -487,23 +425,7 @@ static int usbg_read_int(const char *path, const char *name, const char *file,
#define usbg_read_dec(p, n, f, d) usbg_read_int(p, n, f, 10, d)
#define usbg_read_hex(p, n, f, d) usbg_read_int(p, n, f, 16, d)
-static int usbg_read_bool(const char *path, const char *name, const char *file,
- bool *dest)
-{
- int buf;
- int ret;
-
- ret = usbg_read_dec(path, name, file, &buf);
- if (ret != USBG_SUCCESS)
- goto out;
-
- *dest = !!buf;
-out:
- return ret;
-}
-
-static int usbg_read_string(const char *path, const char *name,
- const char *file, char *buf)
+static int usbg_read_string(char *path, char *name, char *file, char *buf)
{
char *p = NULL;
int ret;
@@ -521,30 +443,7 @@ static int usbg_read_string(const char *path, const char *name,
return ret;
}
-static int usbg_read_string_alloc(const char *path, const char *name,
- const char *file, const char **dest)
-{
- char buf[USBG_MAX_FILE_SIZE];
- char *new_buf = NULL;
- int ret = USBG_SUCCESS;
-
- ret = usbg_read_string(path, name, file, buf);
- if (ret != USBG_SUCCESS)
- goto out;
-
- new_buf = strdup(buf);
- if (!new_buf) {
- ret = USBG_ERROR_NO_MEM;
- goto out;
- }
-
- *dest = new_buf;
-out:
- return ret;
-}
-
-static int usbg_write_buf(const char *path, const char *name, const char *file,
- const char *buf)
+static int usbg_write_buf(char *path, char *name, char *file, char *buf)
{
char p[USBG_MAX_PATH_LENGTH];
FILE *fp;
@@ -574,8 +473,8 @@ static int usbg_write_buf(const char *path, const char *name, const char *file,
return ret;
}
-static int usbg_write_int(const char *path, const char *name, const char *file,
- int value, const char *str)
+static int usbg_write_int(char *path, char *name, char *file, int value,
+ char *str)
{
char buf[USBG_MAX_STR_LENGTH];
int nmb;
@@ -587,13 +486,11 @@ static int usbg_write_int(const char *path, const char *name, const char *file,
}
#define usbg_write_dec(p, n, f, v) usbg_write_int(p, n, f, v, "%d\n")
-#define usbg_write_hex(p, n, f, v) usbg_write_int(p, n, f, v, "0x%x\n")
#define usbg_write_hex16(p, n, f, v) usbg_write_int(p, n, f, v, "0x%04x\n")
#define usbg_write_hex8(p, n, f, v) usbg_write_int(p, n, f, v, "0x%02x\n")
-#define usbg_write_bool(p, n, f, v) usbg_write_dec(p, n, f, !!v)
-static inline int usbg_write_string(const char *path, const char *name,
- const char *file, const char *buf)
+static inline int usbg_write_string(char *path, char *name, char *file,
+ char *buf)
{
return usbg_write_buf(path, name, file, buf);
}
@@ -609,7 +506,6 @@ static inline void usbg_free_function(usbg_function *f)
{
free(f->path);
free(f->name);
- free(f->label);
free(f);
}
@@ -631,12 +527,6 @@ static void usbg_free_gadget(usbg_gadget *g)
{
usbg_config *c;
usbg_function *f;
-
- if (g->last_failed_import) {
- config_destroy(g->last_failed_import);
- free(g->last_failed_import);
- }
-
while (!TAILQ_EMPTY(&g->configs)) {
c = TAILQ_FIRST(&g->configs);
TAILQ_REMOVE(&g->configs, c, cnode);
@@ -652,41 +542,20 @@ static void usbg_free_gadget(usbg_gadget *g)
free(g);
}
-static void usbg_free_udc(usbg_udc *u)
-{
- free(u->name);
- free(u);
-}
-
static void usbg_free_state(usbg_state *s)
{
usbg_gadget *g;
- usbg_udc *u;
-
while (!TAILQ_EMPTY(&s->gadgets)) {
g = TAILQ_FIRST(&s->gadgets);
TAILQ_REMOVE(&s->gadgets, g, gnode);
usbg_free_gadget(g);
}
-
- while (!TAILQ_EMPTY(&s->udcs)) {
- u = TAILQ_FIRST(&s->udcs);
- TAILQ_REMOVE(&s->udcs, u, unode);
- usbg_free_udc(u);
- }
-
- if (s->last_failed_import) {
- config_destroy(s->last_failed_import);
- free(s->last_failed_import);
- }
-
free(s->path);
- free(s->configfs_path);
free(s);
}
-static usbg_gadget *usbg_allocate_gadget(const char *path, const char *name,
+static usbg_gadget *usbg_allocate_gadget(char *path, char *name,
usbg_state *parent)
{
usbg_gadget *g;
@@ -695,11 +564,9 @@ static usbg_gadget *usbg_allocate_gadget(const char *path, const char *name,
if (g) {
TAILQ_INIT(&g->functions);
TAILQ_INIT(&g->configs);
- g->last_failed_import = NULL;
g->name = strdup(name);
g->path = strdup(path);
g->parent = parent;
- g->udc = NULL;
if (!(g->name) || !(g->path)) {
free(g->name);
@@ -748,8 +615,6 @@ out:
return c;
}
-static int usbg_rm_ms_function(usbg_function *f, int opts);
-
static usbg_function *usbg_allocate_function(const char *path,
usbg_function_type type, const char *instance, usbg_gadget *parent)
{
@@ -761,7 +626,6 @@ static usbg_function *usbg_allocate_function(const char *path,
if (!f)
goto out;
- f->label = NULL;
type_name = usbg_get_function_type_str(type);
if (!type_name) {
free(f);
@@ -780,16 +644,6 @@ static usbg_function *usbg_allocate_function(const char *path,
f->parent = parent;
f->type = type;
- /* only composed functions (with subdirs) require this callback */
- switch (usbg_lookup_function_attrs_type(type)) {
- case USBG_F_ATTRS_MS:
- f->rm_callback = usbg_rm_ms_function;
- break;
- default:
- f->rm_callback = NULL;
- break;
- }
-
if (!(f->path)) {
free(f->name);
free(f->path);
@@ -801,7 +655,7 @@ out:
return f;
}
-static usbg_binding *usbg_allocate_binding(const char *path, const char *name,
+static usbg_binding *usbg_allocate_binding(char *path, char *name,
usbg_config *parent)
{
usbg_binding *b;
@@ -823,108 +677,20 @@ static usbg_binding *usbg_allocate_binding(const char *path, const char *name,
return b;
}
-static usbg_udc *usbg_allocate_udc(usbg_state *parent, const char *name)
-{
- usbg_udc *u;
-
- u = malloc(sizeof(*u));
- if (!u)
- goto out;
-
- u->gadget = NULL;
- u->parent = parent;
- u->name = strdup(name);
- if (!u->name) {
- free(u);
- u = NULL;
- }
-
- out:
- return u;
-}
-
-static int ubsg_rm_file(const char *path, const char *name)
-{
- int ret = USBG_SUCCESS;
- int nmb;
- char buf[USBG_MAX_PATH_LENGTH];
-
- nmb = snprintf(buf, sizeof(buf), "%s/%s", path, name);
- if (nmb < sizeof(buf)) {
- nmb = unlink(buf);
- if (nmb != 0)
- ret = usbg_translate_error(errno);
- } else {
- ret = USBG_ERROR_PATH_TOO_LONG;
- }
-
- return ret;
-}
-
-static int usbg_rm_dir(const char *path, const char *name)
-{
- int ret = USBG_SUCCESS;
- int nmb;
- char buf[USBG_MAX_PATH_LENGTH];
-
- nmb = snprintf(buf, sizeof(buf), "%s/%s", path, name);
- if (nmb < sizeof(buf)) {
- nmb = rmdir(buf);
- if (nmb != 0)
- ret = usbg_translate_error(errno);
- } else {
- ret = USBG_ERROR_PATH_TOO_LONG;
- }
-
- return ret;
-}
-
-static int usbg_rm_all_dirs(const char *path)
-{
- int ret = USBG_SUCCESS;
- int n, i;
- struct dirent **dent;
-
- n = scandir(path, &dent, file_select, alphasort);
- if (n >= 0) {
- for (i = 0; i < n; ++i) {
- if (ret == USBG_SUCCESS)
- ret = usbg_rm_dir(path, dent[i]->d_name);
-
- free(dent[i]);
- }
- free(dent);
- } else {
- ret = usbg_translate_error(errno);
- }
-
- return ret;
-}
-
-char *usbg_ether_ntoa_r(const struct ether_addr *addr, char *buf)
-{
- sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
- addr->ether_addr_octet[0], addr->ether_addr_octet[1],
- addr->ether_addr_octet[2], addr->ether_addr_octet[3],
- addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
- return buf;
-}
-
static int usbg_parse_function_net_attrs(usbg_function *f,
- usbg_f_net_attrs *f_net_attrs)
+ usbg_function_attrs *f_attrs)
{
struct ether_addr *addr;
- struct ether_addr addr_buf;
- char str_addr[USBG_MAX_STR_LENGTH];
+ char str_addr[40];
int ret;
ret = usbg_read_string(f->path, f->name, "dev_addr", str_addr);
if (ret != USBG_SUCCESS)
goto out;
- addr = ether_aton_r(str_addr, &addr_buf);
+ addr = ether_aton(str_addr);
if (addr) {
- f_net_attrs->dev_addr = *addr;
+ f_attrs->net.dev_addr = *addr;
} else {
ret = USBG_ERROR_IO;
goto out;
@@ -934,215 +700,19 @@ static int usbg_parse_function_net_attrs(usbg_function *f,
if (ret != USBG_SUCCESS)
goto out;
- addr = ether_aton_r(str_addr, &addr_buf);
+ addr = ether_aton(str_addr);
if (addr) {
- f_net_attrs->host_addr = *addr;
+ f_attrs->net.host_addr = *addr;
} else {
ret = USBG_ERROR_IO;
goto out;
}
- ret = usbg_read_dec(f->path, f->name, "qmult", &(f_net_attrs->qmult));
+ ret = usbg_read_string(f->path, f->name, "ifname", f_attrs->net.ifname);
if (ret != USBG_SUCCESS)
goto out;
- ret = usbg_read_string_alloc(f->path, f->name, "ifname",
- &(f_net_attrs->ifname));
-out:
- return ret;
-}
-
-static int usbg_parse_function_ms_lun_attrs(const char *path, const char *lun,
- usbg_f_ms_lun_attrs *lun_attrs)
-{
- int ret;
-
- memset(lun_attrs, 0, sizeof(*lun_attrs));
-
- ret = sscanf(lun, "lun.%d", &lun_attrs->id);
- if (ret != 1)
- goto out;
-
- ret = usbg_read_bool(path, lun, "cdrom", &(lun_attrs->cdrom));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_bool(path, lun, "ro", &(lun_attrs->ro));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_bool(path, lun, "nofua", &(lun_attrs->nofua));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_bool(path, lun, "removable", &(lun_attrs->removable));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_string_alloc(path, lun, "file",
- &(lun_attrs->filename));
-
-out:
- return ret;
-}
-
-static inline int lun_select(const struct dirent *dent)
-{
- int ret;
- int id;
-
- ret = file_select(dent);
- if (!ret)
- goto out;
-
- ret = sscanf(dent->d_name, "lun.%d", &id);
-out:
- return ret;
-}
-
-static inline int lun_sort(const struct dirent **d1, const struct dirent **d2)
-{
- int ret;
- int id1, id2;
-
- ret = sscanf((*d1)->d_name, "lun.%d", &id1);
- if (ret != 1)
- goto err;
-
- ret = sscanf((*d2)->d_name, "lun.%d", &id2);
- if (ret != 1)
- goto err;
-
- if (id1 < id2)
- ret = 1;
-
- return id1 < id2 ? -1 : id1 > id2;
-err:
- /*
- * This should not happened because dentries has been
- * already checked by lun_select function. This
- * error procedure is just in case.
- */
- return -1;
-}
-
-static int usbg_parse_function_ms_attrs(usbg_function *f,
- usbg_f_ms_attrs *f_ms_attrs)
-{
- int ret;
- int nmb;
- int i = 0;
- char fpath[USBG_MAX_PATH_LENGTH];
- usbg_f_ms_lun_attrs *lun_attrs;
- usbg_f_ms_lun_attrs **luns;
- struct dirent **dent;
-
- ret = usbg_read_bool(f->path, f->name, "stall",
- &(f_ms_attrs->stall));
- if (ret != USBG_SUCCESS)
- goto out;
-
-
- nmb = snprintf(fpath, sizeof(fpath), "%s/%s/",
- f->path, f->name);
- if (nmb >= sizeof(fpath)) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto out;
- }
-
- nmb = scandir(fpath, &dent, lun_select, lun_sort);
- if (nmb < 0) {
- ret = usbg_translate_error(errno);
- goto out;
- }
-
- luns = calloc(nmb + 1, sizeof(*luns));
- if (!luns) {
- ret = USBG_ERROR_NO_MEM;
- goto err;
- }
-
- f_ms_attrs->luns = luns;
- f_ms_attrs->nluns = nmb;
-
- for (i = 0; i < nmb; i++) {
- lun_attrs = malloc(sizeof(*lun_attrs));
- if (!lun_attrs) {
- ret = USBG_ERROR_NO_MEM;
- goto err;
- }
-
- ret = usbg_parse_function_ms_lun_attrs(fpath, dent[i]->d_name,
- lun_attrs);
- if (ret != USBG_SUCCESS) {
- free(lun_attrs);
- goto err;
- }
-
- luns[i] = lun_attrs;
- free(dent[i]);
- }
- free(dent);
-
- return USBG_SUCCESS;
-
-err:
- while (i < nmb) {
- free(dent[i]);
- ++i;
- }
- free(dent);
-
- usbg_cleanup_function_attrs(
- container_of((usbg_f_attrs *)f_ms_attrs,
- usbg_function_attrs, attrs));
-out:
- return ret;
-}
-
-static int usbg_parse_function_midi_attrs(usbg_function *f,
- usbg_f_midi_attrs *attrs)
-{
- int ret;
-
- ret = usbg_read_dec(f->path, f->name, "index", &(attrs->index));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_string_alloc(f->path, f->name, "id", &(attrs->id));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_dec(f->path, f->name, "in_ports", (int*)&(attrs->in_ports));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_dec(f->path, f->name, "out_ports", (int*)&(attrs->out_ports));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_dec(f->path, f->name, "buflen", (int*)&(attrs->buflen));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_dec(f->path, f->name, "qlen", (int*)&(attrs->qlen));
- if (ret != USBG_SUCCESS)
- goto out;
-
-out:
- return ret;
-}
-
-static int usbg_parse_function_loopback_attrs(usbg_function *f,
- usbg_f_loopback_attrs *attrs)
-{
- int ret;
-
- ret = usbg_read_dec(f->path, f->name, "buflen", (int *)&(attrs->buflen));
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_read_dec(f->path, f->name, "qlen", (int *)&(attrs->qlen));
+ ret = usbg_read_dec(f->path, f->name, "qmult", &(f_attrs->net.qmult));
out:
return ret;
@@ -1152,70 +722,34 @@ static int usbg_parse_function_attrs(usbg_function *f,
usbg_function_attrs *f_attrs)
{
int ret;
- int attrs_type;
-
- attrs_type = usbg_lookup_function_attrs_type(f->type);
- if (attrs_type < 0) {
- ret = attrs_type;
- goto out;
- }
- switch (attrs_type) {
- case USBG_F_ATTRS_SERIAL:
- f_attrs->header.attrs_type = USBG_F_ATTRS_SERIAL;
+ switch (f->type) {
+ case F_SERIAL:
+ case F_ACM:
+ case F_OBEX:
ret = usbg_read_dec(f->path, f->name, "port_num",
- &(f_attrs->attrs.serial.port_num));
- break;
-
- case USBG_F_ATTRS_NET:
- f_attrs->header.attrs_type = USBG_F_ATTRS_NET;
- ret = usbg_parse_function_net_attrs(f, &(f_attrs->attrs.net));
+ &(f_attrs->serial.port_num));
break;
-
- case USBG_F_ATTRS_PHONET:
- f_attrs->header.attrs_type = USBG_F_ATTRS_PHONET;
- ret = usbg_read_string_alloc(f->path, f->name, "ifname",
- &(f_attrs->attrs.phonet.ifname));
- break;
-
- case USBG_F_ATTRS_FFS:
- {
- usbg_f_ffs_attrs *ffs_attrs = &(f_attrs->attrs.ffs);
-
- f_attrs->header.attrs_type = USBG_F_ATTRS_FFS;
- ffs_attrs->dev_name = strdup(f->instance);
- if (!ffs_attrs->dev_name)
- ret = USBG_ERROR_NO_MEM;
- else
- ret = USBG_SUCCESS;
- break;
- }
-
- case USBG_F_ATTRS_MS:
- f_attrs->header.attrs_type = USBG_F_ATTRS_MS;
- ret = usbg_parse_function_ms_attrs(f, &(f_attrs->attrs.ms));
- break;
-
- case USBG_F_ATTRS_MIDI:
- f_attrs->header.attrs_type = USBG_F_ATTRS_MIDI;
- ret = usbg_parse_function_midi_attrs(f, &(f_attrs->attrs.midi));
+ case F_ECM:
+ case F_SUBSET:
+ case F_NCM:
+ case F_EEM:
+ case F_RNDIS:
+ ret = usbg_parse_function_net_attrs(f, f_attrs);
break;
-
- case USBG_F_ATTRS_LOOPBACK:
- f_attrs->header.attrs_type = USBG_F_ATTRS_LOOPBACK;
- ret = usbg_parse_function_loopback_attrs(f, &(f_attrs->attrs.loopback));
+ case F_PHONET:
+ ret = usbg_read_string(f->path, f->name, "ifname",
+ f_attrs->phonet.ifname);
break;
-
default:
ERROR("Unsupported function type\n");
ret = USBG_ERROR_NOT_SUPPORTED;
- break;
}
-out:
+
return ret;
}
-static int usbg_parse_functions(const char *path, usbg_gadget *g)
+static int usbg_parse_functions(char *path, usbg_gadget *g)
{
usbg_function *f;
int i, n;
@@ -1260,7 +794,7 @@ out:
return ret;
}
-static int usbg_parse_config_attrs(const char *path, const char *name,
+static int usbg_parse_config_attrs(char *path, char *name,
usbg_config_attrs *c_attrs)
{
int buf, ret;
@@ -1277,7 +811,7 @@ static int usbg_parse_config_attrs(const char *path, const char *name,
return ret;
}
-static int usbg_parse_config_strs(const char *path, const char *name,
+static int usbg_parse_config_strs(char *path, char *name,
int lang, usbg_config_strs *c_strs)
{
DIR *dir;
@@ -1304,7 +838,8 @@ static int usbg_parse_config_strs(const char *path, const char *name,
return ret;
}
-static int usbg_parse_config_binding(usbg_config *c, char *bpath, int path_size)
+static int usbg_parse_config_binding(usbg_config *c, char *bpath,
+ int path_size)
{
int nmb;
int ret;
@@ -1315,7 +850,7 @@ static int usbg_parse_config_binding(usbg_config *c, char *bpath, int path_size)
usbg_function *f;
usbg_binding *b;
- nmb = readlink(bpath, target, sizeof(target) - 1 );
+ nmb = readlink(bpath, target, sizeof(target));
if (nmb < 0) {
ret = usbg_translate_error(errno);
goto out;
@@ -1418,7 +953,7 @@ out:
return ret;
}
-static int usbg_parse_configs(const char *path, usbg_gadget *g)
+static int usbg_parse_configs(char *path, usbg_gadget *g)
{
int i, n;
int ret = USBG_SUCCESS;
@@ -1450,7 +985,7 @@ out:
return ret;
}
-static int usbg_parse_gadget_attrs(const char *path, const char *name,
+static int usbg_parse_gadget_attrs(char *path, char *name,
usbg_gadget_attrs *g_attrs)
{
int buf, ret;
@@ -1463,6 +998,12 @@ static int usbg_parse_gadget_attrs(const char *path, const char *name,
else
goto out;
+ ret = usbg_read_hex(path, name, "bcdDevice", &buf);
+ if (ret == USBG_SUCCESS)
+ g_attrs->bcdDevice = (uint16_t) buf;
+ else
+ goto out;
+
ret = usbg_read_hex(path, name, "bDeviceClass", &buf);
if (ret == USBG_SUCCESS)
g_attrs->bDeviceClass = (uint8_t)buf;
@@ -1499,17 +1040,11 @@ static int usbg_parse_gadget_attrs(const char *path, const char *name,
else
goto out;
- ret = usbg_read_hex(path, name, "bcdDevice", &buf);
- if (ret == USBG_SUCCESS)
- g_attrs->bcdDevice = (uint16_t) buf;
- else
- goto out;
-
out:
return ret;
}
-static int usbg_parse_gadget_strs(const char *path, const char *name, int lang,
+static int usbg_parse_gadget_strs(char *path, char *name, int lang,
usbg_gadget_strs *g_strs)
{
int ret;
@@ -1550,17 +1085,12 @@ out:
static inline int usbg_parse_gadget(usbg_gadget *g)
{
int ret;
- char buf[USBG_MAX_STR_LENGTH];
/* UDC bound to, if any */
- ret = usbg_read_string(g->path, g->name, "UDC", buf);
+ ret = usbg_read_string(g->path, g->name, "UDC", g->udc);
if (ret != USBG_SUCCESS)
goto out;
- g->udc = usbg_get_udc(g->parent, buf);
- if (g->udc)
- g->udc->gadget = g;
-
ret = usbg_parse_functions(g->path, g);
if (ret != USBG_SUCCESS)
goto out;
@@ -1570,7 +1100,7 @@ out:
return ret;
}
-static int usbg_parse_gadgets(const char *path, usbg_state *s)
+static int usbg_parse_gadgets(char *path, usbg_state *s)
{
usbg_gadget *g;
int i, n;
@@ -1605,86 +1135,18 @@ static int usbg_parse_gadgets(const char *path, usbg_state *s)
return ret;
}
-static int usbg_parse_udcs(usbg_state *s)
+static int usbg_init_state(char *path, usbg_state *s)
{
- usbg_udc *u;
- int n, i;
int ret = USBG_SUCCESS;
- struct dirent **dent;
-
- n = scandir("/sys/class/udc", &dent, file_select, alphasort);
- if (n < 0) {
- ret = usbg_translate_error(errno);
- goto out;
- }
-
- for (i = 0; i < n; ++i) {
- if (ret == USBG_SUCCESS) {
- u = usbg_allocate_udc(s, dent[i]->d_name);
- if (u)
- TAILQ_INSERT_TAIL(&s->udcs, u, unode);
- else
- ret = USBG_ERROR_NO_MEM;
- }
-
- free(dent[i]);
- }
- free(dent);
-
-out:
- return ret;
-}
-
-static usbg_state *usbg_allocate_state(const char *configfs_path, char *path)
-{
- usbg_state *s;
-
- s = malloc(sizeof(*s));
- if (!s)
- goto err;
-
- s->configfs_path = strdup(configfs_path);
- if (!s->configfs_path)
- goto cpath_failed;
/* State takes the ownership of path and should free it */
s->path = path;
- s->last_failed_import = NULL;
TAILQ_INIT(&s->gadgets);
- TAILQ_INIT(&s->udcs);
-
- return s;
-cpath_failed:
- free(s);
-err:
- return NULL;
-}
-
-static int usbg_parse_state(usbg_state *s)
-{
- int ret = USBG_SUCCESS;
-
- /*
- * USBG_ERROR_NOT_FOUND is returned if we are running on machine where
- * there is no udc support in kernel (no /sys/class/udc dir).
- * This check allows to run library on such machine or if we don't
- * have rights to read this directory.
- * User will be able to finish init function and manage gadgets but
- * wont be able to bind it as there is no UDC.
- */
- ret = usbg_parse_udcs(s);
- if (ret != USBG_SUCCESS && ret != USBG_ERROR_NOT_FOUND &&
- ret != USBG_ERROR_NO_ACCESS) {
- ERROR("Unable to parse udcs");
- goto out;
- }
-
- ret = usbg_parse_gadgets(s->path, s);
+ ret = usbg_parse_gadgets(path, s);
if (ret != USBG_SUCCESS)
- ERROR("unable to parse %s\n", s->path);
+ ERRORNO("unable to parse %s\n", path);
-out:
return ret;
}
@@ -1692,14 +1154,13 @@ out:
* User API
*/
-int usbg_init(const char *configfs_path, usbg_state **state)
+int usbg_init(char *configfs_path, usbg_state **state)
{
int ret = USBG_SUCCESS;
DIR *dir;
char *path;
- usbg_state *s;
- ret = asprintf(&path, "%s/" GADGETS_DIR, configfs_path);
+ ret = asprintf(&path, "%s/usb_gadget", configfs_path);
if (ret < 0)
return USBG_ERROR_NO_MEM;
else
@@ -1707,33 +1168,21 @@ int usbg_init(const char *configfs_path, usbg_state **state)
/* Check if directory exist */
dir = opendir(path);
- if (!dir) {
+ if (dir) {
+ closedir(dir);
+ *state = malloc(sizeof(usbg_state));
+ ret = *state ? usbg_init_state(path, *state)
+ : USBG_ERROR_NO_MEM;
+ if (*state && ret != USBG_SUCCESS) {
+ ERRORNO("couldn't init gadget state\n");
+ usbg_free_state(*state);
+ }
+ } else {
ERRORNO("couldn't init gadget state\n");
ret = usbg_translate_error(errno);
- goto err;
+ free(path);
}
- closedir(dir);
- s = usbg_allocate_state(configfs_path, path);
- if (!s) {
- ret = USBG_ERROR_NO_MEM;
- goto err;
- }
-
- ret = usbg_parse_state(s);
- if (ret != USBG_SUCCESS) {
- ERROR("couldn't init gadget state\n");
- usbg_free_state(s);
- goto out;
- }
-
- *state = s;
-
- return ret;
-
-err:
- free(path);
-out:
return ret;
}
@@ -1742,25 +1191,20 @@ void usbg_cleanup(usbg_state *s)
usbg_free_state(s);
}
-const char *usbg_get_configfs_path(usbg_state *s)
-{
- return s ? s->configfs_path : NULL;
-}
-
size_t usbg_get_configfs_path_len(usbg_state *s)
{
- return s ? strlen(s->configfs_path) : USBG_ERROR_INVALID_PARAM;
+ return s ? strlen(s->path) : USBG_ERROR_INVALID_PARAM;
}
-int usbg_cpy_configfs_path(usbg_state *s, char *buf, size_t len)
+int usbg_get_configfs_path(usbg_state *s, char *buf, size_t len)
{
- if (!s || !buf || len == 0)
- return USBG_ERROR_INVALID_PARAM;
-
- buf[--len] = '\0';
- strncpy(buf, s->configfs_path, len);
+ int ret = USBG_SUCCESS;
+ if (s && buf)
+ strncpy(buf, s->path, len);
+ else
+ ret = USBG_ERROR_INVALID_PARAM;
- return USBG_SUCCESS;
+ return ret;
}
usbg_gadget *usbg_get_gadget(usbg_state *s, const char *name)
@@ -1797,17 +1241,6 @@ usbg_config *usbg_get_config(usbg_gadget *g, int id, const char *label)
return c;
}
-usbg_udc *usbg_get_udc(usbg_state *s, const char *name)
-{
- usbg_udc *u;
-
- TAILQ_FOREACH(u, &s->udcs, unode)
- if (!strcmp(u->name, name))
- return u;
-
- return NULL;
-}
-
usbg_binding *usbg_get_binding(usbg_config *c, const char *name)
{
usbg_binding *b;
@@ -1830,259 +1263,10 @@ usbg_binding *usbg_get_link_binding(usbg_config *c, usbg_function *f)
return NULL;
}
-int usbg_rm_binding(usbg_binding *b)
-{
- int ret = USBG_SUCCESS;
- usbg_config *c;
-
- if (!b)
- return USBG_ERROR_INVALID_PARAM;
-
- c = b->parent;
-
- ret = ubsg_rm_file(b->path, b->name);
- if (ret == USBG_SUCCESS) {
- TAILQ_REMOVE(&(c->bindings), b, bnode);
- usbg_free_binding(b);
- }
-
- return ret;
-}
-
-int usbg_rm_config(usbg_config *c, int opts)
-{
- int ret = USBG_ERROR_INVALID_PARAM;
- usbg_gadget *g;
-
- if (!c)
- return ret;
-
- g = c->parent;
-
- if (opts & USBG_RM_RECURSE) {
- /* Recursive flag was given
- * so remove all bindings and strings */
- char spath[USBG_MAX_PATH_LENGTH];
- int nmb;
- usbg_binding *b;
-
- while (!TAILQ_EMPTY(&c->bindings)) {
- b = TAILQ_FIRST(&c->bindings);
- ret = usbg_rm_binding(b);
- if (ret != USBG_SUCCESS)
- goto out;
- }
-
- nmb = snprintf(spath, sizeof(spath), "%s/%s/%s", c->path,
- c->name, STRINGS_DIR);
- if (nmb >= sizeof(spath)) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto out;
- }
-
- ret = usbg_rm_all_dirs(spath);
- if (ret != USBG_SUCCESS)
- goto out;
- }
-
- ret = usbg_rm_dir(c->path, c->name);
- if (ret == USBG_SUCCESS) {
- TAILQ_REMOVE(&(g->configs), c, cnode);
- usbg_free_config(c);
- }
-
-out:
- return ret;
-}
-
-static int usbg_rm_ms_function(usbg_function *f, int opts)
-{
- int ret;
- int nmb;
- int i;
- char lpath[USBG_MAX_PATH_LENGTH];
- struct dirent **dent;
-
- ret = snprintf(lpath, sizeof(lpath), "%s/%s/", f->path, f->name);
- if (ret >= sizeof(lpath)) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto out;
- }
-
- nmb = scandir(lpath, &dent, lun_select, lun_sort);
- if (nmb < 0) {
- ret = usbg_translate_error(errno);
- goto out;
- }
-
- for (i = nmb - 1; i > 0; --i) {
- ret = usbg_rm_dir(lpath, dent[i]->d_name);
- free(dent[i]);
- if (ret)
- goto err_free_dent_loop;
- }
- free(dent[0]);
- free(dent);
-
- return USBG_SUCCESS;
-
-err_free_dent_loop:
- while (--i >= 0)
- free(dent[i]);
- free(dent[i]);
-out:
- return ret;
-}
-
-int usbg_rm_function(usbg_function *f, int opts)
-{
- int ret = USBG_ERROR_INVALID_PARAM;
- usbg_gadget *g;
-
- if (!f)
- return ret;
-
- g = f->parent;
-
- if (opts & USBG_RM_RECURSE) {
- /* Recursive flag was given
- * so remove all bindings to this function */
- usbg_config *c;
- usbg_binding *b;
-
- TAILQ_FOREACH(c, &g->configs, cnode) {
- b = TAILQ_FIRST(&c->bindings);
- while (b != NULL) {
- if (b->target == f) {
- usbg_binding *b_next = TAILQ_NEXT(b, bnode);
- ret = usbg_rm_binding(b);
- if (ret != USBG_SUCCESS)
- return ret;
-
- b = b_next;
- } else {
- b = TAILQ_NEXT(b, bnode);
- }
- } /* while */
- } /* TAILQ_FOREACH */
- }
-
- if (f->rm_callback) {
- ret = f->rm_callback(f, opts);
- if (ret != USBG_SUCCESS)
- goto out;
- }
-
- ret = usbg_rm_dir(f->path, f->name);
- if (ret == USBG_SUCCESS) {
- TAILQ_REMOVE(&(g->functions), f, fnode);
- usbg_free_function(f);
- }
-
-out:
- return ret;
-}
-
-int usbg_rm_gadget(usbg_gadget *g, int opts)
-{
- int ret = USBG_ERROR_INVALID_PARAM;
- usbg_state *s;
- if (!g)
- goto out;
-
- s = g->parent;
-
- if (opts & USBG_RM_RECURSE) {
- /* Recursive flag was given
- * so remove all configs and functions
- * using recursive flags */
- usbg_config *c;
- usbg_function *f;
- int nmb;
- char spath[USBG_MAX_PATH_LENGTH];
-
- while (!TAILQ_EMPTY(&g->configs)) {
- c = TAILQ_FIRST(&g->configs);
- ret = usbg_rm_config(c, opts);
- if (ret != USBG_SUCCESS)
- goto out;
- }
-
- while (!TAILQ_EMPTY(&g->functions)) {
- f = TAILQ_FIRST(&g->functions);
- ret = usbg_rm_function(f, opts);
- if (ret != USBG_SUCCESS)
- goto out;
- }
-
- nmb = snprintf(spath, sizeof(spath), "%s/%s/%s", g->path,
- g->name, STRINGS_DIR);
- if (nmb >= sizeof(spath)) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto out;
- }
-
- ret = usbg_rm_all_dirs(spath);
- if (ret != USBG_SUCCESS)
- goto out;
- }
-
- ret = usbg_rm_dir(g->path, g->name);
- if (ret == USBG_SUCCESS) {
- TAILQ_REMOVE(&(s->gadgets), g, gnode);
- usbg_free_gadget(g);
- }
-
-out:
- return ret;
-}
-
-int usbg_rm_config_strs(usbg_config *c, int lang)
-{
- int ret = USBG_SUCCESS;
- int nmb;
- char path[USBG_MAX_PATH_LENGTH];
-
- if (!c)
- return USBG_ERROR_INVALID_PARAM;
-
- nmb = snprintf(path, sizeof(path), "%s/%s/%s/0x%x", c->path, c->name,
- STRINGS_DIR, lang);
- if (nmb < sizeof(path))
- ret = usbg_rm_dir(path, "");
- else
- ret = USBG_ERROR_PATH_TOO_LONG;
-
- return ret;
-}
-
-int usbg_rm_gadget_strs(usbg_gadget *g, int lang)
-{
- int ret = USBG_SUCCESS;
- int nmb;
- char path[USBG_MAX_PATH_LENGTH];
-
- if (!g)
- return USBG_ERROR_INVALID_PARAM;
-
- nmb = snprintf(path, sizeof(path), "%s/%s/%s/0x%x", g->path, g->name,
- STRINGS_DIR, lang);
- if (nmb < sizeof(path))
- ret = usbg_rm_dir(path, "");
- else
- ret = USBG_ERROR_PATH_TOO_LONG;
-
- return ret;
-}
-
-
-static int usbg_create_empty_gadget(usbg_state *s, const char *name,
- usbg_gadget **g)
+static int usbg_create_empty_gadget(usbg_state *s, char *name, usbg_gadget **g)
{
char gpath[USBG_MAX_PATH_LENGTH];
- char buf[USBG_MAX_STR_LENGTH];
int nmb;
- usbg_gadget *gad;
int ret = USBG_SUCCESS;
nmb = snprintf(gpath, sizeof(gpath), "%s/%s", s->path, name);
@@ -2092,39 +1276,33 @@ static int usbg_create_empty_gadget(usbg_state *s, const char *name,
}
*g = usbg_allocate_gadget(s->path, name, s);
- if (!*g) {
- ret = USBG_ERROR_NO_MEM;
- goto out;
- }
-
- gad = *g; /* alias only */
+ if (*g) {
+ usbg_gadget *gad = *g; /* alias only */
+
+ ret = mkdir(gpath, S_IRWXU|S_IRWXG|S_IRWXO);
+ if (ret == 0) {
+ /* Should be empty but read the default */
+ ret = usbg_read_string(gad->path, gad->name, "UDC",
+ gad->udc);
+ if (ret != USBG_SUCCESS)
+ rmdir(gpath);
+ } else {
+ ret = usbg_translate_error(errno);
+ }
- ret = mkdir(gpath, S_IRWXU|S_IRWXG|S_IRWXO);
- if (ret == 0) {
- /* Should be empty but read the default */
- ret = usbg_read_string(gad->path, gad->name,
- "UDC", buf);
if (ret != USBG_SUCCESS) {
- rmdir(gpath);
- } else {
- gad->udc = usbg_get_udc(s, buf);
- if (gad->udc)
- gad->udc->gadget = gad;
+ usbg_free_gadget(*g);
+ *g = NULL;
}
} else {
- ret = usbg_translate_error(errno);
- }
-
- if (ret != USBG_SUCCESS) {
- usbg_free_gadget(*g);
- *g = NULL;
+ ret = USBG_ERROR_NO_MEM;
}
out:
return ret;
}
-int usbg_create_gadget_vid_pid(usbg_state *s, const char *name,
+int usbg_create_gadget_vid_pid(usbg_state *s, char *name,
uint16_t idVendor, uint16_t idProduct, usbg_gadget **g)
{
int ret;
@@ -2158,9 +1336,8 @@ int usbg_create_gadget_vid_pid(usbg_state *s, const char *name,
return ret;
}
-int usbg_create_gadget(usbg_state *s, const char *name,
- const usbg_gadget_attrs *g_attrs, const usbg_gadget_strs *g_strs,
- usbg_gadget **g)
+int usbg_create_gadget(usbg_state *s, char *name,
+ usbg_gadget_attrs *g_attrs, usbg_gadget_strs *g_strs, usbg_gadget **g)
{
usbg_gadget *gad;
int ret;
@@ -2200,147 +1377,39 @@ int usbg_get_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs)
: USBG_ERROR_INVALID_PARAM;
}
-const char *usbg_get_gadget_name(usbg_gadget *g)
-{
- return g ? g->name : NULL;
-}
-
size_t usbg_get_gadget_name_len(usbg_gadget *g)
{
return g ? strlen(g->name) : USBG_ERROR_INVALID_PARAM;
}
-int usbg_cpy_gadget_name(usbg_gadget *g, char *buf, size_t len)
-{
- if (!g || !buf || len == 0)
- return USBG_ERROR_INVALID_PARAM;
-
- buf[--len] = '\0';
- strncpy(buf, g->name, len);
-
- return USBG_SUCCESS;
-}
-
-const char *usbg_get_udc_name(usbg_udc *u)
-{
- return u ? u->name : NULL;
-}
-
-size_t usbg_get_udc_name_len(usbg_udc *u)
-{
- return u ? strlen(u->name) : USBG_ERROR_INVALID_PARAM;
-}
-
-int usbg_cpy_udc_name(usbg_udc *u, char *buf, size_t len)
-{
- if (!u || !buf || len == 0)
- return USBG_ERROR_INVALID_PARAM;
-
- buf[--len] = '\0';
- strncpy(buf, u->name, len);
-
- return USBG_SUCCESS;
-}
-
-int usbg_set_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr, int val)
-{
- const char *attr_name;
- int ret = USBG_ERROR_INVALID_PARAM;
-
- if (!g)
- goto out;
-
- attr_name = usbg_get_gadget_attr_str(attr);
- if (!attr_name)
- goto out;
-
- ret = usbg_write_hex(g->path, g->name, attr_name, val);
-
-out:
- return ret;
-}
-
-int usbg_get_gadget_attr(usbg_gadget *g, usbg_gadget_attr attr)
+int usbg_get_gadget_name(usbg_gadget *g, char *buf, size_t len)
{
- const char *attr_name;
- int ret = USBG_ERROR_INVALID_PARAM;
-
- if (!g)
- goto out;
-
- attr_name = usbg_get_gadget_attr_str(attr);
- if (!attr_name)
- goto out;
-
- usbg_read_hex(g->path, g->name, attr_name, &ret);
+ int ret = USBG_SUCCESS;
+ if (g && buf)
+ strncpy(buf, g->name, len);
+ else
+ ret = USBG_ERROR_INVALID_PARAM;
-out:
return ret;
}
-usbg_udc *usbg_get_gadget_udc(usbg_gadget *g)
+size_t usbg_get_gadget_udc_len(usbg_gadget *g)
{
- usbg_udc *u = NULL;
-
- if (!g)
- goto out;
- /*
- * if gadget was enabled we have to check if kernel
- * didn't modify the UDC file due to some errors.
- * For example some FFS daemon could just get
- * a segmentation fault or sth
- */
- if (g->udc) {
- char buf[USBG_MAX_STR_LENGTH];
- int ret;
-
- ret = usbg_read_string(g->path, g->name, "UDC", buf);
- if (ret != USBG_SUCCESS)
- goto out;
-
- if (!strcmp(g->udc->name, buf)) {
- /* Gadget is still assigned to this UDC */
- u = g->udc;
- } else {
- /* Kernel decided to detach this gadget */
- g->udc->gadget = NULL;
- g->udc = NULL;
- }
- }
-
-out:
- return u;
+ return g ? strlen(g->udc) : USBG_ERROR_INVALID_PARAM;
}
-usbg_gadget *usbg_get_udc_gadget(usbg_udc *u)
+int usbg_get_gadget_udc(usbg_gadget *g, char *buf, size_t len)
{
- usbg_gadget *g = NULL;
-
- if (!u)
- goto out;
- /*
- * if gadget was enabled on this UDC we have to check if kernel
- * didn't modify this due to some errors.
- * For example some FFS daemon could just get a segmentation fault
- * what causes detach of gadget
- */
- if (u->gadget) {
- usbg_udc *u_checked;
-
- u_checked = usbg_get_gadget_udc(u->gadget);
- if (u_checked) {
- g = u->gadget;
- } else {
- u->gadget->udc = NULL;
- u->gadget = NULL;
- }
- }
+ int ret = USBG_SUCCESS;
+ if (g && buf)
+ strncpy(buf, g->udc, len);
+ else
+ ret = USBG_ERROR_INVALID_PARAM;
-out:
- return g;
+ return ret;
}
-int usbg_set_gadget_attrs(usbg_gadget *g, const usbg_gadget_attrs *g_attrs)
+int usbg_set_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs)
{
int ret;
if (!g || !g_attrs)
@@ -2442,7 +1511,7 @@ int usbg_get_gadget_strs(usbg_gadget *g, int lang,
g_strs) : USBG_ERROR_INVALID_PARAM;
}
-static int usbg_check_dir(const char *path)
+static int usbg_check_dir(char *path)
{
int ret = USBG_SUCCESS;
DIR *dir;
@@ -2457,40 +1526,8 @@ static int usbg_check_dir(const char *path)
return ret;
}
-int usbg_set_gadget_str(usbg_gadget *g, usbg_gadget_str str, int lang,
- const char *val)
-{
- const char *str_name;
- int ret = USBG_ERROR_INVALID_PARAM;
- char path[USBG_MAX_PATH_LENGTH];
- int nmb;
-
- if (!g)
- goto out;
-
- str_name = usbg_get_gadget_str_name(str);
- if (!str_name)
- goto out;
-
- nmb = snprintf(path, sizeof(path), "%s/%s/%s/0x%x", g->path, g->name,
- STRINGS_DIR, lang);
- if (nmb >= sizeof(path)) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto out;
- }
-
- ret = usbg_check_dir(path);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_string(path, "", str_name, val);
-
-out:
- return ret;
-}
-
int usbg_set_gadget_strs(usbg_gadget *g, int lang,
- const usbg_gadget_strs *g_strs)
+ usbg_gadget_strs *g_strs)
{
char path[USBG_MAX_PATH_LENGTH];
int nmb;
@@ -2523,7 +1560,7 @@ out:
return ret;
}
-int usbg_set_gadget_serial_number(usbg_gadget *g, int lang, const char *serno)
+int usbg_set_gadget_serial_number(usbg_gadget *g, int lang, char *serno)
{
int ret = USBG_ERROR_INVALID_PARAM;
@@ -2544,7 +1581,7 @@ int usbg_set_gadget_serial_number(usbg_gadget *g, int lang, const char *serno)
return ret;
}
-int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang, const char *mnf)
+int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang, char *mnf)
{
int ret = USBG_ERROR_INVALID_PARAM;
@@ -2565,7 +1602,7 @@ int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang, const char *mnf)
return ret;
}
-int usbg_set_gadget_product(usbg_gadget *g, int lang, const char *prd)
+int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd)
{
int ret = USBG_ERROR_INVALID_PARAM;
@@ -2587,36 +1624,16 @@ int usbg_set_gadget_product(usbg_gadget *g, int lang, const char *prd)
}
int usbg_create_function(usbg_gadget *g, usbg_function_type type,
- const char *instance, const usbg_function_attrs *f_attrs,
- usbg_function **f)
+ char *instance, usbg_function_attrs *f_attrs, usbg_function **f)
{
char fpath[USBG_MAX_PATH_LENGTH];
usbg_function *func;
int ret = USBG_ERROR_INVALID_PARAM;
int n, free_space;
- if (!g || !f)
+ if (!g || !f || !instance)
return ret;
- /* if attrs type is set, check if it has correct type */
- if (f_attrs && f_attrs->header.attrs_type) {
- int attrs_type;
- attrs_type = usbg_lookup_function_attrs_type(type);
- if (attrs_type < 0 || attrs_type != f_attrs->header.attrs_type)
- return ret;
- }
-
- if (!instance) {
- /* If someone creates ffs function and doesn't pass instance name
- this means that device name from attrs should be used */
- if (type == F_FFS && f_attrs && f_attrs->attrs.ffs.dev_name) {
- instance = f_attrs->attrs.ffs.dev_name;
- f_attrs = NULL;
- } else {
- return ret;
- }
- }
-
func = usbg_get_function(g, type, instance);
if (func) {
ERROR("duplicate function name\n");
@@ -2634,9 +1651,8 @@ int usbg_create_function(usbg_gadget *g, usbg_function_type type,
*f = usbg_allocate_function(fpath, type, instance, g);
func = *f;
if (!func) {
- ERROR("allocating function\n");
+ ERRORNO("allocating function\n");
ret = USBG_ERROR_NO_MEM;
- goto out;
}
free_space = sizeof(fpath) - n;
@@ -2664,11 +1680,10 @@ out:
}
int usbg_create_config(usbg_gadget *g, int id, const char *label,
- const usbg_config_attrs *c_attrs, const usbg_config_strs *c_strs,
- usbg_config **c)
+ usbg_config_attrs *c_attrs, usbg_config_strs *c_strs, usbg_config **c)
{
char cpath[USBG_MAX_PATH_LENGTH];
- usbg_config *conf = NULL;
+ usbg_config *conf;
int ret = USBG_ERROR_INVALID_PARAM;
int n, free_space;
@@ -2695,7 +1710,7 @@ int usbg_create_config(usbg_gadget *g, int id, const char *label,
*c = usbg_allocate_config(cpath, label, id, g);
conf = *c;
if (!conf) {
- ERROR("allocating configuration\n");
+ ERRORNO("allocating configuration\n");
ret = USBG_ERROR_NO_MEM;
goto out;
}
@@ -2703,10 +1718,8 @@ int usbg_create_config(usbg_gadget *g, int id, const char *label,
free_space = sizeof(cpath) - n;
/* Append string at the end of previous one */
n = snprintf(&(cpath[n]), free_space, "/%s", (*c)->name);
- if (n >= free_space) {
+ if (n < free_space) {
ret = USBG_ERROR_PATH_TOO_LONG;
- usbg_free_config(conf);
- goto out;
}
ret = mkdir(cpath, S_IRWXU | S_IRWXG | S_IRWXO);
@@ -2732,25 +1745,20 @@ out:
return ret;
}
-const char *usbg_get_config_label(usbg_config *c)
-{
- return c ? c->label : NULL;
-}
-
size_t usbg_get_config_label_len(usbg_config *c)
{
return c ? strlen(c->label) : USBG_ERROR_INVALID_PARAM;
}
-int usbg_cpy_config_label(usbg_config *c, char *buf, size_t len)
+int usbg_get_config_label(usbg_config *c, char *buf, size_t len)
{
- if (!c || !buf || len == 0)
- return USBG_ERROR_INVALID_PARAM;
-
- buf[--len] = '\0';
- strncpy(buf, c->label, len);
+ int ret = USBG_SUCCESS;
+ if (c && buf)
+ strncpy(buf, c->label, len);
+ else
+ ret = USBG_ERROR_INVALID_PARAM;
- return USBG_SUCCESS;
+ return ret;
}
int usbg_get_config_id(usbg_config *c)
@@ -2758,32 +1766,27 @@ int usbg_get_config_id(usbg_config *c)
return c ? c->id : USBG_ERROR_INVALID_PARAM;
}
-const char *usbg_get_function_instance(usbg_function *f)
-{
- return f ? f->instance : NULL;
-}
-
size_t usbg_get_function_instance_len(usbg_function *f)
{
return f ? strlen(f->instance) : USBG_ERROR_INVALID_PARAM;
}
-int usbg_cpy_function_instance(usbg_function *f, char *buf, size_t len)
+int usbg_get_function_instance(usbg_function *f, char *buf, size_t len)
{
- if (!f || !buf || len == 0)
- return USBG_ERROR_INVALID_PARAM;
-
- buf[--len] = '\0';
- strncpy(buf, f->instance, len);
+ int ret = USBG_SUCCESS;
+ if (f && buf)
+ strncpy(buf, f->instance, len);
+ else
+ ret = USBG_ERROR_INVALID_PARAM;
- return USBG_SUCCESS;
+ return ret;
}
-int usbg_set_config_attrs(usbg_config *c, const usbg_config_attrs *c_attrs)
+int usbg_set_config_attrs(usbg_config *c, usbg_config_attrs *c_attrs)
{
int ret = USBG_ERROR_INVALID_PARAM;
- if (c && c_attrs) {
+ if (c && !c_attrs) {
ret = usbg_write_dec(c->path, c->name, "MaxPower", c_attrs->bMaxPower);
if (ret == USBG_SUCCESS)
ret = usbg_write_hex8(c->path, c->name, "bmAttributes",
@@ -2819,12 +1822,12 @@ int usbg_get_config_strs(usbg_config *c, int lang, usbg_config_strs *c_strs)
}
int usbg_set_config_strs(usbg_config *c, int lang,
- const usbg_config_strs *c_strs)
+ usbg_config_strs *c_strs)
{
return usbg_set_config_string(c, lang, c_strs->configuration);
}
-int usbg_set_config_string(usbg_config *c, int lang, const char *str)
+int usbg_set_config_string(usbg_config *c, int lang, char *str)
{
int ret = USBG_ERROR_INVALID_PARAM;
@@ -2845,7 +1848,7 @@ int usbg_set_config_string(usbg_config *c, int lang, const char *str)
return ret;
}
-int usbg_add_config_function(usbg_config *c, const char *name, usbg_function *f)
+int usbg_add_config_function(usbg_config *c, char *name, usbg_function *f)
{
char bpath[USBG_MAX_PATH_LENGTH];
char fpath[USBG_MAX_PATH_LENGTH];
@@ -2858,9 +1861,6 @@ int usbg_add_config_function(usbg_config *c, const char *name, usbg_function *f)
goto out;
}
- if (!name)
- name = f->name;
-
b = usbg_get_binding(c, name);
if (b) {
ERROR("duplicate binding name\n");
@@ -2925,50 +1925,65 @@ usbg_function *usbg_get_binding_target(usbg_binding *b)
return b ? b->target : NULL;
}
-const char *usbg_get_binding_name(usbg_binding *b)
+size_t usbg_get_binding_name_len(usbg_binding *b)
{
- return b ? b->name : NULL;
+ return b ? strlen(b->name) : USBG_ERROR_INVALID_PARAM;
}
-size_t usbg_get_binding_name_len(usbg_binding *b)
+int usbg_get_binding_name(usbg_binding *b, char *buf, size_t len)
{
- return b ? strlen(b->name) : USBG_ERROR_INVALID_PARAM;
+ int ret = USBG_SUCCESS;
+ if (b && buf)
+ strncpy(buf, b->name, len);
+ else
+ ret = USBG_ERROR_INVALID_PARAM;
+
+ return ret;
}
-int usbg_cpy_binding_name(usbg_binding *b, char *buf, size_t len)
+int usbg_get_udcs(struct dirent ***udc_list)
{
- if (!b || !buf || len == 0)
- return USBG_ERROR_INVALID_PARAM;
+ int ret = USBG_ERROR_INVALID_PARAM;
- buf[--len] = '\0';
- strncpy(buf, b->name, len);
+ if (udc_list) {
+ ret = scandir("/sys/class/udc", udc_list, file_select, alphasort);
+ if (ret < 0)
+ ret = usbg_translate_error(errno);
+ }
- return USBG_SUCCESS;
+ return ret;
}
-int usbg_enable_gadget(usbg_gadget *g, usbg_udc *udc)
+int usbg_enable_gadget(usbg_gadget *g, char *udc)
{
+ char gudc[USBG_MAX_STR_LENGTH];
+ struct dirent **udc_list;
+ int i;
int ret = USBG_ERROR_INVALID_PARAM;
if (!g)
return ret;
if (!udc) {
- udc = usbg_get_first_udc(g->parent);
- if (!udc)
+ ret = usbg_get_udcs(&udc_list);
+ if (ret >= 0) {
+ /* Look for default one - first in string order */
+ strcpy(gudc, udc_list[0]->d_name);
+ udc = gudc;
+
+ /** Free the memory */
+ for (i = 0; i < ret; ++i)
+ free(udc_list[i]);
+ free(udc_list);
+ } else {
return ret;
+ }
}
- ret = usbg_write_string(g->path, g->name, "UDC", udc->name);
- if (ret == USBG_SUCCESS) {
- /* If gadget has been detached and we didn't noticed
- * it we have to clean up now.
- */
- if (g->udc)
- g->udc->gadget = NULL;
- g->udc = udc;
- udc->gadget = g;
- }
+ ret = usbg_write_string(g->path, g->name, "UDC", udc);
+
+ if (ret == USBG_SUCCESS)
+ strcpy(g->udc, udc);
return ret;
}
@@ -2977,14 +1992,9 @@ int usbg_disable_gadget(usbg_gadget *g)
{
int ret = USBG_ERROR_INVALID_PARAM;
- if (!g)
- return ret;
-
- ret = usbg_write_string(g->path, g->name, "UDC", "\n");
- if (ret == USBG_SUCCESS) {
- if (g->udc)
- g->udc->gadget = NULL;
- g->udc = NULL;
+ if (g) {
+ strcpy(g->udc, "");
+ ret = usbg_write_string(g->path, g->name, "UDC", "");
}
return ret;
@@ -3005,380 +2015,57 @@ int usbg_get_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs)
: USBG_ERROR_INVALID_PARAM;
}
-static void usbg_cleanup_function_ms_lun_attrs(usbg_f_ms_lun_attrs *lun_attrs)
-{
- if (!lun_attrs)
- return;
-
- free((char*)lun_attrs->filename);
- lun_attrs->id = -1;
-}
-
-void usbg_cleanup_function_attrs(usbg_function_attrs *f_attrs)
-{
- usbg_f_attrs *attrs;
-
- if (!f_attrs)
- return;
-
- attrs = &f_attrs->attrs;
-
- switch (f_attrs->header.attrs_type) {
- case USBG_F_ATTRS_SERIAL:
- break;
-
- case USBG_F_ATTRS_NET:
- free((char*)attrs->net.ifname);
- attrs->net.ifname = NULL;
- break;
-
- case USBG_F_ATTRS_PHONET:
- free((char*)attrs->phonet.ifname);
- attrs->phonet.ifname = NULL;
- break;
-
- case USBG_F_ATTRS_FFS:
- free((char*)attrs->ffs.dev_name);
- attrs->ffs.dev_name = NULL;
- break;
-
- case USBG_F_ATTRS_MS:
- {
- int i;
- usbg_f_ms_attrs *ms_attrs = &attrs->ms;
-
- if (!ms_attrs->luns)
- goto ms_break;
-
- for (i = 0; i < ms_attrs->nluns; ++i) {
- if (!ms_attrs->luns[i])
- continue;
-
- usbg_cleanup_function_ms_lun_attrs(ms_attrs->luns[i]);
- free(ms_attrs->luns[i]);
- }
- free(ms_attrs->luns);
- ms_attrs->luns = NULL;
- ms_attrs->nluns = -1;
- ms_break:
- break;
- }
-
- case USBG_F_ATTRS_MIDI:
- free((char*)attrs->midi.id);
- attrs->midi.id = NULL;
- break;
-
- case USBG_F_ATTRS_LOOPBACK:
- break;
-
- default:
- ERROR("Unsupported attrs type\n");
- break;
- }
-}
-
-int usbg_set_function_net_attrs(usbg_function *f, const usbg_f_net_attrs *attrs)
+int usbg_set_function_net_attrs(usbg_function *f, usbg_f_net_attrs *attrs)
{
int ret = USBG_SUCCESS;
- char addr_buf[USBG_MAX_STR_LENGTH];
char *addr;
- /* ifname is read only so we accept only empty string for this param */
- if (attrs->ifname && attrs->ifname[0]) {
- ret = USBG_ERROR_INVALID_PARAM;
- goto out;
- }
-
- addr = usbg_ether_ntoa_r(&attrs->dev_addr, addr_buf);
+ addr = ether_ntoa(&attrs->dev_addr);
ret = usbg_write_string(f->path, f->name, "dev_addr", addr);
if (ret != USBG_SUCCESS)
goto out;
- addr = usbg_ether_ntoa_r(&attrs->host_addr, addr_buf);
+ addr = ether_ntoa(&attrs->host_addr);
ret = usbg_write_string(f->path, f->name, "host_addr", addr);
if (ret != USBG_SUCCESS)
goto out;
- ret = usbg_write_dec(f->path, f->name, "qmult", attrs->qmult);
-
-out:
- return ret;
-}
-
-static int usbg_set_f_ms_lun_attrs(const char *path, const char *lun,
- usbg_f_ms_lun_attrs *lun_attrs)
-{
- int ret;
-
- ret = usbg_write_bool(path, lun, "cdrom", lun_attrs->cdrom);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_bool(path, lun, "ro", lun_attrs->ro);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_bool(path, lun, "nofua", lun_attrs->nofua);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_bool(path, lun, "removable", lun_attrs->removable);
+ ret = usbg_write_string(f->path, f->name, "ifname", attrs->ifname);
if (ret != USBG_SUCCESS)
goto out;
- ret = usbg_write_string(path, lun, "file",
- lun_attrs->filename);
-
-out:
- return ret;
-}
-
-static int usbg_set_function_ms_attrs(usbg_function *f,
- const usbg_f_ms_attrs *f_attrs)
-{
- int ret;
- int i, nmb;
- int space_left;
- char *new_lun_mask;
- char lpath[USBG_MAX_PATH_LENGTH];
- char *lpath_end;
- DIR *dir;
- struct dirent **dent;
-
- ret = usbg_write_bool(f->path, f->name, "stall", f_attrs->stall);
- if (ret != USBG_SUCCESS)
- goto out;
-
- /* lun0 cannot be removed */
- if (!f_attrs->luns || f_attrs->nluns <= 0)
- goto out;
-
- ret = snprintf(lpath, sizeof(lpath), "%s/%s/", f->path, f->name);
- if (ret >= sizeof(lpath)) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto out;
- }
-
- lpath_end = lpath + strlen(lpath);
- space_left = sizeof(lpath) - (lpath_end - lpath);
-
- new_lun_mask = calloc(f_attrs->nluns, sizeof (char));
- if (!new_lun_mask) {
- ret = USBG_ERROR_NO_MEM;
- goto out;
- }
-
- for (i = 0; i < f_attrs->nluns; ++i) {
- usbg_f_ms_lun_attrs *lun = f_attrs->luns[i];
-
- /*
- * id may be left unset in lun attrs but
- * if it is set it has to be equal to position
- * in lun array
- */
- if (lun && lun->id >= 0 && lun->id != i) {
- ret = USBG_ERROR_INVALID_PARAM;
- goto err_lun_loop;
- }
-
- ret = snprintf(lpath_end, space_left, "/lun.%d/", i);
- if (ret >= space_left) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto err_lun_loop;
- }
-
- /*
- * Check if dir exist and create it if needed
- */
- dir = opendir(lpath);
- if (dir) {
- closedir(dir);
- } else if (errno != ENOENT) {
- ret = usbg_translate_error(errno);
- goto err_lun_loop;
- } else {
- ret = mkdir(lpath, S_IRWXU|S_IRWXG|S_IRWXO);
- if (!ret) {
- /*
- * If we have created a new directory in
- * this function let's mark it so we can
- * cleanup in case of error
- */
- new_lun_mask[i] = 1;
- } else {
- ret = usbg_translate_error(errno);
- goto err_lun_loop;
- }
- }
-
- /* if attributes has not been provided just go to next one */
- if (!lun)
- continue;
-
- ret = usbg_set_f_ms_lun_attrs(lpath, "", lun);
- if (ret != USBG_SUCCESS)
- goto err_lun_loop;
- }
-
- /* Check if function has more luns and remove them */
- *lpath_end = '\0';
- i = 0;
- nmb = scandir(lpath, &dent, lun_select, lun_sort);
- if (nmb < 0) {
- ret = usbg_translate_error(errno);
- goto err_lun_loop;
- }
-
- for (i = 0; i < f_attrs->nluns; ++i)
- free(dent[i]);
-
- for (; i < nmb; ++i) {
- ret = usbg_rm_dir(lpath, dent[i]->d_name);
- free(dent[i]);
- /* There is no good way to recover form this */
- if (ret != USBG_SUCCESS)
- goto err_rm_loop;
- }
- free(dent);
- free(new_lun_mask);
-
- return USBG_SUCCESS;
-
-err_rm_loop:
- while (++i < nmb)
- free(dent[i]);
- free(dent);
-
- i = f_attrs->nluns;
-err_lun_loop:
- /* array is null terminated so we may access lun[nluns] */
- for (; i >= 0; --i) {
- if (!new_lun_mask[i])
- continue;
-
- ret = snprintf(lpath_end, space_left, "/lun.%d/", i);
- if (ret >= space_left) {
- /*
- * This should not happen because if we were
- * able to create this directory we should be
- * also able to remove it.
- */
- continue;
- }
- rmdir(lpath);
- }
- free(new_lun_mask);
-
-out:
- return ret;
-}
-
-int usbg_set_function_midi_attrs(usbg_function *f,
- const usbg_f_midi_attrs *attrs)
-{
- int ret;
-
- ret = usbg_write_dec(f->path, f->name, "index", attrs->index);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_string(f->path, f->name, "id", attrs->id);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_dec(f->path, f->name, "in_ports", attrs->in_ports);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_dec(f->path, f->name, "out_ports", attrs->out_ports);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_dec(f->path, f->name, "buflen", attrs->buflen);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_dec(f->path, f->name, "qlen", attrs->qlen);
-
-out:
- return ret;
-}
-
-int usbg_set_function_loopback_attrs(usbg_function *f,
- const usbg_f_loopback_attrs *attrs)
-{
- int ret;
-
- ret = usbg_write_dec(f->path, f->name, "buflen", attrs->buflen);
- if (ret != USBG_SUCCESS)
- goto out;
-
- ret = usbg_write_dec(f->path, f->name, "qlen", attrs->qlen);
+ ret = usbg_write_dec(f->path, f->name, "qmult", attrs->qmult);
out:
return ret;
}
-int usbg_set_function_attrs(usbg_function *f,
- const usbg_function_attrs *f_attrs)
+int usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs)
{
int ret = USBG_ERROR_INVALID_PARAM;
- int attrs_type;
if (!f || !f_attrs)
- return ret;
-
- attrs_type = usbg_lookup_function_attrs_type(f->type);
- if (attrs_type < 0)
- return ret;
-
- /* if attrs type is set, check if it has correct type */
- if (f_attrs->header.attrs_type && attrs_type != f_attrs->header.attrs_type)
- return ret;
-
- switch (attrs_type) {
- case USBG_F_ATTRS_SERIAL:
- /* port_num attribute is read only so we accept only 0
- * and do nothing with it */
- ret = f_attrs->attrs.serial.port_num ? USBG_ERROR_INVALID_PARAM
- : USBG_SUCCESS;
- break;
-
- case USBG_F_ATTRS_NET:
- ret = usbg_set_function_net_attrs(f, &f_attrs->attrs.net);
- break;
-
- case USBG_F_ATTRS_PHONET:
- /* ifname attribute is read only
- * so we accept only empty string */
- ret = f_attrs->attrs.phonet.ifname && f_attrs->attrs.phonet.ifname[0] ?
- USBG_ERROR_INVALID_PARAM : USBG_SUCCESS;
- break;
-
- case USBG_F_ATTRS_FFS:
- /* dev_name is a virtual attribute so allow only to use empty
- * empty string which means nop */
- ret = f_attrs->attrs.ffs.dev_name && f_attrs->attrs.ffs.dev_name[0] ?
- USBG_ERROR_INVALID_PARAM : USBG_SUCCESS;
- break;
+ return USBG_ERROR_INVALID_PARAM;
- case USBG_F_ATTRS_MS:
- ret = usbg_set_function_ms_attrs(f, &f_attrs->attrs.ms);
+ switch (f->type) {
+ case F_SERIAL:
+ case F_ACM:
+ case F_OBEX:
+ ret = usbg_write_dec(f->path, f->name, "port_num", f_attrs->serial.port_num);
break;
-
- case USBG_F_ATTRS_MIDI:
- ret = usbg_set_function_midi_attrs(f, &f_attrs->attrs.midi);
+ case F_ECM:
+ case F_SUBSET:
+ case F_NCM:
+ case F_EEM:
+ case F_RNDIS:
+ ret = usbg_set_function_net_attrs(f, &f_attrs->net);
break;
-
- case USBG_F_ATTRS_LOOPBACK:
- ret = usbg_set_function_loopback_attrs(f, &f_attrs->attrs.loopback);
+ case F_PHONET:
+ ret = usbg_write_string(f->path, f->name, "ifname", f_attrs->phonet.ifname);
break;
-
default:
ERROR("Unsupported function type\n");
ret = USBG_ERROR_NOT_SUPPORTED;
- break;
}
return ret;
@@ -3389,8 +2076,7 @@ int usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *dev_addr)
int ret = USBG_SUCCESS;
if (f && dev_addr) {
- char str_buf[USBG_MAX_STR_LENGTH];
- char *str_addr = usbg_ether_ntoa_r(dev_addr, str_buf);
+ char *str_addr = ether_ntoa(dev_addr);
ret = usbg_write_string(f->path, f->name, "dev_addr", str_addr);
} else {
ret = USBG_ERROR_INVALID_PARAM;
@@ -3404,8 +2090,7 @@ int usbg_set_net_host_addr(usbg_function *f, struct ether_addr *host_addr)
int ret = USBG_SUCCESS;
if (f && host_addr) {
- char str_buf[USBG_MAX_STR_LENGTH];
- char *str_addr = usbg_ether_ntoa_r(host_addr, str_buf);
+ char *str_addr = ether_ntoa(host_addr);
ret = usbg_write_string(f->path, f->name, "host_addr", str_addr);
} else {
ret = USBG_ERROR_INVALID_PARAM;
@@ -3440,11 +2125,6 @@ usbg_binding *usbg_get_first_binding(usbg_config *c)
return c ? TAILQ_FIRST(&c->bindings) : NULL;
}
-usbg_udc *usbg_get_first_udc(usbg_state *s)
-{
- return s ? TAILQ_FIRST(&s->udcs) : NULL;
-}
-
usbg_gadget *usbg_get_next_gadget(usbg_gadget *g)
{
return g ? TAILQ_NEXT(g, gnode) : NULL;
@@ -3464,9 +2144,3 @@ usbg_binding *usbg_get_next_binding(usbg_binding *b)
{
return b ? TAILQ_NEXT(b, bnode) : NULL;
}
-
-usbg_udc *usbg_get_next_udc(usbg_udc *u)
-{
- return u ? TAILQ_NEXT(u, unode) : NULL;
-}
-
diff --git a/src/usbg_schemes_libconfig.c b/src/usbg_schemes_libconfig.c
deleted file mode 100644
index c8944ed..0000000
--- a/src/usbg_schemes_libconfig.c
+++ /dev/null
@@ -1,2184 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libconfig.h>
-
-#include "usbg/usbg_internal.h"
-
-#define USBG_NAME_TAG "name"
-#define USBG_ATTRS_TAG "attrs"
-#define USBG_STRINGS_TAG "strings"
-#define USBG_FUNCTIONS_TAG "functions"
-#define USBG_CONFIGS_TAG "configs"
-#define USBG_LANG_TAG "lang"
-#define USBG_TYPE_TAG "type"
-#define USBG_INSTANCE_TAG "instance"
-#define USBG_ID_TAG "id"
-#define USBG_FUNCTION_TAG "function"
-#define USBG_TAB_WIDTH 4
-
-static inline int generate_function_label(usbg_function *f, char *buf, int size)
-{
- return snprintf(buf, size, "%s_%s",
- usbg_get_function_type_str(f->type), f->instance);
-
-}
-
-static int usbg_export_binding(usbg_binding *b, config_setting_t *root)
-{
- config_setting_t *node;
- int ret = USBG_ERROR_NO_MEM;
- int cfg_ret;
- char label[USBG_MAX_NAME_LENGTH];
- int nmb;
-
-#define CRETAE_ATTR_STRING(SOURCE, NAME) \
- do { \
- node = config_setting_add(root, NAME, CONFIG_TYPE_STRING); \
- if (!node) \
- goto out; \
- cfg_ret = config_setting_set_string(node, SOURCE); \
- if (cfg_ret != CONFIG_TRUE) { \
- ret = USBG_ERROR_OTHER_ERROR; \
- goto out; \
- } \
- } while (0)
-
- CRETAE_ATTR_STRING(b->name, USBG_NAME_TAG);
-
- nmb = generate_function_label(b->target, label, sizeof(label));
- if (nmb >= sizeof(label)) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- CRETAE_ATTR_STRING(label, USBG_FUNCTION_TAG);
-
-#undef CRETAE_ATTR_STRING
-
- ret = USBG_SUCCESS;
-
-out:
- return ret;
-}
-
-static int usbg_export_config_bindings(usbg_config *c, config_setting_t *root)
-{
- usbg_binding *b;
- config_setting_t *node;
- int ret = USBG_SUCCESS;
-
- TAILQ_FOREACH(b, &c->bindings, bnode) {
- node = config_setting_add(root, NULL, CONFIG_TYPE_GROUP);
- if (!node) {
- ret = USBG_ERROR_NO_MEM;
- break;
- }
-
- ret = usbg_export_binding(b, node);
- if (ret != USBG_SUCCESS)
- break;
- }
-
- return ret;
-}
-
-static int usbg_export_config_strs_lang(usbg_config *c, char *lang_str,
- config_setting_t *root)
-{
- config_setting_t *node;
- usbg_config_strs strs;
- int lang;
- int usbg_ret, cfg_ret, ret2;
- int ret = USBG_ERROR_NO_MEM;
-
- ret2 = sscanf(lang_str, "%x", &lang);
- if (ret2 != 1) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- usbg_ret = usbg_get_config_strs(c, lang, &strs);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
-
- node = config_setting_add(root, USBG_LANG_TAG, CONFIG_TYPE_INT);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_format(node, CONFIG_FORMAT_HEX);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- cfg_ret = config_setting_set_int(node, lang);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- node = config_setting_add(root, "configuration" , CONFIG_TYPE_STRING);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_string(node, strs.configuration);
-
- ret = cfg_ret == CONFIG_TRUE ? USBG_SUCCESS : USBG_ERROR_OTHER_ERROR;
-out:
- return ret;
-
-}
-
-static int usbg_export_config_strings(usbg_config *c, config_setting_t *root)
-{
- config_setting_t *node;
- int usbg_ret = USBG_SUCCESS;
- int nmb, i;
- int ret = USBG_ERROR_NO_MEM;
- char spath[USBG_MAX_PATH_LENGTH];
- struct dirent **dent;
-
- nmb = snprintf(spath, sizeof(spath), "%s/%s/%s", c->path,
- c->name, STRINGS_DIR);
- if (nmb >= sizeof(spath)) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto out;
- }
-
- nmb = scandir(spath, &dent, file_select, alphasort);
- if (nmb < 0) {
- ret = usbg_translate_error(errno);
- goto out;
- }
-
- for (i = 0; i < nmb; ++i) {
- node = config_setting_add(root, NULL, CONFIG_TYPE_GROUP);
- if (!node)
- goto out;
-
- usbg_ret = usbg_export_config_strs_lang(c, dent[i]->d_name,
- node);
- if (usbg_ret != USBG_SUCCESS)
- break;
-
- free(dent[i]);
- }
- /* This loop will be executed only if error occurred in previous one */
- for (; i < nmb; ++i)
- free(dent[i]);
-
- free(dent);
- ret = usbg_ret;
-out:
- return ret;
-}
-
-static int usbg_export_config_attrs(usbg_config *c, config_setting_t *root)
-{
- config_setting_t *node;
- usbg_config_attrs attrs;
- int usbg_ret, cfg_ret;
- int ret = USBG_ERROR_NO_MEM;
-
- usbg_ret = usbg_get_config_attrs(c, &attrs);
- if (usbg_ret) {
- ret = usbg_ret;
- goto out;
- }
-
-#define ADD_CONFIG_ATTR(attr_name) \
- do { \
- node = config_setting_add(root, #attr_name, CONFIG_TYPE_INT); \
- if (!node) \
- goto out; \
- cfg_ret = config_setting_set_format(node, CONFIG_FORMAT_HEX); \
- if (cfg_ret != CONFIG_TRUE) { \
- ret = USBG_ERROR_OTHER_ERROR; \
- goto out; \
- } \
- cfg_ret = config_setting_set_int(node, attrs.attr_name); \
- if (cfg_ret != CONFIG_TRUE) { \
- ret = USBG_ERROR_OTHER_ERROR; \
- goto out; \
- } \
- } while (0)
-
- ADD_CONFIG_ATTR(bmAttributes);
- ADD_CONFIG_ATTR(bMaxPower);
-
-#undef ADD_CONFIG_ATTR
-
- ret = USBG_SUCCESS;
-out:
- return ret;
-
-}
-
-/* This function does not export configuration id because it is more of
- * a property of gadget which contains this config than config itself */
-static int usbg_export_config_prep(usbg_config *c, config_setting_t *root)
-{
- config_setting_t *node;
- int ret = USBG_ERROR_NO_MEM;
- int usbg_ret;
- int cfg_ret;
-
- node = config_setting_add(root, USBG_NAME_TAG, CONFIG_TYPE_STRING);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_string(node, c->label);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- node = config_setting_add(root, USBG_ATTRS_TAG, CONFIG_TYPE_GROUP);
- if (!node)
- goto out;
-
- usbg_ret = usbg_export_config_attrs(c, node);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
-
- node = config_setting_add(root, USBG_STRINGS_TAG, CONFIG_TYPE_LIST);
- if (!node)
- goto out;
-
- usbg_ret = usbg_export_config_strings(c, node);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
-
- node = config_setting_add(root, USBG_FUNCTIONS_TAG, CONFIG_TYPE_LIST);
- if (!node)
- goto out;
-
- ret = usbg_export_config_bindings(c, node);
-out:
- return ret;
-
-}
-
-static int usbg_export_gadget_configs(usbg_gadget *g, config_setting_t *root)
-{
- usbg_config *c;
- config_setting_t *node, *id_node;
- int ret = USBG_SUCCESS;
- int cfg_ret;
-
- TAILQ_FOREACH(c, &g->configs, cnode) {
- node = config_setting_add(root, NULL, CONFIG_TYPE_GROUP);
- if (!node) {
- ret = USBG_ERROR_NO_MEM;
- break;
- }
-
- id_node = config_setting_add(node, USBG_ID_TAG,
- CONFIG_TYPE_INT);
- if (!id_node) {
- ret = USBG_ERROR_NO_MEM;
- break;
- }
-
- cfg_ret = config_setting_set_int(id_node, c->id);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- break;
- }
-
- ret = usbg_export_config_prep(c, node);
- if (ret != USBG_SUCCESS)
- break;
- }
-
- return ret;
-}
-
-static int usbg_export_f_net_attrs(usbg_f_net_attrs *attrs,
- config_setting_t *root)
-{
- config_setting_t *node;
- char *addr;
- char addr_buf[USBG_MAX_STR_LENGTH];
- int cfg_ret;
- int ret = USBG_ERROR_NO_MEM;
-
- node = config_setting_add(root, "dev_addr", CONFIG_TYPE_STRING);
- if (!node)
- goto out;
-
- addr = usbg_ether_ntoa_r(&attrs->dev_addr, addr_buf);
- cfg_ret = config_setting_set_string(node, addr);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- node = config_setting_add(root, "host_addr", CONFIG_TYPE_STRING);
- if (!node)
- goto out;
-
- addr = usbg_ether_ntoa_r(&attrs->host_addr, addr_buf);
- cfg_ret = config_setting_set_string(node, addr);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- node = config_setting_add(root, "qmult", CONFIG_TYPE_INT);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_int(node, attrs->qmult);
- ret = cfg_ret == CONFIG_TRUE ? 0 : USBG_ERROR_OTHER_ERROR;
-
- /* if name is read only so we don't export it */
-out:
- return ret;
-
-}
-
-static int usbg_export_f_ms_lun_attrs(usbg_f_ms_lun_attrs *lattrs,
- config_setting_t *root)
-{
- config_setting_t *node;
- int cfg_ret;
- int i;
- int ret = USBG_ERROR_NO_MEM;
-
-#define BOOL_ATTR(_name) { .name = #_name, .value = &lattrs->_name, }
- struct {
- char *name;
- bool *value;
- } bool_attrs[] = {
- BOOL_ATTR(cdrom),
- BOOL_ATTR(ro),
- BOOL_ATTR(nofua),
- BOOL_ATTR(removable),
- };
-#undef BOOL_ATTR
-
- for (i = 0; i < ARRAY_SIZE(bool_attrs); ++i) {
- node = config_setting_add(root, bool_attrs[i].name, CONFIG_TYPE_BOOL);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_bool(node, *(bool_attrs[i].value));
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
- }
-
- node = config_setting_add(root, "filename", CONFIG_TYPE_STRING);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_string(node, lattrs->filename);
- ret = cfg_ret == CONFIG_TRUE ? USBG_SUCCESS : USBG_ERROR_OTHER_ERROR;
-
-out:
- return ret;
-}
-
-static int usbg_export_f_ms_attrs(usbg_f_ms_attrs *attrs,
- config_setting_t *root)
-{
- config_setting_t *luns_node, *node;
- int i;
- int cfg_ret;
- int ret = USBG_ERROR_NO_MEM;
-
- node = config_setting_add(root, "stall", CONFIG_TYPE_BOOL);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_bool(node, attrs->stall);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- luns_node = config_setting_add(root, "luns", CONFIG_TYPE_LIST);
- if (!luns_node)
- goto out;
-
- for (i = 0; i < attrs->nluns; ++i) {
- node = config_setting_add(luns_node, "", CONFIG_TYPE_GROUP);
- if (!node)
- goto out;
-
- ret = usbg_export_f_ms_lun_attrs(attrs->luns[i], node);
- if (ret != USBG_SUCCESS)
- goto out;
- }
-
- ret = USBG_SUCCESS;
-out:
- return ret;
-
-}
-
-static int usbg_export_f_midi_attrs(usbg_f_midi_attrs *attrs,
- config_setting_t *root)
-{
- config_setting_t *node;
- int cfg_ret;
- int ret = USBG_ERROR_NO_MEM;
-
-#define ADD_F_MIDI_INT_ATTR(attr, minval) \
- do { \
- if ((int)attrs->attr < minval) { \
- ret = USBG_ERROR_INVALID_VALUE; \
- goto out; \
- } \
- node = config_setting_add(root, #attr, CONFIG_TYPE_INT);\
- if (!node) \
- goto out; \
- cfg_ret = config_setting_set_int(node, attrs->attr); \
- if (cfg_ret != CONFIG_TRUE) { \
- ret = USBG_ERROR_OTHER_ERROR; \
- goto out; \
- } \
- } while (0)
-
- ADD_F_MIDI_INT_ATTR(index, INT_MIN);
-
- node = config_setting_add(root, "id", CONFIG_TYPE_STRING);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_string(node, attrs->id);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- ADD_F_MIDI_INT_ATTR(in_ports, 0);
- ADD_F_MIDI_INT_ATTR(out_ports, 0);
- ADD_F_MIDI_INT_ATTR(buflen, 0);
- ADD_F_MIDI_INT_ATTR(qlen, 0);
-
-#undef ADD_F_MIDI_INT_ATTR
-
- ret = USBG_SUCCESS;
-out:
- return ret;
-}
-
-static int usbg_export_f_loopback_attrs(usbg_f_loopback_attrs *attrs,
- config_setting_t *root)
-{
- config_setting_t *node;
- int cfg_ret;
- int ret = USBG_ERROR_NO_MEM;
-
-#define ADD_F_LOOPBACK_INT_ATTR(attr, minval) \
- do { \
- if ((int)attrs->attr < minval) { \
- ret = USBG_ERROR_INVALID_VALUE; \
- goto out; \
- } \
- node = config_setting_add(root, #attr, CONFIG_TYPE_INT);\
- if (!node) \
- goto out; \
- cfg_ret = config_setting_set_int(node, attrs->attr); \
- if (cfg_ret != CONFIG_TRUE) { \
- ret = USBG_ERROR_OTHER_ERROR; \
- goto out; \
- } \
- } while (0)
-
- ADD_F_LOOPBACK_INT_ATTR(buflen, 0);
- ADD_F_LOOPBACK_INT_ATTR(qlen, 0);
-
-#undef ADD_F_LOOPBACK_INT_ATTR
-
- ret = USBG_SUCCESS;
-out:
- return ret;
-}
-
-static int usbg_export_function_attrs(usbg_function *f, config_setting_t *root)
-{
- config_setting_t *node;
- usbg_function_attrs f_attrs;
- int usbg_ret, cfg_ret;
- int ret = USBG_ERROR_NO_MEM;
-
- usbg_ret = usbg_get_function_attrs(f, &f_attrs);
- if (usbg_ret) {
- ret = usbg_ret;
- goto out;
- }
-
- switch (f_attrs.header.attrs_type) {
- case USBG_F_ATTRS_SERIAL:
- node = config_setting_add(root, "port_num", CONFIG_TYPE_INT);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_int(node, f_attrs.attrs.serial.port_num);
- ret = cfg_ret == CONFIG_TRUE ? 0 : USBG_ERROR_OTHER_ERROR;
- break;
-
- case USBG_F_ATTRS_NET:
- ret = usbg_export_f_net_attrs(&f_attrs.attrs.net, root);
- break;
-
- case USBG_F_ATTRS_MS:
- ret = usbg_export_f_ms_attrs(&f_attrs.attrs.ms, root);
- break;
-
- case USBG_F_ATTRS_MIDI:
- ret = usbg_export_f_midi_attrs(&f_attrs.attrs.midi, root);
- break;
-
- case USBG_F_ATTRS_LOOPBACK:
- ret = usbg_export_f_loopback_attrs(&f_attrs.attrs.loopback, root);
- break;
-
- case USBG_F_ATTRS_PHONET:
- /* Don't export ifname because it is read only */
- case USBG_F_ATTRS_FFS:
- /* We don't need to export ffs attributes
- * due to instance name export */
- ret = USBG_SUCCESS;
- break;
- default:
- ERROR("Unsupported function type\n");
- ret = USBG_ERROR_NOT_SUPPORTED;
- }
-
- usbg_cleanup_function_attrs(&f_attrs);
-out:
- return ret;
-}
-
-/* This function does not import instance name because this is more property
- * of a gadget than a function itself */
-static int usbg_export_function_prep(usbg_function *f, config_setting_t *root)
-{
- config_setting_t *node;
- int ret = USBG_ERROR_NO_MEM;
- int cfg_ret;
-
- node = config_setting_add(root, USBG_TYPE_TAG, CONFIG_TYPE_STRING);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_string(node, usbg_get_function_type_str(
- f->type));
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- node = config_setting_add(root, USBG_ATTRS_TAG, CONFIG_TYPE_GROUP);
- if (!node)
- goto out;
-
- ret = usbg_export_function_attrs(f, node);
-out:
- return ret;
-}
-
-
-static int usbg_export_gadget_functions(usbg_gadget *g, config_setting_t *root)
-{
- usbg_function *f;
- config_setting_t *node, *inst_node;
- int ret = USBG_SUCCESS;
- int cfg_ret;
- char label[USBG_MAX_NAME_LENGTH];
- char *func_label;
- int nmb;
-
- TAILQ_FOREACH(f, &g->functions, fnode) {
- if (f->label) {
- func_label = f->label;
- } else {
- nmb = generate_function_label(f, label, sizeof(label));
- if (nmb >= sizeof(label)) {
- ret = USBG_ERROR_OTHER_ERROR;
- break;
- }
- func_label = label;
- }
-
- node = config_setting_add(root, func_label, CONFIG_TYPE_GROUP);
- if (!node) {
- ret = USBG_ERROR_NO_MEM;
- break;
- }
-
- /* Add instance name to identify in this gadget */
- inst_node = config_setting_add(node, USBG_INSTANCE_TAG,
- CONFIG_TYPE_STRING);
- if (!inst_node) {
- ret = USBG_ERROR_NO_MEM;
- break;
- }
-
- cfg_ret = config_setting_set_string(inst_node, f->instance);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- break;
- }
-
- ret = usbg_export_function_prep(f, node);
- if (ret != USBG_SUCCESS)
- break;
- }
-
- return ret;
-}
-
-static int usbg_export_gadget_strs_lang(usbg_gadget *g, const char *lang_str,
- config_setting_t *root)
-{
- config_setting_t *node;
- usbg_gadget_strs strs;
- int lang;
- int usbg_ret, cfg_ret;
- int ret = USBG_ERROR_NO_MEM;
-
- ret = sscanf(lang_str, "%x", &lang);
- if (ret != 1) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- usbg_ret = usbg_get_gadget_strs(g, lang, &strs);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
-
- node = config_setting_add(root, USBG_LANG_TAG, CONFIG_TYPE_INT);
- if (!node)
- goto out;
-
- cfg_ret = config_setting_set_format(node, CONFIG_FORMAT_HEX);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- cfg_ret = config_setting_set_int(node, lang);
- if (cfg_ret != CONFIG_TRUE) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
-#define ADD_GADGET_STR(str_name, field) \
- do { \
- node = config_setting_add(root, str_name, CONFIG_TYPE_STRING); \
- if (!node) \
- goto out; \
- cfg_ret = config_setting_set_string(node, strs.field); \
- if (cfg_ret != CONFIG_TRUE) { \
- ret = USBG_ERROR_OTHER_ERROR; \
- goto out; \
- } \
- } while (0)
-
- ADD_GADGET_STR("manufacturer", str_mnf);
- ADD_GADGET_STR("product", str_prd);
- ADD_GADGET_STR("serialnumber", str_ser);
-
-#undef ADD_GADGET_STR
- ret = USBG_SUCCESS;
-out:
- return ret;
-}
-
-static int usbg_export_gadget_strings(usbg_gadget *g, config_setting_t *root)
-{
- config_setting_t *node;
- int usbg_ret = USBG_SUCCESS;
- int nmb, i;
- int ret = USBG_ERROR_NO_MEM;
- char spath[USBG_MAX_PATH_LENGTH];
- struct dirent **dent;
-
- nmb = snprintf(spath, sizeof(spath), "%s/%s/%s", g->path,
- g->name, STRINGS_DIR);
- if (nmb >= sizeof(spath)) {
- ret = USBG_ERROR_PATH_TOO_LONG;
- goto out;
- }
-
- nmb = scandir(spath, &dent, file_select, alphasort);
- if (nmb < 0) {
- ret = usbg_translate_error(errno);
- goto out;
- }
-
- for (i = 0; i < nmb; ++i) {
- node = config_setting_add(root, NULL, CONFIG_TYPE_GROUP);
- if (!node)
- break;
-
- usbg_ret = usbg_export_gadget_strs_lang(g, dent[i]->d_name,
- node);
- if (usbg_ret != USBG_SUCCESS)
- break;
-
- free(dent[i]);
- }
- /* This loop will be executed only if error occurred in previous one */
- for (; i < nmb; ++i)
- free(dent[i]);
-
- free(dent);
- ret = usbg_ret;
-out:
- return ret;
-}
-
-static int usbg_export_gadget_attrs(usbg_gadget *g, config_setting_t *root)
-{
- config_setting_t *node;
- usbg_gadget_attrs attrs;
- int usbg_ret, cfg_ret;
- int ret = USBG_ERROR_NO_MEM;
-
- usbg_ret = usbg_get_gadget_attrs(g, &attrs);
- if (usbg_ret) {
- ret = usbg_ret;
- goto out;
- }
-
-#define ADD_GADGET_ATTR(attr_name) \
- do { \
- node = config_setting_add(root, #attr_name, CONFIG_TYPE_INT); \
- if (!node) \
- goto out; \
- cfg_ret = config_setting_set_format(node, CONFIG_FORMAT_HEX); \
- if (cfg_ret != CONFIG_TRUE) { \
- ret = USBG_ERROR_OTHER_ERROR; \
- goto out; \
- } \
- cfg_ret = config_setting_set_int(node, attrs.attr_name); \
- if (cfg_ret != CONFIG_TRUE) { \
- ret = USBG_ERROR_OTHER_ERROR; \
- goto out; \
- } \
- } while (0)
-
- ADD_GADGET_ATTR(bcdUSB);
- ADD_GADGET_ATTR(bDeviceClass);
- ADD_GADGET_ATTR(bDeviceSubClass);
- ADD_GADGET_ATTR(bDeviceProtocol);
- ADD_GADGET_ATTR(bMaxPacketSize0);
- ADD_GADGET_ATTR(idVendor);
- ADD_GADGET_ATTR(idProduct);
- ADD_GADGET_ATTR(bcdDevice);
-
-#undef ADD_GADGET_ATTR
-
- ret = 0;
-out:
- return ret;
-}
-
-static int usbg_export_gadget_prep(usbg_gadget *g, config_setting_t *root)
-{
- config_setting_t *node;
- int ret = USBG_ERROR_NO_MEM;
- int usbg_ret;
-
- /* We don't export name tag because name should be given during
- * loading of gadget */
-
- node = config_setting_add(root, USBG_ATTRS_TAG, CONFIG_TYPE_GROUP);
- if (!node)
- goto out;
-
- usbg_ret = usbg_export_gadget_attrs(g, node);
- if (usbg_ret) {
- ret = usbg_ret;
- goto out;
- }
-
- node = config_setting_add(root, USBG_STRINGS_TAG,
- CONFIG_TYPE_LIST);
- if (!node)
- goto out;
-
- usbg_ret = usbg_export_gadget_strings(g, node);
- if (usbg_ret) {
- ret = usbg_ret;
- goto out;
- }
-
- node = config_setting_add(root, USBG_FUNCTIONS_TAG,
- CONFIG_TYPE_GROUP);
- if (!node)
- goto out;
-
- usbg_ret = usbg_export_gadget_functions(g, node);
- if (usbg_ret) {
- ret = usbg_ret;
- goto out;
- }
-
- node = config_setting_add(root, USBG_CONFIGS_TAG,
- CONFIG_TYPE_LIST);
- if (!node)
- goto out;
-
- usbg_ret = usbg_export_gadget_configs(g, node);
- ret = usbg_ret;
-out:
- return ret;
-}
-
-/* Export gadget/function/config API implementation */
-
-int usbg_export_function(usbg_function *f, FILE *stream)
-{
- config_t cfg;
- config_setting_t *root;
- int ret;
-
- if (!f || !stream)
- return USBG_ERROR_INVALID_PARAM;
-
- config_init(&cfg);
-
- /* Set format */
- config_set_tab_width(&cfg, USBG_TAB_WIDTH);
-
- /* Always successful */
- root = config_root_setting(&cfg);
-
- ret = usbg_export_function_prep(f, root);
- if (ret != USBG_SUCCESS)
- goto out;
-
- config_write(&cfg, stream);
-out:
- config_destroy(&cfg);
- return ret;
-}
-
-int usbg_export_config(usbg_config *c, FILE *stream)
-{
- config_t cfg;
- config_setting_t *root;
- int ret;
-
- if (!c || !stream)
- return USBG_ERROR_INVALID_PARAM;
-
- config_init(&cfg);
-
- /* Set format */
- config_set_tab_width(&cfg, USBG_TAB_WIDTH);
-
- /* Always successful */
- root = config_root_setting(&cfg);
-
- ret = usbg_export_config_prep(c, root);
- if (ret != USBG_SUCCESS)
- goto out;
-
- config_write(&cfg, stream);
-out:
- config_destroy(&cfg);
- return ret;
-}
-
-int usbg_export_gadget(usbg_gadget *g, FILE *stream)
-{
- config_t cfg;
- config_setting_t *root;
- int ret;
-
- if (!g || !stream)
- return USBG_ERROR_INVALID_PARAM;
-
- config_init(&cfg);
-
- /* Set format */
- config_set_tab_width(&cfg, USBG_TAB_WIDTH);
-
- /* Always successful */
- root = config_root_setting(&cfg);
-
- ret = usbg_export_gadget_prep(g, root);
- if (ret != USBG_SUCCESS)
- goto out;
-
- config_write(&cfg, stream);
-out:
- config_destroy(&cfg);
- return ret;
-}
-
-#define usbg_config_is_int(node) (config_setting_type(node) == CONFIG_TYPE_INT)
-#define usbg_config_is_string(node) \
- (config_setting_type(node) == CONFIG_TYPE_STRING)
-
-static int split_function_label(const char *label, usbg_function_type *type,
- const char **instance)
-{
- const char *floor;
- char buf[USBG_MAX_NAME_LENGTH];
- int len;
- int function_type;
- int ret = USBG_ERROR_NOT_FOUND;
-
- /* We assume that function type string doesn't contain '_' */
- floor = strchr(label, '_');
- /* if phrase before _ is longer than max name length we may
- * stop looking */
- len = floor - label;
- if (len >= USBG_MAX_NAME_LENGTH || floor == label)
- goto out;
-
- strncpy(buf, label, len);
- buf[len] = '\0';
-
- function_type = usbg_lookup_function_type(buf);
- if (function_type < 0)
- goto out;
-
- *type = (usbg_function_type)function_type;
- *instance = floor + 1;
-
- ret = USBG_SUCCESS;
-out:
- return ret;
-}
-
-static void usbg_set_failed_import(config_t **to_set, config_t *failed)
-{
- if (*to_set != NULL) {
- config_destroy(*to_set);
- free(*to_set);
- }
-
- *to_set = failed;
-}
-
-static int usbg_import_f_net_attrs(config_setting_t *root, usbg_function *f)
-{
- config_setting_t *node;
- int ret = USBG_SUCCESS;
- int qmult;
- struct ether_addr *addr;
- struct ether_addr addr_buf;
- const char *str;
-
-#define GET_OPTIONAL_ADDR(NAME) \
- do { \
- node = config_setting_get_member(root, #NAME); \
- if (node) { \
- str = config_setting_get_string(node); \
- if (!str) { \
- ret = USBG_ERROR_INVALID_TYPE; \
- goto out; \
- } \
- \
- addr = ether_aton_r(str, &addr_buf); \
- if (!addr) { \
- ret = USBG_ERROR_INVALID_VALUE; \
- goto out; \
- } \
- ret = usbg_set_net_##NAME(f, addr); \
- if (ret != USBG_SUCCESS) \
- goto out; \
- } \
- } while (0)
-
- GET_OPTIONAL_ADDR(host_addr);
- GET_OPTIONAL_ADDR(dev_addr);
-
-#undef GET_OPTIONAL_ADDR
-
- node = config_setting_get_member(root, "qmult");
- if (node) {
- if (!usbg_config_is_int(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
- qmult = config_setting_get_int(node);
- ret = usbg_set_net_qmult(f, qmult);
- }
-
-out:
- return ret;
-}
-
-static int usbg_import_f_ms_lun_attrs(usbg_f_ms_lun_attrs *lattrs,
- config_setting_t *root)
-{
- config_setting_t *node;
- int i;
- int ret = USBG_ERROR_NO_MEM;
-
-#define BOOL_ATTR(_name, _default_val) \
- { .name = #_name, .value = &lattrs->_name, }
- struct {
- char *name;
- bool *value;
- bool default_val;
- } bool_attrs[] = {
- BOOL_ATTR(cdrom, false),
- BOOL_ATTR(ro, false),
- BOOL_ATTR(nofua, false),
- BOOL_ATTR(removable, true),
- };
-#undef BOOL_ATTR
-
- memset(lattrs, 0, sizeof(*lattrs));
- lattrs->id = -1;
-
- for (i = 0; i < ARRAY_SIZE(bool_attrs); ++i) {
- *(bool_attrs[i].value) = bool_attrs[i].default_val;
-
- node = config_setting_get_member(root, bool_attrs[i].name);
- if (!node)
- continue;
-
- ret = config_setting_type(node);
- switch (ret) {
- case CONFIG_TYPE_INT:
- *(bool_attrs[i].value) = !!config_setting_get_int(node);
- break;
- case CONFIG_TYPE_BOOL:
- *(bool_attrs[i].value) = config_setting_get_bool(node);
- break;
- default:
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
- }
-
- node = config_setting_get_member(root, "filename");
- if (node) {
- if (!usbg_config_is_string(node)) {
- ret = USBG_ERROR_INVALID_PARAM;
- goto out;
- }
- lattrs->filename = (char *)config_setting_get_string(node);
- } else {
- lattrs->filename = "";
- }
-
- ret = USBG_SUCCESS;
-out:
- return ret;
-}
-
-static int usbg_import_f_ms_attrs(config_setting_t *root, usbg_function *f)
-{
- config_setting_t *luns_node, *node;
- int i;
- int ret = USBG_ERROR_NO_MEM;
- usbg_function_attrs attrs;
- usbg_f_ms_attrs *ms_attrs = &attrs.attrs.ms;
-
- memset(&attrs, 0, sizeof(attrs));
-
- node = config_setting_get_member(root, "stall");
- if (node) {
- ret = config_setting_type(node);
- switch (ret) {
- case CONFIG_TYPE_INT:
- ms_attrs->stall = !!config_setting_get_int(node);
- break;
- case CONFIG_TYPE_BOOL:
- ms_attrs->stall = config_setting_get_bool(node);
- break;
- default:
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
- }
-
- luns_node = config_setting_get_member(root, "luns");
- if (!node) {
- ret = USBG_ERROR_INVALID_PARAM;
- goto out;
- }
-
- if (!config_setting_is_list(luns_node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
-
- ms_attrs->nluns = config_setting_length(luns_node);
-
- ms_attrs->luns = calloc(ms_attrs->nluns + 1, sizeof(*(ms_attrs->luns)));
- if (!ms_attrs->luns) {
- ret = USBG_ERROR_NO_MEM;
- goto out;
- }
-
- for (i = 0; i < ms_attrs->nluns; ++i) {
- node = config_setting_get_elem(luns_node, i);
- if (!node) {
- ret = USBG_ERROR_INVALID_FORMAT;
- goto free_luns;
- }
-
- if (!config_setting_is_group(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto free_luns;
- }
-
- ms_attrs->luns[i] = malloc(sizeof(*(ms_attrs->luns[i])));
- if (!ms_attrs->luns[i]) {
- ret = USBG_ERROR_NO_MEM;
- goto free_luns;
- }
-
- ret = usbg_import_f_ms_lun_attrs(ms_attrs->luns[i], node);
- if (ret != USBG_SUCCESS)
- goto free_luns;
- }
-
- ret = usbg_set_function_attrs(f, &attrs);
-
-free_luns:
- while (--i >= 0)
- if (ms_attrs->luns[i])
- free(ms_attrs->luns[i]);
- free(ms_attrs->luns);
-out:
- return ret;
-
-}
-
-static int usbg_import_f_midi_attrs(config_setting_t *root, usbg_function *f)
-{
- config_setting_t *node;
- int ret = USBG_ERROR_NO_MEM;
- int tmp;
- usbg_function_attrs attrs;
- usbg_f_midi_attrs *midi_attrs = &attrs.attrs.midi;
-
- attrs.header.attrs_type = USBG_F_ATTRS_MIDI;
-
-#define ADD_F_MIDI_INT_ATTR(attr, defval, minval) \
- do { \
- node = config_setting_get_member(root, #attr); \
- if (node) { \
- if (!usbg_config_is_int(node)) { \
- ret = USBG_ERROR_INVALID_TYPE; \
- goto out; \
- } \
- tmp = config_setting_get_int(node); \
- if (tmp < minval) { \
- ret = USBG_ERROR_INVALID_VALUE; \
- goto out; \
- } \
- midi_attrs->attr = tmp; \
- } else { \
- midi_attrs->attr = defval; \
- } \
- } while (0)
-
- ADD_F_MIDI_INT_ATTR(index, -1, INT_MIN);
- ADD_F_MIDI_INT_ATTR(in_ports, 1, 0);
- ADD_F_MIDI_INT_ATTR(out_ports, 1, 0);
- ADD_F_MIDI_INT_ATTR(buflen, 256, 0);
- ADD_F_MIDI_INT_ATTR(qlen, 32, 0);
-
-#undef ADD_F_MIDI_INT_ATTR
-
- node = config_setting_get_member(root, "id");
- if (node) {
- if (!usbg_config_is_string(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
-
- midi_attrs->id = config_setting_get_string(node);
- } else {
- midi_attrs->id = "";
- }
-
-
- ret = usbg_set_function_attrs(f, &attrs);
-out:
- return ret;
-}
-
-static int usbg_import_f_loopback_attrs(config_setting_t *root, usbg_function *f)
-{
- config_setting_t *node;
- int ret = USBG_ERROR_NO_MEM;
- int tmp;
- usbg_function_attrs attrs;
- usbg_f_loopback_attrs *loopback_attrs = &attrs.attrs.loopback;
-
- attrs.header.attrs_type = USBG_F_ATTRS_LOOPBACK;
-
-#define ADD_F_LOOPBACK_INT_ATTR(attr, defval, minval) \
- do { \
- node = config_setting_get_member(root, #attr); \
- if (node) { \
- if (!usbg_config_is_int(node)) { \
- ret = USBG_ERROR_INVALID_TYPE; \
- goto out; \
- } \
- tmp = config_setting_get_int(node); \
- if (tmp < minval) { \
- ret = USBG_ERROR_INVALID_VALUE; \
- goto out; \
- } \
- loopback_attrs->attr = tmp; \
- } else { \
- loopback_attrs->attr = defval; \
- } \
- } while (0)
-
- ADD_F_LOOPBACK_INT_ATTR(buflen, 4096, 0);
- ADD_F_LOOPBACK_INT_ATTR(qlen, 32, 0);
-
-#undef ADD_F_LOOPBACK_INT_ATTR
-
- ret = usbg_set_function_attrs(f, &attrs);
-out:
- return ret;
-}
-
-static int usbg_import_function_attrs(config_setting_t *root, usbg_function *f)
-{
- int ret = USBG_SUCCESS;
- int attrs_type;
-
- attrs_type = usbg_lookup_function_attrs_type(f->type);
- if (attrs_type < 0) {
- ret = attrs_type;
- goto out;
- }
-
- switch (attrs_type) {
- case USBG_F_ATTRS_SERIAL:
- /* Don't import port_num because it is read only */
- break;
-
- case USBG_F_ATTRS_NET:
- ret = usbg_import_f_net_attrs(root, f);
- break;
-
- case USBG_F_ATTRS_PHONET:
- /* Don't import ifname because it is read only */
- break;
-
- case USBG_F_ATTRS_FFS:
- /* We don't need to import ffs attributes
- * due to instance name import */
- break;
-
- case USBG_F_ATTRS_MS:
- ret = usbg_import_f_ms_attrs(root, f);
- break;
-
- case USBG_F_ATTRS_MIDI:
- ret = usbg_import_f_midi_attrs(root, f);
- break;
-
- case USBG_F_ATTRS_LOOPBACK:
- ret = usbg_import_f_loopback_attrs(root, f);
- break;
-
- default:
- ERROR("Unsupported function type\n");
- ret = USBG_ERROR_NOT_SUPPORTED;
- break;
- }
-
-out:
- return ret;
-}
-
-static int usbg_import_function_run(usbg_gadget *g, config_setting_t *root,
- const char *instance, usbg_function **f)
-{
- config_setting_t *node;
- const char *type_str;
- int usbg_ret;
- int function_type;
- int ret = USBG_ERROR_MISSING_TAG;
-
- /* function type is mandatory */
- node = config_setting_get_member(root, USBG_TYPE_TAG);
- if (!node)
- goto out;
-
- type_str = config_setting_get_string(node);
- if (!type_str) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
-
- /* Check if this type is supported */
- function_type = usbg_lookup_function_type(type_str);
- if (function_type < 0) {
- ret = USBG_ERROR_NOT_SUPPORTED;
- goto out;
- }
-
- /* All data collected, let's get to work and create this function */
- ret = usbg_create_function(g, (usbg_function_type)function_type,
- instance, NULL, f);
-
- if (ret != USBG_SUCCESS)
- goto out;
-
- /* Attrs are optional */
- node = config_setting_get_member(root, USBG_ATTRS_TAG);
- if (node) {
- usbg_ret = usbg_import_function_attrs(node, *f);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
- }
-out:
- return ret;
-}
-
-static usbg_function *usbg_lookup_function(usbg_gadget *g, const char *label)
-{
- usbg_function *f;
- int usbg_ret;
-
- /* check if such function has also been imported */
- TAILQ_FOREACH(f, &g->functions, fnode) {
- if (f->label && !strcmp(f->label, label))
- break;
- }
-
- /* if not let's check if label follows the naming convention */
- if (!f) {
- usbg_function_type type;
- const char *instance;
-
- usbg_ret = split_function_label(label, &type, &instance);
- if (usbg_ret != USBG_SUCCESS)
- goto out;
-
- /* check if such function exist */
- f = usbg_get_function(g, type, instance);
- }
-
-out:
- return f;
-}
-
-/* We have a string which should match with one of function names */
-static int usbg_import_binding_string(config_setting_t *root, usbg_config *c)
-{
- const char *func_label;
- usbg_function *target;
- int ret;
-
- func_label = config_setting_get_string(root);
- if (!func_label) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- target = usbg_lookup_function(c->parent, func_label);
- if (!target) {
- ret = USBG_ERROR_NOT_FOUND;
- goto out;
- }
-
- ret = usbg_add_config_function(c, target->name, target);
-out:
- return ret;
-}
-
-static int usbg_import_binding_group(config_setting_t *root, usbg_config *c)
-{
- config_setting_t *node;
- const char *func_label, *name;
- usbg_function *target;
- int ret;
-
- node = config_setting_get_member(root, USBG_FUNCTION_TAG);
- if (!node) {
- ret = USBG_ERROR_MISSING_TAG;
- goto out;
- }
-
- /* It is allowed to provide link to existing function
- * or define unlabeled instance of function in this place */
- if (usbg_config_is_string(node)) {
- func_label = config_setting_get_string(node);
- if (!func_label) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- target = usbg_lookup_function(c->parent, func_label);
- if (!target) {
- ret = USBG_ERROR_NOT_FOUND;
- goto out;
- }
- } else if (config_setting_is_group(node)) {
- config_setting_t *inst_node;
- const char *instance;
-
- inst_node = config_setting_get_member(node, USBG_INSTANCE_TAG);
- if (!inst_node) {
- ret = USBG_ERROR_MISSING_TAG;
- goto out;
- }
-
- instance = config_setting_get_string(inst_node);
- if (!instance) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
-
- ret = usbg_import_function_run(c->parent, node,
- instance, &target);
- if (ret != USBG_SUCCESS)
- goto out;
- } else {
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
-
- /* Name tag is optional. When no such tag, default one will be used */
- node = config_setting_get_member(root, USBG_NAME_TAG);
- if (node) {
- if (!usbg_config_is_string(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
-
- name = config_setting_get_string(node);
- if (!name) {
- ret = USBG_ERROR_OTHER_ERROR;
- goto out;
- }
- } else {
- name = target->name;
- }
-
- ret = usbg_add_config_function(c, name, target);
-out:
- return ret;
-}
-
-static int usbg_import_config_bindings(config_setting_t *root, usbg_config *c)
-{
- config_setting_t *node;
- int ret = USBG_SUCCESS;
- int count, i;
-
- count = config_setting_length(root);
-
- for (i = 0; i < count; ++i) {
- node = config_setting_get_elem(root, i);
-
- if (usbg_config_is_string(node))
- ret = usbg_import_binding_string(node, c);
- else if (config_setting_is_group(node))
- ret = usbg_import_binding_group(node, c);
- else
- ret = USBG_ERROR_INVALID_TYPE;
-
- if (ret != USBG_SUCCESS)
- break;
- }
-
- return ret;
-}
-
-static int usbg_import_config_strs_lang(config_setting_t *root, usbg_config *c)
-{
- config_setting_t *node;
- int lang;
- const char *str;
- usbg_config_strs c_strs = {{0}};
- int ret = USBG_ERROR_INVALID_TYPE;
-
- node = config_setting_get_member(root, USBG_LANG_TAG);
- if (!node) {
- ret = USBG_ERROR_MISSING_TAG;
- goto out;
- }
-
- if (!usbg_config_is_int(node))
- goto out;
-
- lang = config_setting_get_int(node);
-
- /* Configuration string is optional */
- node = config_setting_get_member(root, "configuration");
- if (node) {
- if (!usbg_config_is_string(node))
- goto out;
-
- str = config_setting_get_string(node);
-
- /* Auto truncate the string to max length */
- strncpy(c_strs.configuration, str, USBG_MAX_STR_LENGTH);
- c_strs.configuration[USBG_MAX_STR_LENGTH - 1] = 0;
- }
-
- ret = usbg_set_config_strs(c, lang, &c_strs);
-
-out:
- return ret;
-}
-
-static int usbg_import_config_strings(config_setting_t *root, usbg_config *c)
-{
- config_setting_t *node;
- int ret = USBG_SUCCESS;
- int count, i;
-
- count = config_setting_length(root);
-
- for (i = 0; i < count; ++i) {
- node = config_setting_get_elem(root, i);
- if (!config_setting_is_group(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- break;
- }
-
- ret = usbg_import_config_strs_lang(node, c);
- if (ret != USBG_SUCCESS)
- break;
- }
-
- return ret;
-}
-
-static int usbg_import_config_attrs(config_setting_t *root, usbg_config *c)
-{
- config_setting_t *node;
- int usbg_ret;
- int bmAttributes, bMaxPower;
- int ret = USBG_ERROR_INVALID_TYPE;
-
- node = config_setting_get_member(root, "bmAttributes");
- if (node) {
- if (!usbg_config_is_int(node))
- goto out;
-
- bmAttributes = config_setting_get_int(node);
- usbg_ret = usbg_set_config_bm_attrs(c, bmAttributes);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
- }
-
- node = config_setting_get_member(root, "bMaxPower");
- if (node) {
- if (!usbg_config_is_int(node))
- goto out;
-
- bMaxPower = config_setting_get_int(node);
- usbg_ret = usbg_set_config_max_power(c, bMaxPower);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
- }
-
- /* Empty attrs section is also considered to be valid */
- ret = USBG_SUCCESS;
-out:
- return ret;
-
-}
-
-static int usbg_import_config_run(usbg_gadget *g, config_setting_t *root,
- int id, usbg_config **c)
-{
- config_setting_t *node;
- const char *name;
- usbg_config *newc;
- int usbg_ret;
- int ret = USBG_ERROR_MISSING_TAG;
-
- /*
- * Label is mandatory,
- * if attrs aren't present defaults are used
- */
- node = config_setting_get_member(root, USBG_NAME_TAG);
- if (!node)
- goto out;
-
- name = config_setting_get_string(node);
- if (!name) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto out;
- }
-
- /* Required data collected, let's create our config */
- usbg_ret = usbg_create_config(g, id, name, NULL, NULL, &newc);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
-
- /* Attrs are optional */
- node = config_setting_get_member(root, USBG_ATTRS_TAG);
- if (node) {
- if (!config_setting_is_group(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto error2;
- }
-
- usbg_ret = usbg_import_config_attrs(node, newc);
- if (usbg_ret != USBG_SUCCESS)
- goto error;
- }
-
- /* Strings are also optional */
- node = config_setting_get_member(root, USBG_STRINGS_TAG);
- if (node) {
- if (!config_setting_is_list(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto error2;
- }
-
- usbg_ret = usbg_import_config_strings(node, newc);
- if (usbg_ret != USBG_SUCCESS)
- goto error;
- }
-
- /* Functions too, because some config may not be
- * fully configured and not contain any function */
- node = config_setting_get_member(root, USBG_FUNCTIONS_TAG);
- if (node) {
- if (!config_setting_is_list(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto error2;
- }
-
- usbg_ret = usbg_import_config_bindings(node, newc);
- if (usbg_ret != USBG_SUCCESS)
- goto error;
- }
-
- *c = newc;
- ret = USBG_SUCCESS;
-out:
- return ret;
-
-error:
- ret = usbg_ret;
-error2:
- /* We ignore returned value, if function fails
- * there is no way to handle it */
- usbg_rm_config(newc, USBG_RM_RECURSE);
- return ret;
-}
-
-static int usbg_import_gadget_configs(config_setting_t *root, usbg_gadget *g)
-{
- config_setting_t *node, *id_node;
- int id;
- usbg_config *c;
- int ret = USBG_SUCCESS;
- int count, i;
-
- count = config_setting_length(root);
-
- for (i = 0; i < count; ++i) {
- node = config_setting_get_elem(root, i);
- if (!node) {
- ret = USBG_ERROR_OTHER_ERROR;
- break;
- }
-
- if (!config_setting_is_group(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- break;
- }
-
- /* Look for id */
- id_node = config_setting_get_member(node, USBG_ID_TAG);
- if (!id_node) {
- ret = USBG_ERROR_MISSING_TAG;
- break;
- }
-
- if (!usbg_config_is_int(id_node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- break;
- }
-
- id = config_setting_get_int(id_node);
-
- ret = usbg_import_config_run(g, node, id, &c);
- if (ret != USBG_SUCCESS)
- break;
- }
-
- return ret;
-}
-
-static int usbg_import_gadget_functions(config_setting_t *root, usbg_gadget *g)
-{
- config_setting_t *node, *inst_node;
- const char *instance;
- const char *label;
- usbg_function *f;
- int ret = USBG_SUCCESS;
- int count, i;
-
- count = config_setting_length(root);
-
- for (i = 0; i < count; ++i) {
- node = config_setting_get_elem(root, i);
- if (!node) {
- ret = USBG_ERROR_OTHER_ERROR;
- break;
- }
-
- if (!config_setting_is_group(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- break;
- }
-
- /* Look for instance name */
- inst_node = config_setting_get_member(node, USBG_INSTANCE_TAG);
- if (!inst_node) {
- ret = USBG_ERROR_MISSING_TAG;
- break;
- }
-
- if (!usbg_config_is_string(inst_node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- break;
- }
-
- instance = config_setting_get_string(inst_node);
- if (!instance) {
- ret = USBG_ERROR_OTHER_ERROR;
- break;
- }
-
- ret = usbg_import_function_run(g, node, instance, &f);
- if (ret != USBG_SUCCESS)
- break;
-
- /* Set the label given by user */
- label = config_setting_name(node);
- if (!label) {
- ret = USBG_ERROR_OTHER_ERROR;
- break;
- }
-
- f->label = strdup(label);
- if (!f->label) {
- ret = USBG_ERROR_NO_MEM;
- break;
- }
- }
-
- return ret;
-}
-
-static int usbg_import_gadget_strs_lang(config_setting_t *root, usbg_gadget *g)
-{
- config_setting_t *node;
- int lang;
- const char *str;
- usbg_gadget_strs g_strs = {{0}};
- int ret = USBG_ERROR_INVALID_TYPE;
-
- node = config_setting_get_member(root, USBG_LANG_TAG);
- if (!node) {
- ret = USBG_ERROR_MISSING_TAG;
- goto out;
- }
-
- if (!usbg_config_is_int(node))
- goto out;
-
- lang = config_setting_get_int(node);
-
- /* Auto truncate the string to max length */
-#define GET_OPTIONAL_GADGET_STR(NAME, FIELD) \
- do { \
- node = config_setting_get_member(root, #NAME); \
- if (node) { \
- if (!usbg_config_is_string(node)) \
- goto out; \
- str = config_setting_get_string(node); \
- strncpy(g_strs.FIELD, str, USBG_MAX_STR_LENGTH); \
- g_strs.FIELD[USBG_MAX_STR_LENGTH - 1] = '\0'; \
- } \
- } while (0)
-
- GET_OPTIONAL_GADGET_STR(manufacturer, str_mnf);
- GET_OPTIONAL_GADGET_STR(product, str_prd);
- GET_OPTIONAL_GADGET_STR(serialnumber, str_ser);
-
-#undef GET_OPTIONAL_GADGET_STR
-
- ret = usbg_set_gadget_strs(g, lang, &g_strs);
-
-out:
- return ret;
-}
-
-static int usbg_import_gadget_strings(config_setting_t *root, usbg_gadget *g)
-{
- config_setting_t *node;
- int ret = USBG_SUCCESS;
- int count, i;
-
- count = config_setting_length(root);
-
- for (i = 0; i < count; ++i) {
- node = config_setting_get_elem(root, i);
- if (!config_setting_is_group(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- break;
- }
-
- ret = usbg_import_gadget_strs_lang(node, g);
- if (ret != USBG_SUCCESS)
- break;
- }
-
- return ret;
-}
-
-
-static int usbg_import_gadget_attrs(config_setting_t *root, usbg_gadget *g)
-{
- config_setting_t *node;
- int usbg_ret;
- int val;
- int ret = USBG_ERROR_INVALID_TYPE;
-
-#define GET_OPTIONAL_GADGET_ATTR(NAME, FUNC_END, TYPE) \
- do { \
- node = config_setting_get_member(root, #NAME); \
- if (node) { \
- if (!usbg_config_is_int(node)) \
- goto out; \
- val = config_setting_get_int(node); \
- if (val < 0 || val > ((1L << (sizeof(TYPE)*8)) - 1)) { \
- ret = USBG_ERROR_INVALID_VALUE; \
- goto out; \
- } \
- usbg_ret = usbg_set_gadget_##FUNC_END(g, (TYPE)val); \
- if (usbg_ret != USBG_SUCCESS) { \
- ret = usbg_ret; \
- goto out; \
- } \
- } \
- } while (0)
-
- GET_OPTIONAL_GADGET_ATTR(bcdUSB, device_bcd_usb, uint16_t);
- GET_OPTIONAL_GADGET_ATTR(bDeviceClass, device_class, uint8_t);
- GET_OPTIONAL_GADGET_ATTR(bDeviceSubClass, device_subclass, uint8_t);
- GET_OPTIONAL_GADGET_ATTR(bDeviceProtocol, device_protocol, uint8_t);
- GET_OPTIONAL_GADGET_ATTR(bMaxPacketSize0, device_max_packet, uint8_t);
- GET_OPTIONAL_GADGET_ATTR(idVendor, vendor_id, uint16_t);
- GET_OPTIONAL_GADGET_ATTR(idProduct, product_id, uint16_t);
- GET_OPTIONAL_GADGET_ATTR(bcdDevice, device_bcd_device, uint16_t);
-
-#undef GET_OPTIONAL_GADGET_ATTR
-
- /* Empty attrs section is also considered to be valid */
- ret = USBG_SUCCESS;
-out:
- return ret;
-
-}
-
-static int usbg_import_gadget_run(usbg_state *s, config_setting_t *root,
- const char *name, usbg_gadget **g)
-{
- config_setting_t *node;
- usbg_gadget *newg;
- int usbg_ret;
- int ret = USBG_ERROR_MISSING_TAG;
-
- /* There is no mandatory data in gadget so let's start with
- * creating a new gadget */
- usbg_ret = usbg_create_gadget(s, name, NULL, NULL, &newg);
- if (usbg_ret != USBG_SUCCESS) {
- ret = usbg_ret;
- goto out;
- }
-
- /* Attrs are optional */
- node = config_setting_get_member(root, USBG_ATTRS_TAG);
- if (node) {
- if (!config_setting_is_group(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto error2;
- }
-
- usbg_ret = usbg_import_gadget_attrs(node, newg);
- if (usbg_ret != USBG_SUCCESS)
- goto error;
- }
-
- /* Strings are also optional */
- node = config_setting_get_member(root, USBG_STRINGS_TAG);
- if (node) {
- if (!config_setting_is_list(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto error2;
- }
-
- usbg_ret = usbg_import_gadget_strings(node, newg);
- if (usbg_ret != USBG_SUCCESS)
- goto error;
- }
-
- /* Functions too, because some gadgets may not be fully
- * configured and don't have any function or have all functions
- * defined inline in configurations */
- node = config_setting_get_member(root, USBG_FUNCTIONS_TAG);
- if (node) {
- if (!config_setting_is_group(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto error2;
- }
- usbg_ret = usbg_import_gadget_functions(node, newg);
- if (usbg_ret != USBG_SUCCESS)
- goto error;
- }
-
- /* Some gadget may not be fully configured
- * so configs are also optional */
- node = config_setting_get_member(root, USBG_CONFIGS_TAG);
- if (node) {
- if (!config_setting_is_list(node)) {
- ret = USBG_ERROR_INVALID_TYPE;
- goto error2;
- }
- usbg_ret = usbg_import_gadget_configs(node, newg);
- if (usbg_ret != USBG_SUCCESS)
- goto error;
- }
-
- *g = newg;
- ret = USBG_SUCCESS;
-out:
- return ret;
-
-error:
- ret = usbg_ret;
-error2:
- /* We ignore returned value, if function fails
- * there is no way to handle it */
- usbg_rm_gadget(newg, USBG_RM_RECURSE);
- return ret;
-}
-
-int usbg_import_function(usbg_gadget *g, FILE *stream, const char *instance,
- usbg_function **f)
-{
- config_t *cfg;
- config_setting_t *root;
- usbg_function *newf;
- int ret, cfg_ret;
-
- if (!g || !stream || !instance)
- return USBG_ERROR_INVALID_PARAM;
-
- cfg = malloc(sizeof(*cfg));
- if (!cfg)
- return USBG_ERROR_NO_MEM;
-
- config_init(cfg);
-
- cfg_ret = config_read(cfg, stream);
- if (cfg_ret != CONFIG_TRUE) {
- usbg_set_failed_import(&g->last_failed_import, cfg);
- ret = USBG_ERROR_INVALID_FORMAT;
- goto out;
- }
-
- /* Always successful */
- root = config_root_setting(cfg);
-
- ret = usbg_import_function_run(g, root, instance, &newf);
- if (ret != USBG_SUCCESS) {
- usbg_set_failed_import(&g->last_failed_import, cfg);
- goto out;
- }
-
- if (f)
- *f = newf;
-
- config_destroy(cfg);
- free(cfg);
- /* Clean last error */
- usbg_set_failed_import(&g->last_failed_import, NULL);
-out:
- return ret;
-
-}
-
-int usbg_import_config(usbg_gadget *g, FILE *stream, int id, usbg_config **c)
-{
- config_t *cfg;
- config_setting_t *root;
- usbg_config *newc;
- int ret, cfg_ret;
-
- if (!g || !stream || id < 0)
- return USBG_ERROR_INVALID_PARAM;
-
- cfg = malloc(sizeof(*cfg));
- if (!cfg)
- return USBG_ERROR_NO_MEM;
-
- config_init(cfg);
-
- cfg_ret = config_read(cfg, stream);
- if (cfg_ret != CONFIG_TRUE) {
- usbg_set_failed_import(&g->last_failed_import, cfg);
- ret = USBG_ERROR_INVALID_FORMAT;
- goto out;
- }
-
- /* Always successful */
- root = config_root_setting(cfg);
-
- ret = usbg_import_config_run(g, root, id, &newc);
- if (ret != USBG_SUCCESS) {
- usbg_set_failed_import(&g->last_failed_import, cfg);
- goto out;
- }
-
- if (c)
- *c = newc;
-
- config_destroy(cfg);
- free(cfg);
- /* Clean last error */
- usbg_set_failed_import(&g->last_failed_import, NULL);
-out:
- return ret;
-}
-
-int usbg_import_gadget(usbg_state *s, FILE *stream, const char *name,
- usbg_gadget **g)
-{
- config_t *cfg;
- config_setting_t *root;
- usbg_gadget *newg;
- int ret, cfg_ret;
-
- if (!s || !stream || !name)
- return USBG_ERROR_INVALID_PARAM;
-
- cfg = malloc(sizeof(*cfg));
- if (!cfg)
- return USBG_ERROR_NO_MEM;
-
- config_init(cfg);
-
- cfg_ret = config_read(cfg, stream);
- if (cfg_ret != CONFIG_TRUE) {
- usbg_set_failed_import(&s->last_failed_import, cfg);
- ret = USBG_ERROR_INVALID_FORMAT;
- goto out;
- }
-
- /* Always successful */
- root = config_root_setting(cfg);
-
- ret = usbg_import_gadget_run(s, root, name, &newg);
- if (ret != USBG_SUCCESS) {
- usbg_set_failed_import(&s->last_failed_import, cfg);
- goto out;
- }
-
- if (g)
- *g = newg;
-
- config_destroy(cfg);
- free(cfg);
- /* Clean last error */
- usbg_set_failed_import(&s->last_failed_import, NULL);
-out:
- return ret;
-}
-
-const char *usbg_get_func_import_error_text(usbg_gadget *g)
-{
- if (!g || !g->last_failed_import)
- return NULL;
-
- return config_error_text(g->last_failed_import);
-}
-
-int usbg_get_func_import_error_line(usbg_gadget *g)
-{
- if (!g || !g->last_failed_import)
- return -1;
-
- return config_error_line(g->last_failed_import);
-}
-
-const char *usbg_get_config_import_error_text(usbg_gadget *g)
-{
- if (!g || !g->last_failed_import)
- return NULL;
-
- return config_error_text(g->last_failed_import);
-}
-
-int usbg_get_config_import_error_line(usbg_gadget *g)
-{
- if (!g || !g->last_failed_import)
- return -1;
-
- return config_error_line(g->last_failed_import);
-}
-
-const char *usbg_get_gadget_import_error_text(usbg_state *s)
-{
- if (!s || !s->last_failed_import)
- return NULL;
-
- return config_error_text(s->last_failed_import);
-}
-
-int usbg_get_gadget_import_error_line(usbg_state *s)
-{
- if (!s || !s->last_failed_import)
- return -1;
-
- return config_error_line(s->last_failed_import);
-}
-
diff --git a/src/usbg_schemes_none.c b/src/usbg_schemes_none.c
deleted file mode 100644
index 915890c..0000000
--- a/src/usbg_schemes_none.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- */
-
-#include <usbg/usbg.h>
-#include "usbg/usbg_internal.h"
-
-int usbg_export_function(__attribute__ ((unused)) usbg_function *f,
- __attribute__ ((unused)) FILE *stream)
-{
- return USBG_ERROR_NOT_SUPPORTED;
-}
-
-int usbg_export_config(__attribute__ ((unused)) usbg_config *c,
- __attribute__ ((unused)) FILE *stream)
-{
- return USBG_ERROR_NOT_SUPPORTED;
-}
-
-int usbg_export_gadget(__attribute__ ((unused)) usbg_gadget *g,
- __attribute__ ((unused)) FILE *stream)
-{
- return USBG_ERROR_NOT_SUPPORTED;
-}
-
-int usbg_import_function(__attribute__ ((unused)) usbg_gadget *g,
- __attribute__ ((unused)) FILE *stream,
- __attribute__ ((unused)) const char *instance,
- __attribute__ ((unused)) usbg_function **f)
-{
- return USBG_ERROR_NOT_SUPPORTED;
-}
-
-int usbg_import_config(__attribute__ ((unused)) usbg_gadget *g,
- __attribute__ ((unused)) FILE *stream,
- __attribute__ ((unused)) int id,
- __attribute__ ((unused)) usbg_config **c)
-{
- return USBG_ERROR_NOT_SUPPORTED;
-}
-
-int usbg_import_gadget(__attribute__ ((unused)) usbg_state *s,
- __attribute__ ((unused)) FILE *stream,
- __attribute__ ((unused)) const char *name,
- __attribute__ ((unused)) usbg_gadget **g)
-{
- return USBG_ERROR_NOT_SUPPORTED;
-}
-
-const char *usbg_get_func_import_error_text(
- __attribute__ ((unused)) usbg_gadget *g)
-{
- return NULL;
-}
-
-int usbg_get_func_import_error_line(__attribute__ ((unused)) usbg_gadget *g)
-{
- return USBG_ERROR_NOT_SUPPORTED;
-}
-
-const char *usbg_get_config_import_error_text(
- __attribute__ ((unused)) usbg_gadget *g)
-{
- return NULL;
-}
-
-int usbg_get_config_import_error_line(__attribute__ ((unused)) usbg_gadget *g)
-{
- return USBG_ERROR_NOT_SUPPORTED;
-}
-
-const char *usbg_get_gadget_import_error_text(
- __attribute__ ((unused)) usbg_state *s)
-{
- return NULL;
-}
-
-int usbg_get_gadget_import_error_line(__attribute__ ((unused)) usbg_state *s)
-{
- return USBG_ERROR_NOT_SUPPORTED;
-}
-
-void config_destroy(__attribute__ ((unused)) config_t *config)
-{
- return;
-}
diff --git a/tests/Makefile.am b/tests/Makefile.am
deleted file mode 100644
index 01feea4..0000000
--- a/tests/Makefile.am
+++ /dev/null
@@ -1,14 +0,0 @@
-check_PROGRAMS = test
-test_SOURCES = test.c usbg-test.c usbg-io-wrappers.c
-test_LDFLAGS = -ldl
-test_LDFLAGS += $(CMOCKA_LIBS)
-test_LDFLAGS += $(LIBCONFIG_LIBS)
-test_LDADD = ./libusbgx.so
-test_CPPFLAGS = -I$(top_srcdir)/include/
-
-./libusbgx.so:
- -ln -s $(top_srcdir)/src/.libs/libusbgx.so* .
-CLEANFILES = libusbgx.so*
-
-check_SCRIPTS = ./test.sh
-TESTS = $(check_SCRIPTS)
diff --git a/tests/test.c b/tests/test.c
deleted file mode 100644
index bd17af9..0000000
--- a/tests/test.c
+++ /dev/null
@@ -1,2697 +0,0 @@
-#include <usbg/usbg.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <time.h>
-
-#ifdef HAS_LIBCONFIG
-#include <libconfig.h>
-#endif
-
-#include "usbg-test.h"
-
-/**
- * @file tests/test.c
- */
-
-#define USBG_TEST(name, test, setup, teardown) \
- {name, test, setup, teardown}
-
-#define FILLED_STR(len, c) \
- { [0 ... len - 2] = c, [len - 1] = '\0' }
-
-/* two levels of macros allow to strigify result of macro expansion */
-#define STR(s) #s
-#define XSTR(s) STR(s)
-/* unique string */
-#define UNIQUE XSTR(__COUNTER__)
-
-#define FUNC_FROM_TYPE(t) { \
- .type = t, \
- .instance = "instance"UNIQUE \
-}
-
-#define CONF_FROM_BOUND(b) { \
- .label = "c", \
- .id = __COUNTER__, \
- .bound_funcs = b \
-}
-
-static usbg_gadget_attrs min_gadget_attrs = {
- .bcdUSB = 0x0000,
- .bDeviceClass = 0x0,
- .bDeviceSubClass = 0x0,
- .bDeviceProtocol = 0x0,
- .bMaxPacketSize0 = 0x0,
- .idVendor = 0x0000,
- .idProduct = 0x0000,
- .bcdDevice = 0x0000
-};
-
-static usbg_gadget_attrs max_gadget_attrs = {
- .bcdUSB = 0xffff,
- .bDeviceClass = 0xff,
- .bDeviceSubClass = 0xff,
- .bDeviceProtocol = 0xff,
- .bMaxPacketSize0 = 0xff,
- .idVendor = 0xffff,
- .idProduct = 0xffff,
- .bcdDevice = 0xffff
-};
-
-/* PATH_MAX is limit for path length */
-#define LONG_PATH_LEN PATH_MAX/2
-static char long_path_str[] = FILLED_STR(LONG_PATH_LEN, 'x');
-
-/* NAME_MAX is limit for filename length */
-static char long_usbg_string[] = FILLED_STR(NAME_MAX, 'x');
-
-static usbg_config_strs simple_config_strs= {
- .configuration = "configuration string"
-};
-
-static usbg_config_attrs max_config_attrs = {
- .bmAttributes = 0xff,
- .bMaxPower = 0xff
-};
-
-static usbg_config_attrs min_config_attrs = {
- .bmAttributes = 0x00,
- .bMaxPower = 0x00
-};
-
-/**
- * @brief Simplest udcs names
- * @details Used to go through init when testing other things
- */
-static char *simple_udcs[] = {
- "UDC1",
- "UDC2",
- NULL
-};
-
-static char *long_udcs[] = {
- long_usbg_string,
- "UDC1",
- NULL
-};
-
-/**
- * @brief Simplest functions names
- * @details Used to go through init when testing other things
- */
-static struct test_function simple_funcs[] = {
- FUNC_FROM_TYPE(F_ECM),
- FUNC_FROM_TYPE(F_ACM),
- TEST_FUNCTION_LIST_END
-};
-
-/**
- * @brief All functions types
- * @details When testing with this in state, check if all func types are
- * processed correctly
- */
-static struct test_function all_funcs[] = {
- FUNC_FROM_TYPE(F_SERIAL),
- FUNC_FROM_TYPE(F_ACM),
- FUNC_FROM_TYPE(F_OBEX),
- FUNC_FROM_TYPE(F_ECM),
- FUNC_FROM_TYPE(F_SUBSET),
- FUNC_FROM_TYPE(F_NCM),
- FUNC_FROM_TYPE(F_EEM),
- FUNC_FROM_TYPE(F_RNDIS),
- FUNC_FROM_TYPE(F_PHONET),
- FUNC_FROM_TYPE(F_FFS),
- TEST_FUNCTION_LIST_END
-};
-
-static struct test_function same_type_funcs[] = {
- FUNC_FROM_TYPE(F_SERIAL),
- FUNC_FROM_TYPE(F_SERIAL),
- FUNC_FROM_TYPE(F_SERIAL),
- TEST_FUNCTION_LIST_END
-};
-
-/**
- * @brief No functions at all
- * @details Check if gadget with no functions (or config with no bindings)
- * is processed correctly.
- */
-static struct test_function no_funcs[] = {
- TEST_FUNCTION_LIST_END
-};
-
-/**
- * @brief Simple configs
- * @details Used to pass through init when testing other things
- */
-static struct test_config simple_confs[] = {
- CONF_FROM_BOUND(simple_funcs),
- TEST_CONFIG_LIST_END
-};
-
-/**
- * @brief Configs bound to all avaible function types
- */
-static struct test_config all_bindings_confs[] = {
- CONF_FROM_BOUND(no_funcs),
- CONF_FROM_BOUND(all_funcs),
- TEST_CONFIG_LIST_END
-};
-
-#define GADGET(n, u, c, f) \
- { \
- .name = n, \
- .udc = u, \
- .configs = c, \
- .functions = f \
- }
-
-/**
- * @brief Simplest gadget
- */
-static struct test_gadget simple_gadgets[] = {
- GADGET("g1", "UDC1", simple_confs, simple_funcs),
- TEST_GADGET_LIST_END
-};
-
-/**
- * @brief Gadgets with all avaible functions
- */
-static struct test_gadget all_funcs_gadgets[] = {
- GADGET("all_funcs_gadget1", "UDC1", all_bindings_confs, all_funcs),
- TEST_GADGET_LIST_END
-};
-
-static struct test_gadget long_udc_gadgets[] = {
- GADGET("long_udc_gadgets", long_usbg_string, simple_confs, simple_funcs),
- TEST_GADGET_LIST_END
-};
-
-struct test_function_attrs_data {
- struct test_state *state;
- usbg_function_attrs *attrs;
-};
-struct test_data {
- struct test_state *state;
- struct usbg_state *usbg_state;
-};
-
-#define FUNC_ATTRS(t, label, a...) { \
- .header = { \
- .attrs_type = t \
- }, \
- .attrs = { \
- .label = { a } \
- }, \
-}
-
-static usbg_function_attrs simple_serial_attrs = FUNC_ATTRS(USBG_F_ATTRS_SERIAL, serial, 42);
-static usbg_function_attrs simple_net_attrs = FUNC_ATTRS(USBG_F_ATTRS_NET, net, {}, {}, "if", 1);
-static usbg_function_attrs simple_phonet_attrs = FUNC_ATTRS(USBG_F_ATTRS_PHONET, phonet, "if");
-static usbg_function_attrs writable_serial_attrs = FUNC_ATTRS(USBG_F_ATTRS_SERIAL, serial, 0);
-static usbg_function_attrs writable_net_attrs = FUNC_ATTRS(USBG_F_ATTRS_NET, net, {}, {}, "", 42);
-static usbg_function_attrs writable_phonet_attrs = FUNC_ATTRS(USBG_F_ATTRS_PHONET, phonet, "");
-static usbg_function_attrs simple_ffs_attrs = FUNC_ATTRS(USBG_F_ATTRS_FFS, ffs, "0");
-static usbg_function_attrs writable_ffs_attrs = FUNC_ATTRS(USBG_F_ATTRS_FFS, ffs, "");
-
-struct test_gadget_strs_data {
- struct test_state *state;
- usbg_gadget_strs *strs;
-};
-
-#define STATE(p, g, u) { \
- .configfs_path = p, \
- .gadgets = g, \
- .udcs = u \
-}
-
-/**
- * @brief Simple state
- */
-static struct test_state simple_state = STATE("config", simple_gadgets, simple_udcs);
-
-/**
- * @brief State with all functions avaible
- */
-static struct test_state all_funcs_state = STATE("all_funcs_configfs", all_funcs_gadgets, simple_udcs);
-
-static struct test_state long_path_state = STATE(long_path_str, simple_gadgets, simple_udcs);
-
-static struct test_state long_udc_state = STATE("simple_path", long_udc_gadgets, long_udcs);
-
-static usbg_config_attrs *get_random_config_attrs()
-{
- usbg_config_attrs *ret;
-
- ret = safe_malloc(sizeof(*ret));
-
- srand(time(NULL));
- ret->bmAttributes = rand() % max_config_attrs.bmAttributes;
- ret->bMaxPower = rand() % max_config_attrs.bMaxPower;
-
- return ret;
-}
-
-static usbg_gadget_attrs *get_random_gadget_attrs()
-{
- usbg_gadget_attrs *ret;
-
- ret = safe_malloc(sizeof(*ret));
-
- srand(time(NULL));
- ret->bcdUSB = rand() % max_gadget_attrs.bcdUSB;
- ret->bDeviceClass = rand() % max_gadget_attrs.bDeviceClass;
- ret->bDeviceSubClass = rand() % max_gadget_attrs.bDeviceSubClass;
- ret->bDeviceProtocol = rand() % max_gadget_attrs.bDeviceProtocol;
- ret->bMaxPacketSize0 = rand() % max_gadget_attrs.bMaxPacketSize0;
- ret->idVendor = rand() % max_gadget_attrs.idVendor;
- ret->idProduct = rand() % max_gadget_attrs.idProduct;
- ret->bcdDevice = rand() % max_gadget_attrs.bcdDevice;
-
- return ret;
-}
-
-/**
- * @brief Add given attributes to all configs in state
- * @return Prepared state where configs has given attributes
- */
-static void *prepare_state_with_config_attrs(struct test_state *state,
- usbg_config_attrs *attrs)
-{
- struct test_gadget *tg;
- struct test_config *tc;
-
- for (tg = state->gadgets; tg->name; ++tg)
- for (tc = tg->configs; tc->label; ++tc)
- tc->attrs = attrs;
-
- state = prepare_state(state);
- return state;
-}
-
-static int setup_max_config_attrs_state(void **state)
-{
- *state = prepare_state_with_config_attrs(&simple_state, &max_config_attrs);
- return 0;
-}
-
-static int setup_min_config_attrs_state(void **state)
-{
- *state = prepare_state_with_config_attrs(&simple_state, &min_config_attrs);
- return 0;
-}
-
-static int setup_random_config_attrs_state(void **state)
-{
- *state = prepare_state_with_config_attrs(&simple_state, get_random_config_attrs());
- return 0;
-}
-
-static int setup_simple_config_strs_state(void **state)
-{
- struct test_gadget *tg;
- struct test_config *tc;
-
- for (tg = simple_state.gadgets; tg->name; ++tg)
- for (tc = tg->configs; tc->label; ++tc)
- tc->strs = &simple_config_strs;
-
- *state = prepare_state(&simple_state);
- return 0;
-}
-
-/**
- * @brief Prepare test_state with one gadget containing given function list
- * @details For testing only functions. We put them in a gadget as simply
- * as possible.
- * @param[in] func Pointer to list of functions
- * @return Pointer to test state with given functions
- */
-static struct test_state *put_func_in_state(struct test_function *func)
-{
- struct test_state *st;
- struct test_gadget *g;
- struct test_config *c;
- char **udcs;
-
- st = safe_calloc(1, sizeof(*st));
- /* Do not need config */
- c = safe_calloc(1, sizeof(*c));
- g = safe_calloc(2, sizeof(*g));
- udcs = safe_calloc(2, sizeof(*udcs));
-
- g[0].name = "g1";
- g[0].udc = "UDC1";
- g[0].configs = c;
- g[0].functions = func;
- g[0].writable = 1;
-
- udcs[0] = "UDC1";
- g[0].writable = 1;
-
- st->configfs_path = "config";
- st->gadgets = g;
- st->udcs = udcs;
- st->writable = 1;
-
- st = prepare_state(st);
-
- return st;
-}
-
-/**
- * @brief Setup simple state with some gadgets, configs and functions
- */
-static int setup_simple_state(void **state)
-{
- *state = prepare_state(&simple_state);
- return 0;
-}
-
-/**
- * @brief Setup state with all avaible functions
- */
-static int setup_all_funcs_state(void **state)
-{
- *state = prepare_state(&all_funcs_state);
- return 0;
-}
-
-/**
- * @brief Setup state with few functions of the same type
- */
-static int setup_same_type_funcs_state(void **state)
-{
- *state = put_func_in_state(same_type_funcs);
- return 0;
-}
-
-/**
- * @brief Setup state with very long path name
- */
-static int setup_long_path_state(void **state)
-{
- *state = prepare_state(&long_path_state);
- return 0;
-}
-
-/**
- * @brief Setup state with long udc name
- */
-static int setup_long_udc_state(void **state)
-{
- *state = prepare_state(&long_udc_state);
- return 0;
-}
-
-/**
- * @brief Setup state with gadget strings of random length
- * @param[out] state Pointer to pointer to test_gadget_strs_data structure
- * with initialized state and strings
- */
-static int setup_random_len_gadget_strs_data(void **state)
-{
- usbg_gadget_strs *strs;
- struct test_gadget_strs_data *data;
-
- /* will fill memory with zeros */
- strs = safe_calloc(1, sizeof(*strs));
- data = safe_malloc(sizeof(*data));
-
- srand(time(NULL));
-
- memset(strs->str_ser, 'x', rand() % USBG_MAX_STR_LENGTH);
- memset(strs->str_mnf, 'x', rand() % USBG_MAX_STR_LENGTH);
- memset(strs->str_prd, 'x', rand() % USBG_MAX_STR_LENGTH);
-
- data->strs = strs;
-
- data->state = prepare_state(&simple_state);
- *state = data;
- return 0;
-}
-
-static void *setup_f_attrs(int f_type, usbg_function_attrs *attrs)
-{
- struct test_function_attrs_data *data;
- struct test_function *func;
-
- data = safe_malloc(sizeof(*data));
-
- func = safe_calloc(2, sizeof(*func));
- func[0].type = f_type;
- func[0].instance = "0";
- func[0].writable = 1;
-
- data->state = put_func_in_state(func);
- data->attrs = attrs;
- return data;
-}
-
-static int setup_f_serial_attrs(void **state)
-{
- *state = setup_f_attrs(F_SERIAL, &simple_serial_attrs);
- return 0;
-}
-
-static int setup_f_serial_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_SERIAL, &writable_serial_attrs);
- return 0;
-}
-
-static int setup_f_acm_attrs(void **state)
-{
- *state = setup_f_attrs(F_ACM, &simple_serial_attrs);
- return 0;
-}
-
-static int setup_f_acm_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_ACM, &writable_serial_attrs);
- return 0;
-}
-
-static int setup_f_obex_attrs(void **state)
-{
- *state = setup_f_attrs(F_OBEX, &simple_serial_attrs);
- return 0;
-}
-
-static int setup_f_obex_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_OBEX, &writable_serial_attrs);
- return 0;
-}
-
-static int setup_f_ecm_attrs(void **state)
-{
- *state = setup_f_attrs(F_ECM, &simple_net_attrs);
- return 0;
-}
-
-static int setup_f_ecm_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_ECM, &writable_net_attrs);
- return 0;
-}
-
-static int setup_f_subset_attrs(void **state)
-{
- *state = setup_f_attrs(F_SUBSET, &simple_net_attrs);
- return 0;
-}
-
-static int setup_f_subset_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_SUBSET, &writable_net_attrs);
- return 0;
-}
-
-static int setup_f_ncm_attrs(void **state)
-{
- *state = setup_f_attrs(F_NCM, &simple_net_attrs);
- return 0;
-}
-
-static int setup_f_ncm_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_NCM, &writable_net_attrs);
- return 0;
-}
-
-static int setup_f_eem_attrs(void **state)
-{
- *state = setup_f_attrs(F_EEM, &simple_net_attrs);
- return 0;
-}
-
-static int setup_f_eem_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_EEM, &writable_net_attrs);
- return 0;
-}
-
-static int setup_f_rndis_attrs(void **state)
-{
- *state = setup_f_attrs(F_RNDIS, &simple_net_attrs);
- return 0;
-}
-
-static int setup_f_rndis_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_RNDIS, &writable_net_attrs);
- return 0;
-}
-
-static int setup_f_phonet_attrs(void **state)
-{
- *state = setup_f_attrs(F_PHONET, &simple_phonet_attrs);
- return 0;
-}
-
-static int setup_f_phonet_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_PHONET, &writable_phonet_attrs);
- return 0;
-}
-
-static int setup_f_ffs_attrs(void **state)
-{
- *state = setup_f_attrs(F_FFS, &simple_ffs_attrs);
- return 0;
-}
-
-static int setup_f_ffs_writable_attrs(void **state)
-{
- *state = setup_f_attrs(F_FFS, &writable_ffs_attrs);
- return 0;
-}
-
-/**
- * @brief Tests usbg_get_gadget function with given state
- * @details Check if gadgets are returned correctly
- */
-static void test_get_gadget(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_gadget(ts, s, assert_gadget_equal);
-}
-
-/**
- * @brief Tests usbg_get_gadget with non-existing gadget name
- * @details Check if get_gadget will not find non-existing gadgets and
- * will not cause crash.
- */
-static void test_get_gadget_fail(void **state)
-{
- usbg_gadget *g = NULL;
- usbg_state *s = NULL;
- struct test_state *st;
-
- safe_init_with_state(state, &st, &s);
-
- g = usbg_get_gadget(s, "non-existing-gadget");
- assert_null(g);
-}
-
-/**
- * @brief Tests usbg_get_first_gadget function
- * @details Check if gadget returned by get_first_gadget is actually first one
- */
-static void test_get_first_gadget(void **state)
-{
- usbg_gadget *g = NULL;
- usbg_state *s = NULL;
- struct test_state *st;
-
- safe_init_with_state(state, &st, &s);
-
- g = usbg_get_first_gadget(s);
- assert_non_null(g);
- assert_gadget_equal(g, &st->gadgets[0]);
-}
-
-/**
- * @brief Tests get_first_gadget with invalid arguments
- */
-static void test_get_first_gadget_fail(void **state)
-{
- usbg_gadget *g;
-
- g = usbg_get_first_gadget(NULL);
- assert_null(g);
-}
-
-static void try_get_gadget_name(usbg_gadget *g, struct test_gadget *tg)
-{
- const char *name;
-
- name = usbg_get_gadget_name(g);
- assert_string_equal(name, tg->name);
-}
-
-/**
- * @brief Tests getting name of gadget
- * @details Check if gadget name is returned correctly
- */
-static void test_get_gadget_name(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_gadget(ts, s, try_get_gadget_name);
-}
-
-static void try_get_gadget_name_len(usbg_gadget *g, struct test_gadget *tg)
-{
- int len;
- int expected;
-
- expected = strlen(tg->name);
- len = usbg_get_gadget_name_len(g);
- assert_int_equal(len, expected);
-}
-
-/**
- * @brief Tests getting name length of gadget
- * @details Check if returned name length is equal original
- */
-static void test_get_gadget_name_len(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_gadget(ts, s, try_get_gadget_name_len);
-}
-
-/**
- * @brief Tests getting name of gadget with invalid arguments
- * @details Check if trying to get name of wrong (non-existing) gadget
- * will not cause crash, but return NULL as expected.
- */
-static void test_get_gadget_name_fail(void **state)
-{
- const char *name;
-
- name = usbg_get_gadget_name(NULL);
- assert_null(name);
-}
-
-static void try_cpy_gadget_name(usbg_gadget *g, struct test_gadget *tg)
-{
- char name[USBG_MAX_NAME_LENGTH];
- int ret;
-
- ret = usbg_cpy_gadget_name(g, name, USBG_MAX_NAME_LENGTH);
- assert_int_equal(ret, USBG_SUCCESS);
- assert_string_equal(name, tg->name);
-}
-
-/**
- * @brief Tests copying gadget's name
- * @details Check if copying gadget name copy actual name correctly
- */
-static void test_cpy_gadget_name(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_gadget(ts, s, try_cpy_gadget_name);
-}
-
-/**
- * @brief Test copying gadet name with invalid arguments
- * @details Check if trying to copy gadget name into non-existing buffer,
- * or give invalid buffer length, or invalid gadget will be handled by library
- * and return correct error codes
- */
-static void test_cpy_gadget_name_fail(void **state)
-{
- usbg_gadget *g = NULL;
- usbg_state *s = NULL;
- struct test_state *st;
- int i = 0;
- char name[USBG_MAX_NAME_LENGTH];
- int ret;
-
- safe_init_with_state(state, &st, &s);
-
- for (i = 0; st->gadgets[i].name; i++) {
- g = usbg_get_gadget(s, st->gadgets[i].name);
- assert_non_null(g);
-
- ret = usbg_cpy_gadget_name(g, name, 0);
- assert_int_equal(ret, USBG_ERROR_INVALID_PARAM);
-
- ret = usbg_cpy_gadget_name(g, NULL, USBG_MAX_NAME_LENGTH);
- assert_int_equal(ret, USBG_ERROR_INVALID_PARAM);
- }
-
- ret = usbg_cpy_gadget_name(NULL, name, USBG_MAX_NAME_LENGTH);
- assert_int_equal(ret, USBG_ERROR_INVALID_PARAM);
-}
-
-/**
- * @brief Tests init by comparing test state and usbg state
- * @details Check if usbg state after init match given state and
- * if init returned success code
- */
-static void test_init(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *st;
-
- safe_init_with_state(state, &st, &s);
-
- assert_state_equal(s, st);
-}
-
-/**
- * @brief Test getting function by name
- * @param[in] state Pointer to pointer to correctly initialized test_state structure
- */
-static void test_get_function(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_function(ts, s, assert_func_equal);
-}
-
-/**
- * @brief Tests usbg_get_function with some non-existing functions
- * @details Check if get function will return NULL, when invalid
- * functions names and types are passed as arguments and will not cause crash.
- * @param[in] state Pointer to pointer to correctly initialized test_state structure
- */
-static void test_get_function_fail(void **state)
-{
- usbg_state *s = NULL;
- usbg_gadget *g = NULL;
- usbg_function *f = NULL;
- struct test_state *st;
-
- safe_init_with_state(state, &st, &s);
-
- g = usbg_get_first_gadget(s);
- assert_non_null(g);
-
- f = usbg_get_function(g, F_ACM, "non-existing-instance");
- assert_null(f);
-
- f = usbg_get_function(g, 9001, "0");
- assert_null(f);
-}
-
-
-/**
- * @brief Tests function type translation to string
- * @param[in] state Pointer to pointer to correctly initialized test_state structure
- * @details Check if get_function_type_str returns proper strings for all types.
- */
-static void test_get_function_type_str(void **state)
-{
- struct {
- usbg_function_type type;
- const char *str;
- } types[] = {
- {F_SERIAL, "gser"},
- {F_ACM, "acm"},
- {F_OBEX, "obex"},
- {F_ECM, "ecm"},
- {F_SUBSET, "geth"},
- {F_NCM, "ncm"},
- {F_EEM, "eem"},
- {F_RNDIS, "rndis"},
- {F_PHONET, "phonet"},
- {F_FFS, "ffs"},
- };
-
- const char *str;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(types); i++) {
- str = usbg_get_function_type_str(types[i].type);
- assert_non_null(str);
- assert_string_equal(str, types[i].str);
- }
-}
-
-static struct {
- usbg_gadget_str code;
- const char *name;
-} gadget_str_names[] = {
- {STR_PRODUCT, "product"},
- {STR_MANUFACTURER, "manufacturer"},
- {STR_SERIAL_NUMBER, "serialnumber"},
-};
-
-/**
- * @brief Tests gadget codeing name getting
- * @param[in] state Pointer to pointer to correctly initialized test_state codeucture
- * @details Check if usbg_get_gadget_code_name returns proper codeings for all types.
- */
-static void test_get_gadget_str_name(void **state)
-{
- const char *name;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(gadget_str_names); i++) {
- name = usbg_get_gadget_str_name(gadget_str_names[i].code);
- assert_non_null(name);
- assert_string_equal(name, gadget_str_names[i].name);
- }
-}
-
-/**
- * @brief Tests gadget codeing code getting by its name
- * @param[in] state Pointer to pointer to correctly initialized test_state codeucture
- * @details Check if usbg_lookup_gadget_code returns values matching codeings
- */
-static void test_lookup_gadget_str(void **state)
-{
- int i, code;
-
- for (i = 0; i < ARRAY_SIZE(gadget_str_names); i++) {
- code = usbg_lookup_gadget_str(gadget_str_names[i].name);
- assert_return_code(code, 0);
- assert_int_equal(code, gadget_str_names[i].code);
- }
-}
-
-/**
- * @brief Tests function type translation to string with unknown funcs
- * @param[in] state Not used parameter
- * @details Check if get_function_type_str returns NULL, when given
- * function type is unknown.
- */
-static void test_get_function_type_str_fail(void **state)
-{
- const char *str;
-
- str = usbg_get_function_type_str(-1);
- assert_null(str);
-}
-
-/**
- * @brief Get instance of given function and check it
- * @param[in] f Usbg function
- * @param[in] tf Test function which should match f
- */
-static void try_get_function_instance(usbg_function *f, struct test_function *tf)
-{
- const char *str;
-
- str = usbg_get_function_instance(f);
- assert_string_equal(str, tf->instance);
-}
-
-/**
- * @brief Tests getting function instance from usbg_function structure
- * @param[in] state Pointer to pointer to correctly initialized test_state structure
- * @details Check if returned instance name is correct.
- */
-static void test_get_function_instance(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_function(ts, s, try_get_function_instance);
-}
-
-/**
- * @brief Cpy instance of given usbg function and check it
- * @param[in] f Usbg function
- * @param[in] tf Test function which should match f
- */
-static void try_cpy_function_instance(usbg_function *f, struct test_function *tf)
-{
- char str[USBG_MAX_NAME_LENGTH];
- int ret;
- int small_len = 2;
-
- ret = usbg_cpy_function_instance(f, str, USBG_MAX_NAME_LENGTH);
- assert_int_equal(ret, USBG_SUCCESS);
- assert_string_equal(str, tf->instance);
-
- ret = usbg_cpy_function_instance(f, str, small_len);
- assert_int_equal(ret, USBG_SUCCESS);
- assert_memory_equal(str, tf->instance, small_len - 1);
- assert_int_equal(str[small_len - 1], '\0');
-}
-
-/**
- * @brief Tests copying function instance from usbg_function structure into buffer
- * @param[in] state Pointer to pointer to correctly initialized state
- * @details Check if buffer contains expected string
- */
-static void test_cpy_function_instance(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_function(ts, s, try_cpy_function_instance);
-}
-
-/**
- * @brief Get function type and check it
- * @param[in] f Usbg function
- * @param[in] tf Test function which should match f by type
- */
-static void try_get_function_type(usbg_function *f, struct test_function *tf)
-{
- usbg_function_type type;
-
- type = usbg_get_function_type(f);
- assert_int_equal(type, tf->type);
-}
-
-/**
- * @brief Tests getting function type
- * @details Check if getting function type returns what was expected.
- * State must be proper (init must end with success).
- * @param[in] state Pointer to pointer to correctly initialized state
- */
-static void test_get_function_type(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_function(ts, s, try_get_function_type);
-}
-
-/**
- * @brief Check if function instance length is correct
- * @param[in] f Usbg function
- * @param[in] tf Test function which should match f
- */
-static void try_get_function_instance_len(usbg_function *f, struct test_function *tf)
-{
- size_t len;
- len = usbg_get_function_instance_len(f);
- assert_int_equal(len, strlen(tf->instance));
-}
-
-/**
- * @brief Tests getting length of function instance name
- * @details Check if returned instance name length matches
- * actual length of instance name
- * @param[in] state Pointer to pointer to correctly initialized state
- */
-static void test_get_function_instance_len(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_function(ts, s, try_get_function_instance_len);
-}
-
-/**
- * @brief Tests getting configfs path from usbg state
- * @param[in,out] state Pointer to pointer to correctly initialized test state.
- * When finished, it contains pointer to usbg_state which should be cleaned.
- */
-static void test_get_configfs_path(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *st;
- const char *path;
-
- safe_init_with_state(state, &st, &s);
-
- path = usbg_get_configfs_path(s);
- assert_path_equal(path, st->configfs_path);
-}
-
-/**
- * @brief Tests getting configfs path length from usbg state
- * @param[in,out] state Pointer to pointer to correctly initialized test state.
- * When finished, it contains pointer to usbg_state which should be cleaned.
- */
-static void test_get_configfs_path_len(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *st;
- int ret, len;
-
- safe_init_with_state(state, &st, &s);
-
- ret = usbg_get_configfs_path_len(s);
- len = strlen(st->configfs_path);
- assert_int_equal(ret, len);
-}
-
-/**
- * @brief Tests copying configfs path into buffer
- * @param[in,out] state Pointer to pointer to correctly initialized test state.
- * When finished, it contains pointer to usbg_state which should be cleaned.
- */
-static void test_cpy_configfs_path(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *st;
- char path[PATH_MAX];
- int ret;
-
- safe_init_with_state(state, &st, &s);
-
- ret = usbg_cpy_configfs_path(s, path, PATH_MAX);
- assert_int_equal(ret, USBG_SUCCESS);
- assert_path_equal(path, st->configfs_path);
-}
-
-/**
- * @brief Tests getting config by name
- * @param[in,out] state Pointer to pointer to correctly initialized test state.
- * When finished, it contains pointer to usbg_state which should be cleaned.
- */
-static void test_get_config(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_config(ts, s, assert_config_equal);
-}
-
-static void test_get_config_without_label(void **state)
-{
- usbg_state *s = NULL;
- usbg_gadget *g = NULL;
- usbg_config *c = NULL;
- struct test_state *ts;
- struct test_gadget *tg;
- struct test_config *tc;
-
- safe_init_with_state(state, &ts, &s);
-
- for (tg = ts->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
- for (tc = tg->configs; tc->label; tc++) {
- c = usbg_get_config(g, tc->id, NULL);
- assert_non_null(c);
- assert_config_equal(c, tc);
- }
- }
-}
-
-/**
- * @bried Tests getting non-existing config
- * @param[in,out] state Pointer to pointer to correctly initialized test state.
- * When finished, it contains pointer to usbg_state which should be cleaned.
- */
-static void test_get_config_fail(void **state)
-{
- usbg_state *s = NULL;
- usbg_gadget *g = NULL;
- usbg_config *c = NULL;
- struct test_state *ts;
- struct test_gadget *tg;
-
- safe_init_with_state(state, &ts, &s);
-
- for (tg = ts->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
-
- c = usbg_get_config(g, 0, "non-existing-config");
- assert_null(c);
-
- c = usbg_get_config(g, -9001, "c");
- assert_null(c);
-
- c = usbg_get_config(g, -9001, NULL);
- assert_null(c);
- }
-}
-
-/**
- * @brief Get config label and check it
- * @param[in] c Usbg config
- * @param[in] tc Test config which should match c
- */
-static void try_get_config_label(usbg_config *c, struct test_config *tc)
-{
- const char *label;
- label = usbg_get_config_label(c);
- assert_string_equal(label, tc->label);
-}
-
-/**
- * @brief Tests getting config label
- * @param[in,out] state Pointer to pointer to correctly initialized test state.
- * When finished, it contains pointer to usbg_state which should be cleaned.
- */
-static void test_get_config_label(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_config(ts, s, try_get_config_label);
-}
-
-/**
- * @brief Check config id with test structure
- * @param[in] c Usbg config
- * @param[in] tc Test config which should match c
- */
-static void try_get_config_id(usbg_config *c, struct test_config *tc)
-{
- int id;
- id = usbg_get_config_id(c);
- assert_int_equal(id, tc->id);
-}
-
-/**
- * @brief Tests getting config id
- * @param[in,out] state Pointer to pointer to correctly initialized test state.
- * When finished, it contains pointer to usbg_state which should be cleaned.
- */
-static void test_get_config_id(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_config(ts, s, try_get_config_id);
-}
-
-/**
- * @brief Test getting given attributes from gadgets present in state
- * @param[in] s Pointer to usbg state
- * @param[in] ts Pointer to test state matching given usbg state
- * @param[in] attrs Pointer to gadget attributes which should be put in
- * virtual filesystem for writting by usbg
- */
-static void try_get_gadget_attrs(usbg_state *s, struct test_state *ts,
- usbg_gadget_attrs *attrs)
-{
- usbg_gadget *g = NULL;
- usbg_gadget_attrs actual;
- struct test_gadget *tg;
- int ret;
-
- for (tg = ts->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
-
- push_gadget_attrs(tg, attrs);
- ret = usbg_get_gadget_attrs(g, &actual);
-
- assert_int_equal(ret, 0);
- assert_gadget_attrs_equal(&actual, attrs);
- }
-}
-
-/**
- * @brief Tests getting gadget attributes
- * @param[in] state Pointer to correctly initialized test_state structure
- **/
-static void test_get_gadget_attrs(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
-
- try_get_gadget_attrs(s, ts, &min_gadget_attrs);
- try_get_gadget_attrs(s, ts, &max_gadget_attrs);
- try_get_gadget_attrs(s, ts, get_random_gadget_attrs());
-}
-
-/**
- * @brief Test setting given attributes on gadgets present in state
- * @param[in] s Pointer to usbg state
- * @param[in] ts Pointer to test state matching given usbg state
- * @param[in] attrs Pointer to gadget attributes to be set
- */
-static void try_set_gadget_attrs(usbg_state *s, struct test_state *ts,
- usbg_gadget_attrs *attrs)
-{
- usbg_gadget *g = NULL;
- struct test_gadget *tg;
- int ret;
-
- for (tg = ts->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
-
- pull_gadget_attrs(tg, attrs);
- ret = usbg_set_gadget_attrs(g, attrs);
-
- assert_int_equal(ret, 0);
- }
-}
-/**
- * @brief Tests setting gadget attributes
- * @param[in] state Pointer to correctly initialized test_state structure
- **/
-static void test_set_gadget_attrs(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
-
- try_set_gadget_attrs(s, ts, &min_gadget_attrs);
- try_set_gadget_attrs(s, ts, &max_gadget_attrs);
- try_set_gadget_attrs(s, ts, get_random_gadget_attrs());
-}
-
-/**
- * @brief Test setting given attributes on gadgets present in state one by one,
- * using functions specific for each attribute
- * @param[in] s Pointer to usbg state
- * @param[in] ts Pointer to test state matching given usbg state
- * @param[in] attrs Pointer to gadget attributes to be set
- */
-static void try_set_specific_gadget_attr(usbg_state *s, struct test_state *ts,
- usbg_gadget_attrs *attrs)
-{
- usbg_gadget *g = NULL;
- struct test_gadget *tg;
- int ret;
- int i;
- int attr;
-
- for (tg = ts->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
-
- for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; i++) {
- attr = get_gadget_attr(attrs, i);
- pull_gadget_attribute(tg, i, attr);
- usbg_set_gadget_attr(g, i, attr);
- assert_int_equal(ret, 0);
- }
- }
-}
-
-/**
- * @brief Tests setting gadget attributes one by one
- * @param[in] state Pointer to correctly initialized test_state structure
- **/
-static void test_set_specific_gadget_attr(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
-
- try_set_specific_gadget_attr(s, ts, &min_gadget_attrs);
- try_set_specific_gadget_attr(s, ts, &max_gadget_attrs);
- try_set_specific_gadget_attr(s, ts, get_random_gadget_attrs());
-}
-
-/**
- * @brief Tests getting udc from state
- * @param[in] state Pointer to correctly initialized test_state structure
- **/
-void test_get_udc(void **state)
-{
- struct test_state *ts;
- char **tu;
- struct test_gadget *tg;
- usbg_state *s = NULL;
- usbg_udc *u = NULL;
- usbg_gadget *g = NULL;
-
- safe_init_with_state(state, &ts, &s);
-
- for (tu = ts->udcs; *tu; tu++) {
- u = usbg_get_udc(s, *tu);
- assert_non_null(u);
- assert_string_equal(*tu, u->name);
- assert_int_equal(s, u->parent);
- }
-
- for (tg = ts->gadgets; tg->name; tg++) {
- u = usbg_get_udc(s, tg->udc);
- g = usbg_get_gadget(s, tg->name);
- assert_int_equal(u->gadget, g);
- }
-}
-
-static void test_get_gadget_attr_str(void **state)
-{
- struct {
- usbg_gadget_attr attr;
- const char *str;
- } attrs[] = {
- {BCD_USB, "bcdUSB"},
- {B_DEVICE_CLASS, "bDeviceClass"},
- {B_DEVICE_SUB_CLASS, "bDeviceSubClass"},
- {B_DEVICE_PROTOCOL, "bDeviceProtocol"},
- {B_MAX_PACKET_SIZE_0, "bMaxPacketSize0"},
- {ID_VENDOR, "idVendor"},
- {ID_PRODUCT, "idProduct"},
- {BCD_DEVICE, "bcdDevice"},
- };
-
- const char *str;
- int i, j;
-
- for (i = 0; i < ARRAY_SIZE(attrs); i++) {
- str = usbg_get_gadget_attr_str(attrs[i].attr);
- assert_non_null(str);
- assert_string_equal(str, attrs[i].str);
- }
-
- /* Check if iteration over values works */
- for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; ++i) {
- str = usbg_get_gadget_attr_str(i);
- assert_non_null(str);
-
- for (j = 0; j < ARRAY_SIZE(attrs); ++j)
- if (attrs[j].attr == i) {
- assert_string_equal(str, attrs[j].str);
- break;
- }
-
- assert_int_not_equal(j, ARRAY_SIZE(attrs));
- }
-}
-
-static void test_get_gadget_attr_str_fail(void **state)
-{
- const char *str;
-
- str = usbg_get_gadget_attr_str(USBG_GADGET_ATTR_MIN - 1);
- assert_null(str);
-
- str = usbg_get_gadget_attr_str(USBG_GADGET_ATTR_MAX);
- assert_null(str);
-}
-
-/**
- * @brief set gadget strings
- * @details Also do it one by one
- * @param[in] data Pointer to correctly initialized test_gadget_strs_data structure
- */
-static void test_set_gadget_strs(void **data)
-{
- struct test_gadget_strs_data *ts;
- struct test_gadget *tg;
- usbg_state *s = NULL;
- usbg_gadget *g = NULL;
- int i;
- int ret;
-
- ts = (struct test_gadget_strs_data *)(*data);
- *data = NULL;
-
- init_with_state(ts->state, &s);
- *data = s;
-
- for (tg = ts->state->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
-
- pull_gadget_strs(tg, LANG_US_ENG, ts->strs);
- ret = usbg_set_gadget_strs(g, LANG_US_ENG, ts->strs);
- assert_int_equal(ret, 0);
-
- for (i = 0; i < GADGET_STR_MAX; i++)
- pull_gadget_string(tg, LANG_US_ENG, i, get_gadget_str(ts->strs, i));
-
- ret = usbg_set_gadget_serial_number(g, LANG_US_ENG, ts->strs->str_ser);
- assert_int_equal(ret, 0);
-
- ret = usbg_set_gadget_manufacturer(g, LANG_US_ENG, ts->strs->str_mnf);
- assert_int_equal(ret, 0);
-
- ret = usbg_set_gadget_product(g, LANG_US_ENG, ts->strs->str_prd);
- assert_int_equal(ret, 0);
-
- for (i = 0; i < GADGET_STR_MAX; i++)
- pull_gadget_string(tg, LANG_US_ENG, i, get_gadget_str(ts->strs, i));
-
-
- ret = usbg_set_gadget_str(g, STR_SERIAL_NUMBER, LANG_US_ENG, ts->strs->str_ser);
- assert_int_equal(ret, 0);
-
- ret = usbg_set_gadget_str(g, STR_MANUFACTURER, LANG_US_ENG, ts->strs->str_mnf);
- assert_int_equal(ret, 0);
-
- ret = usbg_set_gadget_str(g, STR_PRODUCT, LANG_US_ENG, ts->strs->str_prd);
- assert_int_equal(ret, 0);
- }
-}
-
-/**
- * @brief get gadget strings
- * @param[in] data Pointer to correctly initialized test_gadget_strs_data structure
- */
-static void test_get_gadget_strs(void **data)
-{
- struct test_gadget_strs_data *ts;
- struct test_gadget *tg;
- usbg_state *s = NULL;
- usbg_gadget *g = NULL;
- usbg_gadget_strs strs;
-
- ts = (struct test_gadget_strs_data *)(*data);
- *data = NULL;
-
- init_with_state(ts->state, &s);
- *data = s;
-
- for (tg = ts->state->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- push_gadget_strs(tg, LANG_US_ENG, ts->strs);
- usbg_get_gadget_strs(g, LANG_US_ENG, &strs);
- assert_gadget_strs_equal(&strs, ts->strs);
- }
-}
-
-/**
- * @brief Get binding target
- * @details Check if given function is target of given binding
- * @param[in] tb Test function
- * @param[in] b Binding
- */
-static void try_get_binding_target(struct test_binding *tb, usbg_binding *b)
-{
- usbg_function *f;
-
- f = usbg_get_binding_target(b);
- assert_non_null(f);
- assert_func_equal(f, tb->target);
-}
-
-/**
- * @brief Test get binding target
- * @details Test all bindings present in given state
- * @param[in, out] state Pointer to pointer to correctly initialized test state,
- * will point to usbg state when finished.
- */
-static void test_get_binding_target(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_binding(ts, s, try_get_binding_target);
-}
-
-/**
- * @brief Get binding name
- * @details Check if name of given binding is equal name of given function
- * @param[in] tb Test function
- * @param[in] b Binding
- */
-static void try_get_binding_name(struct test_binding *tb, usbg_binding *b)
-{
- const char *s;
-
- s = usbg_get_binding_name(b);
- assert_non_null(s);
- assert_string_equal(s, tb->name);
-}
-
-/**
- * @brief Test get bindig name from all binding present in state
- * @param[in, out] state Pointer to pointer to correctly initialized test state,
- * will point to usbg state when finished.
- */
-static void test_get_binding_name(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_binding(ts, s, try_get_binding_name);
-}
-
-/**
- * @brief Get binding name length
- * @param[in] tb Test function
- * @param[in] b Binding
- */
-static void try_get_binding_name_len(struct test_binding *tb, usbg_binding *b)
-{
- int n;
-
- n = usbg_get_binding_name_len(b);
- assert_int_equal(n, strlen(tb->name));
-}
-
-/**
- * @brief Test get binding name length from all bindings present in state
- * @param[in, out] state Pointer to pointer to correctly initialized test state,
- * will point to usbg state when finished.
- */
-static void test_get_binding_name_len(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_binding(ts, s, try_get_binding_name_len);
-}
-
-/**
- * @brief Set config strings
- * @param[in] c Config on which string should be set
- * @param[in] tc Test config containing strings to be set
- */
-static void try_set_config_strs(usbg_config *c, struct test_config *tc)
-{
- pull_config_strs(tc, LANG_US_ENG, tc->strs);
- usbg_set_config_strs(c, LANG_US_ENG, tc->strs);
-}
-
-/**
- * @brief Test setting strings
- * @details Set strings in all configs present in state
- * @param[in, out] state Pointer to pointer to correctly initialized test state,
- * will point to usbg state when finished.
- */
-static void test_set_config_strs(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_config(ts, s, try_set_config_strs);
-}
-
-/**
- * @brief Set strings one by one on config
- * @param[in] c Config on which string should be set
- * @param[in] tc Test config containing strings to be set
- */
-static void try_set_config_string(usbg_config *c, struct test_config *tc)
-{
- pull_config_string(tc, LANG_US_ENG, tc->strs->configuration);
- usbg_set_config_string(c, LANG_US_ENG, tc->strs->configuration);
-}
-
-/**
- * @brief Test setting strings one by one
- * @details Set strings on all configs present in given state
- * @param[in, out] state Pointer to pointer to correctly initialized test state,
- * will point to usbg state when finished.
- */
-static void test_set_config_string(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_config(ts, s, try_set_config_string);
-}
-
-/**
- * @brief Get config strings
- * @details Assume that given configs have the same strings
- * @param[in] c Config from which strings should be get
- * @param[in] tc Test config expected to have the same string as c
- */
-static void try_get_config_strs(usbg_config *c, struct test_config *tc)
-{
- usbg_config_strs strs;
- push_config_strs(tc, LANG_US_ENG, tc->strs);
- usbg_get_config_strs(c, LANG_US_ENG, &strs);
- assert_string_equal(tc->strs->configuration, strs.configuration);
-}
-
-/**
- * @brief Test getting congig strings
- * @details Get config strings on all configs present in given state
- * @param[in, out] state Pointer to pointer to correctly initialized test state,
- * will point to usbg state when finished.
- */
-static void test_get_config_strs(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_config(ts, s, try_get_config_strs);
-}
-
-/**
- * @brief Get config attributes
- * @details Assume that attributes which will be returned are the same as
- * given test state contains.
- * @param[in] c Usbg config
- * @param[in] tc Test config with set attributes
- */
-static void try_get_config_attrs(usbg_config *c, struct test_config *tc)
-{
- usbg_config_attrs attrs;
-
- push_config_attrs(tc, tc->attrs);
- usbg_get_config_attrs(c, &attrs);
- assert_config_attrs_equal(tc->attrs, &attrs);
-}
-
-/**
- * @brief Test getting config attributes
- * @details Get config attributes on all configfs in state
- * @param[in, out] state Pointer to pointer to correctly initialized test state,
- * will point to usbg state when finished.
- */
-static void test_get_config_attrs(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_config(ts, s, try_get_config_attrs);
-}
-
-/**
- * @brief Set config attributes in given config
- * @param[in] c Usbg config
- * @param[in] tc Test config with attributes which will be set
- */
-static void try_set_config_attrs(usbg_config *c, struct test_config *tc)
-{
- pull_config_attrs(tc, tc->attrs);
- usbg_set_config_attrs(c, tc->attrs);
-}
-
-/**
- * @brief Test setting config attributes
- * @details Set config attributes on all configs in state
- * @param[in, out] state Pointer to pointer to correctly initialized test state,
- * will point to usbg state when finished.
- */
-static void test_set_config_attrs(void **state)
-{
- usbg_state *s = NULL;
- struct test_state *ts;
-
- safe_init_with_state(state, &ts, &s);
- for_each_test_config(ts, s, try_set_config_attrs);
-}
-
-/**
- * @brieg Test creating config
- * @details Start with empty gadgets, add all functions from given state
- * @param[in, out] state Pointer to pointer to correctly initialized test state,
- * will point to usbg state when finished.
- */
-static void test_create_config(void **state)
-{
- usbg_state *s = NULL;
- usbg_gadget *g = NULL;
- usbg_config *c = NULL;
- struct test_state *ts;
- struct test_state *empty;
- struct test_gadget *tg;
- struct test_config *tc;
-
- ts = (struct test_state *)(*state);
- *state = NULL;
-
- empty = build_empty_gadget_state(ts);
-
- init_with_state(empty, &s);
- *state = s;
-
- for (tg = ts->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
- for (tc = tg->configs; tc->label; tc++) {
- pull_create_config(tc);
- usbg_create_config(g, tc->id, tc->label,
- tc->attrs, tc->strs, &c);
- assert_config_equal(c, tc);
- }
- }
-}
-
-/**
- * @brief Start with empty gadget, add all functions from given one
- */
-static void test_create_function(void **state)
-{
- usbg_state *s = NULL;
- usbg_gadget *g = NULL;
- usbg_function *f = NULL;
- struct test_state *ts;
- struct test_state *empty;
- struct test_gadget *tg;
- struct test_function *tf;
-
- ts = (struct test_state *)(*state);
- *state = NULL;
-
- empty = build_empty_gadget_state(ts);
-
- init_with_state(empty, &s);
- *state = s;
-
- for (tg = ts->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
- for (tf = tg->functions; tf->instance; tf++) {
- pull_create_function(tf);
- usbg_create_function(g, tf->type, tf->instance,
- tf->attrs, &f);
- assert_func_equal(f, tf);
- }
- }
-}
-
-/**
- * @brief Test only one given function for attribute getting
- * @param[in] state Pointer to pointer to correctly initialized state
- */
-static void test_get_function_attrs(void **state)
-{
- struct test_function_attrs_data *data;
- usbg_state *s;
- usbg_function *f;
- usbg_gadget *g;
- usbg_function_attrs actual;
- int ret;
-
- data = (struct test_function_attrs_data *)(*state);
- *state = NULL;
-
-
- init_with_state(data->state, &s);
- *state = s;
-
- g = usbg_get_first_gadget(s);
- assert_non_null(g);
- f = usbg_get_first_function(g);
- assert_non_null(f);
-
- push_function_attrs(&data->state->gadgets[0].functions[0], data->attrs);
- ret = usbg_get_function_attrs(f, &actual);
-
- assert_int_equal(ret, 0);
- assert_function_attrs_equal(&actual, data->attrs, data->attrs->header.attrs_type);
-
- usbg_cleanup_function_attrs(&actual);
-}
-
-/**
- * @brief Test setting attributes in only one given function
- * @param[in] state Pointer to pointer to correctly initialized state
- */
-static void test_set_function_attrs(void **state)
-{
- struct test_function_attrs_data *data;
- usbg_state *s;
- usbg_function *f;
- usbg_gadget *g;
- int ret;
-
- data = (struct test_function_attrs_data *)(*state);
- *state = NULL;
-
- init_with_state(data->state, &s);
- *state = s;
-
- g = usbg_get_first_gadget(s);
- assert_non_null(g);
- f = usbg_get_first_function(g);
- assert_non_null(f);
-
- pull_function_attrs(&data->state->gadgets[0].functions[0], data->attrs);
- ret = usbg_set_function_attrs(f, data->attrs);
-
- assert_int_equal(ret, 0);
-}
-
-/**
- *
- * @brief cleanup usbg state
- */
-static int teardown_state(void **state)
-{
- usbg_state *s = NULL;
-
- s = (usbg_state *)(*state);
- if (s != NULL)
- usbg_cleanup(s);
-
- cleanup_stack();
- return 0;
-}
-
-/* Custom macro for defining test with given name and fixed teardown function */
-#define USBG_TEST_TS(name, test, setup) \
- USBG_TEST(name, test, setup, teardown_state)
-
-/**
- * @page usbg_tests Tests
- * @brief This is list of test cases
- * @tests_start
- */
-
-#ifndef DOXYGEN
-static struct CMUnitTest tests[] = {
-#endif
-
- /**
- * @usbg_test
- * @test_desc{test_init_simple,
- * Check if init was successfull on simple configfs state,
- * usbg_init}
- */
- USBG_TEST_TS("test_init_simple",
- test_init, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_init_all_funcs,
- * Check if init was successfull when all avaible functions
- * are present in configfs,
- * usbg_init}
- */
- USBG_TEST_TS("test_init_all_funcs",
- test_init, setup_all_funcs_state),
- /**
- * @usbg_test
- * @test_desc{test_init_long_path,
- * Try to initialize libusbg with long configfs path,
- * usbg_init}
- */
- USBG_TEST_TS("test_init_long_path",
- test_init, setup_long_path_state),
- /**
- * @usbg_test
- * @test_desc{test_init_long_udc,
- * Try to initialize libusbg with long udc name,
- * usbg_init}
- */
- USBG_TEST_TS("test_init_long_udc",
- test_init, setup_long_udc_state),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_simple,
- * Check if simple gadget will be correcty returned,
- * usbg_get_gadget}
- */
- USBG_TEST_TS("test_get_gadget_simple",
- test_get_gadget, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_fail_simple,
- * Check if getting non-existing and wrong gadgets cause
- * expected failure and error codes are correct,
- * usbg_get_gadget}
- */
- USBG_TEST_TS("test_get_gadget_fail_simple",
- test_get_gadget_fail, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_first_gadget_simple,
- * Check if gadget returned by get_first_gadget
- * is actually first one,
- * usbg_get_first_gadget}
- */
- USBG_TEST_TS("test_get_first_gadget_simple",
- test_get_first_gadget, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_first_gadget_fail,
- * Check if getting first gadget from state returns NULL when
- * invalid parameters are passed,
- * usbg_get_first_gadget}
- */
- unit_test(test_get_first_gadget_fail),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_name_simple,
- * Check if returned gadget name matches expected value,
- * usbg_get_gadget_name}
- */
- USBG_TEST_TS("test_get_gadget_name_simple",
- test_get_gadget_name, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_name_len,
- * Check if returned simple gadget name length matches expected value,
- * usbg_get_gadget_name}
- */
- USBG_TEST_TS("test_get_gadget_name_len_simple",
- test_get_gadget_name_len, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_name_fail,
- * Check if trying to get name of invalid gadget
- * cause expected failure (name is null),
- * usbg_get_gadget_name}
- */
- unit_test(test_get_gadget_name_fail),
- /**
- * @usbg_test
- * @test_desc{test_cpy_gadget_name_simple,
- * Check if getting simple gadget name into buffer work as expected,
- * usbg_cpy_gadget_name}
- */
- USBG_TEST_TS("test_cpy_gadget_name_simple",
- test_cpy_gadget_name, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_cpy_gadget_name_fail_simple,
- * Check if writting gadget name into buffer fail when
- * invalid parameters are passed,
- * usbg_cpy_gadget_name}
- */
- USBG_TEST_TS("test_cpy_gadget_name_fail_simple",
- test_cpy_gadget_name_fail, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_function_simple,
- * Check if function can be correctly get from simple state,
- * usbg_get_function}
- */
- USBG_TEST_TS("test_get_function_simple",
- test_get_function, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_function_all_funcs,
- * Check if getting function work on all function types,
- * usbg_get_function}
- */
- USBG_TEST_TS("test_get_function_all_funcs",
- test_get_function, setup_all_funcs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_function_same_type_funcs,
- * Check if having multiple functions with the same type does not
- * cause failure
- * usbg_get_function}
- */
- USBG_TEST_TS("test_get_function_same_type_funcs",
- test_get_function, setup_same_type_funcs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_function_fail_simple,
- * Check if trying to get invalid function's name ends
- * with expected error,
- * usbg_get_function}
- */
- USBG_TEST_TS("test_get_function_fail_simple",
- test_get_function_fail, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_function_instance_simple,
- * Check if getting simple instance returns what expected,
- * usbg_get_function_instance}
- */
- USBG_TEST_TS("test_get_function_instance_simple",
- test_get_function_instance, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_cpy_function_instance_simple,
- * Check if copying simple instance into buffer returns what expected,
- * usbg_cpy_function_instance}
- */
- USBG_TEST_TS("test_cpy_function_instance_simple",
- test_cpy_function_instance, setup_all_funcs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_function_type_simple,
- * Check if function type is returned correctly,
- * usbg_get_function_type}
- */
- USBG_TEST_TS("test_get_function_type_simple",
- test_get_function_type, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_function_type_all_funcs,
- * Check if all function types are returned correctly,
- * usbg_get_function_type}
- */
- USBG_TEST_TS("test_get_function_type_all_funcs",
- test_get_function_type, setup_all_funcs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_function_instance_len_simple,
- * Check if function instance length is returned correctly,
- * usbg_get_function_instance_len}
- */
- USBG_TEST_TS("test_get_function_instance_len_simple",
- test_get_function_instance_len, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_function_type_str,
- * Compare returned function types strings with expected values,
- * usbg_get_function_type_str}
- */
- unit_test(test_get_function_type_str),
- /**
- * @usbg_test
- * @test_desc{test_get_function_type_str_fail,
- * Try to get type string of unknown type,
- * usbg_get_function_type_str}
- */
- unit_test(test_get_function_type_str_fail),
- /**
- * @usbg_test
- * @test_desc{test_get_configfs_path_simple,
- * heck if simple configfs path was returned correctly,
- * usbg_get_configfs_path}
- */
- USBG_TEST_TS("test_get_configfs_path_simple",
- test_get_configfs_path, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_configfs_path_len,
- * Check if configfs path length is correctly calculated,
- * usbg_get_configfs_path_len}
- */
- USBG_TEST_TS("test_get_configfs_path_len_simple",
- test_get_configfs_path_len, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_cpy_configfs_path_simple,
- * Copy simple configfs path into buffer and compare with original,
- * usbg_cpy_configfs_path}
- */
- USBG_TEST_TS("test_cpy_configfs_path_simple",
- test_cpy_configfs_path, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_config_simple,
- * Check if returned simple config matches original one,
- * usbg_get_config}
- */
- USBG_TEST_TS("test_get_config_simple",
- test_get_config, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_config_without_label_simple,
- * Check if returned simple config matches original one,
- * usbg_get_config}
- */
- USBG_TEST_TS("test_get_config_without_label_simple",
- test_get_config_without_label, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_config_fail,
- * Check if trying to get non-existing or invalid config
- * fails as expected,
- * usbg_get_config}*/
- USBG_TEST_TS("test_get_config_fail",
- test_get_config_fail, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_config_label_simple,
- * Check if returned simple config label matches original one,
- * usbg_get_config_label}
- */
- USBG_TEST_TS("test_get_config_label_simple",
- test_get_config_label, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_config_id_simple,
- * Check if returned simple config id matches original one,
- * usbg_get_config_id}
- */
- USBG_TEST_TS("test_get_config_id_simple",
- test_get_config_id, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_attrs_simple,
- * Get gadget attributes list and compare them with original,
- * usbg_get_gadget_attrs}
- */
- USBG_TEST_TS("test_get_gadget_attrs_simple",
- test_get_gadget_attrs, setup_simple_state),
- /**
- * @usbg_tets
- * @test_desc{test_set_gadget_attrs_simple,
- * Set gadget attributes list\, check if everything is wrote
- * as expected,
- * usbg_set_gadget_attrs}
- */
- USBG_TEST_TS("test_set_gadget_attrs_simple",
- test_set_gadget_attrs, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_set_specific_gadget_attr_simple,
- * Set gadget attributes one by one,
- * usbg_set_gadget_attrs}
- */
- USBG_TEST_TS("test_set_specific_gadget_attr_simple",
- test_set_specific_gadget_attr, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_udc_simple,
- * Get udc name from state,
- * usbg_get_udc}
- */
- USBG_TEST_TS("test_get_udc_simple",
- test_get_udc, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_udc_long,
- * Get udc name witch very long name,
- * usbg_get_udc}
- */
- USBG_TEST_TS("test_get_udc_long",
- test_get_udc, setup_long_udc_state),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_attr_str,
- * Compare returned gadget attribute strings witch expected values
- * usbg_get_gadget_attr_str}
- */
- unit_test(test_get_gadget_attr_str),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_attr_str_fail,
- * Check returned gadget attribute strings for invalid arguments
- * usbg_get_gadget_attr_str}
- */
- unit_test(test_get_gadget_attr_str_fail),
- /**
- * @usbg_test
- * @test_desc{test_set_gadget_strs_random,
- * Set gadget strings of random length,
- * usbg_set_gadget_strs}
- */
- USBG_TEST_TS("test_set_gadget_strs_random",
- test_set_gadget_strs, setup_random_len_gadget_strs_data),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_strs_random,
- * Get gadget strings,
- * usbg_get_gadget_strs}
- */
- USBG_TEST_TS("test_get_gadget_strs_random",
- test_get_gadget_strs, setup_random_len_gadget_strs_data),
- /**
- * @usbg_test
- * @test_desc{test_get_binding_target_simple,
- * Get binding target,
- * usbg_get_binding_target}
- */
- USBG_TEST_TS("test_get_binding_target_simple",
- test_get_binding_target, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_binding_name_simple,
- * Get binding name,
- * usbg_get_binding_name}
- */
- USBG_TEST_TS("test_get_binding_name_simple",
- test_get_binding_name, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_get_binding_name_len_simple,
- * Get binding name length,
- * usbg_get_binding_name_len}
- */
- USBG_TEST_TS("test_get_binding_name_len_simple",
- test_get_binding_name_len, setup_simple_state),
- /**
- * @usbg_test
- * @test_desc{test_set_config_strs_simple,
- * Set simple strings in set of configurations,
- * usbg_set_config_strs}
- */
- USBG_TEST_TS("test_set_config_strs_simple",
- test_set_config_strs, setup_simple_config_strs_state),
- /**
- * @usbg_test
- * @test_desc{test_set_config_string_simple,
- * Set simple string in set of configurations,
- * usbg_set_config_string}
- */
- USBG_TEST_TS("test_set_config_string_simple",
- test_set_config_string, setup_simple_config_strs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_config_strs_simple,
- * Get simple strings from set of configurations,
- * usbg_get_config_strs}
- */
- USBG_TEST_TS("test_get_config_strs_simple",
- test_get_config_strs, setup_simple_config_strs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_config_attrs_max,
- * Get config attributes with max values,
- * usbg_get_config_attrs}
- */
- USBG_TEST_TS("test_get_config_attrs_max",
- test_get_config_attrs, setup_max_config_attrs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_config_attrs_min,
- * Get config attributes with minimum values,
- * usbg_get_config_attrs}
- */
- USBG_TEST_TS("test_get_config_attrs_min",
- test_get_config_attrs, setup_min_config_attrs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_config_attrs_random,
- * Get config attributes with random values,
- * usbg_get_config_attrs}
- */
- USBG_TEST_TS("test_get_config_attrs_random",
- test_get_config_attrs, setup_random_config_attrs_state),
- /**
- * @usbg_test
- * @test_desc{test_set_config_attrs_max,
- * Set config attributes with max values,
- * usbg_set_config_attrs}
- */
- USBG_TEST_TS("test_set_config_attrs_max",
- test_set_config_attrs, setup_max_config_attrs_state),
- /**
- * @usbg_test
- * @test_desc{test_set_config_attrs_min,
- * Set config attributes with minimum values,
- * usbg_set_config_attrs}
- */
- USBG_TEST_TS("test_set_config_attrs_min",
- test_set_config_attrs, setup_min_config_attrs_state),
- /**
- * @usbg_test
- * @test_desc{test_set_config_attrs_random,
- * Set config attributes with random values,
- * usbg_set_config_attrs}
- */
- USBG_TEST_TS("test_set_config_attrs_random",
- test_set_config_attrs, setup_random_config_attrs_state),
- /**
- * @usbg_test
- * @test_desc{test_create_config_random,
- * Create config with random attributes
- * usbg_create_config}
- */
- USBG_TEST_TS("test_create_config_random",
- test_create_config, setup_random_config_attrs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_f_serial_attrs,
- * Get f_serial function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_serial_attrs",
- test_get_function_attrs, setup_f_serial_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_obex_attrs,
- * Get f_obex function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_obex_attrs",
- test_get_function_attrs, setup_f_obex_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_acm_attrs,
- * Get f_acm function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_acm_attrs",
- test_get_function_attrs, setup_f_acm_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_ecm_attrs,
- * Get f_ecm function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_ecm_attrs",
- test_get_function_attrs, setup_f_ecm_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_eem_attrs,
- * Get f_eem function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_eem_attrs",
- test_get_function_attrs, setup_f_eem_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_subset_attrs,
- * Get f_subset function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_subset_attrs",
- test_get_function_attrs, setup_f_subset_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_ncm_attrs,
- * Get f_ncm function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_ncm_attrs",
- test_get_function_attrs, setup_f_ncm_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_serial_attrs,
- * Get f_rndis function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_rndis_attrs",
- test_get_function_attrs, setup_f_rndis_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_phonet_attrs,
- * Get f_phonet function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_phonet_attrs",
- test_get_function_attrs, setup_f_phonet_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_serial_attrs,
- * Get f_ffs function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_get_f_ffs_attrs",
- test_get_function_attrs, setup_f_ffs_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_serial_attrs,
- * Set f_serial function attributes,
- * usbg_set_function_attrs}
- */
- USBG_TEST_TS("test_set_f_serial_attrs",
- test_set_function_attrs, setup_f_serial_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_acm_attrs,
- * Set f_acm function attributes,
- * usbg_set_function_attrs}
- */
- USBG_TEST_TS("test_set_f_acm_attrs",
- test_set_function_attrs, setup_f_acm_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_serial_obex,
- * Set f_obex function attributes,
- * usbg_set_function_attrs}
- */
- USBG_TEST_TS("test_set_f_obex_attrs",
- test_set_function_attrs, setup_f_obex_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_ecm_attrs,
- * Set f_ecm function attributes,
- * usbg_set_function_attrs}
- */
- USBG_TEST_TS("test_set_f_ecm_attrs",
- test_set_function_attrs, setup_f_ecm_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_eem_attrs,
- * Set f_eem function attributes,
- * usbg_set_function_attrs}
- */
- USBG_TEST_TS("test_set_f_eem_attrs",
- test_set_function_attrs, setup_f_eem_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_subset_attrs,
- * Set f_subset function attributes,
- * usbg_set_function_attrs}
- */
- USBG_TEST_TS("test_set_f_subset_attrs",
- test_set_function_attrs, setup_f_subset_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_ncm_attrs,
- * Set f_ncm function attributes,
- * usbg_set_function_attrs}
- */
- USBG_TEST_TS("test_set_f_ncm_attrs",
- test_set_function_attrs, setup_f_ncm_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_serial_attrs,
- * Set f_rndis function attributes,
- * usbg_get_function_attrs}
- */
- USBG_TEST_TS("test_set_f_rndis_attrs",
- test_set_function_attrs, setup_f_rndis_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_phonet_attrs,
- * Set f_phonet function attributes,
- * usbg_set_function_attrs}
- */
- USBG_TEST_TS("test_set_f_phonet_attrs",
- test_set_function_attrs, setup_f_phonet_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_get_f_serial_attrs,
- * Set f_ffs function attributes,
- * usbg_set_function_attrs}
- */
- USBG_TEST_TS("test_set_f_ffs_attrs",
- test_set_function_attrs, setup_f_ffs_writable_attrs),
- /**
- * @usbg_test
- * @test_desc{test_create_all_functions,
- * Create full set of functions in empty state,
- * usbg_get_binding_name_len}
- */
- USBG_TEST_TS("test_create_all_functions",
- test_create_function, setup_all_funcs_state),
- /**
- * @usbg_test
- * @test_desc{test_get_gadget_str_name,
- * Compare returned gadget string name with expected
- * usbg_get_gadget_str_name}
- */
- unit_test(test_get_gadget_str_name),
- /**
- * @usbg_test
- * @test_desc{test_lookup_gadget_str,
- * Compare returned gadget string code with expected
- * usbg_lookup_gadget_str}
- */
- unit_test(test_lookup_gadget_str),
-
-#ifndef DOXYGEN
-};
-#endif
-
-/**
- * @usbg_test
- * @tests_end
- */
-
-#define TESTS_TAG "tests"
-/* for autotools compability */
-#define SKIPPED_CODE 77
-
-#ifdef HAS_LIBCONFIG
-
-static int gen_test_config(FILE *output)
-{
- config_t cfg;
- config_setting_t *root;
- config_setting_t *tests_node, *node;
- int i;
- int ret = SKIPPED_CODE, cfg_ret = 0;
-
- config_init(&cfg);
- config_set_tab_width(&cfg, 4);
-
- root = config_root_setting(&cfg);
- tests_node = config_setting_add(root, TESTS_TAG, CONFIG_TYPE_LIST);
- if (!tests_node) {
- ret = -ENOMEM;
- goto out;
- }
-
- for (i = 0; i < ARRAY_SIZE(tests); ++i) {
- node = config_setting_add(tests_node, NULL, CONFIG_TYPE_STRING);
- if (!node) {
- ret = -ENOMEM;
- goto out;
- }
-
- cfg_ret = config_setting_set_string(node, tests[i].name);
- if (cfg_ret != CONFIG_TRUE) {
- ret = -EINVAL;
- goto out;
- }
- }
-
- config_write(&cfg, output);
-out:
- config_destroy(&cfg);
- return ret;
-}
-
-#else
-
-static int gen_test_config(FILE *output)
-{
- fprintf(stderr, "Libconfig is not supported\n");
- return -ENOTSUP;
-}
-
-#endif /* HAS_LIBCONFIG */
-
-static int lookup_test(const char *name)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(tests); ++i)
- if (!strcmp(name, tests[i].name))
- return i;
-
- return -1;
-}
-
-static void test_skipped(void **state)
-{
- skip();
-}
-
-#ifdef HAS_LIBCONFIG
-static int apply_test_config(FILE *input)
-{
- config_t cfg;
- config_setting_t *root;
- config_setting_t *tests_node, *node;
- int i, count, ind;
- int ret = 0, cfg_ret = 0;
- const char *test_name;
- char selected[ARRAY_SIZE(tests)];
-
- for (i = 0; i < ARRAY_SIZE(selected); ++i)
- selected[i] = 0;
-
- config_init(&cfg);
-
- cfg_ret = config_read(&cfg, input);
- if (cfg_ret != CONFIG_TRUE) {
- fprintf(stderr, "Wrong config format\n");
- ret = -EINVAL;
- goto out;
- }
-
- root = config_root_setting(&cfg);
- tests_node = config_setting_get_member(root, TESTS_TAG);
- if (!tests_node || !config_setting_is_list(tests_node)) {
- fprintf(stderr, "Missing or incorrect tests list\n");
- ret = -EINVAL;
- goto out;
- }
-
- count = config_setting_length(tests_node);
- for (i = 0; i < count; ++i) {
- node = config_setting_get_elem(tests_node, i);
- if (!node) {
- ret = -EINVAL;
- goto out;
- }
-
- test_name = config_setting_get_string(node);
- if (!test_name) {
- fprintf(stderr, "Incorrect tests list. Element %d\n", i);
- ret = -EINVAL;
- goto out;
- }
-
- ind = lookup_test(test_name);
- if (ind < 0) {
- fprintf(stderr, "Test %s not found.\n", test_name);
- ret = -EINVAL;
- goto out;
- }
-
- selected[ind] = 1;
- }
-
- for (i = 0; i < ARRAY_SIZE(selected); ++i) {
- if (selected[i])
- continue;
-
- tests[i].test_func = &test_skipped;
- tests[i].setup_func = NULL;
- tests[i].teardown_func = NULL;
- }
-out:
- config_destroy(&cfg);
- return ret;
-}
-
-#else
-
-static int apply_test_config(FILE *input)
-{
- fprintf(stderr, "Libconfig is not supported\n");
- return -ENOTSUP;
-}
-
-#endif /* HAS_LIBCONFIG */
-
-static void print_help()
-{
- fprintf(stderr,
- "libusbgx test suit:\n"
- " --generate-config - generates config to stdout and exit\n"
- " --use-config - runs test suit using config from stdin\n"
- " -h --help - print this message\n"
- );
-}
-
-int main(int argc, char **argv)
-{
- enum {
- GENERATE_CONFIG = 0x01,
- USE_CONFIG = 0x02,
- };
-
- int options = 0;
- int opt;
- int ret = -EINVAL;
-
- static struct option long_options[] = {
- {"generate-config", no_argument, 0, 1},
- {"use-config", no_argument, 0, 2},
- {"help", no_argument, 0, 'h'},
- {NULL, 0, 0, 0}
- };
-
- while (1) {
- opt = getopt_long(argc, argv, "h", long_options, NULL);
- if (opt < 0)
- break;
-
- switch (opt) {
- case 1:
- options |= GENERATE_CONFIG;
- break;
- case 2:
- options |= USE_CONFIG;
- break;
- case 'h':
- default:
- print_help();
- goto out;
- }
- }
-
- if (optind < argc ||
- ((options & GENERATE_CONFIG) &&
- (options & USE_CONFIG))) {
- print_help();
- goto out;
- }
-
- if (options & GENERATE_CONFIG) {
- ret = gen_test_config(stdout);
- goto out;
- }
-
- if (options & USE_CONFIG) {
- ret = apply_test_config(stdin);
- if (ret)
- goto out;
- }
-
- ret = cmocka_run_group_tests(tests, NULL, NULL);
-
-out:
- return ret;
-}
diff --git a/tests/test.sh b/tests/test.sh
deleted file mode 100755
index 45b8e3e..0000000
--- a/tests/test.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/bash
-
-#USE_CONFIG=0
-#GENERATE_CONFIG=0
-#HELP=$HELP
-
-# for autotools compability (config can be passed by environment variable)
-if [[ -n $USE_CONFIG ]]
-then
- CONFIG_FILE=$USE_CONFIG
-elif [[ -n $GENERATE_CONFIG ]]
-then
- CONFIG_FILE=$GENERATE_CONFIG
-fi
-
-function usage {
- echo "libusbgx test suit"
- echo "Usage: ./test.sh [option]"
- echo "Options:"
- echo " --generate-config filename - generates config to given file and exit"
- echo " --use-config filename - runs test suit using config from given file"
- echo " -h --help - print this message"
-}
-
-# Parse arguments
-
-ARGS=$(getopt --long generate-config:,use-config:,help -o h -- "$@" )
-
-if [ $? -ne 0 ]
-then
- HELP=1
-fi
-
-eval set -- $ARGS
-
-while true; do
- case $1 in
- -h|--help)
- HELP=1
- shift
- ;;
- --use-config)
- USE_CONFIG=1
- CONFIG_FILE=$2
- shift 2
- ;;
- --generate-config)
- GENERATE_CONFIG=1
- CONFIG_FILE=$2
- shift 2
- ;;
- --)
- shift
- break
- ;;
- *)
- HELP=1
- shift
- ;;
- esac
-done
-
-# Run test with io functions ovverride
-
-if [[ -n $USE_CONFIG ]]
-then
- LD_LIBRARY_PATH=. ./test --use-config < $CONFIG_FILE
-elif [[ -n $GENERATE_CONFIG ]]
-then
- LD_LIBRARY_PATH=. ./test --generate-config > $CONFIG_FILE
-elif [[ -n $HELP ]]
-then
- usage
- exit 77 # autotools consider it skipped
-else
- LD_LIBRARY_PATH=. ./test
-fi
-
diff --git a/tests/usbg-io-wrappers.c b/tests/usbg-io-wrappers.c
deleted file mode 100644
index d8f471a..0000000
--- a/tests/usbg-io-wrappers.c
+++ /dev/null
@@ -1,203 +0,0 @@
-#define _GNU_SOURCE
-#include <dirent.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-#include <cmocka.h>
-#include <dlfcn.h>
-#include <errno.h>
-
-typedef int (*fputs_f_type)(const char *, FILE *);
-typedef int (*fflush_f_type)(FILE *);
-typedef fflush_f_type ferror_f_type;
-
-/**
- * @brief Simulates opening file
- * @details Checks if path is equal expected value and returns given pointer
- * from cmocka queue
- */
-FILE *fopen(const char *path, const char *mode)
-{
- check_expected(path);
- return mock_ptr_type(FILE *);
-}
-
-/**
- * @brief Simulates closing file
- * @details Does absolutely nothing, always acts as successfull close
- */
-int fclose(FILE *fp)
-{
- check_expected(fp);
- return mock_type(int);
-}
-
-/**
- * @brief Simulates reading file
- * @details Does not read any file, instead returns value from cmocka queue
- * @return value specified by caller previously
- */
-char *fgets(char *s, int size, FILE *stream)
-{
- check_expected(stream);
- strncpy(s, mock_ptr_type(char *), size);
- return s;
-}
-
-/**
- * @brief Simulates opening directory
- * @details Does not open any dir, instead returns user-specified value
- * @return value specified by caller previously
- */
-DIR *opendir(const char *name)
-{
- int err;
-
- check_expected(name);
- err = mock_type(int);
- if (err)
- errno = err;
-
- return mock_ptr_type(DIR *);
-}
-
-/**
- * @brief Simulates closing directory
- * @details Does nothing and ends successfully.
- */
-int closedir(DIR *dirp)
-{
- check_expected(dirp);
- return mock_type(int);
-}
-
-/**
- * @brief Simulates scanning directory
- * @details Checks if dirp has expected value. Then consecutive values from
- * cmocka queue are proceed. First value must be integer and indicates number
- * of directory entries which should be returned. Next number of values indicate
- * names of directory entries.
- */
-int scandir(const char *dirp, struct dirent ***namelist,
- int (*filter)(const struct dirent *),
- int (*compar)(const struct dirent **, const struct dirent **))
-{
- int count;
- int i, j = 0;
- char *name;
- struct dirent **entries;
- struct dirent *entry;
- int tmp, expected;
-
- check_expected(dirp);
- count = mock_type(int);
-
- if (count > 0)
- entries = calloc(count, sizeof(*entries));
- else
- entries = NULL;
-
- for (i = 0; i < count; i++) {
- name = mock_ptr_type(char *);
- entry = malloc(sizeof(*entry));
- if (strlen(name) >= NAME_MAX)
- fail();
-
- strcpy(entry->d_name, name);
- entry->d_type = mock_type(unsigned char);
-
- expected = mock_type(int);
- if (filter) {
- tmp = filter(entry);
- assert_int_equal(tmp, expected);
- if (tmp)
- entries[j++] = entry;
- else
- free(entry);
- }
- }
-
- if (compar)
- qsort(entries, count, sizeof(*entries),
- (int (*)(const void *,const void *))compar);
-
- *namelist = entries;
- return j;
-}
-
-/**
- * @brief Simultes readlink, with user-specified behavior
- * @datails Check if path and bufsiz equal expedted values and
- * write to buf string given by cmocka
- */
-ssize_t readlink(const char *path, char *buf, size_t bufsiz)
-{
- char *res;
- int reslen;
-
- check_expected(path);
- check_expected(bufsiz);
- res = mock_ptr_type(char *);
- reslen = strlen(res);
- if (bufsiz <= reslen)
- fail();
-
- strcpy(buf, res);
-
- return reslen;
-}
-
-/**
- * @brief Simulates puts, with user-specified behavior
- * @details Check if user is trying to write expected data
- * @return value received from cmocka queue
- */
-int fputs(const char *s, FILE *stream)
-{
- /* Cmocka (or anything else) may want to print some errors.
- * Especially when running fputs itself */
- if (stream == stderr || stream == stdout) {
- fputs_f_type orig_fputs;
- orig_fputs = (fputs_f_type)dlsym(RTLD_NEXT, "fputs");
- return orig_fputs(s, stream);
- }
-
- check_expected(stream);
- check_expected(s);
- return mock_type(int);
-}
-
-int mkdir(const char *pathname, mode_t mode)
-{
- check_expected(pathname);
- check_expected(mode);
- return mock_type(int);
-}
-
-/**
- * @brief Does nothing.
- */
-int fflush(FILE *stream)
-{
- if (stream == stderr || stream == stdout) {
- fflush_f_type orig_fflush;
- orig_fflush = (fflush_f_type)dlsym(RTLD_NEXT, "fflush");
- return orig_fflush(stream);
- }
-
- return 0;
-}
-
-int ferror(FILE *stream)
-{
- if (stream == stderr || stream == stdout) {
- ferror_f_type orig_ferror;
- orig_ferror = (ferror_f_type)dlsym(RTLD_NEXT, "ferror");
- return orig_ferror(stream);
- }
-
- return 0;
-}
diff --git a/tests/usbg-test.c b/tests/usbg-test.c
deleted file mode 100644
index c332795..0000000
--- a/tests/usbg-test.c
+++ /dev/null
@@ -1,1389 +0,0 @@
-#include <usbg/usbg.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <setjmp.h>
-#include <cmocka.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-#include <limits.h>
-#include <errno.h>
-#include <time.h>
-
-#include "usbg-test.h"
-
-static struct simple_stack{
- void *ptr;
- struct simple_stack *next;
-} *cleanup_top = NULL;
-
-static const char *gadget_str_names[] = {
- "serialnumber",
- "manufacturer",
- "product"
-};
-
-static const char *config_attr_names[] = {
- "MaxPower",
- "bmAttributes"
-};
-
-static attr_format config_attr_format[] = {
- [MAX_POWER] = FORMAT_DEC,
- [BM_ATTRIBUTES] = FORMAT_HEX
-};
-
-void free_later(void *ptr)
-{
- struct simple_stack *t;
-
- t = malloc(sizeof(*t));
- t->ptr = ptr;
- t->next = cleanup_top;
- cleanup_top = t;
-}
-
-void cleanup_stack()
-{
- struct simple_stack *t;
-
- while (cleanup_top) {
- free(cleanup_top->ptr);
- t = cleanup_top->next;
- free(cleanup_top);
- cleanup_top = t;
- }
-}
-
-/* Represent last file/dir opened, next should have bigger numbers.*/
-static int file_id = 0;
-static int dir_id = 0;
-
-#define PUSH_FILE(file, content) do {\
- file_id++;\
- expect_path(fopen, path, file);\
- will_return(fopen, file_id);\
- expect_value(fgets, stream, file_id);\
- will_return(fgets, content);\
- expect_value(fclose, fp, file_id);\
- will_return(fclose, 0);\
-} while(0)
-
-#define PUSH_FILE_ALWAYS(dflt) do {\
- expect_any_count(fopen, path, -1);\
- will_return_always(fopen, 1);\
- expect_any_count(fgets, stream, 1);\
- will_return_always(fgets, dflt);\
- expect_any_count(fclose, fp, 1);\
- will_return_always(fclose, 0);\
-} while(0)
-
-#define PUSH_EMPTY_DIR(p) do {\
- expect_string(scandir, dirp, p);\
- will_return(scandir, 0);\
-} while(0)
-
-#define EXPECT_OPENDIR(n) do {\
- dir_id++;\
- expect_path(opendir, name, n);\
- will_return(opendir, 0);\
- will_return(opendir, dir_id);\
- expect_value(closedir, dirp, dir_id);\
- will_return(closedir, 0);\
-} while(0)
-
-#define EXPECT_OPENDIR_ERROR(n, e) do {\
- expect_path(opendir, name, n);\
- will_return(opendir, e);\
- will_return(opendir, NULL);\
-} while(0)
-
-#define PUSH_DIR(p, c) do {\
- expect_path(scandir, dirp, p);\
- will_return(scandir, c);\
-} while(0)
-
-#define PUSH_DIR_ENTRY(name, type) do {\
- will_return(scandir, name);\
- will_return(scandir, type);\
- will_return(scandir, 1);\
-} while(0)
-
-#define PUSH_LINK(p, c, len) do {\
- expect_path(readlink, path, p);\
- expect_in_range(readlink, bufsiz, len, INT_MAX);\
- will_return(readlink, c);\
-} while(0)
-
-#define EXPECT_WRITE(file, content) do {\
- file_id++;\
- expect_path(fopen, path, file);\
- will_return(fopen, file_id);\
- expect_value(fputs, stream, file_id);\
- expect_string(fputs, s, content);\
- will_return(fputs, 0);\
- expect_value(fclose, fp, file_id);\
- will_return(fclose, 0);\
-} while(0)
-
-#define EXPECT_HEX_WRITE(file, content) do {\
- file_id++;\
- expect_path(fopen, path, file);\
- will_return(fopen, file_id);\
- expect_value(fputs, stream, file_id);\
- expect_check(fputs, s, hex_str_equal_display_error, content);\
- will_return(fputs, 0);\
- expect_value(fclose, fp, file_id);\
- will_return(fclose, 0);\
-} while(0)
-
-#define EXPECT_MKDIR(p) do {\
- expect_path(mkdir, pathname, p);\
- expect_value(mkdir, mode, 00777);\
- will_return(mkdir, 0);\
-} while(0)
-
-/**
- * @brief Compare test gadgets' names
- */
-static int test_gadget_cmp(struct test_gadget *a, struct test_gadget *b)
-{
- return strcoll(a->name, b->name);
-}
-
-/**
- * @brief Compare test functions' names
- */
-static int test_function_cmp(struct test_function *a, struct test_function *b)
-{
- return strcoll(a->name, b->name);
-}
-
-/**
- * @brief Compare test bindings' names
- */
-static int test_binding_cmp(struct test_binding *a, struct test_binding *b)
-{
- return strcoll(a->name, b->name);
-}
-
-/**
- * @brief Compare test configs' names
- */
-static int test_config_cmp(struct test_config *a, struct test_config *b)
-{
- return strcoll(a->name, b->name);
-}
-
-void prepare_binding(struct test_binding *b, struct test_function *f, char *fpath)
-{
- if (!f->name)
- prepare_function(f, fpath);
-
- if (!b->name) {
- b->name = strdup(f->name);
- if (b->name == NULL)
- fail();
- free_later(b->name);
- }
-
- b->target = f;
-}
-
-void prepare_config(struct test_config *c, char *cpath, char *fpath)
-{
- int count = 0;
- struct test_function *f;
- struct test_binding *b;
- int i;
-
- safe_asprintf(&c->name, "%s.%d", c->label, c->id);
-
- c->path = cpath;
-
- /* check if bindings has been already filled */
- if (!c->bindings) {
- for (f = c->bound_funcs; f->instance; f++)
- count++;
-
- c->bindings = safe_calloc(count + 1, sizeof(*c->bindings));
- } else {
- for (b = c->bindings; b->name; b++)
- count++;
- }
-
- for (i = 0; i < count; i++)
- prepare_binding(&c->bindings[i], &c->bound_funcs[i], fpath);
-
- qsort(c->bindings, count, sizeof(*c->bindings),
- (int (*)(const void *, const void *))test_binding_cmp);
-
-}
-
-void prepare_function(struct test_function *f, char *path)
-{
- const char *func_type;
-
- func_type = usbg_get_function_type_str(f->type);
- if (func_type == NULL)
- fail();
-
- safe_asprintf(&f->name, "%s.%s", func_type, f->instance);
-
- f->path = path;
-}
-
-void prepare_gadget(struct test_state *state, struct test_gadget *g)
-{
- struct test_config *c;
- struct test_function *f;
- char *fpath;
- char *cpath;
- int count;
-
- g->path = strdup(state->path);
- if (!g->path)
- fail();
-
- free_later(g->path);
-
- safe_asprintf(&fpath, "%s/%s/functions", g->path, g->name);
-
- count = 0;
- for (f = g->functions; f->instance; f++) {
- prepare_function(f, fpath);
- count++;
- }
-
- /* Path needs to be known somehow when list is empty */
- f->path = fpath;
-
- qsort(g->functions, count, sizeof(*g->functions),
- (int (*)(const void *, const void *))test_function_cmp);
-
- safe_asprintf(&cpath, "%s/%s/configs", g->path, g->name);
-
- count = 0;
- for (c = g->configs; c->label; c++) {
- prepare_config(c, cpath, fpath);
- count++;
- }
-
- /* Path needs to be known somehow when list is empty */
- c->path = cpath;
-
- qsort(g->configs, count, sizeof(*g->configs),
- (int (*)(const void *, const void *))test_config_cmp);
-
-}
-
-static void cpy_test_function(struct test_function *to,
- struct test_function *from)
-{
- /* Reuse instance */
- to->instance = from->instance;
- to->type = from->type;
- /* path and name is not being copied because
- it has not been allocated now */
-
- to->writable = 1;
-}
-
-static struct test_function *dup_test_functions(struct test_function *functions)
-{
- struct test_function *f, *nf, *new_functions;
- int count = 0;
-
- for (f = functions; f->instance; ++f)
- ++count;
-
- new_functions = safe_calloc(count + 1, sizeof(*f));
-
- for (f = functions, nf = new_functions; f->instance; ++f, ++nf)
- cpy_test_function(nf, f);
-
- return new_functions;
-}
-
-static struct test_function *get_new_binding_target(struct test_function *which,
- struct test_function *old,
- int count,
- struct test_function *new)
-{
- struct test_function *ret = NULL;
-
- /* Should duplicate function? */
- if (which < old || ((which - old) > count)) {
- /* We may need to do a deep copy */
- if (!which->writable) {
- ret = safe_calloc(1, sizeof(*ret));
- cpy_test_function(ret, which);
- } else {
- ret = which;
- }
- } else if (old != new) {
- /* Function has been copied in bound_funcs so just
- set new address */
- ret = which - old + new;
- } else {
- /* Functions are reused so leave address as is */
- ret = which;
- }
-
- return ret;
-}
-
-static void cpy_test_binding(struct test_binding *to,
- struct test_binding *from,
- struct test_function *old,
- int func_count,
- struct test_function *new)
-{
- /* Reuse name */
- to->name = from->name;
- to->target = get_new_binding_target(from->target, old, func_count, new);
-
- to->writable = 1;
-}
-
-static struct test_binding *dup_test_bindings(struct test_binding *bindings,
- struct test_function *old,
- int func_count,
- struct test_function *new)
-{
- struct test_binding *b, *nb, *new_bindings;
- int count = 0;
-
- for (b = bindings; b->name; ++b)
- ++count;
-
- new_bindings = safe_calloc(count + 1, sizeof(*b));
-
- for (b = bindings, nb = new_bindings; b->name; ++b, ++nb)
- cpy_test_binding(nb, b, old, func_count, new);
-
- return new_bindings;
-}
-
-static void cpy_test_config(struct test_config *to,
- struct test_config *from)
-{
- int func_count = 0;
- struct test_function *f;
- struct test_binding *b;
-
- /* Reuse label */
- to->label = from->label;
- to->id = from->id;
- to->strs = from->strs;
- to->attrs = from->attrs;
-
- if (from->bound_funcs) {
- /* If at least one function is not writable
- we have to copy all of them */
- for (f = from->bound_funcs; f->instance; ++f) {
- ++func_count;
- if (!f->writable && !to->bound_funcs) {
- to->bound_funcs =
- dup_test_functions(from->bound_funcs);
- }
- }
-
- if (!f->name && !to->bound_funcs)
- to->bound_funcs = from->bound_funcs;
- }
-
- /* If bindings are set copy also them */
- if (from->bindings) {
- /* If at least one function is not writable
- we have to copy all of them */
- for (b = from->bindings; b->name; ++b)
- if (!b->writable)
- to->bindings =
- dup_test_bindings(from->bindings,
- from->bound_funcs,
- func_count,
- to->bound_funcs);
-
- /* if we are reusing binding we have to translate target
- address to new one which is writable */
- if (!b->name && !to->bindings) {
- to->bindings = from->bindings;
- for (b = from->bindings; b->name; ++b)
- b->target =
- get_new_binding_target(
- b->target,
- from->bound_funcs,
- func_count,
- to->bound_funcs);
- }
- }
-
- to->writable = 1;
-}
-
-static struct test_config *dup_test_configs(struct test_config *configs)
-{
- struct test_config *c, *nc, *new_configs;
- int count = 0;
-
- for (c = configs; c->label; ++c)
- ++count;
-
- new_configs = safe_calloc(count + 1, sizeof(*c));
-
- for (c = configs, nc = new_configs; c->label; ++c, ++nc)
- cpy_test_config(nc, c);
-
- return new_configs;
-}
-
-static void cpy_test_gadget(struct test_gadget *to, struct test_gadget *from)
-{
- struct test_function *f;
- struct test_config *c;
-
- /* Reuse name and udc */
- to->name = from->name;
- to->udc = from->udc;
- /* path is not being copied because it has not been allocated */
-
- /* If at least one function is not writable
- we have to copy all of them */
- for (f = from->functions; f->instance; ++f)
- if (!f->writable) {
- to->functions =
- dup_test_functions(from->functions);
- break;
- }
-
- if (!f->name && !to->functions)
- to->functions = from->functions;
-
-
- /* If at least one config is not writable
- we have to copy all of them */
- for (c = from->configs; c->label; ++c)
- if (!c->writable) {
- to->configs = dup_test_configs(from->configs);
- break;
- }
-
- if (!c->name && !to->configs)
- to->configs = from->configs;
-
- to->writable = 1;
-}
-
-static struct test_gadget *dup_test_gadgets(struct test_gadget *gadgets)
-{
- struct test_gadget *g, *ng, *new_gadgets;
- int count = 0;
-
- for (g = gadgets; g->name; ++g)
- ++count;
-
- new_gadgets = safe_calloc(count + 1, sizeof(*g));
-
- for (g = gadgets, ng = new_gadgets; g->name; ++g, ++ng)
- cpy_test_gadget(ng, g);
-
- return new_gadgets;
-}
-
-static struct test_state *dup_test_state(struct test_state *state)
-{
- struct test_state *new_state;
- struct test_gadget *g;
-
- new_state = safe_calloc(1, sizeof(*new_state));
-
- /* We don't copy configfs path because it is never changed
- if you would like to free it before test end replace
- this code with strdup */
- new_state->configfs_path = state->configfs_path;
-
- /* path is not being copied because it has not been allocated */
-
- /* If at least one gadget is not writable we have to copy all of them */
- for (g = state->gadgets; g->name; ++g)
- if (!g->writable) {
- new_state->gadgets =
- dup_test_gadgets(state->gadgets);
- break;
- }
-
- if (!g->name && !new_state->gadgets)
- new_state->gadgets = state->gadgets;
-
- /* udcs are also never changed so leave them as they are */
- new_state->udcs = state->udcs;
-
- new_state->writable = 1;
-
- return new_state;
-}
-
-struct test_state *prepare_state(struct test_state *state)
-{
- struct test_gadget *g;
- struct test_state *new_state;
- int count = 0;
-
- if (!state->writable)
- new_state = dup_test_state(state);
- else
- new_state = state;
-
- safe_asprintf(&(new_state->path), "%s/usb_gadget",
- new_state->configfs_path);
-
- for (g = new_state->gadgets; g->name; g++) {
- prepare_gadget(new_state, g);
- count++;
- }
-
- qsort(new_state->gadgets, count, sizeof(*new_state->gadgets),
- (int (*)(const void *, const void *))test_gadget_cmp);
-
- return new_state;
-}
-
-struct test_state *build_empty_gadget_state(struct test_state *ts)
-{
- struct test_state *ret;
- struct test_gadget *tg;
- int count = 0;
-
- ret = safe_malloc(sizeof(*ret));
- ret->udcs = ts->udcs;
- ret->configfs_path = ts->configfs_path;
-
- for (tg = ts->gadgets; tg->name; ++tg)
- count++;
-
- ret->gadgets = safe_calloc(count+1, sizeof(*ts->gadgets));
- memcpy(ret->gadgets, ts->gadgets, count*sizeof(*ts->gadgets));
-
- for (tg = ret->gadgets; tg->name; ++tg) {
- tg->configs = safe_calloc(1, sizeof(*tg->configs));
- tg->functions = safe_calloc(1, sizeof(*tg->functions));
- }
-
- return prepare_state(ret);
-}
-
-/* Simulation of configfs for init */
-
-static void push_binding(struct test_config *conf, struct test_binding *binding)
-{
- char *s_path;
- char *d_path;
-
- safe_asprintf(&s_path, "%s/%s/%s", conf->path, conf->name, binding->name);
- safe_asprintf(&d_path, "%s/%s", binding->target->path, binding->target->name);
-
- PUSH_LINK(s_path, d_path, USBG_MAX_PATH_LENGTH - 1);
-}
-
-static void push_config(struct test_config *c)
-{
- struct test_binding *b;
- int count = 0;
- char *path;
-
- safe_asprintf(&path, "%s/%s", c->path, c->name);
-
- for (b = c->bindings; b->name; b++)
- count++;
-
- PUSH_DIR(path, count);
- for (b = c->bindings; b->name; b++) {
- PUSH_DIR_ENTRY(b->name, DT_LNK);
- push_binding(c, b);
- }
-}
-
-static void push_gadget(struct test_gadget *g)
-{
- int count;
- struct test_config *c;
- struct test_function *f;
- char *path;
-
- safe_asprintf(&path, "%s/%s/UDC", g->path, g->name);
- PUSH_FILE(path, g->udc);
-
- count = 0;
- for (f = g->functions; f->instance; f++)
- count++;
-
- PUSH_DIR(f->path, count);
- for (f = g->functions; f->instance; f++)
- PUSH_DIR_ENTRY(f->name, DT_DIR);
-
- count = 0;
- for (c = g->configs; c->label; c++)
- count++;
-
- PUSH_DIR(c->path, count);
- for (c = g->configs; c->label; c++)
- PUSH_DIR_ENTRY(c->name, DT_DIR);
-
- for (c = g->configs; c->label; c++)
- push_config(c);
-}
-
-void push_init(struct test_state *state)
-{
- char **udc;
- struct test_gadget *g;
- int count = 0;
-
- EXPECT_OPENDIR(state->path);
-
- for (udc = state->udcs; *udc; udc++)
- count++;
-
- PUSH_DIR("/sys/class/udc", count);
- for (udc = state->udcs; *udc; udc++)
- PUSH_DIR_ENTRY(*udc, DT_REG);
-
- count = 0;
- for (g = state->gadgets; g->name; g++)
- count++;
-
- PUSH_DIR(state->path, count);
- for (g = state->gadgets; g->name; g++) {
- PUSH_DIR_ENTRY(g->name, DT_DIR);
- }
-
- for (g = state->gadgets; g->name; g++)
- push_gadget(g);
-}
-
-int get_gadget_attr(usbg_gadget_attrs *attrs, usbg_gadget_attr attr)
-{
- int ret = -1;
-
- switch (attr) {
- case BCD_USB:
- ret = attrs->bcdUSB;
- break;
- case B_DEVICE_CLASS:
- ret = attrs->bDeviceClass;
- break;
- case B_DEVICE_SUB_CLASS:
- ret = attrs->bDeviceSubClass;
- break;
- case B_DEVICE_PROTOCOL:
- ret = attrs->bDeviceProtocol;
- break;
- case B_MAX_PACKET_SIZE_0:
- ret = attrs->bMaxPacketSize0;
- break;
- case ID_VENDOR:
- ret = attrs->idVendor;
- break;
- case ID_PRODUCT:
- ret = attrs->idProduct;
- break;
- case BCD_DEVICE:
- ret = attrs->bcdDevice;
- break;
- default:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-void pull_gadget_attribute(struct test_gadget *gadget,
- usbg_gadget_attr attr, int value)
-{
- char *path;
- char *content;
-
- safe_asprintf(&path, "%s/%s/%s",
- gadget->path, gadget->name, usbg_get_gadget_attr_str(attr));
-
- safe_asprintf(&content, "0x%x\n", value);
-
- EXPECT_HEX_WRITE(path, content);
-}
-
-void push_gadget_attribute(struct test_gadget *gadget,
- usbg_gadget_attr attr, int value)
-{
- char *path;
- char *content;
-
- safe_asprintf(&path, "%s/%s/%s",
- gadget->path, gadget->name, usbg_get_gadget_attr_str(attr));
- safe_asprintf(&content, "0x%x\n", value);
-
- PUSH_FILE(path, content);
-}
-
-void push_gadget_attrs(struct test_gadget *gadget, usbg_gadget_attrs *attrs)
-{
- int i;
-
- for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; i++)
- push_gadget_attribute(gadget, i, get_gadget_attr(attrs, i));
-}
-
-void pull_gadget_attrs(struct test_gadget *gadget, usbg_gadget_attrs *attrs)
-{
- int i;
-
- for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; i++)
- pull_gadget_attribute(gadget, i, get_gadget_attr(attrs, i));
-}
-
-void init_with_state(struct test_state *in, usbg_state **out)
-{
- int usbg_ret;
-
- push_init(in);
- usbg_ret = usbg_init(in->configfs_path, out);
- assert_int_equal(usbg_ret, USBG_SUCCESS);
-}
-
-void safe_init_with_state(void **state, struct test_state **ts, usbg_state **s)
-{
- *ts = (struct test_state *)(*state);
- *state = NULL;
-
- init_with_state(*ts, s);
- *state = *s;
-}
-
-static int get_config_attr(usbg_config_attrs *attrs, config_attr attr)
-{
- int ret;
-
- switch (attr) {
- case MAX_POWER:
- ret = attrs->bMaxPower;
- break;
- case BM_ATTRIBUTES:
- ret = attrs->bmAttributes;
- break;
- default:
- ret = -1;
- break;
- }
-
- return ret;
-}
-
-void push_config_attribute(struct test_config *config, config_attr attr,
- int value)
-{
- char *path;
- char *content;
-
- safe_asprintf(&path, "%s/%s/%s", config->path, config->name, config_attr_names[attr]);
-
- switch (config_attr_format[attr]) {
- case FORMAT_HEX:
- safe_asprintf(&content, "0x%x\n", value);
- break;
- case FORMAT_DEC:
- safe_asprintf(&content, "%d\n", value);
- break;
- }
-
- PUSH_FILE(path, content);
-}
-
-
-void push_config_attrs(struct test_config *config, usbg_config_attrs *attrs)
-{
- int i;
-
- for (i = 0; i < CONFIG_ATTR_MAX; ++i)
- push_config_attribute(config, i, get_config_attr(attrs, i));
-}
-
-void pull_config_attribute(struct test_config *config, config_attr attr,
- int value)
-{
- char *path;
- char *content;
-
- safe_asprintf(&path, "%s/%s/%s", config->path, config->name, config_attr_names[attr]);
-
- switch (config_attr_format[attr]) {
- case FORMAT_HEX:
- safe_asprintf(&content, "0x%x\n", value);
- break;
- case FORMAT_DEC:
- safe_asprintf(&content, "%d\n", value);
- break;
- }
-
- switch (config_attr_format[attr]) {
- case FORMAT_HEX:
- EXPECT_HEX_WRITE(path, content);
- break;
- case FORMAT_DEC:
- EXPECT_WRITE(path, content);
- break;
- }
-}
-
-void pull_config_attrs(struct test_config *config, usbg_config_attrs *attrs)
-{
- int i;
-
- for (i = 0; i < CONFIG_ATTR_MAX; ++i)
- pull_config_attribute(config, i, get_config_attr(attrs, i));
-}
-
-const char *get_gadget_str(usbg_gadget_strs *strs, gadget_str str)
-{
- const char *ret = NULL;
-
- switch (str) {
- case STR_SER:
- ret = strs->str_ser;
- break;
- case STR_MNF:
- ret = strs->str_mnf;
- break;
- case STR_PRD:
- ret = strs->str_prd;
- break;
- default:
- ret = NULL;
- break;
- }
-
- return ret;
-}
-
-static void pull_gadget_str_dir(struct test_gadget *gadget, int lang)
-{
- char *dir;
- int tmp;
-
- safe_asprintf(&dir, "%s/%s/strings/0x%x",
- gadget->path, gadget->name, lang);
-
- srand(time(NULL));
- tmp = rand() % 2;
-
- if (tmp) {
- EXPECT_OPENDIR(dir);
- } else {
- EXPECT_OPENDIR_ERROR(dir, ENOENT);
- EXPECT_MKDIR(dir);
- }
-}
-
-static void pull_gadget_str(struct test_gadget *gadget, const char *attr_name,
- int lang, const char *content)
-{
- char *path;
-
- safe_asprintf(&path, "%s/%s/strings/0x%x/%s",
- gadget->path, gadget->name, lang, attr_name);
- EXPECT_WRITE(path, content);
-}
-
-void pull_gadget_string(struct test_gadget *gadget, int lang,
- gadget_str str, const char *content)
-{
- pull_gadget_str_dir(gadget, lang);
- pull_gadget_str(gadget, gadget_str_names[str], lang, content);
-}
-
-void pull_gadget_strs(struct test_gadget *gadget, int lang, usbg_gadget_strs *strs)
-{
- int i;
-
- pull_gadget_str_dir(gadget, lang);
- for (i = 0; i < GADGET_STR_MAX; i++)
- pull_gadget_str(gadget, gadget_str_names[i], lang, get_gadget_str(strs, i));
-}
-
-static void push_gadget_str_dir(struct test_gadget *gadget, int lang)
-{
- char *dir;
-
- safe_asprintf(&dir, "%s/%s/strings/0x%x",
- gadget->path, gadget->name, lang);
-
- EXPECT_OPENDIR(dir);
-}
-
-static void push_gadget_str(struct test_gadget *gadget, const char *attr_name,
- int lang, const char *content)
-{
- char *path;
-
- safe_asprintf(&path, "%s/%s/strings/0x%x/%s",
- gadget->path, gadget->name, lang, attr_name);
- PUSH_FILE(path, content);
-}
-
-void push_gadget_strs(struct test_gadget *gadget, int lang, usbg_gadget_strs *strs)
-{
- int i;
-
- push_gadget_str_dir(gadget, lang);
- for (i = 0; i < GADGET_STR_MAX; i++)
- push_gadget_str(gadget, gadget_str_names[i], lang, get_gadget_str(strs, i));
-}
-
-void pull_config_string(struct test_config *config, int lang, const char *str)
-{
- char *path;
- int tmp;
-
-
- safe_asprintf(&path, "%s/%s/strings/0x%x",
- config->path, config->name, lang);
-
- srand(time(NULL));
- tmp = rand() % 2;
-
- if (tmp) {
- EXPECT_OPENDIR(path);
- } else {
- EXPECT_OPENDIR_ERROR(path, ENOENT);
- EXPECT_MKDIR(path);
- }
-
- safe_asprintf(&path, "%s/configuration", path);
-
- EXPECT_WRITE(path, str);
-}
-
-void pull_config_strs(struct test_config *config, int lang, usbg_config_strs *strs)
-{
- pull_config_string(config, lang, strs->configuration);
-}
-
-void push_config_string(struct test_config *config, int lang, const char *str)
-{
- char *path;
-
- safe_asprintf(&path, "%s/%s/strings/0x%x",
- config->path, config->name, lang);
-
- EXPECT_OPENDIR(path);
-
- safe_asprintf(&path, "%s/configuration", path);
-
- PUSH_FILE(path, str);
-}
-
-void push_config_strs(struct test_config *config, int lang, usbg_config_strs *strs)
-{
- push_config_string(config, lang, strs->configuration);
-}
-
-void assert_config_attrs_equal(usbg_config_attrs *actual, usbg_config_attrs *expected)
-{
- assert_int_equal(actual->bmAttributes, expected->bmAttributes);
- assert_int_equal(actual->bMaxPower, expected->bMaxPower);
-}
-
-void pull_create_config(struct test_config *tc)
-{
- char *path;
-
- safe_asprintf(&path, "%s/%s", tc->path, tc->name);
- EXPECT_MKDIR(path);
-
- if (tc->attrs)
- pull_config_attrs(tc, tc->attrs);
- if (tc->strs)
- pull_config_strs(tc, LANG_US_ENG, tc->strs);
-}
-
-#define ETHER_ADDR_STR_LEN 19
-
-static void push_serial_attrs(struct test_function *func,
- usbg_f_serial_attrs *attrs)
-{
- char *path;
- char *content;
-
- safe_asprintf(&path, "%s/%s/port_num", func->path, func->name);
- safe_asprintf(&content, "%d\n", attrs->port_num);
- PUSH_FILE(path, content);
-}
-
-static void push_net_attrs(struct test_function *func,
- usbg_f_net_attrs *attrs)
-{
- char *path;
- char *content;
-
- safe_asprintf(&path, "%s/%s/dev_addr", func->path, func->name);
-
- content = safe_malloc(ETHER_ADDR_STR_LEN * sizeof(char));
- ether_ntoa_r(&attrs->dev_addr, content);
-
- PUSH_FILE(path, content);
-
- path = safe_malloc(USBG_MAX_PATH_LENGTH * sizeof(char));
- sprintf(path, "%s/%s/host_addr",
- func->path, func->name);
-
- content = safe_malloc(ETHER_ADDR_STR_LEN * sizeof(char));
- ether_ntoa_r(&attrs->host_addr, content);
-
- PUSH_FILE(path, content);
-
- safe_asprintf(&path, "%s/%s/qmult", func->path, func->name);
- safe_asprintf(&content, "%d\n", attrs->qmult);
- PUSH_FILE(path, content);
-
- safe_asprintf(&path, "%s/%s/ifname", func->path, func->name);
- safe_asprintf(&content, "%s\n", attrs->ifname);
- PUSH_FILE(path, content);
-}
-
-static void push_phonet_attrs(struct test_function *func,
- usbg_f_phonet_attrs *attrs)
-{
- char *path;
- char *content;
-
- safe_asprintf(&path, "%s/%s/ifname", func->path, func->name);
- safe_asprintf(&content, "%s\n", attrs->ifname);
- PUSH_FILE(path, content);
-}
-
-void push_function_attrs(struct test_function *func, usbg_function_attrs *function_attrs)
-{
- int attrs_type;
- usbg_f_attrs *attrs = &function_attrs->attrs;
-
- attrs_type = usbg_lookup_function_attrs_type(func->type);
-
- switch (attrs_type) {
- case USBG_F_ATTRS_SERIAL:
- push_serial_attrs(func, &attrs->serial);
- break;
- case USBG_F_ATTRS_NET:
- push_net_attrs(func, &attrs->net);
- break;
- case USBG_F_ATTRS_PHONET:
- push_phonet_attrs(func, &attrs->phonet);
- break;
- case USBG_F_ATTRS_FFS:
- // ffs does not exist in filesystem
- default:
- break;
- }
-}
-
-static void pull_function_net_attrs(struct test_function *func, usbg_f_net_attrs *attrs)
-{
- char *path;
- char *content;
-
- safe_asprintf(&path, "%s/%s/dev_addr", func->path, func->name);
-
- content = safe_malloc(ETHER_ADDR_STR_LEN * sizeof(char));
- usbg_ether_ntoa_r(&attrs->dev_addr, content);
-
- EXPECT_WRITE(path, content);
-
- safe_asprintf(&path, "%s/%s/host_addr", func->path, func->name);
-
- content = safe_malloc(ETHER_ADDR_STR_LEN * sizeof(char));
- usbg_ether_ntoa_r(&attrs->host_addr, content);
-
- EXPECT_WRITE(path, content);
-
- safe_asprintf(&path, "%s/%s/qmult", func->path, func->name);
- safe_asprintf(&content, "%d\n", attrs->qmult);
- EXPECT_WRITE(path, content);
-}
-
-void pull_function_attrs(struct test_function *func, usbg_function_attrs *attrs)
-{
- /* only net attributes are writtable */
- if (attrs->header.attrs_type == USBG_F_ATTRS_NET)
- pull_function_net_attrs(func, &attrs->attrs.net);
-}
-
-void pull_create_function(struct test_function *tf)
-{
- char *path;
- int tmp;
-
- tmp = asprintf(&path, "%s/%s", tf->path, tf->name);
- if (tmp < 0)
- fail();
- free_later(path);
-
- EXPECT_MKDIR(path);
- if (tf->attrs)
- pull_function_attrs(tf, tf->attrs);
-}
-
-void assert_func_equal(usbg_function *f, struct test_function *expected)
-{
- assert_string_equal(f->instance, expected->instance);
- assert_int_equal(f->type, expected->type);
- assert_path_equal(f->path, expected->path);
-}
-
-void assert_binding_equal(usbg_binding *b, struct test_binding *expected)
-{
- assert_string_equal(b->name, expected->name);
- assert_func_equal(b->target, expected->target);
-}
-
-void assert_config_equal(usbg_config *c, struct test_config *expected)
-{
- int i = 0;
- usbg_binding *b;
-
- assert_int_equal(c->id, expected->id);
- assert_string_equal(c->label, expected->label);
- assert_path_equal(c->path, expected->path);
- usbg_for_each_binding(b, c)
- assert_binding_equal(b, &expected->bindings[i++]);
-}
-
-void assert_gadget_equal(usbg_gadget *g, struct test_gadget *expected)
-{
- usbg_config *c;
- usbg_function *f;
- int i;
-
- assert_string_equal(g->name, expected->name);
- assert_path_equal(g->path, expected->path);
-
- i = 0;
- usbg_for_each_function(f, g)
- assert_func_equal(f, &expected->functions[i++]);
-
- i = 0;
- usbg_for_each_config(c, g)
- assert_config_equal(c, &expected->configs[i++]);
-}
-
-void assert_state_equal(usbg_state *s, struct test_state *expected)
-{
- usbg_gadget *g;
- int i = 0;
-
- assert_path_equal(s->path, expected->path);
- assert_path_equal(s->configfs_path, expected->configfs_path);
-
- usbg_for_each_gadget(g, s)
- assert_gadget_equal(g, &expected->gadgets[i++]);
-}
-
-#define SIGNUM(x) (((x) > 0) - ((x) < 0))
-
-int path_cmp(const char *actual, const char *expected)
-{
- const char *a = actual;
- const char *b = expected;
-
- while (*a != '\0' && *b != '\0') {
- if (*a != *b)
- break;
- do
- ++a;
- while (*a == '/');
-
- do
- ++b;
- while (*b == '/');
- }
-
- return SIGNUM(*a - *b);
-}
-
-int path_equal_display_error(const LargestIntegralType actual, const LargestIntegralType expected)
-{
- if (path_cmp((const char *)actual, (const char *)expected) == 0) {
- return 1;
- }
-
- fprintf(stderr, "%s != %s\n", (const char *)actual, (const char *)expected);
- return 0;
-}
-
-void assert_path_equal(const char *actual, const char *expected)
-{
- if (path_equal_display_error(
- cast_to_largest_integral_type(actual),
- cast_to_largest_integral_type(expected)) == 0)
- fail();
-}
-
-int hex_str_cmp(const char *actual, const char *expected)
-{
- int a, b;
-
- sscanf(actual, "%x", &a);
- sscanf(expected, "%x", &b);
-
- return SIGNUM(a - b);
-}
-
-int hex_str_equal_display_error(const LargestIntegralType actual, const LargestIntegralType expected)
-{
- if (hex_str_cmp((const char *)actual, (const char *)expected) == 0) {
- return 1;
- }
-
- fprintf(stderr, "%s != %s\n", (const char *)actual, (const char *)expected);
- return 0;
-}
-
-void assert_gadget_attrs_equal(usbg_gadget_attrs *actual,
- usbg_gadget_attrs *expected)
-{
- int i;
-
- for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; i++)
- assert_int_equal(get_gadget_attr(actual, i), get_gadget_attr(expected, i));
-}
-
-void assert_gadget_strs_equal(usbg_gadget_strs *actual, usbg_gadget_strs *expected)
-{
- int i;
- for (i = 0; i < GADGET_STR_MAX; i++)
- assert_string_equal(get_gadget_str(actual, i), get_gadget_str(expected, i));
-}
-
-void assert_f_serial_attrs_equal(usbg_f_serial_attrs *actual,
- usbg_f_serial_attrs *expected)
-{
- assert_int_equal(actual->port_num, expected->port_num);
-}
-
-static void assert_ether_addrs_equal(const struct ether_addr *ea1,
- const struct ether_addr *ea2)
-{
- assert_memory_equal(ea1->ether_addr_octet, ea2->ether_addr_octet,
- ETHER_ADDR_LEN);
-}
-
-void assert_f_net_attrs_equal(usbg_f_net_attrs *actual, usbg_f_net_attrs *expected)
-{
- assert_ether_addrs_equal(&actual->dev_addr, &expected->dev_addr);
- assert_ether_addrs_equal(&actual->host_addr, &expected->host_addr);
- assert_string_equal(actual->ifname, expected->ifname);
- assert_int_equal(actual->qmult, expected->qmult);
-}
-
-void assert_f_phonet_attrs_equal(usbg_f_phonet_attrs *actual,
- usbg_f_phonet_attrs *expected)
-{
- assert_string_equal(actual->ifname, expected->ifname);
-}
-
-void assert_f_ffs_attrs_equal(usbg_f_ffs_attrs *actual, usbg_f_ffs_attrs *expected)
-{
- assert_string_equal(actual->dev_name, expected->dev_name);
-}
-
-void assert_function_attrs_equal(usbg_function_attrs *actual,
- usbg_function_attrs *expected, usbg_f_attrs_type type)
-{
- switch (type) {
- case USBG_F_ATTRS_SERIAL:
- assert_f_serial_attrs_equal(&actual->attrs.serial, &expected->attrs.serial);
- break;
- case USBG_F_ATTRS_NET:
- assert_f_net_attrs_equal(&actual->attrs.net, &expected->attrs.net);
- break;
- case USBG_F_ATTRS_PHONET:
- assert_f_phonet_attrs_equal(&actual->attrs.phonet, &expected->attrs.phonet);
- break;
- case USBG_F_ATTRS_FFS:
- assert_f_ffs_attrs_equal(&actual->attrs.ffs, &expected->attrs.ffs);
- break;
- default:
- fail();
- }
-}
-
-
-void for_each_test_function(struct test_state *ts, usbg_state *s, FunctionTest fun)
-{
- struct test_gadget *tg;
- struct test_function *tf;
- usbg_gadget *g = NULL;
- usbg_function *f = NULL;
-
- for (tg = ts->gadgets; tg->name; ++tg) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
- for (tf = tg->functions; tf->instance; ++tf) {
- f = usbg_get_function(g, tf->type, tf->instance);
- fun(f, tf);
- }
- }
-}
-
-void for_each_test_config(struct test_state *ts, usbg_state *s, ConfigTest fun)
-{
- usbg_gadget *g = NULL;
- usbg_config *c = NULL;
- struct test_gadget *tg;
- struct test_config *tc;
-
- for (tg = ts->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
- for (tc = tg->configs; tc->label; tc++) {
- c = usbg_get_config(g, tc->id, tc->label);
- fun(c, tc);
- }
- }
-}
-
-void for_each_binding(struct test_state *ts, usbg_state *s, BindingTestFunc fun)
-{
- struct test_gadget *tg;
- struct test_config *tc;
- struct test_binding *tb;
- usbg_gadget *g = NULL;
- usbg_config *c = NULL;
- usbg_binding *b = NULL;
-
- for (tg = ts->gadgets; tg->name; tg++) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
- for (tc = tg->configs; tc->label; tc++) {
- c = usbg_get_config(g, tc->id, tc->label);
- assert_non_null(c);
-
- b = usbg_get_first_binding(c);
- for (tb = tc->bindings; tb->name; ++tb) {
- assert_non_null(b);
- fun(tb, b);
- b = usbg_get_next_binding(b);
- }
- }
- }
-}
-
-void for_each_test_gadget(struct test_state *ts, usbg_state *s, GadgetTestFunc fun)
-{
- struct test_gadget *tg;
- usbg_gadget *g = NULL;
-
- for (tg = ts->gadgets; tg->name; ++tg) {
- g = usbg_get_gadget(s, tg->name);
- assert_non_null(g);
- fun(g, tg);
- }
-}
diff --git a/tests/usbg-test.h b/tests/usbg-test.h
deleted file mode 100644
index 127b90e..0000000
--- a/tests/usbg-test.h
+++ /dev/null
@@ -1,549 +0,0 @@
-#ifndef USBG_TEST_H
-#define USBG_TEST_H
-
-#include <usbg/usbg.h>
-#include <sys/queue.h>
-#include "usbg/usbg_internal.h"
-
-/* Simple structures for defining gadgets. All arrays should be null-terminated.*/
-
-/**
- * @file tests/usbg-test.h
- */
-
-struct test_function
-{
- usbg_function_type type;
- char *instance;
-
- char *path;
- char *name;
- usbg_function_attrs *attrs;
- int writable;
-};
-
-struct test_binding
-{
- struct test_function *target;
- char *name;
- int writable;
-};
-
-struct test_config
-{
- char *label;
- int id;
- struct test_function *bound_funcs;
-
- struct test_binding *bindings;
- char *path;
- char *name;
- int writable;
- usbg_config_strs *strs;
- usbg_config_attrs *attrs;
-};
-
-struct test_gadget
-{
- char *name;
- char *udc;
- struct test_config *configs;
- struct test_function *functions;
-
- char *path;
- int writable;
-};
-
-struct test_state
-{
- char *configfs_path;
- /* filled by prepare_state() */
- char *path;
- struct test_gadget *gadgets;
- char **udcs;
- int writable;
-};
-
-typedef enum {
- STR_SER = 0,
- STR_MNF,
- STR_PRD,
- GADGET_STR_MAX
-} gadget_str;
-
-typedef enum {
- MAX_POWER = 0,
- BM_ATTRIBUTES,
- CONFIG_ATTR_MAX
-} config_attr;
-
-typedef enum {
- FORMAT_HEX,
- FORMAT_DEC
-} attr_format;
-
-#define TEST_FUNCTION_LIST_END { \
- .instance = NULL, \
- }
-
-#define TEST_CONFIG_LIST_END { \
- .label = NULL, \
- .bindings = NULL, \
- }
-
-#define TEST_GADGET_LIST_END { \
- .name = NULL, \
- .udc = NULL, \
- .configs = NULL, \
- .functions = NULL, \
- }
-
-#define expect_path(function, param, data) \
- expect_check(function, param, \
- (CheckParameterValue)(path_equal_display_error), data)
-
-/**
- * @brief Prepare given state for using in tests
- * @details Generate full pathes to state elements and sort state's content.
- * Must be called before pasing state to push_* and pull_* functions.
- * @param[in] state State schema used to genrate test state
- * @return Pointer to state which can be used for testing. Returned value is
- * equal to #state if writable attribute has been set to 1 or pointer
- * to newly allocated test_state filled with suitable values. All memory
- * allocated in this function is scheduled to free using free_later().
- */
-struct test_state *prepare_state(struct test_state *state);
-
-/**
- * @brief Prepare given config for using in tests
- * @details Generate required pathes for given config and sort content
- * (i.e. binding list)
- * @param[in] c Config to be filled out
- * @param[in] cpath Path to configs directory
- * @param[in] fpath Path to functions directory
- */
-void prepare_config(struct test_config *c, char *cpath, char *fpath);
-
-/**
- * @brief Prepare given function for using in tests
- * @details Generate required pathes for given function
- * @param[in] f Function to be filled out
- * @param[in] path Path to functions directory
- */
-void prepare_function(struct test_function *f, char *path);
-
-/**
- * @brief Prepare given gadget for using in tests
- * @details Generate required paths for given gadget and sort it's content
- * (i.e. functions list and config list)
- * @param[in] state Pointer to gadget's parent state
- * @param[in] g Gadget to be filled out
- */
-void prepare_gadget(struct test_state *state, struct test_gadget *g);
-
-/**
- * @brief Fill given binding with required values
- * @details Make given binding point to a function
- * @param[in] b Test binding to be prepared
- * @param[in] f Function to which binding will point
- * @param[in] fpath Path to functions directory
- */
-void prepare_binding(struct test_binding *b, struct test_function *f, char *fpath);
-
-/**
- * @brief Prepare fake filesystem to init usbg with given test state
- * @details Use wrapped i/o functions to simulate configfs state for usbg.
- * Calling usbg_init without preparation and with mocked i/o functions
- * may fail.
- * @param[in] state Fake state of configfs defined in test
- */
-void push_init(struct test_state *state);
-
-/**
- * Prepare specific attributes writting/reading
- **/
-
-/**
- * @brief Prepare for getting config attributes
- * @param[in] config Configuration from which attributes will be get
- * @param[in] attrs Attributes which will be present in virtual filesystem
- */
-void push_config_attrs(struct test_config *config, usbg_config_attrs *attrs);
-
-/**
- * @brief Preapre for setting config attributes
- * @param[in] config Configuration on which attributes will be set
- * @param[in] attrs Attributes which will be set on given config
- */
-void pull_config_attrs(struct test_config *config, usbg_config_attrs *attrs);
-
-/**
- * @brief Get gadget attribute
- * @param[in] attrs
- * @param[in] attr
- */
-int get_gadget_attr(usbg_gadget_attrs *attrs, usbg_gadget_attr attr);
-
-/**
- * @brief Prepare to write given attribute by libusbg
- * @param[in] gadget Test gadget related to given attribute
- * @param[in] attr Attribute
- * @param[in] value Attributes value
- **/
-void push_gadget_attribute(struct test_gadget *gadget,
- usbg_gadget_attr attr, int value);
-
-/**
- * @brief Prepare to read given attribute by libusbg
- * @param[in] gadget Test gadget related to given attribute
- * @param[in] attr Attribute
- * @param[in] value Attributes value
- **/
-void pull_gadget_attribute(struct test_gadget *gadget,
- usbg_gadget_attr attr, int value);
-
-/**
- * @brief Prepare fake filesystem to get given gadget attributes
- * @details Prepare queue of values passed to wrapped i/o functions,
- * all values got from given attributes structure.
- * @param[in] gadget Pointer to gadget
- * @param[in] attrs Pointer to attributes which gadget should have
- * @warning Calling usbg_get_gadget_attrs function whithout this
- * preparation and with wrapped i/o may fail.
- */
-void push_gadget_attrs(struct test_gadget *gadget, usbg_gadget_attrs *attrs);
-
-/**
- * @brief Prepare fake filesystem for attributes setting attempt.
- * @details Prepare queue of values passed to wrapped i/o functions,
- * corresponding to functions called on attributes setting
- * @param[in] gadget Pointer to gadget
- * @param[in] attrs Pointer to expected attributes
- * @warning Calling usbg_get_gadget_attrs function whithout this
- * preparation and with wrapped i/o may fail.
- */
-void pull_gadget_attrs(struct test_gadget *gadget, usbg_gadget_attrs *attrs);
-
-/**
- * @brief Prepare fake filesystem to get given function attributes
- * @details Prepare queue of values passed to wrapped i/o functions,
- * all values got from given attributes structure.
- * @warning Calling usbg_get_function_attrs function whithout this
- * preparation and with wrapped i/o may fail.
- */
-void push_function_attrs(struct test_function *func, usbg_function_attrs *attrs);
-
-/**
- * @brief Prepare fake filesystem to set given function attributes
- * @details Prepare queue of values passed to wrapped i/o functions,
- * all values got from given attributes structure.
- * @warning Calling usbg_set_function_attrs function whithout this
- * preparation and with wrapped i/o may fail.
- */
-void pull_function_attrs(struct test_function *func, usbg_function_attrs *attrs);
-
-/**
- * @brief Get gadget string
- * @param[in] strs Set of gadget strings
- * @param[in] str Identifier of string which should be returned
- * @return Selected string from given set of strings
- */
-const char *get_gadget_str(usbg_gadget_strs *strs, gadget_str str);
-
-/**
- * @brief Prepare filesystem to set selected gadget string
- * @param[in] gadget Gadget on which str will be set
- * @param[in] lang Language of string
- * @param[in] str String identifier
- * @param[in] content String expected to be set
- */
-void pull_gadget_string(struct test_gadget *gadget, int lang,
- gadget_str str, const char *content);
-
-/**
- * @brief Prepare filesystem to set given gadget strings
- * @param[in] gadget Gadget on which strings will be set
- * @param[in] lang Language of strings
- * @param[in] strs Strings expected to be set
- */
-void pull_gadget_strs(struct test_gadget *gadget, int lang, usbg_gadget_strs *strs);
-
-/**
- * @brief prepare for reading gadget's strings
- */
-void push_gadget_strs(struct test_gadget *gadget, int lang, usbg_gadget_strs *strs);
-
-/**
- * @brief Prepare for /ref usbg_set_config_string calling
- * @details Expect setting the same string as given one
- * @param[in] config on which strings will be set
- * @param[in] lang Language of strings
- * @param[in] str string to be set as configuration string
- */
-void pull_config_string(struct test_config *config, int lang, const char *str);
-
-/**
- * @brief Prepare for writting given config strings
- * @param[in] config on which strings will be set
- * @param[in] lang Language of strings
- * @param[in] strs Strings expected to be set
- */
-void pull_config_strs(struct test_config *config, int lang, usbg_config_strs *strs);
-
-/**
- * @brief Prepare for /ref usbg_get_config_string calling
- * @details Expect setting the same string as given one
- * @param[in] config from which strings will be get
- * @param[in] lang Language of strings
- * @param[in] str string which should be returned as configuration string
- */
-void push_config_string(struct test_config *config, int lang, const char *str);
-
-/**
- * @brief Prepare for reading config strings
- * @param[in] config from which strings will be get
- * @param[in] lang Language of strings
- * @param[in] strs Strings which should be returned
- */
-void push_config_strs(struct test_config *config, int lang, usbg_config_strs *strs);
-
-/**
- * @brief Prepare for creating config
- * @param[in] tc Test config to be created
- */
-void pull_create_config(struct test_config *tc);
-
-/**
- * @brief Prepare for creating function
- * @param[in] tf Test function to be created
- */
-void pull_create_function(struct test_function *tf);
-
-/**
- * @brief Copy state without configs and functions
- * @param[in] ts State to bo copied
- * @return State with empty gadgets
- */
-struct test_state *build_empty_gadget_state(struct test_state *ts);
-
-/**
- * @brief Store given pointer on cleanup stack
- * @details All stacked pointers will be freed by calling cleanup_queue.
- * This can be used to manage memory needed for single test casees.
- */
-void free_later(void *ptr);
-
-/**
- * @brief Cleans up memory no longer needed
- * @details Frees all pointer stored on cleanup stack by calling free_later
- * @warning Calling this function before end of single test usually make test state
- * unusable. Use it only when you no longer need allocated data (at the end of
- * test case, in most cases)
- */
-void cleanup_stack();
-
-/**
- * @brief init usbg with given test state
- */
-void init_with_state(struct test_state *in, usbg_state **out);
-
-/**
- * @brief Safely initialize usbg state from pointer given to test
- * @param[in] state Pointer given to test function
- * @param[out] ts Pointer to be filled with test state
- * @param[out] s Pointer to be filled with usbg state
- */
-void safe_init_with_state(void **state, struct test_state **ts, usbg_state **s);
-
-/**
- * @brief Assert that given config attributes are equal
- */
-void assert_config_attrs_equal(usbg_config_attrs *actual, usbg_config_attrs *expected);
-
-/**
- * @brief Assert that given usbg binding matches given test binding
- * @param[in] f Pointer to usbg binding struct
- * @param[in] expected Pointer to test binding struct with expected values
- */
-void assert_binding_equal(usbg_binding *b, struct test_binding *expected);
-
-/**
- * @brief Assert that given usbg function matches given test function
- * @param[in] f Pointer to usbg function struct
- * @param[in] expected Pointer to test function struct with expected values
- */
-void assert_func_equal(usbg_function *f, struct test_function *expected);
-
-/**
- * @brief Assert that given usbg config matches given test config
- * @param[in] c Pointer to usbg config struct
- * @param[in] expected Pointer to test config struct with expected values
- */
-void assert_config_equal(usbg_config *c, struct test_config *expected);
-
-/**
- * @brief Assert that given usbg gadget matches given test gadget
- * @param[in] g Pointer to usbg gadget struct
- * @param[in] expected Pointer to test gadget struct with expected values
- */
-void assert_gadget_equal(usbg_gadget *g, struct test_gadget *expected);
-
-/**
- * @brief Assert that given usbg state matches given test state
- * @param[in] s Pointer to usbg state struct
- * @param[in] expected Pointer to test state struct with expected values
- */
-void assert_state_equal(usbg_state *s, struct test_state *expected);
-
-/**
- * @brief Compare path names
- * @details Given pathes don't need to exist
- * @return Integer less than, equal to, or greater than zero if a is (respectively)
- * less than, equal to, or greater than b.
- */
-int path_cmp(const char *a, const char *b);
-
-/**
- * @brief Print error when given paths are not equal
- * @return 1 if paths are equal, 0 otherwise
- * @note Argument type is defined by cmocka. This specific function type is defined
- * as custom comparing function in cmocka framework.
- */
-int path_equal_display_error(const LargestIntegralType actual, const LargestIntegralType expected);
-
-/**
- * @brief Compare attributes (as strings)
- * @return Integer less than, equal to, or greater than zero if a is (respectively)
- * less than, equal to, or greater than b.
- */
-int hex_str_cmp(const char *actual, const char *expected);
-
-/**
- * @brief Print error when given attributes are not equal
- * @return 1 if attributes are equal, 0 otherwise
- * @note Argument type is defined by cmocka. This specific function type is defined
- * as custom comparing function in cmocka framework.
- */
-int hex_str_equal_display_error(const LargestIntegralType actual, const LargestIntegralType expected);
-
-/**
- * @brief Assert that given path strings are equal
- * @details Given pathes don't need to exist
- */
-void assert_path_equal(const char *actual, const char *expected);
-
-/**
- * @brief Assert that given usbg gadget attributes sets are equal
- * @param[in] actual Pointer to actual gadget attributes structure
- * @param[in] expected Pointer to expeced gadget attributes structure
- */
-void assert_gadget_attrs_equal(usbg_gadget_attrs *actual,
- usbg_gadget_attrs *expected);
-
-/**
- * @brief Assert that given function attributes are the same.
- * @param[in] actual Pointer to actual attributes object
- * @param[in] expected Pointer to expected attributes obejct
- * @param[in] type Type of function, which attributes are checked
- */
-void assert_function_attrs_equal(usbg_function_attrs *actual,
- usbg_function_attrs *expected, usbg_f_attrs_type type);
-
-/**
- * @brief Assert that given gadget strings are equal
- */
-void assert_gadget_strs_equal(usbg_gadget_strs *actual, usbg_gadget_strs *expected);
-
-/**
- * @brief Function that performs some test on given usbg function
-*/
-typedef void (*FunctionTest)(usbg_function *f, struct test_function *tf);
-
-/**
- * @brief Call given function for all usb functions present in given state
- * @param[in] ts Test state to be tested
- * @param[in] s Properly prepared usbg state to be tested
- * @param[in] fun Function to be called on each usb function in state
- */
-void for_each_test_function(struct test_state *ts, usbg_state *s, FunctionTest fun);
-
-/**
- * @brief Function that performs some test on given usbg config
-*/
-typedef void (*ConfigTest)(usbg_config *c, struct test_config *tc);
-
-/**
- * @brief Call given function for all usb configs present in given state
- * @param[in] ts Test state to be tested
- * @param[in] s Properly prepared usbg state to be tested
- * @param[in] fun Function to be called on each usb function in state
- */
-void for_each_test_config(struct test_state *ts, usbg_state *s, ConfigTest fun);
-
-/**
- * @brief Function that performs test on given usbg binding
- */
-typedef void (*BindingTestFunc)(struct test_binding *tb, usbg_binding *b);
-
-/**
- * @brief Call given function for all usb bindings present in given state
- * @param[in] ts Test state to be tested
- * @param[in] s Properly prepared usbg state to be tested
- * @param[in] fun Function to be called on each usb binding in state
- */
-void for_each_binding(struct test_state *ts, usbg_state *s, BindingTestFunc fun);
-
-/**
- * @brief Function that performs test on given usbg gadget
- */
-typedef void (*GadgetTestFunc)(usbg_gadget *g, struct test_gadget *tg);
-
-/**
- * @brief Call given function for all usb gadgets present in given state
- * @param[in] ts Test state to be tested
- * @param[in] s Properly prepared usbg state to be tested
- * @param[in] fun Function to be called on each usb gadget in state
- */
-void for_each_test_gadget(struct test_state *ts, usbg_state *s, GadgetTestFunc fun);
-
-static inline void *safe_calloc(int count, size_t size)
-{
- void *ptr;
-
- ptr = calloc(count, size);
- if (ptr == NULL)
- fail();
-
- free_later(ptr);
- return ptr;
-}
-
-static inline void *safe_malloc(size_t size)
-{
- void *ptr;
-
- ptr = malloc(size);
- if (ptr == NULL)
- fail();
-
- free_later(ptr);
- return ptr;
-}
-
-static inline int safe_asprintf(char **ptr, const char *fmt, ...)
-{
- va_list args;
- int ret;
-
- va_start(args, fmt);
- ret = vasprintf(ptr, fmt, args);
- va_end(args);
-
- if (ret < 0)
- fail();
-
- free_later(*ptr);
- return ret;
-}
-
-#endif /* USBG_TEST_H */