1
0
Fork 0
mirror of https://github.com/linux-usb-gadgets/libusbgx.git synced 2025-07-12 20:49:45 +03:00

Initial release

Signed-off-by: Matt Porter <matt.porter@linaro.org>
This commit is contained in:
Matt Porter 2013-08-28 10:52:49 -04:00
commit a6a036a403
25 changed files with 13537 additions and 0 deletions

1
AUTHORS Normal file
View file

@ -0,0 +1 @@
Matt Porter <matt.porter@linaro.org>

339
COPYING Normal file
View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

502
COPYING.LGPL Normal file
View file

@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

2
ChangeLog Normal file
View file

@ -0,0 +1,2 @@
Wed, 04 Sep 2013 Matt Porter <matt.porter@linaro.org> 0.0.1
- Initial release

188
DoxygenLayout.xml Normal file
View file

@ -0,0 +1,188 @@
<doxygenlayout version="1.0">
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="filelist" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="dirs" visible="yes" title="" intro=""/>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<allmemberslink visible="yes"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<dirs visible="yes" title=""/>
<nestedgroups visible="yes" title=""/>
<files visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

7
INSTALL Normal file
View file

@ -0,0 +1,7 @@
Installing libgadget:
$ autoreconf -i
$ ./configure
$ make
$ make doxygen-doc [optional]
$ make install

8
Makefile.am Normal file
View file

@ -0,0 +1,8 @@
include $(top_srcdir)/aminclude.am
SUBDIRS = src examples
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = doxygen.cfg
library_includedir=$(includedir)/gadget
library_include_HEADERS = include/gadget/gadget.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libgadget.pc

1
NEWS Normal file
View file

@ -0,0 +1 @@
See README

49
README Normal file
View file

@ -0,0 +1,49 @@
libgadget
---------
libgadget is a C library encapsulating the kernel USB gadget-configfs
userspace API functionality.
It provides routines for creating and parsing USB gadget devices using
the configfs API. Currently, all USB gadget configfs functions that can
be enabled in kernel release 3.11 (Linux for Workgroups!) are supported.
See the Doxygen docs and examples for complete details on the
programming API and INSTALL for installation of the library and
examples.
To run the examples:
$ mkdir /config
$ mount -t configfs none /config
$ gadget-acm-ecm
$ show-gadgets
ID 1d6b:0104 'g1'
UDC 3f120000.usbotg
bDeviceClass 0x00
bDeviceSubClass 0x00
bDeviceProtocol 0x00
bMaxPacketSize0 0x40
bcdDevice 0x0311
bcdUSB 0x0000
idVendor 0x1d6b
idProduct 0x0104
Serial Number 0123456789
Manufacturer Foo Inc.
Product Bar Gadget
Function 'acm.usb0'
port_num 0
Function 'acm.usb1'
port_num 1
Function 'ecm.usb0'
dev_addr 32:1b:dc:a4:bc:a2
host_addr 82:b7:58:62:f6:31
ifname usb0
qmult 5
Configuration 'c.1'
MaxPower 2
bmAttributes 0x80
configuration CDC 2xACM+ECM
acm.GS0 -> acm.usb0
acm.GS1 -> acm.usb0
ecm.usb0 -> ecm.usb0

321
acinclude.m4 Normal file
View file

@ -0,0 +1,321 @@
# This file is part of Autoconf. -*- Autoconf -*-
# Copyright (C) 2004 Oren Ben-Kiki
# This file is distributed under the same terms as the Autoconf macro files.
########## CHANGELOG ##################
# 2009-01-14 Martin Mann
# * DX_ARG_ABLE : new variable 'DX_FLAG_DX_CURRENT_FEATURE'
# * DX_CLEAR_DEPEND : use of explicit variable 'DX_FLAG_DX_CURRENT_FEATURE'
# in AC_SUBST instead of 'DX_FLAG[]DX_CURRENT_FEATURE' which is rejected by
# newer autotools
# Generate automatic documentation using Doxygen. Works in concert with the
# aminclude.m4 file and a compatible doxygen configuration file. Defines the
# following public macros:
#
# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
# for generating a seperate .chi file by the .chm file, and 'MAN', 'RTF',
# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
# paper size.
#
# By default, HTML, PDF and PS documentation is generated as this seems to be
# the most popular and portable combination. MAN pages created by Doxygen are
# usually problematic, though by picking an appropriate subset and doing some
# massaging they might be better than nothing. CHM and RTF are specific for MS
# (note that you can't generate both HTML and CHM at the same time). The XML is
# rather useless unless you apply specialized post-processing to it.
#
# The macro mainly controls the default state of the feature. The use can
# override the default by specifying --enable or --disable. The macros ensure
# that contradictory flags are not given (e.g., --enable-doxygen-html and
# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
# Finally, each feature will be automatically disabled (with a warning) if the
# required programs are missing.
#
# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
# the following parameters: a one-word name for the project for use as a
# filename base etc., an optional configuration file name (the default is
# 'Doxyfile', the same as Doxygen's default), and an optional output directory
# name (the default is 'doxygen-doc').
## ----------##
## Defaults. ##
## ----------##
DX_ENV=""
AC_DEFUN([DX_FEATURE_doc], ON)
AC_DEFUN([DX_FEATURE_dot], ON)
AC_DEFUN([DX_FEATURE_man], OFF)
AC_DEFUN([DX_FEATURE_html], ON)
AC_DEFUN([DX_FEATURE_chm], OFF)
AC_DEFUN([DX_FEATURE_chi], OFF)
AC_DEFUN([DX_FEATURE_rtf], OFF)
AC_DEFUN([DX_FEATURE_xml], OFF)
AC_DEFUN([DX_FEATURE_pdf], ON)
AC_DEFUN([DX_FEATURE_ps], ON)
## --------------- ##
## Private macros. ##
## --------------- ##
# DX_ENV_APPEND(VARIABLE, VALUE)
# ------------------------------
# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
# DX_DIRNAME_EXPR
# ---------------
# Expand into a shell expression prints the directory part of a path.
AC_DEFUN([DX_DIRNAME_EXPR],
[[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
# -------------------------------------
# Expands according to the M4 (static) status of the feature.
AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
# ----------------------------------
# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
AC_DEFUN([DX_REQUIRE_PROG], [
AC_PATH_TOOL([$1], [$2])
if test "$DX_FLAG_DX_CURRENT_FEATURE$$1" = 1; then
AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)
fi
])
# DX_TEST_FEATURE(FEATURE)
# ------------------------
# Expand to a shell expression testing whether the feature is active.
AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
# -------------------------------------------------
# Verify that a required features has the right state before trying to turn on
# the DX_CURRENT_FEATURE.
AC_DEFUN([DX_CHECK_DEPEND], [
test "$DX_FLAG_$1" = "$2" \
|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
requires, contradicts) doxygen-DX_CURRENT_FEATURE])
])
# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
# ----------------------------------------------------------
# Turn off the DX_CURRENT_FEATURE if the required feature is off.
AC_DEFUN([DX_CLEAR_DEPEND], [
test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)
])
# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
# CHECK_DEPEND, CLEAR_DEPEND,
# REQUIRE, DO-IF-ON, DO-IF-OFF)
# --------------------------------------------
# Parse the command-line option controlling a feature. CHECK_DEPEND is called
# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
# otherwise CLEAR_DEPEND is called to turn off the default state if a required
# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
AC_DEFUN([DX_ARG_ABLE], [
AC_DEFUN([DX_CURRENT_FEATURE], [$1])
AC_DEFUN([DX_FLAG_DX_CURRENT_FEATURE], [DX_FLAG_$1])
AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
AC_ARG_ENABLE(doxygen-$1,
[AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
[--enable-doxygen-$1]),
DX_IF_FEATURE([$1], [don't $2], [$2]))],
[
case "$enableval" in
#(
y|Y|yes|Yes|YES)
AC_SUBST([DX_FLAG_$1], 1)
$3
;; #(
n|N|no|No|NO)
AC_SUBST([DX_FLAG_$1], 0)
;; #(
*)
AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
;;
esac
], [
AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
$4
])
if DX_TEST_FEATURE([$1]); then
$5
:
fi
if DX_TEST_FEATURE([$1]); then
AM_CONDITIONAL(DX_COND_$1, :)
$6
:
else
AM_CONDITIONAL(DX_COND_$1, false)
$7
:
fi
])
## -------------- ##
## Public macros. ##
## -------------- ##
# DX_XXX_FEATURE(DEFAULT_STATE)
# -----------------------------
AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])])
AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])])
AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])])
AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])])
AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])])
AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])])
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])])
AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])])
# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
# ---------------------------------------------------------
# PROJECT also serves as the base name for the documentation files.
# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
AC_DEFUN([DX_INIT_DOXYGEN], [
# Files:
AC_SUBST([DX_PROJECT], [$1])
AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
# Environment variables used inside doxygen.cfg:
DX_ENV_APPEND(SRCDIR, $srcdir)
DX_ENV_APPEND(PROJECT, $DX_PROJECT)
DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
# Doxygen itself:
DX_ARG_ABLE(doc, [generate any doxygen documentation],
[],
[],
[DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
DX_REQUIRE_PROG([DX_PERL], perl)],
[DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
# Dot for graphics:
DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_DOT], dot)],
[DX_ENV_APPEND(HAVE_DOT, YES)
DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
[DX_ENV_APPEND(HAVE_DOT, NO)])
# Man pages generation:
DX_ARG_ABLE(man, [generate doxygen manual pages],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_MAN, YES)],
[DX_ENV_APPEND(GENERATE_MAN, NO)])
# RTF file generation:
DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_RTF, YES)],
[DX_ENV_APPEND(GENERATE_RTF, NO)])
# XML file generation:
DX_ARG_ABLE(xml, [generate doxygen XML documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_XML, YES)],
[DX_ENV_APPEND(GENERATE_XML, NO)])
# (Compressed) HTML help generation:
DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_HHC], hhc)],
[DX_ENV_APPEND(HHC_PATH, $DX_HHC)
DX_ENV_APPEND(GENERATE_HTML, YES)
DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
[DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
# Seperate CHI file generation.
DX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],
[DX_CHECK_DEPEND(chm, 1)],
[DX_CLEAR_DEPEND(chm, 1)],
[],
[DX_ENV_APPEND(GENERATE_CHI, YES)],
[DX_ENV_APPEND(GENERATE_CHI, NO)])
# Plain HTML pages generation:
DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
[DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
[DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
[],
[DX_ENV_APPEND(GENERATE_HTML, YES)],
[DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
# PostScript file generation:
DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_LATEX], latex)
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
DX_REQUIRE_PROG([DX_DVIPS], dvips)
DX_REQUIRE_PROG([DX_EGREP], egrep)])
# PDF file generation:
DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
DX_REQUIRE_PROG([DX_EGREP], egrep)])
# LaTeX generation for PS and/or PDF:
if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
AM_CONDITIONAL(DX_COND_latex, :)
DX_ENV_APPEND(GENERATE_LATEX, YES)
else
AM_CONDITIONAL(DX_COND_latex, false)
DX_ENV_APPEND(GENERATE_LATEX, NO)
fi
# Paper size for PS and/or PDF:
AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
[a4wide (default), a4, letter, legal or executive])
case "$DOXYGEN_PAPER_SIZE" in
#(
"")
AC_SUBST(DOXYGEN_PAPER_SIZE, "")
;; #(
a4wide|a4|letter|legal|executive)
DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
;; #(
*)
AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
;;
esac
#For debugging:
echo DX_FLAG_doc=$DX_FLAG_doc
echo DX_FLAG_dot=$DX_FLAG_dot
echo DX_FLAG_man=$DX_FLAG_man
echo DX_FLAG_html=$DX_FLAG_html
echo DX_FLAG_chm=$DX_FLAG_chm
echo DX_FLAG_chi=$DX_FLAG_chi
echo DX_FLAG_rtf=$DX_FLAG_rtf
echo DX_FLAG_xml=$DX_FLAG_xml
echo DX_FLAG_pdf=$DX_FLAG_pdf
echo DX_FLAG_ps=$DX_FLAG_ps
echo DX_ENV=$DX_ENV
])

186
aminclude.am Normal file
View file

@ -0,0 +1,186 @@
# Copyright (C) 2004 Oren Ben-Kiki
# This file is distributed under the same terms as the Automake macro files.
# Generate automatic documentation using Doxygen. Goals and variables values
# are controlled by the various DX_COND_??? conditionals set by autoconf.
#
# The provided goals are:
# doxygen-doc: Generate all doxygen documentation.
# doxygen-run: Run doxygen, which will generate some of the documentation
# (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post
# processing required for the rest of it (PS, PDF, and some MAN).
# doxygen-man: Rename some doxygen generated man pages.
# doxygen-ps: Generate doxygen PostScript documentation.
# doxygen-pdf: Generate doxygen PDF documentation.
#
# Note that by default these are not integrated into the automake goals. If
# doxygen is used to generate man pages, you can achieve this integration by
# setting man3_MANS to the list of man pages generated and then adding the
# dependency:
#
# $(man3_MANS): doxygen-doc
#
# This will cause make to run doxygen and generate all the documentation.
#
# The following variable is intended for use in Makefile.am:
#
# DX_CLEANFILES = everything to clean.
#
# This is usually added to MOSTLYCLEANFILES.
## --------------------------------- ##
## Format-independent Doxygen rules. ##
## --------------------------------- ##
if DX_COND_doc
## ------------------------------- ##
## Rules specific for HTML output. ##
## ------------------------------- ##
if DX_COND_html
DX_CLEAN_HTML = @DX_DOCDIR@/html
endif DX_COND_html
## ------------------------------ ##
## Rules specific for CHM output. ##
## ------------------------------ ##
if DX_COND_chm
DX_CLEAN_CHM = @DX_DOCDIR@/chm
if DX_COND_chi
DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
endif DX_COND_chi
endif DX_COND_chm
## ------------------------------ ##
## Rules specific for MAN output. ##
## ------------------------------ ##
if DX_COND_man
DX_CLEAN_MAN = @DX_DOCDIR@/man
endif DX_COND_man
## ------------------------------ ##
## Rules specific for RTF output. ##
## ------------------------------ ##
if DX_COND_rtf
DX_CLEAN_RTF = @DX_DOCDIR@/rtf
endif DX_COND_rtf
## ------------------------------ ##
## Rules specific for XML output. ##
## ------------------------------ ##
if DX_COND_xml
DX_CLEAN_XML = @DX_DOCDIR@/xml
endif DX_COND_xml
## ----------------------------- ##
## Rules specific for PS output. ##
## ----------------------------- ##
if DX_COND_ps
DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
DX_PS_GOAL = doxygen-ps
doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
cd @DX_DOCDIR@/latex; \
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
$(DX_LATEX) refman.tex; \
$(MAKEINDEX_PATH) refman.idx; \
$(DX_LATEX) refman.tex; \
countdown=5; \
while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
refman.log > /dev/null 2>&1 \
&& test $$countdown -gt 0; do \
$(DX_LATEX) refman.tex; \
countdown=`expr $$countdown - 1`; \
done; \
$(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
endif DX_COND_ps
## ------------------------------ ##
## Rules specific for PDF output. ##
## ------------------------------ ##
if DX_COND_pdf
DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
DX_PDF_GOAL = doxygen-pdf
doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
cd @DX_DOCDIR@/latex; \
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
$(DX_PDFLATEX) refman.tex; \
$(DX_MAKEINDEX) refman.idx; \
$(DX_PDFLATEX) refman.tex; \
countdown=5; \
while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
refman.log > /dev/null 2>&1 \
&& test $$countdown -gt 0; do \
$(DX_PDFLATEX) refman.tex; \
countdown=`expr $$countdown - 1`; \
done; \
mv refman.pdf ../@PACKAGE@.pdf
endif DX_COND_pdf
## ------------------------------------------------- ##
## Rules specific for LaTeX (shared for PS and PDF). ##
## ------------------------------------------------- ##
if DX_COND_latex
DX_CLEAN_LATEX = @DX_DOCDIR@/latex
endif DX_COND_latex
.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
rm -rf @DX_DOCDIR@
$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
DX_CLEANFILES = \
@DX_DOCDIR@/@PACKAGE@.tag \
-r \
$(DX_CLEAN_HTML) \
$(DX_CLEAN_CHM) \
$(DX_CLEAN_CHI) \
$(DX_CLEAN_MAN) \
$(DX_CLEAN_RTF) \
$(DX_CLEAN_XML) \
$(DX_CLEAN_PS) \
$(DX_CLEAN_PDF) \
$(DX_CLEAN_LATEX)
endif DX_COND_doc

8
configure.ac Normal file
View file

@ -0,0 +1,8 @@
AC_INIT([libgadget], [0.0.1], [matt.porter@linaro.org])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_MACRO_DIR([m4])
LT_INIT
AC_CONFIG_FILES([Makefile src/Makefile examples/Makefile libgadget.pc])
DX_INIT_DOXYGEN([$PACKAGE_NAME],[doxygen.cfg])
AC_OUTPUT

1781
doxygen.cfg Normal file

File diff suppressed because it is too large Load diff

5
examples/Makefile.am Normal file
View file

@ -0,0 +1,5 @@
bin_PROGRAMS = show-gadgets gadget-acm-ecm
gadget_acm_ecm_SOURCES = gadget-acm-ecm.c
show_gadgets_SOURCES = show-gadgets.c
AM_CPPFLAGS=-I../include/
AM_LDFLAGS=-L../src/ -lgadget

91
examples/gadget-acm-ecm.c Normal file
View file

@ -0,0 +1,91 @@
/*
* Copyright (C) 2013 Linaro Limited
*
* Matt Porter <matt.porter@linaro.org>
*
* 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 <gadget/gadget.h>
/**
* @file gadget-acm-ecm.c
* @example gadget-acm-ecm.c
* This is an example of how to create an ACM+ECM gadget device.
*/
#define VENDOR 0x1d6b
#define PRODUCT 0x0104
int main(void)
{
struct state *s;
struct gadget *g;
struct function *f;
struct config *c;
struct function *f_acm0, *f_acm1, *f_ecm;
int ret = -EINVAL;
s = gadget_init("/config");
if (!s) {
fprintf(stderr, "Error on USB gadget init\n");
goto error1;
}
g = gadget_create_gadget(s, "g1", VENDOR, PRODUCT);
if (!g) {
fprintf(stderr, "Error on create gadget\n");
goto error2;
}
gadget_set_gadget_serial_number(g, LANG_US_ENG, "0123456789");
gadget_set_gadget_manufacturer(g, LANG_US_ENG, "Foo Inc.");
gadget_set_gadget_product(g, LANG_US_ENG, "Bar Gadget");
f_acm0 = gadget_create_function(g, F_ACM, "usb0");
if (!f_acm0) {
fprintf(stderr, "Error creating acm0 function\n");
goto error2;
}
f_acm1 = gadget_create_function(g, F_ACM, "usb1");
if (!f_acm1) {
fprintf(stderr, "Error creating acm1 function\n");
goto error2;
}
f_ecm = gadget_create_function(g, F_ECM, "usb0");
if (!f_ecm) {
fprintf(stderr, "Error creating ecm function\n");
goto error2;
}
c = gadget_create_config(g, "c.1");
if (!c) {
fprintf(stderr, "Error creating config\n");
goto error2;
}
gadget_set_config_string(c, LANG_US_ENG, "CDC 2xACM+ECM");
gadget_add_config_function(c, "acm.GS0", f_acm0);
gadget_add_config_function(c, "acm.GS1", f_acm1);
gadget_add_config_function(c, "ecm.usb0", f_ecm);
gadget_enable_gadget(g, DEFAULT_UDC);
return 0;
error2:
gadget_cleanup(s);
error1:
return -EINVAL;
}

116
examples/show-gadgets.c Normal file
View file

@ -0,0 +1,116 @@
/*
* Copyright (C) 2013 Linaro Limited
*
* Matt Porter <matt.porter@linaro.org>
*
* 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 <string.h>
#include <gadget/gadget.h>
#include <netinet/ether.h>
/**
* @file show-gadgets.c
* @example show-gadgets.c
* This example shows how to display all configured USB gadgets
* in the system
*/
void show_gadget(struct gadget *g)
{
fprintf(stdout, "ID %04x:%04x '%s'\n",
g->vendor, g->product, g->name);
fprintf(stdout, " UDC\t\t\t%s\n", g->udc);
fprintf(stdout, " bDeviceClass\t\t0x%02x\n", g->dclass);
fprintf(stdout, " bDeviceSubClass\t0x%02x\n", g->dsubclass);
fprintf(stdout, " bDeviceProtocol\t0x%02x\n", g->dproto);
fprintf(stdout, " bMaxPacketSize0\t0x%02x\n", g->maxpacket);
fprintf(stdout, " bcdDevice\t\t0x%04x\n", g->bcddevice);
fprintf(stdout, " bcdUSB\t\t0x%04x\n", g->bcdusb);
fprintf(stdout, " idVendor\t\t0x%04x\n", g->vendor);
fprintf(stdout, " idProduct\t\t0x%04x\n", g->product);
fprintf(stdout, " Serial Number\t\t%s\n", g->str_ser);
fprintf(stdout, " Manufacturer\t\t%s\n", g->str_mnf);
fprintf(stdout, " Product\t\t%s\n", g->str_prd);
}
void show_function(struct function *f)
{
fprintf(stdout, " Function '%s'\n", f->name);
switch (f->type) {
case F_SERIAL:
case F_ACM:
case F_OBEX:
fprintf(stdout, " port_num\t\t%d\n",
f->attr.serial.port_num);
break;
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->attr.net.dev_addr));
fprintf(stdout, " host_addr\t\t%s\n",
ether_ntoa(&f->attr.net.host_addr));
fprintf(stdout, " ifname\t\t%s\n", f->attr.net.ifname);
fprintf(stdout, " qmult\t\t%d\n", f->attr.net.qmult);
break;
case F_PHONET:
fprintf(stdout, " ifname\t\t%s\n", f->attr.phonet.ifname);
break;
default:
fprintf(stdout, " UNKNOWN\n");
}
}
void show_config(struct config *c)
{
struct binding *b;
fprintf(stdout, " Configuration '%s'\n", c->name);
fprintf(stdout, " MaxPower\t\t%d\n", c->maxpower);
fprintf(stdout, " bmAttributes\t0x%02x\n", c->bmattrs);
fprintf(stdout, " configuration\t%s\n", c->str_cfg);
gadget_for_each_binding(b, c)
fprintf(stdout, " %s -> %s\n", b->name,b->target->name);
}
int main(void)
{
struct state *s;
struct gadget *g;
struct function *f;
struct config *c;
struct binding *b;
struct function *f_acm0, *f_acm1, *f_ecm;
s = gadget_init("/config");
if (!s) {
fprintf(stderr, "Error on USB gadget init\n");
return -EINVAL;
}
gadget_for_each_gadget(g, s) {
show_gadget(g);
gadget_for_each_function(f, g)
show_function(f);
gadget_for_each_config(c, g)
show_config(c);
}
gadget_cleanup(s);
return 0;
}

437
include/gadget/gadget.h Normal file
View file

@ -0,0 +1,437 @@
/*
* Copyright (C) 2013 Linaro Limited
*
* Matt Porter <matt.porter@linaro.org>
*
* 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 <dirent.h>
#include <sys/queue.h>
#include <netinet/ether.h>
/**
* @file include/gadget/gadget.h
* @todo Add gadget_remove_[gadget|config|function|binding] APIs
* @todo Clean up static buffers in structures
*/
/**
* @addtogroup libgadget
* Public API for USB gadget-configfs library
* @{
*/
#define DEFAULT_UDC NULL
#define LANG_US_ENG 0x0409
/**
* @struct state
* @brief State of the gadget devices in the system
*/
struct state
{
char path[256];
TAILQ_HEAD(ghead, gadget) gadgets;
};
/**
* @struct gadget
* @brief USB gadget device attributes
*/
struct gadget
{
char name[40];
char path[256];
char udc[256];
int dclass;
int dsubclass;
int dproto;
int maxpacket;
int bcddevice;
int bcdusb;
int product;
int vendor;
char str_ser[256];
char str_mnf[256];
char str_prd[256];
TAILQ_ENTRY(gadget) gnode;
TAILQ_HEAD(chead, config) configs;
TAILQ_HEAD(fhead, function) functions;
struct state *parent;
};
/**
* @struct config
* @brief USB gadget configuration attributes
*/
struct config
{
TAILQ_ENTRY(config) cnode;
TAILQ_HEAD(bhead, binding) bindings;
struct gadget *parent;
char name[40];
char path[256];
int maxpower;
int bmattrs;
char str_cfg[256];
};
/**
* @enum function_type
* @brief Supported USB function types
*/
enum function_type
{
F_SERIAL,
F_ACM,
F_OBEX,
F_ECM,
F_SUBSET,
F_NCM,
F_EEM,
F_RNDIS,
F_PHONET,
};
/**
* @var function_names
* @brief Name strings for supported USB function types
*/
const char *function_names[] =
{
"gser",
"acm",
"obex",
"ecm",
"geth",
"ncm",
"eem",
"rndis",
"phonet",
};
/**
* @struct serial_attrs
* @brief Attributes for Serial, ACM, and OBEX USB functions
*/
struct serial_attrs {
int port_num;
};
/**
* @struct net_attrs
* @brief Attributes for ECM, ECM subset, NCM, EEM, and RNDIS USB functions
*/
struct net_attrs {
struct ether_addr dev_addr;
struct ether_addr host_addr;
char ifname[256];
int qmult;
};
/**
* @struct phonet_attrs
* @brief Attributes for the phonet USB function
*/
struct phonet_attrs {
char ifname[256];
};
/**
* @union attrs
* @brief Attributes for a given function type
*/
union attrs {
struct serial_attrs serial;
struct net_attrs net;
struct phonet_attrs phonet;
};
/**
* @struct function
* @brief USB gadget function attributes
*/
struct function
{
TAILQ_ENTRY(function) fnode;
struct gadget *parent;
char name[40];
char path[256];
enum function_type type;
union attrs attr;
};
/**
* @struct binding
* @brief Describes a binding between a USB gadget configuration
* and a USB gadget function
*/
struct binding
{
TAILQ_ENTRY(binding) bnode;
struct config *parent;
struct function *target;
char name[40];
char path[256];
};
/* Library init and cleanup */
/**
* @brief Initialize the libgadget library state
* @param configfs_path Path to the mounted configfs filesystem
* @return Pointer to a state structure
*/
extern struct state *gadget_init(char *configfs_path);
/**
* @brief Clean up the libgadget library state
* @param s Pointer to state
*/
extern void gadget_cleanup(struct state *s);
/* USB gadget queries */
/**
* @brief Get a gadget device by name
* @param s Pointer to state
* @param name Name of the gadget device
* @return Pointer to gadget or NULL if a matching gadget isn't found
*/
extern struct gadget *gadget_get_gadget(struct state *s, const char *name);
/**
* @brief Get a function by name
* @param g Pointer to gadget
* @param name Name of the function
* @return Pointer to function or NULL if a matching function isn't found
*/
extern struct function *gadget_get_function(struct gadget *g, const char *name);
/**
* @brief Get a configuration by name
* @param g Pointer to gadget
* @param name Name of the configuration
* @return Pointer to config or NULL if a matching config isn't found
*/
extern struct config *gadget_get_config(struct gadget *g, const char *name);
/* USB gadget allocation and configuration */
/**
* @brief Create a new USB gadget device
* @param s Pointer to state
* @param name Name of the gadget
* @param vendor Gadget vendor ID
* @param product Gadget product ID
* @return Pointer to gadget or NULL if the gadget cannot be created
*/
extern struct gadget *gadget_create_gadget(struct state *s, char *name, int vendor, int product);
/**
* @brief Set the USB gadget device class code
* @param g Pointer to gadget
* @param dclass USB device class code
*/
extern void gadget_set_gadget_device_class(struct gadget *g, int dclass);
/**
* @brief Set the USB gadget protocol code
* @param g Pointer to gadget
* @param dprotocol USB protocol code
*/
extern void gadget_set_gadget_device_protocol(struct gadget *g, int dproto);
/**
* @brief Set the USB gadget device subclass code
* @param g Pointer to gadget
* @param dsubclass USB device subclass code
*/
extern void gadget_set_gadget_device_subclass(struct gadget *g, int dsubclass);
/**
* @brief Set the maximum packet size for a gadget
* @param g Pointer to gadget
* @param maxpacket Maximum packet size
*/
extern void gadget_set_gadget_device_max_packet(struct gadget *g, int maxpacket);
/**
* @brief Set the gadget device BCD release number
* @param g Pointer to gadget
* @param bcddevice BCD release number
*/
extern void gadget_set_gadget_device_bcd_device(struct gadget *g, int bcddevice);
/**
* @brief Set the gadget device BCD USB version
* @param g Pointer to gadget
* @param bcdusb BCD USB version
*/
extern void gadget_set_gadget_device_bcd_usb(struct gadget *g, int bcdusb);
/**
* @brief Set the serial number for a gadget
* @param g Pointer to gadget
* @param lang USB language ID
* @param ser Serial number
*/
extern void gadget_set_gadget_serial_number(struct gadget *g, int lang, char *ser);
/**
* @brief Set the manufacturer name for a gadget
* @param g Pointer to gadget
* @param lang USB language ID
* @param mnf Manufacturer
*/
extern void gadget_set_gadget_manufacturer(struct gadget *g, int lang, char *mnf);
/**
* @brief Set the product name for a gadget
* @param g Pointer to gadget
* @param lang USB language ID
* @param prd Product
*/
extern void gadget_set_gadget_product(struct gadget *g, int lang, char *prd);
/* USB function allocation and configuration */
/**
* @brief Create a new USB gadget function
* @param g Pointer to gadget
* @param type Type of function
* @param instance Function instance name
* @return Pointer to function or NULL if it cannot be created
*/
extern struct function *gadget_create_function(struct gadget *g, enum function_type type, char *instance);
/* USB configurations allocation and configuration */
/**
* @brief Create a new USB gadget configuration
* @param g Pointer to gadget
* @param name Name of configuration
* @return Pointer to configuration or NULL if it cannot be created
*/
extern struct config *gadget_create_config(struct gadget *g, char *name);
/**
* @brief Set the configuration maximum power
* @param c Pointer to config
* @param maxpower Maximum power (in 2 mA units)
*/
extern void gadget_set_config_max_power(struct config *c, int maxpower);
/**
* @brief Set the configuration bitmap attributes
* @param c Pointer to config
* @param bmattrs Configuration characteristics
*/
extern void gadget_set_config_bm_attrs(struct config *c, int bmattrs);
/**
* @brief Set the configuration string
* @param c Pointer to config
* @param lang USB language ID
* @param string Configuration description
*/
extern void gadget_set_config_string(struct config *c, int lang, char *string);
/**
* @brief Add a function to a configuration
* @param c Pointer to config
* @param name Name of configuration function binding
* @param f Pointer to function
* @return 0 on success, -1 on failure.
*/
extern int gadget_add_config_function(struct config *c, char *name, struct function *f);
/* 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, -1 on failure
*/
extern int gadget_get_udcs(struct dirent ***udc_list);
/**
* @brief Enable a USB gadget device
* @param g Pointer to gadget
* @param udc Name of UDC to enable gadget
*/
extern void gadget_enable_gadget(struct gadget *g, char *udc);
/**
* @brief Disable a USB gadget device
* @param g Pointer to gadget
*/
extern void gadget_disable_gadget(struct gadget *g);
/*
* USB function-specific attribute configuration
*/
/**
* @brief Set USB function network device address
* @param f Pointer to function
* @param addr Pointer to Ethernet address
*/
extern void gadget_set_net_dev_addr(struct function *f, struct ether_addr *addr);
/**
* @brief Set USB function network host address
* @param f Pointer to function
* @param addr Pointer to Ethernet address
*/
extern void gadget_set_net_host_addr(struct function *f, struct ether_addr *addr);
/**
* @brief Set USB function network qmult
* @param f Pointer to function
* @param qmult Queue length multiplier
*/
extern void gadget_set_net_qmult(struct function *f, int qmult);
/**
* @def gadget_for_each_gadget(g, s)
* Iterates over each gadget
*/
#define gadget_for_each_gadget(g, s) TAILQ_FOREACH(g, &s->gadgets, gnode)
/**
* @def gadget_for_each_function(f, g)
* Iterates over each function
*/
#define gadget_for_each_function(f, g) TAILQ_FOREACH(f, &g->functions, fnode)
/**
* @def gadget_for_each_config(c, g)
* Iterates over each config
*/
#define gadget_for_each_config(c, g) TAILQ_FOREACH(c, &g->configs, cnode)
/**
* @def gadget_for_each_binding(b, c)
* Iterates over each binding
*/
#define gadget_for_each_binding(b, c) TAILQ_FOREACH(b, &c->bindings, bnode)
/**
* @}
*/

11
libgadget.pc.in Normal file
View file

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libgadget
Description: USB gadget-configfs library
Requires:
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lgadget
Cflags: -I${includedir}

8001
m4/libtool.m4 vendored Normal file

File diff suppressed because it is too large Load diff

384
m4/ltoptions.m4 vendored Normal file
View file

@ -0,0 +1,384 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 7 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option `$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl `shared' nor `disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the `shared' and
# `disable-shared' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the `static' and
# `disable-static' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the `fast-install'
# and `disable-fast-install' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
# LT_INIT options.
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for lt_pkg in $withval; do
IFS="$lt_save_ifs"
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

123
m4/ltsugar.m4 vendored Normal file
View file

@ -0,0 +1,123 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

23
m4/ltversion.m4 vendored Normal file
View file

@ -0,0 +1,23 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 3337 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.2])
m4_define([LT_PACKAGE_REVISION], [1.3337])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.2'
macro_revision='1.3337'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

98
m4/lt~obsolete.m4 vendored Normal file
View file

@ -0,0 +1,98 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])

4
src/Makefile.am Normal file
View file

@ -0,0 +1,4 @@
lib_LTLIBRARIES = libgadget.la
libgadget_la_SOURCES = gadget.c
libgadget_la_LDFLAGS = -version-info 0:1:0
AM_CPPFLAGS=-I../include/

851
src/gadget.c Normal file
View file

@ -0,0 +1,851 @@
/*
* Copyright (C) 2013 Linaro Limited
*
* Matt Porter <matt.porter@linaro.org>
*
* 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 <dirent.h>
#include <errno.h>
#include <gadget/gadget.h>
#include <netinet/ether.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/**
* @file gadget.c
* @todo Handle buffer overflows
* @todo Error checking and return code propagation
*/
#define ERROR(msg, ...) do {\
char *str;\
fprintf(stderr, "%s() "msg" \n", \
__func__, ##__VA_ARGS__);\
} while (0)
#define ERRORNO(msg, ...) do {\
char *str;\
fprintf(stderr, "%s() %s: "msg" \n", \
__func__, strerror(errno), ##__VA_ARGS__);\
} while (0)
static int gadget_lookup_function_type(char *name)
{
int i = 0;
int max = sizeof(function_names)/sizeof(char *);
if (!name)
return -1;
do {
if (!strcmp(name, function_names[i]))
break;
i++;
} while (i != max);
if (i == max)
i = -1;
return i;
}
static int bindings_select(const struct dirent *dent)
{
if (dent->d_type == DT_LNK)
return 1;
else
return 0;
}
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 char *gadget_read_buf(char *path, char *name, char *file, char *buf)
{
char p[256];
FILE *fp;
char *ret = NULL;
sprintf(p, "%s/%s/%s", path, name, file);
fp = fopen(p, "r");
if (!fp)
goto out;
ret = fgets(buf, 256, fp);
fclose(fp);
out:
return ret;
}
static int gadget_read_int(char *path, char *name, char *file, int base)
{
char buf[256];
if (gadget_read_buf(path, name, file, buf))
return strtol(buf, NULL, base);
else
return 0;
}
#define gadget_read_dec(p, n, f) gadget_read_int(p, n, f, 10)
#define gadget_read_hex(p, n, f) gadget_read_int(p, n, f, 16)
static void gadget_read_string(char *path, char *name, char *file, char *buf)
{
char *p;
gadget_read_buf(path, name, file, buf);
if ((p = strchr(buf, '\n')) != NULL)
*p = '\0';
}
static void gadget_write_buf(char *path, char *name, char *file, char *buf)
{
char p[256];
FILE *fp;
sprintf(p, "%s/%s/%s", path, name, file);
fp = fopen(p, "w");
if (!fp) {
ERRORNO("%s\n", p);
return;
}
fputs(buf, fp);
fclose(fp);
}
static void gadget_write_int(char *path, char *name, char *file, int value, char *str)
{
char buf[256];
sprintf(buf, str, value);
gadget_write_buf(path, name, file, buf);
}
#define gadget_write_dec(p, n, f, v) gadget_write_int(p, n, f, v, "%d\n")
#define gadget_write_hex16(p, n, f, v) gadget_write_int(p, n, f, v, "0x%04x\n")
#define gadget_write_hex8(p, n, f, v) gadget_write_int(p, n, f, v, "0x%02x\n")
static void gadget_write_string(char *path, char *name, char *file, char *buf)
{
gadget_write_buf(path, name, file, buf);
}
static void gadget_parse_function_attrs(struct function *f)
{
struct ether_addr *addr;
char str_addr[40];
switch (f->type) {
case F_SERIAL:
case F_ACM:
case F_OBEX:
f->attr.serial.port_num = gadget_read_dec(f->path, f->name, "port_num");
break;
case F_ECM:
case F_SUBSET:
case F_NCM:
case F_EEM:
case F_RNDIS:
gadget_read_string(f->path, f->name, "dev_addr", str_addr);
addr = ether_aton(str_addr);
memcpy(&f->attr.net.dev_addr, addr, 6);
gadget_read_string(f->path, f->name, "host_addr", str_addr);
addr = ether_aton(str_addr);
memcpy(&f->attr.net.host_addr, addr, 6);
gadget_read_string(f->path, f->name, "ifname", f->attr.net.ifname);
f->attr.net.qmult = gadget_read_dec(f->path, f->name, "qmult");
break;
case F_PHONET:
gadget_read_string(f->path, f->name, "ifname", f->attr.phonet.ifname);
break;
default:
ERROR("Unsupported function type\n");
}
}
static int gadget_parse_functions(char *path, struct gadget *g)
{
struct function *f;
int i, n;
struct dirent **dent;
char fpath[256];
sprintf(fpath, "%s/%s/functions", path, g->name);
TAILQ_INIT(&g->functions);
n = scandir(fpath, &dent, file_select, alphasort);
for (i=0; i < n; i++) {
f = malloc(sizeof(struct function));
f->parent = g;
strcpy(f->name, dent[i]->d_name);
strcpy(f->path, fpath);
f->type = gadget_lookup_function_type(strtok(dent[i]->d_name, "."));
gadget_parse_function_attrs(f);
TAILQ_INSERT_TAIL(&g->functions, f, fnode);
free(dent[i]);
}
free(dent);
}
static void gadget_parse_config_attrs(struct config *c)
{
c->maxpower = gadget_read_dec(c->path, c->name, "MaxPower");
c->bmattrs = gadget_read_hex(c->path, c->name, "bmAttributes");
gadget_read_string(c->path, c->name, "strings/0x409/configuration", c->str_cfg);
}
static void gadget_parse_config_bindings(struct config *c)
{
int i, n;
struct dirent **dent;
char bpath[256];
struct gadget *g = c->parent;
struct binding *b;
struct function *f;
sprintf(bpath, "%s/%s", c->path, c->name);
TAILQ_INIT(&c->bindings);
n = scandir(bpath, &dent, bindings_select, alphasort);
for (i=0; i < n; i++) {
TAILQ_FOREACH(f, &g->functions, fnode) {
int n;
char contents[256];
char cpath[256];
char fname[40];
sprintf(cpath, "%s/%s", bpath, dent[i]->d_name);
n = readlink(cpath, contents, 256);
if (n<0)
ERRORNO("bytes %d contents %s\n", n, contents);
strcpy(fname, f->name);
if (strstr(contents, strtok(fname, "."))) {
b = malloc(sizeof(struct binding));
strcpy(b->name, dent[i]->d_name);
strcpy(b->path, bpath);
b->target = f;
TAILQ_INSERT_TAIL(&c->bindings, b, bnode);
break;
}
}
free(dent[i]);
}
free(dent);
}
static int gadget_parse_configs(char *path, struct gadget *g)
{
struct config *c;
int i, n;
struct dirent **dent;
char cpath[256];
sprintf(cpath, "%s/%s/configs", path, g->name);
TAILQ_INIT(&g->configs);
n = scandir(cpath, &dent, file_select, alphasort);
for (i=0; i < n; i++) {
c = malloc(sizeof(struct config));
c->parent = g;
strcpy(c->name, dent[i]->d_name);
strcpy(c->path, cpath);
gadget_parse_config_attrs(c);
gadget_parse_config_bindings(c);
TAILQ_INSERT_TAIL(&g->configs, c, cnode);
free(dent[i]);
}
free(dent);
}
static void gadget_parse_attrs(char *path, struct gadget *g)
{
/* UDC bound to, if any */
gadget_read_string(path, g->name, "UDC", g->udc);
/* Actual attributes */
g->dclass = gadget_read_hex(path, g->name, "bDeviceClass");
g->dsubclass = gadget_read_hex(path, g->name, "bDeviceSubClass");
g->dproto = gadget_read_hex(path, g->name, "bDeviceProtocol");
g->maxpacket = gadget_read_hex(path, g->name, "bMaxPacketSize0");
g->bcddevice = gadget_read_hex(path, g->name, "bcdDevice");
g->bcdusb = gadget_read_hex(path, g->name, "bcdUSB");
g->vendor = gadget_read_hex(path, g->name, "idVendor");
g->product = gadget_read_hex(path, g->name, "idProduct");
/* Strings - hardcoded to U.S. English only for now */
gadget_read_string(path, g->name, "strings/0x409/serialnumber", g->str_ser);
gadget_read_string(path, g->name, "strings/0x409/manufacturer", g->str_mnf);
gadget_read_string(path, g->name, "strings/0x409/product", g->str_prd);
}
static int gadget_parse_gadgets(char *path, struct state *s)
{
struct gadget *g;
int i, n;
struct dirent **dent;
TAILQ_INIT(&s->gadgets);
n = scandir(path, &dent, file_select, alphasort);
for (i=0; i < n; i++) {
g = malloc(sizeof(struct gadget));
strcpy(g->name, dent[i]->d_name);
strcpy(g->path, s->path);
g->parent = s;
gadget_parse_attrs(path, g);
gadget_parse_functions(path, g);
gadget_parse_configs(path, g);
TAILQ_INSERT_TAIL(&s->gadgets, g, gnode);
free(dent[i]);
}
free(dent);
return 0;
}
static int gadget_init_state(char *path, struct state *s)
{
strcpy(s->path, path);
if (gadget_parse_gadgets(path, s) < 0) {
ERRORNO("unable to parse %s\n", path);
return -1;
}
return 0;
}
/*
* User API
*/
struct state *gadget_init(char *configfs_path)
{
int ret;
struct stat sts;
char path[256];
struct state *s = NULL;
strcpy(path, configfs_path);
ret = stat(strcat(path, "/usb_gadget"), &sts);
if (ret < 0) {
ERRORNO("%s", path);
goto out;
}
if (!S_ISDIR(sts.st_mode)) {
ERRORNO("%s", path);
goto out;
}
s = malloc(sizeof(struct state));
if (s)
gadget_init_state(path, s);
else
ERRORNO("couldn't init gadget state\n");
out:
return s;
}
void gadget_cleanup(struct state *s)
{
struct gadget *g;
struct config *c;
struct binding *b;
struct function *f;
while (!TAILQ_EMPTY(&s->gadgets)) {
g = TAILQ_FIRST(&s->gadgets);
while (!TAILQ_EMPTY(&g->configs)) {
c = TAILQ_FIRST(&g->configs);
while(!TAILQ_EMPTY(&c->bindings)) {
b = TAILQ_FIRST(&c->bindings);
TAILQ_REMOVE(&c->bindings, b, bnode);
free(b);
}
TAILQ_REMOVE(&g->configs, c, cnode);
free(c);
}
while (!TAILQ_EMPTY(&g->functions)) {
f = TAILQ_FIRST(&g->functions);
TAILQ_REMOVE(&g->functions, f, fnode);
free(f);
}
TAILQ_REMOVE(&s->gadgets, g, gnode);
free(g);
}
free(s);
}
struct gadget *gadget_get_gadget(struct state *s, const char *name)
{
struct gadget *g;
TAILQ_FOREACH(g, &s->gadgets, gnode)
if (!strcmp(g->name, name))
return g;
return NULL;
}
struct function *gadget_get_function(struct gadget *g, const char *name)
{
struct function *f;
TAILQ_FOREACH(f, &g->functions, fnode)
if (!strcmp(f->name, name))
return f;
return NULL;
}
struct config *gadget_get_config(struct gadget *g, const char *name)
{
struct config *c;
TAILQ_FOREACH(c, &g->configs, cnode)
if (!strcmp(c->name, name))
return c;
return NULL;
}
struct binding *gadget_get_binding(struct config *c, const char *name)
{
struct binding *b;
TAILQ_FOREACH(b, &c->bindings, bnode)
if (!strcmp(b->name, name))
return b;
return NULL;
}
struct binding *gadget_get_link_binding(struct config *c, struct function *f)
{
struct binding *b;
TAILQ_FOREACH(b, &c->bindings, bnode)
if (b->target == f)
return b;
return NULL;
}
struct gadget *gadget_create_gadget(struct state *s, char *name,
int vendor, int product)
{
char gpath[256];
struct gadget *g, *cur;
int ret;
if (!s)
return NULL;
g = gadget_get_gadget(s, name);
if (g) {
ERROR("duplicate gadget name\n");
return NULL;
}
sprintf(gpath, "%s/%s", s->path, name);
ret = mkdir(gpath, S_IRWXU|S_IRWXG|S_IRWXO);
if (ret < 0) {
ERRORNO("%s\n", gpath);
return NULL;
}
g = malloc(sizeof(struct gadget));
if (!g) {
ERRORNO("allocating gadget\n");
return NULL;
}
TAILQ_INIT(&g->configs);
TAILQ_INIT(&g->functions);
strcpy(g->name, name);
sprintf(g->path, "%s", s->path);
g->parent = s;
g->vendor = vendor;
g->product = product;
gadget_write_hex16(s->path, name, "idVendor", vendor);
gadget_write_hex16(s->path, name, "idProduct", product);
/* Insert in string order */
if (TAILQ_EMPTY(&s->gadgets) ||
(strcmp(name, TAILQ_FIRST(&s->gadgets)->name) < 0))
TAILQ_INSERT_HEAD(&s->gadgets, g, gnode);
else if (strcmp(name, TAILQ_LAST(&s->gadgets, ghead)->name) > 0)
TAILQ_INSERT_TAIL(&s->gadgets, g, gnode);
else
TAILQ_FOREACH(cur, &s->gadgets, gnode) {
if (strcmp(name, cur->name) > 0)
continue;
TAILQ_INSERT_BEFORE(cur, g, gnode);
}
return g;
}
void gadget_set_gadget_device_class(struct gadget *g, int dclass)
{
g->dclass = dclass;
gadget_write_hex8(g->path, "", "bDeviceClass", dclass);
}
void gadget_set_gadget_device_protocol(struct gadget *g, int dproto)
{
g->dproto = dproto;
gadget_write_hex8(g->path, "", "bDeviceProtocol", dproto);
}
void gadget_set_gadget_device_subclass(struct gadget *g, int dsubclass)
{
g->dsubclass = dsubclass;
gadget_write_hex8(g->path, "", "bDeviceSubClass", dsubclass);
}
void gadget_set_gadget_device_max_packet(struct gadget *g, int maxpacket)
{
g->maxpacket = maxpacket;
gadget_write_hex8(g->path, "", "bMaxPacketSize0", maxpacket);
}
void gadget_set_gadget_device_bcd_device(struct gadget *g, int bcddevice)
{
g->bcddevice = bcddevice;
gadget_write_hex16(g->path, "", "bcdDevice", bcddevice);
}
void gadget_set_gadget_device_bcd_usb(struct gadget *g, int bcdusb)
{
g->bcdusb = bcdusb;
gadget_write_hex16(g->path, "", "bcdUSB", bcdusb);
}
void gadget_set_gadget_serial_number(struct gadget *g, int lang, char *serno)
{
char path[256];
sprintf(path, "%s/%s/%s/0x%x", g->path, g->name, "strings", lang);
mkdir(path, S_IRWXU|S_IRWXG|S_IRWXO);
strcpy(g->str_ser, serno);
gadget_write_string(path, "", "serialnumber", serno);
}
void gadget_set_gadget_manufacturer(struct gadget *g, int lang, char *mnf)
{
char path[256];
sprintf(path, "%s/%s/%s/0x%x", g->path, g->name, "strings", lang);
mkdir(path, S_IRWXU|S_IRWXG|S_IRWXO);
strcpy(g->str_mnf, mnf);
gadget_write_string(path, "", "manufacturer", mnf);
}
void gadget_set_gadget_product(struct gadget *g, int lang, char *prd)
{
char path[256];
sprintf(path, "%s/%s/%s/0x%x", g->path, g->name, "strings", lang);
mkdir(path, S_IRWXU|S_IRWXG|S_IRWXO);
strcpy(g->str_prd, prd);
gadget_write_string(path, "", "product", prd);
}
struct function *gadget_create_function(struct gadget *g, enum function_type type, char *instance)
{
char fpath[256];
char name[256];
struct function *f, *cur;
int ret;
if (!g)
return NULL;
/**
* @todo Check for legal function type
*/
sprintf(name, "%s.%s", function_names[type], instance);
f = gadget_get_function(g, name);
if (f) {
ERROR("duplicate function name\n");
return NULL;
}
sprintf(fpath, "%s/%s/functions/%s", g->path, g->name, name);
ret = mkdir(fpath, S_IRWXU|S_IRWXG|S_IRWXO);
if (ret < 0) {
ERRORNO("%s\n", fpath);
return NULL;
}
f = malloc(sizeof(struct function));
if (!f) {
ERRORNO("allocating function\n");
return NULL;
}
strcpy(f->name, name);
sprintf(f->path, "%s/%s/%s", g->path, g->name, "functions");
f->type = type;
gadget_parse_function_attrs(f);
/* Insert in string order */
if (TAILQ_EMPTY(&g->functions) ||
(strcmp(name, TAILQ_FIRST(&g->functions)->name) < 0))
TAILQ_INSERT_HEAD(&g->functions, f, fnode);
else if (strcmp(name, TAILQ_LAST(&g->functions, fhead)->name) > 0)
TAILQ_INSERT_TAIL(&g->functions, f, fnode);
else
TAILQ_FOREACH(cur, &g->functions, fnode) {
if (strcmp(name, cur->name) > 0)
continue;
TAILQ_INSERT_BEFORE(cur, f, fnode);
}
return f;
}
struct config *gadget_create_config(struct gadget *g, char *name)
{
char cpath[256];
struct config *c, *cur;
int ret;
if (!g)
return NULL;
/**
* @todo Check for legal configuration name
*/
c = gadget_get_config(g, name);
if (c) {
ERROR("duplicate configuration name\n");
return NULL;
}
sprintf(cpath, "%s/%s/configs/%s", g->path, g->name, name);
ret = mkdir(cpath, S_IRWXU|S_IRWXG|S_IRWXO);
if (ret < 0) {
ERRORNO("%s\n", cpath);
return NULL;
}
c = malloc(sizeof(struct config));
if (!c) {
ERRORNO("allocating configuration\n");
return NULL;
}
TAILQ_INIT(&c->bindings);
strcpy(c->name, name);
sprintf(c->path, "%s/%s/%s/%s", g->path, g->name, "configs", name);
/* Insert in string order */
if (TAILQ_EMPTY(&g->configs) ||
(strcmp(name, TAILQ_FIRST(&g->configs)->name) < 0))
TAILQ_INSERT_HEAD(&g->configs, c, cnode);
else if (strcmp(name, TAILQ_LAST(&g->configs, chead)->name) > 0)
TAILQ_INSERT_TAIL(&g->configs, c, cnode);
else
TAILQ_FOREACH(cur, &g->configs, cnode) {
if (strcmp(name, cur->name) > 0)
continue;
TAILQ_INSERT_BEFORE(cur, c, cnode);
}
return c;
}
void gadget_set_config_max_power(struct config *c, int maxpower)
{
c->maxpower = maxpower;
gadget_write_dec(c->path, c->name, "MaxPower", maxpower);
}
void gadget_set_config_bm_attrs(struct config *c, int bmattrs)
{
c->bmattrs = bmattrs;
gadget_write_hex8(c->path, c->name, "bmAttributes", bmattrs);
}
void gadget_set_config_string(struct config *c, int lang, char *str)
{
char path[256];
sprintf(path, "%s/%s/0x%x", c->path, "strings", lang);
mkdir(path, S_IRWXU|S_IRWXG|S_IRWXO);
strcpy(c->str_cfg, str);
gadget_write_string(path, "", "configuration", str);
}
int gadget_add_config_function(struct config *c, char *name, struct function *f)
{
char bpath[256];
char fpath[256];
struct binding *b;
struct binding *cur;
int ret = -1;
if (!c || !f)
return ret;
b = gadget_get_binding(c, name);
if (b) {
ERROR("duplicate binding name\n");
return ret;
}
b = gadget_get_link_binding(c, f);
if (b) {
ERROR("duplicate binding link\n");
return ret;
}
sprintf(bpath, "%s/%s", c->path, name);
sprintf(fpath, "%s/%s", f->path, f->name);
ret = symlink(fpath, bpath);
if (ret < 0) {
ERRORNO("%s -> %s\n", bpath, fpath);
return ret;
}
b = malloc(sizeof(struct binding));
if (!b) {
ERRORNO("allocating binding\n");
return -1;
}
strcpy(b->name, name);
strcpy(b->path, bpath);
b->target = f;
/* Insert in string order */
if (TAILQ_EMPTY(&c->bindings) ||
(strcmp(name, TAILQ_FIRST(&c->bindings)->name) < 0))
TAILQ_INSERT_HEAD(&c->bindings, b, bnode);
else if (strcmp(name, TAILQ_LAST(&c->bindings, bhead)->name) > 0)
TAILQ_INSERT_TAIL(&c->bindings, b, bnode);
else
TAILQ_FOREACH(cur, &c->bindings, bnode) {
if (strcmp(name, cur->name) > 0)
continue;
TAILQ_INSERT_BEFORE(cur, b, bnode);
}
return 0;
}
int gadget_get_udcs(struct dirent ***udc_list)
{
return scandir("/sys/class/udc", udc_list, file_select, alphasort);
}
void gadget_enable_gadget(struct gadget *g, char *udc)
{
char gudc[256];
struct dirent **udc_list;
int n;
if (!udc) {
n = gadget_get_udcs(&udc_list);
if (!n)
return;
strcpy(gudc, udc_list[0]->d_name);
while (n--)
free(udc_list[n]);
free(udc_list);
} else
strcpy (gudc, udc);
strcpy(g->udc, gudc);
gadget_write_string(g->path, g->name, "UDC", gudc);
}
void gadget_disable_gadget(struct gadget *g)
{
strcpy(g->udc, "");
gadget_write_string(g->path, g->name, "UDC", "");
}
/*
* USB function-specific attribute configuration
*/
void gadget_set_net_dev_addr(struct function *f, struct ether_addr *dev_addr)
{
char *str_addr;
memcpy(&f->attr.net.dev_addr, dev_addr, 6);
str_addr = ether_ntoa(dev_addr);
gadget_write_string(f->path, f->name, "dev_addr", str_addr);
}
void gadget_set_net_host_addr(struct function *f, struct ether_addr *host_addr)
{
char *str_addr;
memcpy(&f->attr.net.host_addr, host_addr, 6);
str_addr = ether_ntoa(host_addr);
gadget_write_string(f->path, f->name, "host_addr", str_addr);
}
void gadget_set_net_qmult(struct function *f, int qmult)
{
f->attr.net.qmult = qmult;
gadget_write_dec(f->path, f->name, "qmult", qmult);
}