From c98b2f82a4e532ca61592b08e3ad60749eb9f8d7 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 8 Mar 2002 21:12:35 +0000 Subject: Initial revision --- AUTHORS | 22 + COPYING | 304 +++++++ ChangeLog | 20 + INSTALL | 0 Makefile.am | 7 + Makefile.in | 342 ++++++++ NEWS | 0 README | 35 + acinclude.m4 | 99 +++ aclocal.m4 | 213 +++++ config.guess | 951 ++++++++++++++++++++ config.sub | 955 ++++++++++++++++++++ configure | 2217 +++++++++++++++++++++++++++++++++++++++++++++++ configure.in | 89 ++ hcid/Makefile.am | 28 + hcid/Makefile.in | 362 ++++++++ hcid/hcid.conf | 63 ++ hcid/hcid.h | 92 ++ hcid/kword.c | 75 ++ hcid/kword.h | 36 + hcid/lexer.l | 129 +++ hcid/lib.c | 171 ++++ hcid/lib.h | 85 ++ hcid/main.c | 430 +++++++++ hcid/parser.y | 272 ++++++ hcid/security.c | 477 ++++++++++ install-sh | 251 ++++++ missing | 198 +++++ mkinstalldirs | 40 + pcmcia/Makefile.am | 12 + pcmcia/Makefile.in | 198 +++++ pcmcia/bluetooth | 34 + pcmcia/bluetooth.conf | 26 + scripts/Makefile.am | 18 + scripts/Makefile.in | 227 +++++ scripts/bluepin | 148 ++++ scripts/bluetooth.rc.rh | 72 ++ tools/Makefile.am | 10 + tools/Makefile.in | 433 +++++++++ tools/hciattach.8 | 102 +++ tools/hciattach.c | 751 ++++++++++++++++ tools/hciconfig.c | 524 +++++++++++ tools/hcisecfilter.c | 79 ++ tools/hcitool.c | 368 ++++++++ tools/l2ping.8 | 49 ++ tools/l2ping.c | 251 ++++++ tools/l2test.c | 493 +++++++++++ tools/scotest.c | 358 ++++++++ 48 files changed, 12116 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 acinclude.m4 create mode 100644 aclocal.m4 create mode 100755 config.guess create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.in create mode 100644 hcid/Makefile.am create mode 100644 hcid/Makefile.in create mode 100644 hcid/hcid.conf create mode 100644 hcid/hcid.h create mode 100644 hcid/kword.c create mode 100644 hcid/kword.h create mode 100644 hcid/lexer.l create mode 100644 hcid/lib.c create mode 100644 hcid/lib.h create mode 100644 hcid/main.c create mode 100644 hcid/parser.y create mode 100644 hcid/security.c create mode 100755 install-sh create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 pcmcia/Makefile.am create mode 100644 pcmcia/Makefile.in create mode 100755 pcmcia/bluetooth create mode 100644 pcmcia/bluetooth.conf create mode 100644 scripts/Makefile.am create mode 100644 scripts/Makefile.in create mode 100755 scripts/bluepin create mode 100755 scripts/bluetooth.rc.rh create mode 100644 tools/Makefile.am create mode 100644 tools/Makefile.in create mode 100644 tools/hciattach.8 create mode 100644 tools/hciattach.c create mode 100644 tools/hciconfig.c create mode 100644 tools/hcisecfilter.c create mode 100644 tools/hcitool.c create mode 100644 tools/l2ping.8 create mode 100644 tools/l2ping.c create mode 100644 tools/l2test.c create mode 100644 tools/scotest.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..08f12162 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,22 @@ +Maxim Krasnyansky + Original author. + Primary maintainer. + +Ilguiz Latypov + Patches. Suggestions. + +Jan Beutel + Documentation maintainer. + BlueZ HowTo. + +Jean Tourrilhes + CSR and BrainBoxes specific UART initialization. + +Thomas Moser + Silicon Wave UART initialization. + +Marcel Holtmann + Various patches, fixes and other contributions. + +Nils Faerber + Man pages. diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..357e7469 --- /dev/null +++ b/COPYING @@ -0,0 +1,304 @@ + + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + + ------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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 diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..7149ba9b --- /dev/null +++ b/ChangeLog @@ -0,0 +1,20 @@ +ver 2.0-pre7: + Bluetooth utilities is now a separate package. + +ver 2.0-pre6: + Improved hcitool. + l2test minor output fixes. + hciattach opt to display list of supported devices. + +ver 2.0-pre2: + Additional HCI library functions. + Improved CSR baud rate initialization. + PCMCIA scripts fixes and enhancements. + Documentation update. + +ver 2.0-pre1: + New UART initialization utility. + Hot plugging support for UART based PCMCIA devices. + SCO testing utility. + New authentication utility (bluepin). + Minor fixes and improvements. diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..e69de29b diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..17255ef5 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,7 @@ +# +# $Id$ +# + +EXTRA_DIST = ChangeLog README CREDITS + +SUBDIRS = hcid tools scripts pcmcia diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 00000000..03dcae4e --- /dev/null +++ b/Makefile.in @@ -0,0 +1,342 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# $Id$ +# + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AWK = @AWK@ +CC = @CC@ +DISTRO = @DISTRO@ +GLIB = @GLIB@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LDFLAGS = @GLIB_LDFLAGS@ +LD = @LD@ +LEX = @LEX@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +PCMCIA = @PCMCIA@ +VERSION = @VERSION@ +YACC = @YACC@ + +EXTRA_DIST = ChangeLog README CREDITS + +SUBDIRS = hcid tools scripts pcmcia +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ +Makefile.in NEWS acinclude.m4 aclocal.m4 config.guess config.sub \ +configure configure.in install-sh missing mkinstalldirs + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" != "." || dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: +uninstall: uninstall-recursive +all-am: Makefile +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-tags distclean-generic clean-am + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/README b/README new file mode 100644 index 00000000..69bc3145 --- /dev/null +++ b/README @@ -0,0 +1,35 @@ +BlueZ - Bluetooth protocol stack for Linux +Copyright (C) 2000-2001 Qualcomm Incorporated + +Written 2000,2001 by Maxim Krasnyansky + +Bluetooth utilities + +1. Compilation and Installation. + +In order to compile Bluetooth utilies you need following software packages: + - Linux kernel 2.4.X source code + - GCC compiler + - Lexical Analyzer (flex, lex) + - YACC (yacc, bison, byacc) + +To configure run: + ./configure + +Configure automatically searches for all required components and packages. + +To compile and install run: + make install + +2.0 Information + +Mailing lists: + bluez-announce@lists.sourceforge.net - BlueZ announcements + bluez-users@lists.sourceforge.net - BlueZ general questions and discussions + bluez-devel@lists.sourceforge.net - BlueZ development + bluez-commit@lists.sourceforge.net - BlueZ commits to the CVS repository + +For additional information about the project visit BlueZ web site: + http://bluez.sf.net + +Maxim Krasnyansky diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 00000000..1dc30479 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,99 @@ +dnl Add directory level +AC_DEFUN( AC_ADD_DIRLEVEL, +[ + for i in $1; do + eval o=\$$i + o=`echo $o | sed 's#.\.\./#&../#g'` + eval $i=\$o + done +]) + +dnl Test file +AC_DEFUN( AC_TEST_FILE, +[ + if test -f $1; then + ifelse([$2], , :,[$2]) + else + ifelse([$3], , :,[$3]) + fi +]) + +dnl Test dir +AC_DEFUN( AC_TEST_DIR, +[ + if test -d $1; then + ifelse([$2], , :,[$2]) + else + ifelse([$3], , :,[$3]) + fi +]) + +dnl Test files +AC_DEFUN( AC_TEST_FILES, +[ + ac_file_found=yes + for f in $1; do + if test ! -f $2/$f; then + ac_file_found=no + break; + fi + done + + if test "$ac_file_found" = "yes" ; then + ifelse([$3], , :,[$3]) + else + ifelse([$4], , :,[$4]) + fi +]) + +dnl Search for headers, add path to CPPFLAGS if found +AC_DEFUN( AC_SEARCH_HEADERS, +[ + AC_MSG_CHECKING("for $1") + ac_hdr_found=no + for p in $2; do + AC_TEST_FILES($1, $p, + [ + ac_hdr_found=yes + break + ] + ) + done + if test "$ac_hdr_found" = "yes" ; then + CPPFLAGS="$CPPFLAGS -I$p" + AC_MSG_RESULT( [($p) yes] ) + ifelse([$3], , :,[$3]) + else + AC_MSG_RESULT("no") + ifelse([$4], , :,[$4]) + fi +]) + +dnl Search for library, add path to LIBS if found +AC_DEFUN( AC_SEARCH_LIB, +[ + AC_MSG_CHECKING("for lib$1") + + ac_save_LDFLAGS=$LDFLAGS + + ac_lib_found=no + for p in $3; do + LDFLAGS="-L$p -l$1" + AC_TRY_LINK_FUNC($2, + [ + LIBS="$LIBS -L$p -l$1" + ac_lib_found=yes + break + ] + ) + done + if test "$ac_lib_found" = "yes" ; then + AC_MSG_RESULT( [($p) yes] ) + ifelse([$4], , :,[$4]) + else + AC_MSG_RESULT("no") + ifelse([$5], , :,[$5]) + fi + + LDFLAGS=$ac_save_LDFLAGS +]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 00000000..7b89b4b2 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,213 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4-p5 + +dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +dnl Add directory level +AC_DEFUN( AC_ADD_DIRLEVEL, +[ + for i in $1; do + eval o=\$$i + o=`echo $o | sed 's#.\.\./#&../#g'` + eval $i=\$o + done +]) + +dnl Test file +AC_DEFUN( AC_TEST_FILE, +[ + if test -f $1; then + ifelse([$2], , :,[$2]) + else + ifelse([$3], , :,[$3]) + fi +]) + +dnl Test dir +AC_DEFUN( AC_TEST_DIR, +[ + if test -d $1; then + ifelse([$2], , :,[$2]) + else + ifelse([$3], , :,[$3]) + fi +]) + +dnl Test files +AC_DEFUN( AC_TEST_FILES, +[ + ac_file_found=yes + for f in $1; do + if test ! -f $2/$f; then + ac_file_found=no + break; + fi + done + + if test "$ac_file_found" = "yes" ; then + ifelse([$3], , :,[$3]) + else + ifelse([$4], , :,[$4]) + fi +]) + +dnl Search for headers, add path to CPPFLAGS if found +AC_DEFUN( AC_SEARCH_HEADERS, +[ + AC_MSG_CHECKING("for $1") + ac_hdr_found=no + for p in $2; do + AC_TEST_FILES($1, $p, + [ + ac_hdr_found=yes + break + ] + ) + done + if test "$ac_hdr_found" = "yes" ; then + CPPFLAGS="$CPPFLAGS -I$p" + AC_MSG_RESULT( [($p) yes] ) + ifelse([$3], , :,[$3]) + else + AC_MSG_RESULT("no") + ifelse([$4], , :,[$4]) + fi +]) + +dnl Search for library, add path to LIBS if found +AC_DEFUN( AC_SEARCH_LIB, +[ + AC_MSG_CHECKING("for lib$1") + + ac_save_LDFLAGS=$LDFLAGS + + ac_lib_found=no + for p in $3; do + LDFLAGS="-L$p -l$1" + AC_TRY_LINK_FUNC($2, + [ + LIBS="$LIBS -L$p -l$1" + ac_lib_found=yes + break + ] + ) + done + if test "$ac_lib_found" = "yes" ; then + AC_MSG_RESULT( [($p) yes] ) + ifelse([$4], , :,[$4]) + else + AC_MSG_RESULT("no") + ifelse([$5], , :,[$5]) + fi + + LDFLAGS=$ac_save_LDFLAGS +]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN([AM_MISSING_PROG], +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + + +dnl AM_PROG_LEX +dnl Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT +AC_DEFUN([AM_PROG_LEX], +[missing_dir=ifelse([$1],,`cd $ac_aux_dir && pwd`,$1) +AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex") +AC_PROG_LEX +AC_DECL_YYTEXT]) + diff --git a/config.guess b/config.guess new file mode 100755 index 00000000..2960d6e0 --- /dev/null +++ b/config.guess @@ -0,0 +1,951 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. +# +# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <dummy.s + .globl main + .ent main +main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + ${CC-cc} dummy.s -o dummy 2>/dev/null + if test "$?" = 0 ; then + ./dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + fi + rm -f dummy.s dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]` + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + arm32:NetBSD:*:*) + echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + macppc:NetBSD:*:*) + echo powerpc-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >dummy.c + int main (argc, argv) int argc; char **argv; { + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + ${CC-cc} dummy.c -o dummy \ + && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 ) + sed 's/^ //' << EOF >dummy.c + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (${CC-cc} dummy.c -o dummy 2>/dev/null ) && HP_ARCH=`./dummy` + rm -f dummy.c dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # uname on the ARM produces all sorts of strangeness, and we need to + # filter it out. + case "$UNAME_MACHINE" in + arm* | sa110*) UNAME_MACHINE="arm" ;; + esac + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. + ld_help_string=`ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; + i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; + sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + sed 's/^ //' <dummy.s + .globl main + .ent main + main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + LIBC="" + ${CC-cc} dummy.s -o dummy 2>/dev/null + if test "$?" = 0 ; then + ./dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + + objdump --private-headers dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f dummy.s dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >dummy.c </dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >dummy.c < +main(argc, argv) + int argc; + char *argv[]; +{ +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i?86:UnixWare:*:*) + if /bin/uname -X 2>/dev/null >/dev/null ; then + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + fi + echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION} + exit 0 ;; + pc:*:*:*) + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +rm -f dummy.c dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/config.sub b/config.sub new file mode 100755 index 00000000..00bea6e6 --- /dev/null +++ b/config.sub @@ -0,0 +1,955 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \ + | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \ + | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \ + | mips64 | mipsel | mips64el | mips64orion | mips64orionel \ + | mipstx39 | mipstx39el \ + | sparc | sparclet | sparclite | sparc64 | v850) + basic_machine=$basic_machine-unknown + ;; + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[34567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \ + | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \ + | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \ + | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mipstx39-* | mipstx39el-* \ + | f301-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | k6 | 6x86) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | k6-* | 6x86-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/configure b/configure new file mode 100755 index 00000000..8b56bff4 --- /dev/null +++ b/configure @@ -0,0 +1,2217 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_default_prefix= +ac_help="$ac_help +--with-bluez-libs=DIR BlueZ libraries and header files" +ac_help="$ac_help +--with-glib=DIR GLib libraries and header files" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file= + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + + + + + + + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + + +# Do some error checking and defaulting for the host and target type. +# The inputs are: +# configure --host=HOST --target=TARGET --build=BUILD NONOPT +# +# The rules are: +# 1. You are not allowed to specify --host, --target, and nonopt at the +# same time. +# 2. Host defaults to nonopt. +# 3. If nonopt is not specified, then host defaults to the current host, +# as determined by config.guess. +# 4. Target and build default to nonopt. +# 5. If nonopt is not specified, then target and build default to host. + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +case $host---$target---$nonopt in +NONE---*---* | *---NONE---* | *---*---NONE) ;; +*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; +esac + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:586: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:607: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:625: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +test "$host_alias" != "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:654: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:687: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:740: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:797: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=bluez-utils + +VERSION=1.0 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <> confdefs.h <&6 +echo "configure:843: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:856: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:869: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:882: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:895: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:912: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:942: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:993: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:1025: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 1036 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:1041: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1067: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1072: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1100: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +for ac_prog in gawk mawk nawk awk +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1136: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AWK="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AWK="$ac_cv_prog_AWK" +if test -n "$AWK"; then + echo "$ac_t""$AWK" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$AWK" && break +done + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1177: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +if test $host != $build; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. +set dummy ${ac_tool_prefix}ld; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1238: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$LD"; then + ac_cv_prog_LD="$LD" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_LD="${ac_tool_prefix}ld" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +LD="$ac_cv_prog_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_LD"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ld", so it can be a program name with args. +set dummy ld; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1270: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$LD"; then + ac_cv_prog_LD="$LD" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_LD="ld" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_LD" && ac_cv_prog_LD="ld" +fi +fi +LD="$ac_cv_prog_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + LD="ld" +fi +fi + +# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1305: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +AR="$ac_cv_prog_AR" +if test -n "$AR"; then + echo "$ac_t""$AR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +if test -z "$ac_cv_prog_AR"; then +if test -n "$ac_tool_prefix"; then + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1337: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_AR="ar" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" +fi +fi +AR="$ac_cv_prog_AR" +if test -n "$AR"; then + echo "$ac_t""$AR" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +else + AR="ar" +fi +fi + + +for ac_prog in 'bison -y' byacc +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1375: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$YACC"; then + ac_cv_prog_YACC="$YACC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_YACC="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +YACC="$ac_cv_prog_YACC" +if test -n "$YACC"; then + echo "$ac_t""$YACC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$YACC" && break +done +test -n "$YACC" || YACC="yacc" + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1406: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1427: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1444: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1461: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +missing_dir=`cd $ac_aux_dir && pwd` +for ac_prog in flex lex +do +# Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1491: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$LEX"; then + ac_cv_prog_LEX="$LEX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_LEX="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +LEX="$ac_cv_prog_LEX" +if test -n "$LEX"; then + echo "$ac_t""$LEX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +test -n "$LEX" && break +done +test -n "$LEX" || LEX=""$missing_dir/missing flex"" + +# Extract the first word of "flex", so it can be a program name with args. +set dummy flex; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1524: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$LEX"; then + ac_cv_prog_LEX="$LEX" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_LEX="flex" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex" +fi +fi +LEX="$ac_cv_prog_LEX" +if test -n "$LEX"; then + echo "$ac_t""$LEX" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$LEXLIB" +then + case "$LEX" in + flex*) ac_lib=fl ;; + *) ac_lib=l ;; + esac + echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 +echo "configure:1558: checking for yywrap in -l$ac_lib" >&5 +ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-l$ac_lib $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + LEXLIB="-l$ac_lib" +else + echo "$ac_t""no" 1>&6 +fi + +fi + +echo $ac_n "checking lex output file root""... $ac_c" 1>&6 +echo "configure:1600: checking lex output file root" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # The minimal lex program is just a single line: %%. But some broken lexes +# (Solaris, I think it was) want two %% lines, so accommodate them. +echo '%% +%%' | $LEX +if test -f lex.yy.c; then + ac_cv_prog_lex_root=lex.yy +elif test -f lexyy.c; then + ac_cv_prog_lex_root=lexyy +else + { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; } +fi +fi + +echo "$ac_t""$ac_cv_prog_lex_root" 1>&6 +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root + +echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6 +echo "configure:1621: checking whether yytext is a pointer" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # POSIX says lex can declare yytext either as a pointer or an array; the +# default is implementation-dependent. Figure out which it is, since +# not all implementations provide the %pointer and %array declarations. +ac_cv_prog_lex_yytext_pointer=no +echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c +ac_save_LIBS="$LIBS" +LIBS="$LIBS $LEXLIB" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_prog_lex_yytext_pointer=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +LIBS="$ac_save_LIBS" +rm -f "${LEX_OUTPUT_ROOT}.c" + +fi + +echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6 +if test $ac_cv_prog_lex_yytext_pointer = yes; then + cat >> confdefs.h <<\EOF +#define YYTEXT_POINTER 1 +EOF + +fi + + +# Check whether --with-bluez-libs or --without-bluez-libs was given. +if test "${with_bluez_libs+set}" = set; then + withval="$with_bluez_libs" + + BLUEZ_INCDIR="$withval"/include + BLUEZ_LIBDIR="$withval"/src/.libs + +else + + BLUEZ_INCDIR='../libs/include ../bluez-libs*/include /usr/include/bluetooth' + BLUEZ_LIBDIR='../libs/src/.libs ../bluez-libs*/src/.libs /usr/lib' + + +fi + + + + echo $ac_n "checking "for bluetooth.h"""... $ac_c" 1>&6 +echo "configure:1680: checking "for bluetooth.h"" >&5 + ac_hdr_found=no + for p in $BLUEZ_INCDIR; do + + ac_file_found=yes + for f in bluetooth.h; do + if test ! -f $p/$f; then + ac_file_found=no + break; + fi + done + + if test "$ac_file_found" = "yes" ; then + + ac_hdr_found=yes + break + + + else + : + fi + + done + if test "$ac_hdr_found" = "yes" ; then + CPPFLAGS="$CPPFLAGS -I$p" + echo "$ac_t""($p) yes " 1>&6 + : + else + echo "$ac_t"""no"" 1>&6 + { echo "configure: error: Bluetooth headers not found. + Please install bluez-libs package." 1>&2; exit 1; } + + fi + + + + echo $ac_n "checking "for libbluetooth"""... $ac_c" 1>&6 +echo "configure:1717: checking "for libbluetooth"" >&5 + + ac_save_LDFLAGS=$LDFLAGS + + ac_lib_found=no + for p in $BLUEZ_LIBDIR; do + LDFLAGS="-L$p -lbluetooth" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + LIBS="$LIBS -L$p -lbluetooth" + ac_lib_found=yes + break + + +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* + done + if test "$ac_lib_found" = "yes" ; then + echo "$ac_t""($p) yes " 1>&6 + : + else + echo "$ac_t"""no"" 1>&6 + { echo "configure: error: Bluetooth library not found. + Please compile and install bluez-libs package." 1>&2; exit 1; } + + fi + + LDFLAGS=$ac_save_LDFLAGS + + +# Check whether --with-glib or --without-glib was given. +if test "${with_glib+set}" = set; then + withval="$with_glib" + + GLIB_CFLAGS="-I$withval" + GLIB_LDFLAGS="-L$withval/.libs -lglib" + +else + + echo "$ac_t"""checking for GLib ..."" 1>&6 + # Extract the first word of "glib-config", so it can be a program name with args. +set dummy glib-config; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1775: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_GLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$GLIB"; then + ac_cv_prog_GLIB="$GLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_GLIB="yes" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_GLIB" && ac_cv_prog_GLIB="not found" +fi +fi +GLIB="$ac_cv_prog_GLIB" +if test -n "$GLIB"; then + echo "$ac_t""$GLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test "$GLIB" = "yes"; then + GLIB_CFLAGS="`glib-config --cflags`" + GLIB_LDFLAGS="`glib-config --libs`" + else + { echo "configure: error: GLib not found" 1>&2; exit 1; } + fi + + +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1825: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +DISTRO=unknown + +if test "$cross_compiling" != yes; then + + if test -f /etc/redhat-release; then + DISTRO=redhat + else + : + fi + + + if test -f /etc/mandrake-release; then + DISTRO=redhat + else + : + fi + + + if test -f /etc/debian_version; then + DISTRO=debian + else + : + fi + +fi + +if test "$cross_compiling" != yes; then + + if test -d /etc/pcmcia; then + PCMCIA=pcmcia + else + PCMCIA= + fi + +fi + + + for i in CFLAGS CPPFLAGS LDFLAGS LIBS; do + eval o=\$$i + o=`echo $o | sed 's#.\.\./#&../#g'` + eval $i=\$o + done + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "Makefile hcid/Makefile tools/Makefile scripts/Makefile pcmcia/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@DISTRO@%$DISTRO%g +s%@PCMCIA@%$PCMCIA%g +s%@GLIB_CFLAGS@%$GLIB_CFLAGS%g +s%@GLIB_LDFLAGS@%$GLIB_LDFLAGS%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@AWK@%$AWK%g +s%@LD@%$LD%g +s%@AR@%$AR%g +s%@YACC@%$YACC%g +s%@LEX@%$LEX%g +s%@LEXLIB@%$LEXLIB%g +s%@CPP@%$CPP%g +s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g +s%@GLIB@%$GLIB%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/configure.in b/configure.in new file mode 100644 index 00000000..7bcfab76 --- /dev/null +++ b/configure.in @@ -0,0 +1,89 @@ +dnl +dnl $Id$ +dnl +dnl Process this file with autoconf to produce a configure script. +dnl +AC_INIT() + +AC_SUBST(DISTRO) +AC_SUBST(PCMCIA) + +AC_SUBST(GLIB_CFLAGS) +AC_SUBST(GLIB_LDFLAGS) + +AC_PREFIX_DEFAULT() + +dnl Guess host type. +AC_CANONICAL_SYSTEM +AC_CANONICAL_HOST + +AM_INIT_AUTOMAKE(bluez-utils, 1.0) + +dnl Check for programs. +AC_PROG_CC +AC_PROG_AWK +AC_PROG_INSTALL +AC_CHECK_TOOL(LD, ld, ld) +AC_CHECK_TOOL(AR, ar, ar) + +AC_PROG_YACC +AM_PROG_LEX + +AC_ARG_WITH(bluez-libs, + --with-bluez-libs=DIR BlueZ libraries and header files, + [ + BLUEZ_INCDIR="$withval"/include + BLUEZ_LIBDIR="$withval"/src/.libs + ],[ + BLUEZ_INCDIR='../libs/include ../bluez-libs*/include /usr/include/bluetooth' + BLUEZ_LIBDIR='../libs/src/.libs ../bluez-libs*/src/.libs /usr/lib' + ] +) + +AC_SEARCH_HEADERS(bluetooth.h, $BLUEZ_INCDIR,, + AC_MSG_ERROR(Bluetooth headers not found. + Please install bluez-libs package.) +) + +AC_SEARCH_LIB(bluetooth, hci_open_dev, $BLUEZ_LIBDIR,, + AC_MSG_ERROR(Bluetooth library not found. + Please compile and install bluez-libs package.) +) + +AC_ARG_WITH(glib, + --with-glib=DIR GLib libraries and header files, + [ + GLIB_CFLAGS="-I$withval" + GLIB_LDFLAGS="-L$withval/.libs -lglib" + ],[ + AC_MSG_RESULT("checking for GLib ...") + AC_CHECK_PROG(GLIB, glib-config, yes, [not found]) + if test "$GLIB" = "yes"; then + GLIB_CFLAGS="`glib-config --cflags`" + GLIB_LDFLAGS="`glib-config --libs`" + else + AC_MSG_ERROR(GLib not found) + fi + ] +) + +dnl Check for programs. +AC_PROG_INSTALL + +dnl Check for distro type. +DISTRO=unknown + +if test "$cross_compiling" != yes; then + AC_TEST_FILE(/etc/redhat-release, DISTRO=redhat) + AC_TEST_FILE(/etc/mandrake-release, DISTRO=redhat) + AC_TEST_FILE(/etc/debian_version, DISTRO=debian) +fi + +dnl Check for PCMCIA +if test "$cross_compiling" != yes; then + AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=) +fi + +AC_ADD_DIRLEVEL(CFLAGS CPPFLAGS LDFLAGS LIBS) + +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/hcid/Makefile.am b/hcid/Makefile.am new file mode 100644 index 00000000..edc4f653 --- /dev/null +++ b/hcid/Makefile.am @@ -0,0 +1,28 @@ +# +# $Id$ +# + +sbin_PROGRAMS = hcid + +hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.y lexer.l kword.c +hcid_LDADD = @GLIB_LDFLAGS@ + +CFLAGS += @GLIB_CFLAGS@ +YFLAGS += -d + +CLEANFILES = lexer.c parser.c parser.h + +confdir = $(prefix)/etc/bluetooth +conf_FILE = $(confdir)/hcid.conf +pin_FILE = $(confdir)/pin + +# +# Install configuration files +# +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(confdir) + [ -f $(DESTDIR)$(conf_FILE) ] || \ + $(INSTALL_DATA) $(srcdir)/hcid.conf $(DESTDIR)$(conf_FILE) + [ -f $(DESTDIR)$(pin_FILE) ] || \ + echo "BlueZ" > $(DESTDIR)$(pin_FILE); \ + chmod 600 $(DESTDIR)$(pin_FILE) diff --git a/hcid/Makefile.in b/hcid/Makefile.in new file mode 100644 index 00000000..037379a9 --- /dev/null +++ b/hcid/Makefile.in @@ -0,0 +1,362 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# $Id$ +# + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AWK = @AWK@ +CC = @CC@ +DISTRO = @DISTRO@ +GLIB = @GLIB@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LDFLAGS = @GLIB_LDFLAGS@ +LD = @LD@ +LEX = @LEX@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +PCMCIA = @PCMCIA@ +VERSION = @VERSION@ +YACC = @YACC@ + +sbin_PROGRAMS = hcid + +hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.y lexer.l kword.c +hcid_LDADD = @GLIB_LDFLAGS@ + +CFLAGS = @GLIB_CFLAGS@ +YFLAGS = -d + +CLEANFILES = lexer.c parser.c parser.h + +confdir = $(prefix)/etc/bluetooth +conf_FILE = $(confdir)/hcid.conf +pin_FILE = $(confdir)/pin +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +PROGRAMS = $(sbin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +hcid_OBJECTS = main.o security.o lib.o parser.o lexer.o kword.o +hcid_DEPENDENCIES = +hcid_LDFLAGS = +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LEXLIB = @LEXLIB@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in lexer.c parser.c + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +DEP_FILES = .deps/kword.P .deps/lexer.P .deps/lib.P .deps/main.P \ +.deps/parser.P .deps/security.P +SOURCES = $(hcid_SOURCES) +OBJECTS = $(hcid_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .l .o .s .y +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu hcid/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-sbinPROGRAMS: + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) + +distclean-sbinPROGRAMS: + +maintainer-clean-sbinPROGRAMS: + +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(sbindir) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(sbin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +hcid: $(hcid_OBJECTS) $(hcid_DEPENDENCIES) + @rm -f hcid + $(LINK) $(hcid_LDFLAGS) $(hcid_OBJECTS) $(hcid_LDADD) $(LIBS) +.l.c: + $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@ +.y.c: + $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c + if test -f y.tab.h; then \ + if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \ + else :; fi +parser.h: parser.c + + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = hcid + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu hcid/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-sbinPROGRAMS +install-exec: install-exec-am + +install-data-am: install-data-local +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-sbinPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(sbindir) + + +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: + -test -z "lexerlparserhparserc" || rm -f lexerl parserh parserc +mostlyclean-am: mostlyclean-sbinPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-depend mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-sbinPROGRAMS clean-compile clean-tags clean-depend \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-sbinPROGRAMS distclean-compile distclean-tags \ + distclean-depend distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-sbinPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-depend maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS \ +clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ +install-sbinPROGRAMS mostlyclean-compile distclean-compile \ +clean-compile maintainer-clean-compile tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir \ +mostlyclean-depend distclean-depend clean-depend \ +maintainer-clean-depend info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-local install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# +# Install configuration files +# +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(confdir) + [ -f $(DESTDIR)$(conf_FILE) ] || \ + $(INSTALL_DATA) $(srcdir)/hcid.conf $(DESTDIR)$(conf_FILE) + [ -f $(DESTDIR)$(pin_FILE) ] || \ + echo "BlueZ" > $(DESTDIR)$(pin_FILE); \ + chmod 600 $(DESTDIR)$(pin_FILE) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/hcid/hcid.conf b/hcid/hcid.conf new file mode 100644 index 00000000..cfd06e5f --- /dev/null +++ b/hcid/hcid.conf @@ -0,0 +1,63 @@ +# +# HCI daemon configuration file. +# +# $Id$ +# + +# HCId options +options { + # Automaticaly initialize new devices + autoinit yes; + + # Security Manager mode + # none - Security manager disabled + # auto - Use local PIN for incomming connections + # user - Always ask user for a PIN + # + security auto; + + # PIN helper + pin_helper /bin/bluepin; +} + +# Default settings for HCI devices +device { + # Local device name + # %d - device id + # %h - host name + name "BlueZ (%d)"; + + # Local device class + class 0x100; + + # Default packet type + pkt_type DH1,DM1,HV1; + + # Inquiry and Page scan + iscan enable; pscan enable; + + # Default link mode + # none - no specific policy + # accept - always accept incomming connections + # master - become master on incomming connections, + # deny role switch on outgoint connections + # + #lm accept,master; + # + lm accept; + + # Default link policy + # none - no specific policy + # rswitch - allow role switch + # hold - allow hold mode + # sniff - allow sniff mode + # park - allow park mode + # + #lp hold,sniff; + # + lp hold,sniff,park; + + # Authentication and Encryption + #auth enable; + #encrypt enable; +} diff --git a/hcid/hcid.h b/hcid/hcid.h new file mode 100644 index 00000000..677a02dd --- /dev/null +++ b/hcid/hcid.h @@ -0,0 +1,92 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ +/* + * $Id$ + */ + +#include + +#include + +#include + +#define HCID_CONFIG_FILE "/etc/bluetooth/hcid.conf" +#define HCID_PIN_FILE "/etc/bluetooth/pin" +#define HCID_KEY_FILE "/etc/bluetooth/link_key" +#define HCID_PIN_HELPER "/bin/bluepin" +#define HCID_KEY_NUM 20 +#define HCID_KEY_TTL 172800 /* 2 days */ + +struct device_opts { + char *name; + uint32_t class; + uint16_t pkt_type; + uint16_t scan; + uint16_t link_mode; + uint16_t link_policy; + uint16_t auth; + uint16_t encrypt; +}; +extern struct device_opts devi; + +struct link_key { + bdaddr_t sba; + bdaddr_t dba; + uint8_t key[16]; + uint8_t type; + time_t time; +}; + +struct hcid_opts { + char *host_name; + int auto_init; + int security; + + char *config_file; + + uint8_t pin_code[16]; + int pin_len; + char *pin_helper; + char *pin_file; + + struct link_key **link_key; + int key_num; + char *key_file; + + int sock; +}; +extern struct hcid_opts hcid; + +#define HCID_SEC_NONE 0 +#define HCID_SEC_AUTO 1 +#define HCID_SEC_USER 2 + +int read_config(char *file); + +gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data); +gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data); + +void start_security_manager(int hdev); +void stop_security_manager(int hdev); +void save_link_keys(void); +void flush_link_keys(void); diff --git a/hcid/kword.c b/hcid/kword.c new file mode 100644 index 00000000..a496591f --- /dev/null +++ b/hcid/kword.c @@ -0,0 +1,75 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ +/* + * $Id$ + */ + +#include +#include + +#include "hcid.h" +#include "kword.h" +#include "parser.h" + +struct kword cfg_keyword[] = { + { "options", K_OPTIONS }, + { "default", K_DEVICE }, + { "device", K_DEVICE }, + { "autoinit", K_AUTOINIT }, + { "security", K_SECURITY }, + { "pkt_type", K_PTYPE }, + { "lm", K_LM }, + { "lp", K_LP }, + { "iscan", K_ISCAN }, + { "pscan", K_PSCAN }, + { "name", K_NAME }, + { "class", K_CLASS }, + { "auth", K_AUTH }, + { "encrypt", K_ENCRYPT }, + { "pin_helper", K_PINHELP }, + + { "yes", K_YES }, + { "no", K_NO }, + { "enable", K_YES }, + { "disable", K_NO }, + { NULL , 0 } +}; + +struct kword sec_param[] = { + { "none", HCID_SEC_NONE }, + { "auto", HCID_SEC_AUTO }, + { "user", HCID_SEC_USER }, + { NULL , 0 } +}; + +int lineno; + +int find_keyword(struct kword *kw, char *str) +{ + while( kw->str ){ + if( !strcmp(str,kw->str) ) + return kw->type; + kw++; + } + return -1; +} diff --git a/hcid/kword.h b/hcid/kword.h new file mode 100644 index 00000000..854c91d0 --- /dev/null +++ b/hcid/kword.h @@ -0,0 +1,36 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ +/* + * $Id$ + */ + +struct kword { + char *str; + int type; +}; +extern int lineno; + +extern struct kword cfg_keyword[]; +extern struct kword sec_param[]; + +int find_keyword(struct kword *kw, char *str); diff --git a/hcid/lexer.l b/hcid/lexer.l new file mode 100644 index 00000000..a7af9c63 --- /dev/null +++ b/hcid/lexer.l @@ -0,0 +1,129 @@ +%{ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include + +#include "hcid.h" +#include "kword.h" +#include "parser.h" + +static char str_buf[255]; + +#define ECHO {;} +#define YY_DECL int yylex(void) + +int cfg_error(const char *ftm, ...); +int yyerror(char *str); + +%} + +hex 0x[0-9a-zA-Z]+ +num [0-9]+ +kword [A-Za-z0-9\_\-]+ +word [A-Za-z0-9\-\_+=\!\$\#\%\&\*\^\@@\\\~\.]+ +wordnm {word}:{num} +list ({word}\,*)+ +comment \#.*\n +fname [A-Za-z0-9\_\.\-]+ +path (\/{fname})+ +string \".*\" + +%x OPTION PARAM + +%% +[ \t] { + /* Skip spaces and tabs */ + ; +} + +{comment} { + /* Skip comments */ + lineno++; +} + +\n { + lineno++; +} + +{hex} { + yylval.num = strtol(yytext, NULL, 16); + return NUM; +} + +{num} { + yylval.num = atoi(yytext); + return NUM; +} + +{kword} { + int kw = find_keyword(cfg_keyword, yytext); + if( kw != -1 ) + return kw; + + yylval.str = yytext; + return WORD; +} + +{word} { + yylval.str = yytext; + return WORD; +} + +{string} { + if(yyleng > sizeof(str_buf)-1){ + yyerror("string too long"); + return 0; + } + + strncpy(str_buf, yytext+1, yyleng-2); + str_buf[yyleng-2] = '\0'; + + yylval.str = str_buf; + return STRING; +} + +{list} { + yylval.str = yytext; + return LIST; +} + +{path} { + yylval.str = yytext; + return PATH; +} + +. { + return *yytext; +} + +%% + +int yywrap(void) +{ + return 1; +} diff --git a/hcid/lib.c b/hcid/lib.c new file mode 100644 index 00000000..ac47603d --- /dev/null +++ b/hcid/lib.c @@ -0,0 +1,171 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hcid.h" +#include "lib.h" + +volatile sig_atomic_t __io_canceled; + +/* + * Device name expansion + * %d - device id + */ +char * expand_name(char *dst, char *str, int dev_id) +{ + register int sp, np, olen; + char *opt, buf[10]; + + if (!str && !dst) + return NULL; + + sp = np = 0; + while (str[sp]) { + switch (str[sp]) { + case '%': + opt = NULL; + + switch (str[sp+1]) { + case 'd': + sprintf(buf, "%d", dev_id); + opt = buf; + break; + + case 'h': + opt = hcid.host_name; + break; + + case '%': + dst[np++] = str[sp++]; + /* fall through */ + default: + sp++; + continue; + } + + if (opt) { + /* substitute */ + olen = strlen(opt); + memcpy(dst + np, opt, olen); + np += olen; + } + sp += 2; + continue; + + case '\\': + sp++; + /* fall through */ + default: + dst[np++] = str[sp++]; + break; + } + } + dst[np] = '\0'; + return dst; +} + +/* Returns current host name */ +char * get_host_name(void) +{ + char name[40]; + + if (!gethostname(name, sizeof(name)-1)) { + name[sizeof(name)-1] = 0; + return strdup(name); + } + return strdup("noname"); +} + +/* Functions to manipulate program title */ +extern char **environ; +char *title_start; /* start of the proc title space */ +char *title_end; /* end of the proc title space */ +int title_size; + +void init_title(int argc, char *argv[], char *envp[], const char *name) +{ + int i; + + /* + * Move the environment so settitle can use the space at + * the top of memory. + */ + + for (i = 0; envp[i]; i++); + + environ = (char **) malloc(sizeof (char *) * (i + 1)); + + for (i = 0; envp[i]; i++) + environ[i] = strdup(envp[i]); + environ[i] = NULL; + + /* + * Save start and extent of argv for set_title. + */ + + title_start = argv[0]; + + /* + * Determine how much space we can use for set_title. + * Use all contiguous argv and envp pointers starting at argv[0] + */ + for (i=0; i title_size - 1) + buf[title_size - 1] = '\0'; + + strcat(title_start, buf); +} diff --git a/hcid/lib.h b/hcid/lib.h new file mode 100644 index 00000000..4683c0ff --- /dev/null +++ b/hcid/lib.h @@ -0,0 +1,85 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ +/* + * $Id$ + */ + +#include + +char * expand_name(char *dst, char *str, int dev_id); + +char * get_host_name(void); + +void init_title(int argc, char *argv[], char *env[], const char *name); +void set_title(const char *ftm, ...); + +/* IO cancelation */ +extern volatile sig_atomic_t __io_canceled; + +static inline void io_init(void) +{ + __io_canceled = 0; +} + +static inline void io_cancel(void) +{ + __io_canceled = 1; +} + +/* Read exactly len bytes (Signal safe)*/ +static inline int read_n(int fd, void *buf, int len) +{ + register int t=0, w; + + while (!__io_canceled && len > 0) { + if( (w = read(fd, buf, len)) < 0 ){ + if( errno == EINTR || errno == EAGAIN ) + continue; + return -1; + } + if( !w ) + return 0; + len -= w; buf += w; t += w; + } + + return t; +} + +/* Write exactly len bytes (Signal safe)*/ +static inline int write_n(int fd, void *buf, int len) +{ + register int t=0, w; + + while (!__io_canceled && len > 0) { + if( (w = write(fd, buf, len)) < 0 ){ + if( errno == EINTR || errno == EAGAIN ) + continue; + return -1; + } + if( !w ) + return 0; + len -= w; buf += w; t += w; + } + + return t; +} diff --git a/hcid/main.c b/hcid/main.c new file mode 100644 index 00000000..5b3c3d30 --- /dev/null +++ b/hcid/main.c @@ -0,0 +1,430 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "hcid.h" +#include "lib.h" + +#define VERSION "1.1" + +struct hcid_opts hcid; +struct device_opts devi; + +static GMainLoop *event_loop; + +gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data); +gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data); + +static void usage(void) +{ + printf("hcid - HCI daemon ver %s\n", VERSION); + printf("Usage: \n"); + printf("\thcid [-n not_daemon] [-f config file]\n"); +} + +static void init_device(int hdev) +{ + struct hci_dev_req dr; + int s; + + /* Do initialization in the separate process */ + switch (fork()) { + case 0: + break; + case -1: + syslog(LOG_ERR, "Fork failed. Can't init device hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + default: + return; + } + + set_title("hci%d init", hdev); + + if ((s = hci_open_dev(hdev)) < 0) { + syslog(LOG_ERR, "Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + /* Start HCI device */ + if (ioctl(s, HCIDEVUP, hdev) < 0 && errno != EALREADY) { + syslog(LOG_ERR, "Can't init device hci%d. %s(%d)\n", hdev, + strerror(errno), errno); + exit(1); + } + + dr.dev_id = hdev; + + /* Set packet type */ + if (devi.pkt_type) { + dr.dev_opt = devi.pkt_type; + if (ioctl(s, HCISETPTYPE, (unsigned long)&dr) < 0) { + syslog(LOG_ERR, "Can't set packet type on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + } + } + + /* Set link mode */ + if (devi.link_mode) { + dr.dev_opt = devi.link_mode; + if (ioctl(s, HCISETLINKMODE, (unsigned long)&dr) < 0) { + syslog(LOG_ERR, "Can't set link mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + } + } + + /* Set link policy */ + if (devi.link_policy) { + dr.dev_opt = devi.link_policy; + if (ioctl(s, HCISETLINKPOL, (unsigned long)&dr) < 0) { + syslog(LOG_ERR, "Can't set link policy on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + } + } + + /* Set scan mode */ + dr.dev_opt = devi.scan; + if (ioctl(s, HCISETSCAN, (unsigned long)&dr) < 0) { + syslog(LOG_ERR, "Can't set scan mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + } + + /* Set authentication */ + if (devi.auth) + dr.dev_opt = AUTH_ENABLED; + else + dr.dev_opt = AUTH_DISABLED; + + if (ioctl(s, HCISETAUTH, (unsigned long)&dr) < 0) { + syslog(LOG_ERR, "Can't set auth on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + } + + /* Set encryption */ + if (devi.encrypt) + dr.dev_opt = ENCRYPT_P2P; + else + dr.dev_opt = ENCRYPT_DISABLED; + + if (ioctl(s, HCISETENCRYPT, (unsigned long)&dr) < 0) { + syslog(LOG_ERR, "Can't set encrypt on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + } + + /* Set device class */ + if (devi.class) { + uint32_t class = htobl(devi.class); + write_class_of_dev_cp cp; + + memcpy(cp.dev_class, &class, 3); + hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, + WRITE_CLASS_OF_DEV_CP_SIZE, (void *) &cp); + } + + /* Set device name */ + if (devi.name) { + change_local_name_cp cp; + expand_name(cp.name, devi.name, hdev); + + hci_send_cmd(s, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, + CHANGE_LOCAL_NAME_CP_SIZE, (void *) &cp); + } + + exit(0); +} + +static void init_all_devices(int ctl) +{ + struct hci_dev_list_req *dl; + struct hci_dev_req *dr; + int i; + + if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) { + syslog(LOG_INFO, "Can't allocate devlist buffer. %s(%d)", + strerror(errno), errno); + exit(1); + } + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(ctl, HCIGETDEVLIST, (void*)dl)) { + syslog(LOG_INFO, "Can't get device list. %s(%d)", + strerror(errno), errno); + exit(1); + } + + for (i=0; i < dl->dev_num; i++, dr++) { + if (hcid.auto_init) + init_device(dr->dev_id); + + if (hcid.security && (dr->dev_opt & (1<dev_id); + } + + free(dl); +} + +static void init_defaults(void) +{ + hcid.auto_init = 0; + hcid.security = 0; + + devi.pkt_type = 0; + devi.scan = SCAN_PAGE | SCAN_INQUIRY; + devi.auth = 0; + devi.encrypt = 0; +} + +static void sig_usr1(int sig) +{ + syslog(LOG_INFO, "Flushing link keys"); + flush_link_keys(); +} + +static void sig_term(int sig) +{ + syslog(LOG_INFO, "Terminating"); + g_main_quit(event_loop); + save_link_keys(); +} + +static void sig_hup(int sig) +{ + syslog(LOG_INFO, "Reloading config file"); + init_defaults(); + if (read_config(hcid.config_file) < 0) + syslog(LOG_ERR, "Config reload failed"); + + init_all_devices(hcid.sock); +} + +static inline void device_event(GIOChannel *chan, evt_stack_internal *si) +{ + evt_si_device *sd = (void *) &si->data; + + switch (sd->event) { + case HCI_DEV_REG: + syslog(LOG_INFO, "HCI dev %d registered", sd->dev_id); + if (hcid.auto_init) + init_device(sd->dev_id); + break; + + case HCI_DEV_UNREG: + syslog(LOG_INFO, "HCI dev %d unregistered", sd->dev_id); + break; + + case HCI_DEV_UP: + syslog(LOG_INFO, "HCI dev %d up", sd->dev_id); + if (hcid.security) + start_security_manager(sd->dev_id); + break; + + case HCI_DEV_DOWN: + syslog(LOG_INFO, "HCI dev %d down", sd->dev_id); + if (hcid.security) + stop_security_manager(sd->dev_id); + break; + } +} + +gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + char buf[HCI_MAX_FRAME_SIZE], *ptr; + evt_stack_internal *si; + hci_event_hdr *eh; + int len, type; + GIOError err; + + ptr = buf; + + if ((err = g_io_channel_read(chan, buf, sizeof(buf), &len))) { + if (err == G_IO_ERROR_AGAIN) + return TRUE; + + syslog(LOG_ERR, "Read from control socket failed. %s(%d)", + strerror(errno), errno); + g_main_quit(event_loop); + return FALSE; + } + + type = *ptr++; + + if (type != HCI_EVENT_PKT) + return TRUE; + + eh = (hci_event_hdr *) ptr; + if (eh->evt != EVT_STACK_INTERNAL) + return TRUE; + + ptr += HCI_EVENT_HDR_SIZE; + + si = (evt_stack_internal *) ptr; + switch (si->type) { + case EVT_SI_DEVICE: + device_event(chan, si); + break; + } + + return TRUE; +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc, char *argv[], char *env[]) +{ + int daemon, dofork, opt, fd; + struct sockaddr_hci addr; + struct hci_filter flt; + struct sigaction sa; + GIOChannel *ctl_io; + + daemon = 1; dofork = 1; + + /* Default HCId settings */ + hcid.config_file = HCID_CONFIG_FILE; + hcid.host_name = get_host_name(); + + hcid.pin_file = strdup(HCID_PIN_FILE); + hcid.pin_helper = strdup(HCID_PIN_HELPER); + hcid.key_file = strdup(HCID_KEY_FILE); + hcid.key_num = HCID_KEY_NUM; + + init_defaults(); + + while ((opt=getopt(argc,argv,"f:n")) != EOF) { + switch(opt) { + case 'n': + daemon = 0; + break; + + case 'f': + hcid.config_file = strdup(optarg); + break; + + default: + usage(); + exit(1); + } + } + + if (daemon) { + if (dofork && fork()) + exit(0); + + /* Direct stdin,stdout,stderr to '/dev/null' */ + fd = open("/dev/null", O_RDWR); + dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); + close(fd); + + setsid(); + + chdir("/"); + } + + init_title(argc, argv, env, "hcid: "); + set_title("initializing"); + + /* Start logging to syslog and stderr */ + openlog("hcid", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); + syslog(LOG_INFO, "HCI daemon ver %s started", VERSION); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + sa.sa_handler = sig_usr1; + sigaction(SIGUSR1, &sa, NULL); + + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + /* Create and bind HCI socket */ + if ((hcid.sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { + syslog(LOG_ERR, "Can't open HCI socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Set filter */ + hci_filter_clear(&flt); + hci_filter_set_ptype(HCI_EVENT_PKT, &flt); + hci_filter_set_event(EVT_STACK_INTERNAL, &flt); + if (setsockopt(hcid.sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + syslog(LOG_ERR, "Can't set filter. %s(%d)", strerror(errno), errno); + exit(1); + } + + addr.hci_family = AF_BLUETOOTH; + addr.hci_dev = HCI_DEV_NONE; + if (bind(hcid.sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't bind HCI socket. %s(%d)\n", strerror(errno), errno); + exit(1); + } + + if (read_config(hcid.config_file) < 0) + syslog(LOG_ERR, "Config load failed"); + + /* Create event loop */ + event_loop = g_main_new(FALSE); + + /* Initialize already connected devices */ + init_all_devices(hcid.sock); + + set_title("processing events"); + + ctl_io = g_io_channel_unix_new(hcid.sock); + g_io_add_watch(ctl_io, G_IO_IN, io_stack_event, NULL); + + /* Start event processor */ + g_main_run(event_loop); + + syslog(LOG_INFO, "Exit."); + return 0; +} diff --git a/hcid/parser.y b/hcid/parser.y new file mode 100644 index 00000000..e8be6c99 --- /dev/null +++ b/hcid/parser.y @@ -0,0 +1,272 @@ +%{ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "hcid.h" +#include "kword.h" + +int cfg_error(const char *fmt, ...); + +int yyparse(void); +int yylex(void); +int yyerror(char *s); + +%} + +%union { + char *str; + long num; +} + +%token K_OPTIONS K_DEVICE +%token K_AUTOINIT K_SECURITY +%token K_PTYPE K_NAME K_CLASS K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN +%token K_PINHELP +%token K_YES K_NO + +%token WORD PATH STRING LIST +%token NUM + +%type bool pkt_type link_mode link_policy sec_mode +%type dev_name + +%% +config: statement | config statement; +statement: + K_OPTIONS hcid_options + + | K_DEVICE device_options + + | WORD { + cfg_error("Invalid statement '%s'", $1); + } + | error { + yyclearin; yyerrok; + } + ; + +hcid_options: '{' hcid_opts '}' +hcid_opts: | hcid_opt ';' | error ';' | hcid_opts hcid_opt ';'; +hcid_opt: + K_AUTOINIT bool { + hcid.auto_init = $2; + } + + | K_SECURITY sec_mode { + hcid.security = $2; + } + + | K_PINHELP PATH { + if (hcid.pin_helper) + free(hcid.pin_helper); + hcid.pin_helper = strdup($2); + } + + | WORD { + cfg_error("Unknown option '%s'", $1); + } + ; + +sec_mode: + WORD { + int opt = find_keyword(sec_param, $1); + if (opt < 0) { + cfg_error("Unknown security mode '%s'", $1); + $$ = 0; + } else + $$ = opt; + } + + | K_NO { $$ = HCID_SEC_NONE; } + ; + +device_options: '{' device_opts '}' +device_opts: | device_opt ';' | error ';' | device_opts device_opt ';'; +device_opt: + K_PTYPE pkt_type { + devi.pkt_type = $2; + } + + | K_LM link_mode { + devi.link_mode = $2; + } + + | K_LP link_policy { + devi.link_policy = $2; + } + + | K_NAME dev_name { + if (devi.name) + free(devi.name); + devi.name = $2; + } + + | K_CLASS NUM { + devi.class = $2; + } + + | K_AUTH bool { + devi.auth = $2; + } + + | K_ENCRYPT bool { + devi.encrypt = $2; + } + + | K_ISCAN bool { + if ($2) + devi.scan |= SCAN_INQUIRY; + else + devi.scan &= ~SCAN_INQUIRY; + } + + | K_PSCAN bool { + if ($2) + devi.scan |= SCAN_PAGE; + else + devi.scan &= ~SCAN_PAGE; + } + + | WORD { + cfg_error("Unknown option '%s'",$1); + YYABORT; + } + ; + +dev_name: + WORD { + $$ = strdup($1); + } + + | STRING { + $$ = strdup($1); + } + ; + +pkt_type: + WORD { + int opt; + if (!hci_strtoptype($1, &opt)) + cfg_error("Unknown packet type '%s'", $1); + $$ = opt; + } + + | LIST { + int opt; + if (!hci_strtoptype($1, &opt)) + cfg_error("Unknown packet type '%s'", $1); + $$ = opt; + } + ; + +link_mode: + WORD { + int opt; + if (!hci_strtolm($1, &opt)) + cfg_error("Unknown link mode '%s'", $1); + $$ = opt; + } + + | LIST { + int opt; + if (!hci_strtolm($1, &opt)) + cfg_error("Unknown link mode '%s'", $1); + $$ = opt; + } + ; + +link_policy: + WORD { + int opt; + if (!hci_strtolp($1, &opt)) + cfg_error("Unknown link policy '%s'", $1); + $$ = opt; + } + + | LIST { + int opt; + if (!hci_strtolp($1, &opt)) + cfg_error("Unknown link policy '%s'", $1); + $$ = opt; + } + ; + +bool: K_YES { $$ = 1; } | K_NO { $$ = 0; }; + +%% + +int yyerror(char *s) +{ + syslog(LOG_ERR, "%s line %d\n", s, lineno); + return 0; +} + +int cfg_error(const char *fmt, ...) +{ + char buf[255]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf,sizeof(buf),fmt,ap); + va_end(ap); + + yyerror(buf); + return 0; +} + +/* + * Read config file. + */ +int read_config(char *file) +{ + extern FILE *yyin; + + if( !(yyin = fopen(file,"r")) ){ + syslog(LOG_ERR,"Can not open %s", file); + return -1; + } + + lineno = 1; + yyparse(); + + fclose(yyin); + + return 0; +} diff --git a/hcid/security.c b/hcid/security.c new file mode 100644 index 00000000..bca27805 --- /dev/null +++ b/hcid/security.c @@ -0,0 +1,477 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "hcid.h" +#include "lib.h" + +static GIOChannel *io_chan[HCI_MAX_DEV]; + +void save_link_keys(void) +{ + int n, f; + + umask(0077); + if (!(f = open(hcid.key_file, O_WRONLY | O_CREAT | O_TRUNC, 0))) { + syslog(LOG_ERR, "Can't save key database %s. %s(%d)", + hcid.key_file, strerror(errno), errno); + return; + } + + for (n = 0; n < hcid.key_num; n++) { + if (!hcid.link_key[n]) + continue; + + if (write_n(f, hcid.link_key[n], sizeof(struct link_key)) < 0) + break; + } + + close(f); +} + +void flush_link_keys(void) +{ + int n; + for (n=0; n < hcid.key_num; n++) { + if (hcid.link_key[n]) { + free(hcid.link_key[n]); + hcid.link_key[n] = NULL; + } + } +} + +int read_link_keys(void) +{ + int f, n = 0; + + if (!(f = open(hcid.key_file, O_RDONLY))) { + syslog(LOG_ERR, "Can't open key database %s. %s(%d)", + hcid.key_file, strerror(errno), errno); + return -1; + } + + while (n < hcid.key_num) { + struct link_key *key; + int r; + + key = malloc(sizeof(*key)); + if (!key) + continue; + + r = read_n(f, key, sizeof(*key)); + if (r <= 0) { + free(key); + break; + } + + hcid.link_key[n++] = key; + } + + close(f); + return n; +} + +int read_pin_code(void) +{ + char buf[17]; + FILE *f; + int len; + + if (!(f = fopen(hcid.pin_file, "r"))) { + syslog(LOG_ERR, "Can't open PIN file %s. %s(%d)", + hcid.pin_file, strerror(errno), errno); + return -1; + } + + if (fgets(buf, sizeof(buf), f)) { + strtok(buf, "\n\r"); + len = strlen(buf); + memcpy(hcid.pin_code, buf, len); + hcid.pin_len = len; + } else { + syslog(LOG_ERR, "Can't read PIN file %s. %s(%d)", + hcid.pin_file, strerror(errno), errno); + len = -1; + } + fclose(f); + return len; +} + +/* + PIN helper is an external app that asks user for a PIN. It can + implement its own PIN code generation policy and methods like + PIN look up in some database, etc. + HCId expects following output from PIN helper: + PIN:12345678 - PIN code + ERR - No PIN available +*/ + +static void call_pin_helper(int dev, struct hci_conn_info *ci) +{ + pin_code_reply_cp pr; + char str[255], *pin, name[20]; + bdaddr_t ba; + FILE *pipe; + int len; + + /* Run PIN helper in the separate process */ + switch (fork()) { + case 0: + break; + case -1: + syslog(LOG_ERR, "Can't fork PIN helper. %s(%d)", + strerror(errno), errno); + default: + return; + } + + if (access(hcid.pin_helper, R_OK | X_OK)) { + syslog(LOG_ERR, "Can't exec PIN helper %s. %s(%d)", + hcid.pin_helper, strerror(errno), errno); + goto reject; + } + + name[0] = 0; + //hci_remote_name(dev, &ci->bdaddr, sizeof(name), name, 0); + + baswap(&ba, &ci->bdaddr); + sprintf(str, "%s %s %s \'%s\'", hcid.pin_helper, + ci->out ? "out" : "in", + batostr(&ba), name); + + setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1); + + pipe = popen(str, "r"); + if (!pipe) { + syslog(LOG_ERR, "Can't exec PIN helper. %s(%d)", strerror(errno), errno); + goto reject; + } + + pin = fgets(str, sizeof(str), pipe); + pclose(pipe); + + if (!pin || strlen(pin) < 5) + goto reject; + + strtok(pin, "\n\r"); + + if (strncmp("PIN:", pin, 4)) + goto reject; + + pin += 4; + len = strlen(pin); + + memset(&pr, 0, sizeof(pr)); + bacpy(&pr.bdaddr, &ci->bdaddr); + memcpy(pr.pin_code, pin, len); + pr.pin_len = len; + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, + PIN_CODE_REPLY_CP_SIZE, &pr); + exit(0); + +reject: + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); + exit(0); +} + +static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) +{ + struct link_key *key = NULL; + int n; + + /* Find the key */ + for (n=0; n < hcid.key_num; n++) { + if (!hcid.link_key[n]) + continue; + if (!bacmp(&hcid.link_key[n]->sba, sba) && + !bacmp(&hcid.link_key[n]->dba, dba)) { + key = hcid.link_key[n]; + break; + } + } + + if (key) { + /* Link key found */ + link_key_reply_cp lr; + memcpy(lr.link_key, key->key, 16); + bacpy(&lr.bdaddr, dba); + hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, + LINK_KEY_REPLY_CP_SIZE, &lr); + key->time = time(0); + } else { + /* Link key not found */ + hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba); + } +} + +static void pin_code_request(int dev, bdaddr_t *ba) +{ + struct hci_conn_info_req *cr; + struct hci_conn_info *ci; + + cr = malloc(sizeof(*cr) + sizeof(*ci)); + if (!cr) + return; + + bacpy(&cr->bdaddr, ba); + cr->type = ACL_LINK; + if (ioctl(dev, HCIGETCONNINFO, (unsigned long) cr) < 0) { + syslog(LOG_ERR, "Can't get conn info %s(%d)", + strerror(errno), errno); + /* Reject PIN */ + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, ba); + + free(cr); + return; + } + ci = cr->conn_info; + + if (hcid.security == HCID_SEC_AUTO) { + if (!ci->out) { + /* Incomming connection */ + pin_code_reply_cp pr; + memset(&pr, 0, sizeof(pr)); + bacpy(&pr.bdaddr, ba); + memcpy(pr.pin_code, hcid.pin_code, hcid.pin_len); + pr.pin_len = hcid.pin_len; + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, + PIN_CODE_REPLY_CP_SIZE, &pr); + } else { + /* Outgoing connection */ + + /* Let PIN helper handle that */ + call_pin_helper(dev, ci); + } + } else { + /* Let PIN helper handle that */ + call_pin_helper(dev, ci); + } + free(cr); +} + +static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) +{ + evt_link_key_notify *evt = ptr; + bdaddr_t *dba = &evt->bdaddr; + struct link_key *key; + time_t tm = time(0); + int n, k = -1; + + /* Find a slot */ + for (n=0; n < hcid.key_num; n++) { + key = hcid.link_key[n]; + if (!key || (!bacmp(&key->sba, sba) && !bacmp(&key->dba, dba)) || + (tm - key->time) > HCID_KEY_TTL) { + k = n; + break; + } + } + + if (k != -1) { + /* Update link key */ + key = hcid.link_key[k]; + if (!key && !(key = malloc(sizeof(*key)))) + return; + + bacpy(&key->sba, sba); + bacpy(&key->dba, dba); + memcpy(key->key, evt->link_key, 16); + key->type = evt->key_type; + key->time = tm; + + hcid.link_key[k] = key; + } +} + +gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; + struct hci_dev_info *di = (void *) data; + int len, type, dev; + hci_event_hdr *eh; + GIOError err; + + if (cond & G_IO_NVAL) { + free(data); + return FALSE; + } + + if (cond & (G_IO_HUP | G_IO_ERR)) { + g_io_channel_close(chan); + free(data); + return FALSE; + } + + if ((err = g_io_channel_read(chan, buf, sizeof(buf), &len))) { + if (err == G_IO_ERROR_AGAIN) + return TRUE; + g_io_channel_close(chan); + return FALSE; + } + + type = *ptr++; + + if (type != HCI_EVENT_PKT) + return TRUE; + + eh = (hci_event_hdr *) ptr; + ptr += HCI_EVENT_HDR_SIZE; + + dev = g_io_channel_unix_get_fd(chan); + + switch (eh->evt) { + case EVT_PIN_CODE_REQ: + pin_code_request(dev, (bdaddr_t *) ptr); + break; + + case EVT_LINK_KEY_REQ: + link_key_request(dev, &di->bdaddr, (bdaddr_t *) ptr); + break; + + case EVT_LINK_KEY_NOTIFY: + link_key_notify(dev, &di->bdaddr, ptr); + break; + } + + return TRUE; +} + +int init_security_data(void) +{ + void *buf; + + buf = calloc(hcid.key_num, sizeof(void*)); + if (!buf) { + syslog(LOG_ERR, "Can't allocate link key database. %s(%d)", + strerror(errno), errno); + return -1; + } + hcid.link_key = buf; + read_link_keys(); + + /* Set local PIN code */ + if (hcid.security == HCID_SEC_AUTO) { + if (read_pin_code() < 0) { + strcpy(hcid.pin_code, "bluez"); + hcid.pin_len = 5; + } + } + + return 0; +} + +void start_security_manager(int hdev) +{ + GIOChannel *chan = io_chan[hdev]; + struct hci_dev_info *di; + struct hci_filter flt; + int dev; + + if (chan) + return; + + syslog(LOG_INFO, "Starting security manager %d", hdev); + + if (!hcid.link_key && init_security_data()) + return; + + if ((dev = hci_open_dev(hdev)) < 0) { + syslog(LOG_ERR, "Can't open device hci%d. %s(%d)", + hdev, strerror(errno), errno); + return; + } + + /* Set filter */ + hci_filter_clear(&flt); + hci_filter_set_ptype(HCI_EVENT_PKT, &flt); + hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); + hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); + hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); + if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + syslog(LOG_ERR, "Can't set filter on hci%d. %s(%d)", + hdev, strerror(errno), errno); + close(dev); + return; + } + + di = malloc(sizeof(*di)); + if (!di) { + syslog(LOG_ERR, "Can't allocate device info buffer. %s(%d)", + strerror(errno), errno); + close(dev); + return; + } + + di->dev_id = hdev; + if (ioctl(dev, HCIGETDEVINFO, (void *)di)) { + syslog(LOG_ERR, "Can't get device info. %s(%d)", + strerror(errno), errno); + close(dev); + return; + } + + chan = g_io_channel_unix_new(dev); + g_io_add_watch(chan, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, + io_security_event, (void *) di); + + io_chan[hdev] = chan; +} + +void stop_security_manager(int hdev) +{ + GIOChannel *chan = io_chan[hdev]; + + if (!chan) + return; + + syslog(LOG_INFO, "Stoping security manager %d", hdev); + + close(g_io_channel_unix_get_fd(chan)); + io_chan[hdev] = NULL; +} diff --git a/install-sh b/install-sh new file mode 100755 index 00000000..e9de2384 --- /dev/null +++ b/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/missing b/missing new file mode 100755 index 00000000..d46f79f6 --- /dev/null +++ b/missing @@ -0,0 +1,198 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# 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, 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., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.in; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`$configure_ac'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`$configure_ac'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`$configure_ac'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 00000000..6b3b5fc5 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/pcmcia/Makefile.am b/pcmcia/Makefile.am new file mode 100644 index 00000000..3664b3e7 --- /dev/null +++ b/pcmcia/Makefile.am @@ -0,0 +1,12 @@ +# +# $Id$ +# + +pcmciadir = /etc/pcmcia + +install-data-local: @PCMCIA@ + +pcmcia: + $(mkinstalldirs) $(DESTDIR)$(pcmciadir) + $(INSTALL) -m 755 $(srcdir)/bluetooth $(DESTDIR)$(pcmciadir) + $(INSTALL) -m 644 $(srcdir)/bluetooth.conf $(DESTDIR)$(pcmciadir) diff --git a/pcmcia/Makefile.in b/pcmcia/Makefile.in new file mode 100644 index 00000000..ed120814 --- /dev/null +++ b/pcmcia/Makefile.in @@ -0,0 +1,198 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# $Id$ +# + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AWK = @AWK@ +CC = @CC@ +DISTRO = @DISTRO@ +GLIB = @GLIB@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LDFLAGS = @GLIB_LDFLAGS@ +LD = @LD@ +LEX = @LEX@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +PCMCIA = @PCMCIA@ +VERSION = @VERSION@ +YACC = @YACC@ + +pcmciadir = /etc/pcmcia +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu pcmcia/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = pcmcia + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu pcmcia/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-data-local +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-local install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +install-data-local: @PCMCIA@ + +pcmcia: + $(mkinstalldirs) $(DESTDIR)$(pcmciadir) + $(INSTALL) -m 755 $(srcdir)/bluetooth $(DESTDIR)$(pcmciadir) + $(INSTALL) -m 644 $(srcdir)/bluetooth.conf $(DESTDIR)$(pcmciadir) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/pcmcia/bluetooth b/pcmcia/bluetooth new file mode 100755 index 00000000..ea22ce40 --- /dev/null +++ b/pcmcia/bluetooth @@ -0,0 +1,34 @@ +#!/bin/sh +# +# bluetooth +# +# Initialize a PCMCIA Bluetooth device +# Written by Maxim Krasnyanskiy +# +# $1 - socket +# $2 - device +# + +LOG="/usr/bin/logger -i -t bluetooth -p daemon.notice" + +IDENT="/sbin/cardctl ident $1" + +# Check if card is really a Bluetooth card +if ! $IDENT | grep -i 'bluetooth' > /dev/null 2>&1; then + $LOG "$2 is not a Bluetooth device" + exit +fi + +ID=`$IDENT | awk '/.*id/{print $2 $3}'` +TYPE=`$IDENT | awk '/.*func/{print $2}'` + +$LOG "Bluetooth device id $ID type $TYPE $2" + +case "$TYPE" in + # Serial device + 2) + /sbin/hciattach $DEVICE $ID + ;; +esac + +unset LOG IDENT ID TYPE diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf new file mode 100644 index 00000000..ca48419d --- /dev/null +++ b/pcmcia/bluetooth.conf @@ -0,0 +1,26 @@ +card "Brain Boxes BL-620 Bluetooth Adapter" + version "Brain Boxes", "Bluetooth PC Card" + bind "serial_cs" + +card "Xircom CreditCard CBT Bluetooth Adapter" + version "Xircom", "*", "CBT" + bind "serial_cs" + +card "3Com Bluetooth PC Card" + version "3COM", "*", "Bluetooth PC Card" + bind "serial_cs" + +card "COM One Platinium Bluetooth PC Card" + version "COM1 SA", "MC310 CARD" + bind "serial_cs" + +card "Sphinx PICO Bluetooth Card" + version "SPHINX", "BT-CARD" + bind "serial_cs" + +device "dtl1_cs" + module "dtl1_cs" + +card "Nokia Bluetooth Card DTL-1" + version "Nokia Mobile Phones", "DTL-1" + bind "dtl1_cs" diff --git a/scripts/Makefile.am b/scripts/Makefile.am new file mode 100644 index 00000000..12f32c78 --- /dev/null +++ b/scripts/Makefile.am @@ -0,0 +1,18 @@ +# +# $Id$ +# + +bin_SCRIPTS = bluepin + +install-data-local: @DISTRO@ + +unknown: + -echo Unknown distribution + +redhat: + $(mkinstalldirs) $(DESTDIR)/etc/rc.d/init.d + $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)/etc/rc.d/init.d/bluetooth + +debian: + $(mkinstalldirs) $(DESTDIR)/etc/init.d + $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)/etc/init.d/bluetooth diff --git a/scripts/Makefile.in b/scripts/Makefile.in new file mode 100644 index 00000000..d750a69c --- /dev/null +++ b/scripts/Makefile.in @@ -0,0 +1,227 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# $Id$ +# + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AWK = @AWK@ +CC = @CC@ +DISTRO = @DISTRO@ +GLIB = @GLIB@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LDFLAGS = @GLIB_LDFLAGS@ +LD = @LD@ +LEX = @LEX@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +PCMCIA = @PCMCIA@ +VERSION = @VERSION@ +YACC = @YACC@ + +bin_SCRIPTS = bluepin +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +SCRIPTS = $(bin_SCRIPTS) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else if test -f $(srcdir)/$$p; then \ + echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ + $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + else :; fi; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + list='$(bin_SCRIPTS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ + done +tags: TAGS +TAGS: + + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = scripts + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu scripts/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binSCRIPTS +install-exec: install-exec-am + +install-data-am: install-data-local +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binSCRIPTS +uninstall: uninstall-am +all-am: Makefile $(SCRIPTS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: uninstall-binSCRIPTS install-binSCRIPTS tags distdir info-am \ +info dvi-am dvi check check-am installcheck-am installcheck \ +install-exec-am install-exec install-data-local install-data-am \ +install-data install-am install uninstall-am uninstall all-redirect \ +all-am all installdirs mostlyclean-generic distclean-generic \ +clean-generic maintainer-clean-generic clean mostlyclean distclean \ +maintainer-clean + + +install-data-local: @DISTRO@ + +unknown: + -echo Unknown distribution + +redhat: + $(mkinstalldirs) $(DESTDIR)/etc/rc.d/init.d + $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)/etc/rc.d/init.d/bluetooth + +debian: + $(mkinstalldirs) $(DESTDIR)/etc/init.d + $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)/etc/init.d/bluetooth + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/scripts/bluepin b/scripts/bluepin new file mode 100755 index 00000000..db1f8196 --- /dev/null +++ b/scripts/bluepin @@ -0,0 +1,148 @@ +#!/usr/bin/python +# +# Bluetooth PIN helper +# Written by Maxim Krasnyansky +# + +import sys, os, string + +# +# FIXME: +# +# We have to find actual user and proper X display here. And if +# it's not available (no one's logged in) we should lookup some +# file for predefined PINs. +# +# For now we just assume that we have access to local X display +# and whoever is logged in there will get a window pop. +# + +os.environ['DISPLAY'] = ':0' + +# For X Window display access blueping has to find a user and use +# his(her) .Xauthority file. +# os.environ['XAUTHORITY'] = '/home/maxk/.Xauthority' + +from gtk import * +#import GdkImlib, GtkExtra + +# Dialog Class +DLG_OK = 1 +DLG_CANCEL = 2 +class Dialog(GtkDialog): + result = DLG_CANCEL + args = {} + def __init__(self, modal=FALSE, mesg=None, args = {}): + GtkDialog.__init__(self) + self.args = args + self.set_modal(modal) + self.set_usize(400, 0) + self.set_uposition(300,300) + + self.connect("destroy", self.quit) + self.connect("delete_event", self.quit) + + self.action_area.set_border_width(2) + + ok = GtkButton("Accept") + ok.connect("clicked", self.ok) + self.action_area.pack_start(ok, padding = 20) + ok.show() + + cl = GtkButton("Reject") + cl.connect("clicked", self.cancel) + self.action_area.pack_start(cl, padding = 20) + cl.show() + + if mesg: + msg = GtkLabel() + msg.set_text(mesg) + self.vbox.pack_start(msg, padding = 10) + msg.show() + + self.ents = [] + for k in self.args.keys(): + hbox = GtkHBox() + hbox.set_border_width(5) + self.vbox.pack_start(hbox) + hbox.show() + + l = GtkLabel() + e = GtkEntry() + l.set_text( k ) + e.set_text( self.args[k] ) + e.connect("key_press_event", self.key_press) + hbox.pack_start(l, padding = 10, expand = FALSE) + hbox.pack_start(e) + l.show() + e.show() + + self.ents.append( (k, e) ) + + self.ents[0][1].grab_focus() + + def key_press(self, entry, event): + if event.keyval == GDK.Return: + entry.emit_stop_by_name("key_press_event") + self.ok() + elif event.keyval == GDK.Escape: + entry.emit_stop_by_name("key_press_event") + self.cancel() + + def ok(self, *args): + self.result = DLG_OK + for e in self.ents: + k = e[0] + self.args[k] = e[1].get_text() + self.quit() + + def cancel(self, *args): + self.result = DLG_CANCEL + self.quit() + + def quit(self, *args): + self.hide() + self.destroy() + mainquit() + +def dialog(title, mesg, args, modal = FALSE): + dlg = Dialog(args = args, mesg = mesg, modal = modal) + dlg.set_title(title) + dlg.show() + mainloop() + return dlg.result + +def main(*args): + dir = sys.argv[1] + bdaddr = sys.argv[2] + + if len(sys.argv) > 3: + name = sys.argv[3] + else: + name = "" + + title = "Bluetooth PIN Code" + + # Bluetooth spec recommends automatic strong random PIN generation. + # So eventually we should implement that. + pin = { "PIN": "" } + + if dir == "out": + mesg = "Outgoing connection to " + else: + mesg = "Incomming connection from " + + mesg = mesg + name + "[" + bdaddr + "]" + + if dialog(title, mesg, pin) == DLG_OK: + pin["PIN"] = string.strip(pin["PIN"]) + + if len(pin["PIN"]) >= 4 and len(pin["PIN"]) <=16: + print "PIN:" + pin["PIN"] + else: + print "ERR" + else: + print "ERR" + +# +main() diff --git a/scripts/bluetooth.rc.rh b/scripts/bluetooth.rc.rh new file mode 100755 index 00000000..f0586788 --- /dev/null +++ b/scripts/bluetooth.rc.rh @@ -0,0 +1,72 @@ +#!/bin/sh +# +# bluetooth Bluetooth subsystem starting and stopping +# +# chkconfig: 345 25 90 +# description: Bluetooth subsystem +# + +# Source function library. +. /etc/rc.d/init.d/functions + +# Source Bluetooth configuration. +#. /etc/sysconfig/bluetooth + +prog="Bluetooth" + +UART_CONF="/etc/bluetooth/uart" + +start_uarts() +{ + [ -f /sbin/hciattach -a -f $UART_CONF ] || return + grep -v '^#' $UART_CONF | while read i; do + /sbin/hciattach $i + done +} + +stop_uarts() +{ + killproc hciattach > /dev/null 2>&1 +} + +start() +{ + echo -n $"Starting $prog: " + daemon /sbin/hcid + start_uarts + touch /var/lock/subsys/bluetooth + echo +} + +stop() +{ + echo -n $"Shutting down $prog: " + stop_uarts + killproc hcid + rm -f /var/lock/subsys/bluetooth + echo +} + +[ -f /sbin/hcid ] || exit 0 + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart|reload) + stop + start + ;; + condrestart) + [ -e /var/lock/subsys/bluetooth ] && (stop; start) + ;; + *) + echo $"Usage: $0 {start|stop|restart|reload|condrestart}" + exit 1 +esac + +exit 0 diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 00000000..d3133e5f --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,10 @@ +# +# $Id$ +# + +mandir = $(prefix)/usr/share/man + +sbin_PROGRAMS = hciattach hciconfig +bin_PROGRAMS = hcitool l2ping + +man_MANS = hciattach.8 l2ping.8 diff --git a/tools/Makefile.in b/tools/Makefile.in new file mode 100644 index 00000000..fe838a44 --- /dev/null +++ b/tools/Makefile.in @@ -0,0 +1,433 @@ +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# +# $Id$ +# + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_alias = @build_alias@ +build_triplet = @build@ +host_alias = @host_alias@ +host_triplet = @host@ +target_alias = @target_alias@ +target_triplet = @target@ +AR = @AR@ +AWK = @AWK@ +CC = @CC@ +DISTRO = @DISTRO@ +GLIB = @GLIB@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LDFLAGS = @GLIB_LDFLAGS@ +LD = @LD@ +LEX = @LEX@ +MAKEINFO = @MAKEINFO@ +PACKAGE = @PACKAGE@ +PCMCIA = @PCMCIA@ +VERSION = @VERSION@ +YACC = @YACC@ + +mandir = $(prefix)/usr/share/man + +sbin_PROGRAMS = hciattach hciconfig +bin_PROGRAMS = hcitool l2ping + +man_MANS = hciattach.8 l2ping.8 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +hcitool_SOURCES = hcitool.c +hcitool_OBJECTS = hcitool.o +hcitool_LDADD = $(LDADD) +hcitool_DEPENDENCIES = +hcitool_LDFLAGS = +l2ping_SOURCES = l2ping.c +l2ping_OBJECTS = l2ping.o +l2ping_LDADD = $(LDADD) +l2ping_DEPENDENCIES = +l2ping_LDFLAGS = +hciattach_SOURCES = hciattach.c +hciattach_OBJECTS = hciattach.o +hciattach_LDADD = $(LDADD) +hciattach_DEPENDENCIES = +hciattach_LDFLAGS = +hciconfig_SOURCES = hciconfig.c +hciconfig_OBJECTS = hciconfig.o +hciconfig_LDADD = $(LDADD) +hciconfig_DEPENDENCIES = +hciconfig_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +man8dir = $(mandir)/man8 +MANS = $(man_MANS) + +NROFF = nroff +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +DEP_FILES = .deps/hciattach.P .deps/hciconfig.P .deps/hcitool.P \ +.deps/l2ping.P +SOURCES = hcitool.c l2ping.c hciattach.c hciconfig.c +OBJECTS = hcitool.o l2ping.o hciattach.o hciconfig.o + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +mostlyclean-sbinPROGRAMS: + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) + +distclean-sbinPROGRAMS: + +maintainer-clean-sbinPROGRAMS: + +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(sbindir) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(sbin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +hcitool: $(hcitool_OBJECTS) $(hcitool_DEPENDENCIES) + @rm -f hcitool + $(LINK) $(hcitool_LDFLAGS) $(hcitool_OBJECTS) $(hcitool_LDADD) $(LIBS) + +l2ping: $(l2ping_OBJECTS) $(l2ping_DEPENDENCIES) + @rm -f l2ping + $(LINK) $(l2ping_LDFLAGS) $(l2ping_OBJECTS) $(l2ping_LDADD) $(LIBS) + +hciattach: $(hciattach_OBJECTS) $(hciattach_DEPENDENCIES) + @rm -f hciattach + $(LINK) $(hciattach_LDFLAGS) $(hciattach_OBJECTS) $(hciattach_LDADD) $(LIBS) + +hciconfig: $(hciconfig_OBJECTS) $(hciconfig_DEPENDENCIES) + @rm -f hciconfig + $(LINK) $(hciconfig_LDFLAGS) $(hciconfig_OBJECTS) $(hciconfig_LDADD) $(LIBS) + +install-man8: + $(mkinstalldirs) $(DESTDIR)$(man8dir) + @list='$(man8_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ + done + +uninstall-man8: + @list='$(man8_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.8*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ + rm -f $(DESTDIR)$(man8dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-man8 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-man8 + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = tools + +distdir: $(DISTFILES) + here=`cd $(top_builddir) && pwd`; \ + top_distdir=`cd $(top_distdir) && pwd`; \ + distdir=`cd $(distdir) && pwd`; \ + cd $(top_srcdir) \ + && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu tools/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS install-sbinPROGRAMS +install-exec: install-exec-am + +install-data-am: install-man +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS uninstall-man +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) $(MANS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(sbindir) \ + $(DESTDIR)$(mandir)/man8 + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-sbinPROGRAMS \ + mostlyclean-compile mostlyclean-tags mostlyclean-depend \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-binPROGRAMS clean-sbinPROGRAMS clean-compile clean-tags \ + clean-depend clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-sbinPROGRAMS \ + distclean-compile distclean-tags distclean-depend \ + distclean-generic clean-am + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-sbinPROGRAMS maintainer-clean-compile \ + maintainer-clean-tags maintainer-clean-depend \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS clean-sbinPROGRAMS \ +maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ +install-sbinPROGRAMS mostlyclean-compile distclean-compile \ +clean-compile maintainer-clean-compile install-man8 uninstall-man8 \ +install-man uninstall-man tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir mostlyclean-depend \ +distclean-depend clean-depend maintainer-clean-depend info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tools/hciattach.8 b/tools/hciattach.8 new file mode 100644 index 00000000..b327336b --- /dev/null +++ b/tools/hciattach.8 @@ -0,0 +1,102 @@ +.TH HCIATTACH 8 "Jan 22 2002" BlueZ "Linux System Administration" +.SH NAME +hciattach \- attach serial devices via UART HCI to BlueZ stack +.SH SYNOPSIS +.B hciattach +< +.I tty +> < +.I type +| +.I id +> [ +.I speed +] [ +.I flow +] +.SH DESCRIPTION +.LP +Hciattach is used to attach a serial UART to the Bluetooth stack as HCI +transport interface. +.SH OPTIONS +.TP +.I +This specifies the serial device to attach. A leading +.B /dev +can be omitted. Examples: +.B /dev/ttyS1 +.B ttyS2 +.TP +.I +The +.B type +or +.B id +of the Bluetooth device that is to be attached, i.e. vendor or other device +specific identifier. Currently supported types are +.RS +.TP +.B type +.B description +.TP +any +Unspecified HCI_UART interface, no vendor specific options +.TP +ericsson +Ericsson based modules +.TP +digi +Digianswer based cards +.TP +xircom +Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter +.TP +csr +CSR Casira serial adapter or BrainBoxes serial dongle (BL642) +.TP +bboxes +BrainBoxes PCMCIA card (BL620) +.TP +swave +Silicon Wave kits +.RE + +Supported IDs are (manufacturer id, product id) +.RS +.TP +0x0105, 0x080a +Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter +.TP +0x0160, 0x0002 +BrainBoxes PCMCIA card (BL620) +.RE + +.TP +.I +The +.B speed +specifies the UART speed to use. Baudrates higher than 115.200bps require +vendor specific initializations that are not implemented for all types of +devices. In general the following speeds are supported: + +.B 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 + +Supported vendor devices are automatically initialised to their respective +best settings. +.TP +.I +If the keyword +.B flow +is appended to the list of options then hardware flow control is forced on +the serial link ( +.B CRTSCTS +). All above mentioned device types have +.B flow +set by default. To force no flow control use +.B noflow +instead. + +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Nils Faerber diff --git a/tools/hciattach.c b/tools/hciattach.c new file mode 100644 index 00000000..a4489019 --- /dev/null +++ b/tools/hciattach.c @@ -0,0 +1,751 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +struct uart_t { + char *type; + int m_id; + int p_id; + int proto; + int speed; + int flags; + int (*init) (int fd, struct uart_t *u, struct termios *ti); +}; + +#define FLOW_CTL 0x0001 + +static int uart_speed(int s) +{ + switch (s) { + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; + case 57600: + return B57600; + case 115200: + return B115200; + case 230400: + return B230400; + case 460800: + return B460800; + case 921600: + return B921600; + default: + return B57600; + } +} + +static int set_speed(int fd, struct termios *ti, int speed) +{ + cfsetospeed(ti, uart_speed(speed)); + return tcsetattr(fd, TCSANOW, ti); +} + +static void sig_alarm(int sig) +{ + fprintf(stderr, "Initialization timed out.\n"); + exit(1); +} + +/* + * Read an HCI event from the given file descriptor. + */ +static int read_hci_event(int fd, unsigned char* buf, int size) +{ + int remain, r; + int count = 0; + + if (size <= 0) + return -1; + + /* The first byte identifies the packet type. For HCI event packets, it + * should be 0x04, so we read until we get to the 0x04. */ + while (1) { + r = read(fd, buf, 1); + if (r <= 0) + return -1; + if (buf[0] == 0x04) + break; + } + count++; + + /* The next two bytes are the event code and parameter total length. */ + while (count < 3) { + r = read(fd, buf + count, 3 - count); + if (r <= 0) + return -1; + count += r; + } + + /* Now we read the parameters. */ + if (buf[2] < (size - 3)) + remain = buf[2]; + else + remain = size - 3; + + while ((count - 3) < remain) { + r = read(fd, buf + count, remain - (count - 3)); + if (r <= 0) + return -1; + count += r; + } + return count; +} + +/* + * Ericsson specific initialization + */ +static int ericsson(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[10]; + + /* Switch to default Ericsson baudrate*/ + if (set_speed(fd, ti, 57600) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x09; + cmd[2] = 0xfc; + cmd[3] = 0x01; + + switch (u->speed) { + case 57600: + cmd[4] = 0x03; + break; + case 115200: + cmd[4] = 0x02; + break; + case 230400: + cmd[4] = 0x01; + break; + case 460800: + cmd[4] = 0x00; + break; + default: + cmd[4] = 0x03; + u->speed = 57600; + break; + } + + /* Send initialization command */ + if (write(fd, cmd, 5) != 5) { + perror("Failed to write init command"); + return -1; + } + nanosleep(&tm, NULL); + return 0; +} + +/* + * Digianswer specific initialization + */ +static int digi(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[10]; + + /* Switch to default Digi baudrate*/ + if (set_speed(fd, ti, 9600) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + /* DigiAnswer set baud rate command */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x07; + cmd[2] = 0xfc; + cmd[3] = 0x01; + + switch (u->speed) { + case 57600: + cmd[4] = 0x08; + break; + case 115200: + cmd[4] = 0x09; + break; + default: + cmd[4] = 0x09; + u->speed = 115200; + break; + } + + /* Send initialization command */ + if (write(fd, cmd, 5) != 5) { + perror("Failed to write init command"); + return -1; + } + nanosleep(&tm, NULL); + return 0; +} + +/* + * CSR specific initialization + * Inspired strongly by code in OpenBT and experimentations with Brainboxes + * Pcmcia card. + * Jean Tourrilhes - 14.11.01 + */ +static int csr(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 10000000}; /* 10ms - be generous */ + unsigned char cmd[30]; /* Command */ + unsigned char resp[30]; /* Response */ + int clen = 0; /* Command len */ + static int csr_seq = 0; /* Sequence number of command */ + int divisor; + + /* Switch to default CSR baudrate */ + if (set_speed(fd, ti, 115200) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + /* It seems that if we set the CSR UART speed straight away, it + * won't work, the CSR UART gets into a state where we can't talk + * to it anymore. + * On the other hand, doing a read before setting the CSR speed + * seems to be ok. + * Therefore, the strategy is to read the build ID (useful for + * debugging) and only then set the CSR UART speed. Doing like + * this is more complex but at least it works ;-) + * The CSR UART control may be slow to wake up or something because + * every time I read its speed, its bogus... + * Jean II */ + + /* Try to read the build ID of the CSR chip */ + clen = 5 + (5 + 6) * 2; + /* HCI header */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x00; /* CSR command */ + cmd[2] = 0xfc; /* MANUFACTURER_SPEC */ + cmd[3] = 1 + (5 + 6) * 2; /* len */ + /* CSR MSG header */ + cmd[4] = 0xC2; /* first+last+channel=BCC */ + /* CSR BCC header */ + cmd[5] = 0x00; /* type = GET-REQ */ + cmd[6] = 0x00; /* - msB */ + cmd[7] = 5 + 4; /* len */ + cmd[8] = 0x00; /* - msB */ + cmd[9] = csr_seq & 0xFF;/* seq num */ + cmd[10] = (csr_seq >> 8) & 0xFF; /* - msB */ + csr_seq++; + cmd[11] = 0x19; /* var_id = CSR_CMD_BUILD_ID */ + cmd[12] = 0x28; /* - msB */ + cmd[13] = 0x00; /* status = STATUS_OK */ + cmd[14] = 0x00; /* - msB */ + /* CSR BCC payload */ + memset(cmd + 15, 0, 6 * 2); + + /* Send command */ + do { + if (write(fd, cmd, clen) != clen) { + perror("Failed to write init command (GET_BUILD_ID)"); + return -1; + } + + /* Read reply. */ + if (read_hci_event(fd, resp, 100) < 0) { + perror("Failed to read init response (GET_BUILD_ID)"); + return -1; + } + + /* Event code 0xFF is for vendor-specific events, which is + * what we're looking for. */ + } while (resp[1] != 0xFF); + +#ifdef CSR_DEBUG + { + char temp[512]; + int i; + for (i=0; i < rlen; i++) + sprintf(temp + (i*3), "-%02X", resp[i]); + fprintf(stderr, "Reading CSR build ID %d [%s]\n", rlen, temp + 1); + // In theory, it should look like : + // 04-FF-13-FF-01-00-09-00-00-00-19-28-00-00-73-00-00-00-00-00-00-00 + } +#endif + /* Display that to user */ + fprintf(stderr, "CSR build ID 0x%02X-0x%02X\n", + resp[15] & 0xFF, resp[14] & 0xFF); + + /* Try to read the current speed of the CSR chip */ + clen = 5 + (5 + 4)*2; + /* -- HCI header */ + cmd[3] = 1 + (5 + 4)*2; /* len */ + /* -- CSR BCC header -- */ + cmd[9] = csr_seq & 0xFF; /* seq num */ + cmd[10] = (csr_seq >> 8) & 0xFF; /* - msB */ + csr_seq++; + cmd[11] = 0x02; /* var_id = CONFIG_UART */ + cmd[12] = 0x68; /* - msB */ + +#ifdef CSR_DEBUG + /* Send command */ + do { + if (write(fd, cmd, clen) != clen) { + perror("Failed to write init command (GET_BUILD_ID)"); + return -1; + } + + /* Read reply. */ + if (read_hci_event(fd, resp, 100) < 0) { + perror("Failed to read init response (GET_BUILD_ID)"); + return -1; + } + + /* Event code 0xFF is for vendor-specific events, which is + * what we're looking for. */ + } while (resp[1] != 0xFF); + + { + char temp[512]; + int i; + for (i=0; i < rlen; i++) + sprintf(temp + (i*3), "-%02X", resp[i]); + fprintf(stderr, "Reading CSR UART speed %d [%s]\n", rlen, temp+1); + } +#endif + + /* Now, create the command that will set the UART speed */ + /* CSR BCC header */ + cmd[5] = 0x02; /* type = SET-REQ */ + cmd[6] = 0x00; /* - msB */ + cmd[9] = csr_seq & 0xFF; /* seq num */ + cmd[10] = (csr_seq >> 8) & 0xFF;/* - msB */ + csr_seq++; + + switch (u->speed) { + case 9600: + divisor = 0x0027; + break; + /* Various speeds ommited */ + case 57600: + divisor = 0x00EC; + break; + case 115200: + divisor = 0x01D8; + break; + /* For Brainbox Pcmcia cards */ + case 460800: + divisor = 0x075F; + break; + case 921600: + divisor = 0x0EBF; + break; + default: + /* Safe default */ + divisor = 0x01D8; + u->speed = 115200; + break; + } + /* No parity, one stop bit -> divisor |= 0x0000; */ + cmd[15] = (divisor) & 0xFF; /* divider */ + cmd[16] = (divisor >> 8) & 0xFF; /* - msB */ + /* The rest of the payload will be 0x00 */ + +#ifdef CSR_DEBUG + { + char temp[512]; + int i; + for(i = 0; i < clen; i++) + sprintf(temp + (i*3), "-%02X", cmd[i]); + fprintf(stderr, "Writing CSR UART speed %d [%s]\n", clen, temp + 1); + // In theory, it should look like : + // 01-00-FC-13-C2-02-00-09-00-03-00-02-68-00-00-BF-0E-00-00-00-00-00-00 + // 01-00-FC-13-C2-02-00-09-00-01-00-02-68-00-00-D8-01-00-00-00-00-00-00 + } +#endif + + /* Send the command to set the CSR UART speed */ + if (write(fd, cmd, clen) != clen) { + perror("Failed to write init command (SET_UART_SPEED)"); + return -1; + } + nanosleep(&tm, NULL); + return 0; +} + +/* + * Silicon Wave specific initialization + * Thomas Moser + */ +static int swave(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 500000}; + char cmd[10], rsp[100]; + int r; + + /* Switch to default Silicon Wave baudrate*/ + if (set_speed(fd, ti, 115200) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + // Silicon Wave set baud rate command + // see HCI Vendor Specific Interface from Silicon Wave + // first send a "param access set" command to set the + // appropriate data fields in RAM. Then send a "HCI Reset + // Subcommand", e.g. "soft reset" to make the changes effective. + + cmd[0] = HCI_COMMAND_PKT; // it's a command packet + cmd[1] = 0x0B; // OCF 0x0B = param access set + cmd[2] = 0xfc; // OGF bx111111 = vendor specific + cmd[3] = 0x06; // 6 bytes of data following + cmd[4] = 0x01; // param sub command + cmd[5] = 0x11; // tag 17 = 0x11 = HCI Transport Params + cmd[6] = 0x03; // length of the parameter following + cmd[7] = 0x01; // HCI Transport flow control enable + cmd[8] = 0x01; // HCI Transport Type = UART + + switch (u->speed) { + case 19200: + cmd[9] = 0x03; + break; + case 38400: + cmd[9] = 0x02; + break; + case 57600: + cmd[9] = 0x01; + break; + case 115200: + cmd[9] = 0x00; + break; + default: + u->speed = 115200; + cmd[9] = 0x00; + break; + } + + /* Send initialization command */ + if (write(fd, cmd, 10) != 5) { + perror("Failed to write init command"); + return -1; + } + + // We should wait for a "GET Event" to confirm the success of + // the baud rate setting. Wait some time before reading. Better: + // read with timeout, parse data + // until correct answer, else error handling ... todo ... + + nanosleep(&tm, NULL); + + r = read(fd, rsp, sizeof(rsp)); + if (r > 0) { + // guess it's okay, but we should parse the reply. But since + // I don't react on an error anyway ... todo + // Response packet format: + // 04 Event + // FF Vendor specific + // 07 Parameter length + // 0B Subcommand + // 01 Setevent + // 11 Tag specifying HCI Transport Layer Parameter + // 03 length + // 01 flow on + // 01 Hci Transport type = Uart + // xx Baud rate set (see above) + } else { + // ups, got error. + return -1; + } + + // we probably got the reply. Now we must send the "soft reset": + cmd[0] = HCI_COMMAND_PKT; // it's a command packet + cmd[1] = 0x0B; // OCF 0x0B = param access set + cmd[2] = 0xfc; // OGF bx111111 = vendor specific + cmd[3] = 0x01; // 1 byte of data following + cmd[4] = 0x03; // HCI Reset Subcommand + + // Send initialization command + if (write(fd, cmd, 5) != 5) { + perror("Can't write Silicon Wave reset cmd."); + return -1; + } + + nanosleep(&tm, NULL); + + // now the uart baud rate on the silicon wave module is set and effective. + // change our own baud rate as well. Then there is a reset event comming in + // on the *new* baud rate. This is *undocumented*! The packet looks like this: + // 04 FF 01 0B (which would make that a confirmation of 0x0B = "Param + // subcommand class". So: change to new baud rate, read with timeout, parse + // data, error handling. BTW: all param access in Silicon Wave is done this way. + // Maybe this code would belong in a seperate file, or at least code reuse... + + return 0; +} + +struct uart_t uart[] = { + { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, + { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, + + /* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */ + { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + + /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ + { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, csr }, + + /* BrainBoxes PCMCIA card (BL620) */ + { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 460800, FLOW_CTL, csr }, + + /* Silicon Wave kits */ + { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, swave }, + + /* Sphinx Electronics PICO Card */ + { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + + { NULL, 0 } +}; + +struct uart_t * get_by_id(int m_id, int p_id) +{ + int i; + for (i = 0; uart[i].type; i++) { + if (uart[i].m_id == m_id && uart[i].p_id == p_id) + return &uart[i]; + } + return NULL; +} + +struct uart_t * get_by_type(char *type) +{ + int i; + for (i = 0; uart[i].type; i++) { + if (!strcmp(uart[i].type, type)) + return &uart[i]; + } + return NULL; +} + +/* Initialize UART driver */ +int init_uart(char *dev, struct uart_t *u) +{ + struct termios ti; + int fd, i; + + fd = open(dev, O_RDWR | O_NOCTTY); + if (fd < 0) { + perror("Can't open serial port"); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (tcgetattr(fd, &ti) < 0) { + perror("Can't get port settings"); + return -1; + } + + cfmakeraw(&ti); + + ti.c_cflag |= CLOCAL; + if (u->flags & FLOW_CTL) + ti.c_cflag |= CRTSCTS; + else + ti.c_cflag &= ~CRTSCTS; + + if (tcsetattr(fd, TCSANOW, &ti) < 0) { + perror("Can't set port settings"); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (u->init && u->init(fd, u, &ti) < 0) + return -1; + + tcflush(fd, TCIOFLUSH); + + /* Set actual baudrate */ + if (set_speed(fd, &ti, u->speed) < 0) { + perror("Can't set baud rate"); + return -1; + } + + /* Set TTY to N_HCI line discpline */ + i = N_HCI; + if (ioctl(fd, TIOCSETD, &i) < 0) { + perror("Can't set line disc"); + return -1; + } + + if (ioctl(fd, HCIUARTSETPROTO, u->proto) < 0) { + perror("Can't set device"); + return -1; + } + + return fd; +} + +static void usage(void) +{ + printf("hciattach - HCI UART driver initialization utility\n"); + printf("Usage:\n"); + printf("\thciattach [speed] [flow]\n"); + printf("\thciattach -l\n"); +} + +extern int optind, opterr, optopt; +extern char *optarg; + +int main(int argc, char *argv[]) +{ + struct uart_t *u = NULL; + int detach, opt, i, n; + int to = 5; + struct sigaction sa; + char dev[20]; + + detach = 1; + + while ((opt=getopt(argc, argv, "nt:l")) != EOF) { + switch(opt) { + case 'n': + detach = 0; + break; + + case 't': + to = atoi(optarg); + break; + + case 'l': + for (i = 0; uart[i].type; i++) { + printf("%-10s0x%04x,0x%04x\n", uart[i].type, + uart[i].m_id, uart[i].p_id); + } + exit(0); + + default: + usage(); + exit(1); + } + } + + n = argc - optind; + if (n < 2) { + usage(); + exit(1); + } + + for (n = 0; optind < argc; n++, optind++) { + char *opt; + + opt = argv[optind]; + + switch(n) { + case 0: + dev[0] = 0; + if (!strchr(opt, '/')) + strcpy(dev, "/dev/"); + strcat(dev, opt); + break; + + case 1: + if (strchr(argv[optind], ',')) { + int m_id, p_id; + sscanf(argv[optind], "%x,%x", &m_id, &p_id); + u = get_by_id(m_id, p_id); + } else { + u = get_by_type(opt); + } + + if (!u) { + fprintf(stderr, "Unknow device type or id\n"); + exit(1); + } + + break; + + case 2: + u->speed = atoi(argv[optind]); + break; + + case 3: + if (!strcmp("flow", argv[optind])) + u->flags |= FLOW_CTL; + else + u->flags &= ~FLOW_CTL; + break; + } + } + + if (!u) { + fprintf(stderr, "Unknow device type or id\n"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_alarm; + sigaction(SIGALRM, &sa, NULL); + + /* 5 seconds should be enought for intialization */ + alarm(to); + + n = init_uart(dev, u); + if (n < 0) { + perror("Can't init device"); + exit(1); + } + + alarm(0); + + if (detach) { + if (fork()) return 0; + for (i=0; i<20; i++) + if (i != n) close(i); + } + + while (1) sleep(999999999); + return 0; +} diff --git a/tools/hciconfig.c b/tools/hciconfig.c new file mode 100644 index 00000000..3cbec922 --- /dev/null +++ b/tools/hciconfig.c @@ -0,0 +1,524 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +extern int optind,opterr,optopt; +extern char *optarg; + +static struct hci_dev_info di; +static int all; + +void print_dev_hdr(struct hci_dev_info *di); +void print_dev_info(int ctl, struct hci_dev_info *di); + +void print_dev_list(int ctl, int flags) +{ + struct hci_dev_list_req *dl; + struct hci_dev_req *dr; + int i; + + if( !(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t))) ) { + perror("Can't allocate memory"); + exit(1); + } + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if( ioctl(ctl, HCIGETDEVLIST, (void*)dl) ) { + perror("Can't get device list"); + exit(1); + } + for(i=0; i< dl->dev_num; i++) { + di.dev_id = (dr+i)->dev_id; + if( ioctl(ctl, HCIGETDEVINFO, (void*)&di) ) + continue; + print_dev_info(ctl, &di); + } +} + +void print_pkt_type(struct hci_dev_info *di) +{ + printf("\tPacket type: %s\n", hci_ptypetostr(di->pkt_type)); +} + +void print_link_policy(struct hci_dev_info *di) +{ + printf("\tLink policy: %s\n", hci_lptostr(di->link_policy)); +} + +void print_link_mode(struct hci_dev_info *di) +{ + printf("\tLink mode: %s\n", hci_lmtostr(di->link_mode)); +} + +void print_dev_features(struct hci_dev_info *di) +{ + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + di->features[0], di->features[1], + di->features[2], di->features[3] ); +} + +void cmd_rstat(int ctl, int hdev, char *opt) +{ + /* Reset HCI device stat counters */ + if( ioctl(ctl, HCIDEVRESTAT, hdev) < 0 ) { + printf("Can't reset stats counters hci%d. %s(%d)\n", hdev, + strerror(errno), errno); + exit(1); + } +} + +void cmd_scan(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + dr.dev_opt = SCAN_DISABLED; + if( !strcmp(opt, "iscan") ) + dr.dev_opt = SCAN_INQUIRY; + else if( !strcmp(opt, "pscan") ) + dr.dev_opt = SCAN_PAGE; + else if( !strcmp(opt, "piscan") ) + dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; + + if( ioctl(ctl, HCISETSCAN, (unsigned long)&dr) < 0 ) { + printf("Can't set scan mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_auth(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + if( !strcmp(opt, "auth") ) + dr.dev_opt = AUTH_ENABLED; + else + dr.dev_opt = AUTH_DISABLED; + + if( ioctl(ctl, HCISETAUTH, (unsigned long)&dr) < 0 ) { + printf("Can't set auth on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_encrypt(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + if( !strcmp(opt, "encrypt") ) + dr.dev_opt = ENCRYPT_P2P; + else + dr.dev_opt = ENCRYPT_DISABLED; + + if( ioctl(ctl, HCISETENCRYPT, (unsigned long)&dr) < 0 ) { + printf("Can't set encrypt on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_up(int ctl, int hdev, char *opt) +{ + int ret; + + /* Start HCI device */ + if( (ret = ioctl(ctl, HCIDEVUP, hdev)) < 0 ) { + if( errno == EALREADY ) + return; + printf("Can't init device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + cmd_scan(ctl, hdev, "piscan"); +} + +void cmd_down(int ctl, int hdev, char *opt) +{ + /* Stop HCI device */ + if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) { + printf("Can't down device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_reset(int ctl, int hdev, char *opt) +{ + /* Reset HCI device + if( ioctl(ctl, HCIDEVRESET, hdev) < 0 ){ + printf("Reset failed hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + */ + cmd_down(ctl, hdev, "down"); + cmd_up(ctl, hdev, "up"); +} + +void cmd_ptype(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + + if (hci_strtoptype(opt, &dr.dev_opt)) { + if (ioctl(ctl, HCISETPTYPE, (unsigned long)&dr) < 0) { + printf("Can't set pkttype on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + } else { + print_dev_hdr(&di); + print_pkt_type(&di); + } +} + +void cmd_lp(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + + if (hci_strtolp(opt, &dr.dev_opt)) { + if (ioctl(ctl, HCISETLINKPOL, (unsigned long)&dr) < 0) { + printf("Can't set link policy on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + print_dev_hdr(&di); + print_link_policy(&di); + } +} + +void cmd_lm(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr; + + dr.dev_id = hdev; + + if (hci_strtolm(opt, &dr.dev_opt)) { + if (ioctl(ctl, HCISETLINKMODE, (unsigned long)&dr) < 0) { + printf("Can't set default link mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + print_dev_hdr(&di); + print_link_mode(&di); + } +} + +void cmd_features(int ctl, int hdev, char *opt) +{ + print_dev_hdr(&di); + print_dev_features(&di); +} + +void cmd_name(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + change_local_name_cp cp; + strcpy(cp.name, opt); + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_CHANGE_LOCAL_NAME; + rq.cparam = &cp; + rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't change local name on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + read_local_name_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_NAME; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_NAME_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read local name on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read local name on hci%d returned status %d\n", hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + printf("\tName: '%s'\n", rp.name); + } +} + +void cmd_class(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + if (opt) { + uint32_t cod = htobl(strtoul(opt, NULL, 16)); + write_class_of_dev_cp cp; + + memcpy(cp.dev_class, &cod, 3); + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CLASS_OF_DEV; + rq.cparam = &cp; + rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't write local class of device on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + read_class_of_dev_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_CLASS_OF_DEV; + rq.rparam = &rp; + rq.rlen = READ_CLASS_OF_DEV_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read class of device on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (rp.status) { + printf("Read class of device on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + printf("\tClass: 0x%02x%02x%02x\n", + rp.dev_class[2], rp.dev_class[1], rp.dev_class[0]); + } +} + +void cmd_version(int ctl, int hdev, char *opt) +{ + struct hci_version ver; + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + printf("Can't read version info hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + printf( "\tHCI Ver: 0x%x HCI Rev: 0x%x LMP Ver: 0x%x LMP Subver: 0x%x\n" + "\tManufacturer: %d\n", + ver.hci_ver, ver.hci_rev, ver.lmp_ver, ver.lmp_subver, + ver.manufacturer); +} + +void print_dev_hdr(struct hci_dev_info *di) +{ + static int hdr = -1; + bdaddr_t bdaddr; + + if (hdr == di->dev_id) + return; + hdr = di->dev_id; + + baswap(&bdaddr, &di->bdaddr); + + printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); + printf("\tBD Address: %s ACL MTU: %d:%d SCO: MTU %d:%d\n", + batostr(&bdaddr), di->acl_mtu, di->acl_max, + di->sco_mtu, di->sco_max); +} + +void print_dev_info(int ctl, struct hci_dev_info *di) +{ + struct hci_dev_stats *st = &di->stat; + + print_dev_hdr(di); + + printf("\t%s\n", hci_dflagstostr(di->flags) ); + + printf("\tRX bytes:%d acl:%d sco:%d events:%d errors:%d\n", + st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx); + + printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n", + st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); + + if (all) { + print_dev_features(di); + print_pkt_type(di); + print_link_policy(di); + print_link_mode(di); + + cmd_name(ctl, di->dev_id, NULL); + cmd_class(ctl, di->dev_id, NULL); + cmd_version(ctl, di->dev_id, NULL); + } + + printf("\n"); +} + +struct { + char *cmd; + void (*func)(int ctl, int hdev, char *opt); + char *opt; + char *doc; +} command[] = { + { "up", cmd_up, 0, "Open and initialize HCI device" }, + { "down", cmd_down, 0, "Close HCI device" }, + { "reset", cmd_reset, 0, "Reset HCI device" }, + { "rstat", cmd_rstat, 0, "Reset statistic counters" }, + { "auth", cmd_auth, 0, "Enable Authentication" }, + { "noauth", cmd_auth, 0, "Disable Authentication" }, + { "encrypt",cmd_encrypt,0, "Enable Encryption" }, + { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, + { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, + { "noscan", cmd_scan, 0, "Disable scan" }, + { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, + { "pscan", cmd_scan, 0, "Enable Page scan" }, + { "ptype", cmd_ptype, "[type]", "Get/Set default packet type" }, + { "lm", cmd_lm, "[mode]", "Get/Set default link mode" }, + { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, + { "name", cmd_name, "[name]", "Get/Set local name" }, + { "class", cmd_class, "[class]", "Get/Set class of device" }, + { "version", cmd_version, 0, "Display version information" }, + { "features", cmd_features, 0,"Display device features" }, + { NULL, NULL, 0} +}; + +void usage(void) +{ + int i; + + printf("hciconfig - HCI device configuration utility\n"); + printf("Usage:\n" + "\thciconfig\n" + "\thciconfig [-a] hciX [command]\n"); + printf("Commands:\n"); + for (i=0; command[i].cmd; i++) + printf("\t%-10s %-8s\t%s\n", command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); +} + +int main(int argc, char *argv[], char *env[]) +{ + int opt, ctl, i, cmd=0; + char *dev; + + while ((opt=getopt(argc, argv,"ha")) != EOF) { + switch(opt) { + case 'a': + all = 1; + break; + case 'h': + usage(); + exit(0); + } + } + + /* Open HCI socket */ + if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { + perror("Can't open HCI socket."); + exit(1); + } + + if (argc - optind < 1) { + print_dev_list(ctl, 0); + exit(0); + } + + dev = strdup(argv[optind]); + di.dev_id = atoi(argv[optind]+3); + optind++; + + if (ioctl(ctl, HCIGETDEVINFO, (void*)&di)) { + perror("Can't get device info"); + exit(1); + } + + while (optind < argc) { + for (i=0; command[i].cmd; i++) { + if (strncmp(command[i].cmd, argv[optind],4)) + continue; + + if (command[i].opt) + optind++; + + command[i].func(ctl, di.dev_id, argv[optind]); + cmd = 1; + break; + } + optind++; + } + + if (!cmd) + print_dev_info(ctl, &di); + + close(ctl); + return 0; +} diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c new file mode 100644 index 00000000..bee16df1 --- /dev/null +++ b/tools/hcisecfilter.c @@ -0,0 +1,79 @@ +#include +#include + +#include +#include +#include + +int main(void) +{ + uint32_t type_mask; + uint32_t event_mask[2]; + uint32_t ocf_mask[4]; + + // Packet types + memset((void *)&type_mask, 0, sizeof(type_mask)); + hci_set_bit(HCI_EVENT_PKT, &type_mask); + + printf("Type mask: { 0x%lx }\n", type_mask); + + // Events + memset((void *)event_mask, 0, sizeof(event_mask)); + hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); + hci_set_bit(EVT_INQUIRY_RESULT, event_mask); + + hci_set_bit(EVT_CONN_COMPLETE, event_mask); + hci_set_bit(EVT_CONN_REQUEST, event_mask); + hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); + + hci_set_bit(EVT_AUTH_COMPLETE, event_mask); + hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); + + hci_set_bit(EVT_CMD_COMPLETE, event_mask); + hci_set_bit(EVT_CMD_STATUS, event_mask); + + hci_set_bit(EVT_READ_REMOTE_FEATURES_COMPLETE, event_mask); + hci_set_bit(EVT_READ_REMOTE_VERSION_COMPLETE, event_mask); + hci_set_bit(EVT_REMOTE_NAME_REQ_COMPLETE, event_mask); + + printf("Event mask: { 0x%lx, 0x%lx }\n", event_mask[0], event_mask[1]); + + // OGF_LINK_CTL + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_INQUIRY, ocf_mask); + hci_set_bit(OCF_REMOTE_NAME_REQ, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_VERSION, ocf_mask); + + printf("OGF_LINK_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + // OGF_LINK_POLICY + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); + hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); + + printf("OGF_LINK_POLICY: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + // OGF_HOST_CTL + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_AUTH_ENABLE, ocf_mask); + hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); + hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); + + printf("OGF_HOST_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + // OGF_INFO_PARAM + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_LOCAL_VERSION, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_BUFFER_SIZE, ocf_mask); + hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); + hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); + + printf("OGF_INFO_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); +} diff --git a/tools/hcitool.c b/tools/hcitool.c new file mode 100644 index 00000000..4d6380fb --- /dev/null +++ b/tools/hcitool.c @@ -0,0 +1,368 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +extern int optind,opterr,optopt; +extern char *optarg; + +static int ctl; + +static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) +{ + struct hci_dev_list_req *dl; + struct hci_dev_req *dr; + int i; + + dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); + if (!dl) { + perror("Can't allocate memory"); + return -1; + } + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(ctl, HCIGETDEVLIST, (void*)dl)) { + perror("Can't get device list"); + return -1; + } + + if (!dl->dev_num) + return -1; + + for (i=0; i < dl->dev_num; i++, dr++) { + if (dr->dev_opt & (1<dev_id, arg)) + return dr->dev_id; + } + } + return -1; +} + +static int other_bdaddr(int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) + return 0; + return bacmp((bdaddr_t *)arg, &di.bdaddr); +} + +static int get_route(bdaddr_t *bdaddr) +{ + if (bdaddr) + return for_each_dev(HCI_UP, other_bdaddr, (long) bdaddr); + else + return for_each_dev(HCI_UP, NULL, 0); +} + +static int dev_info(int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + bdaddr_t bdaddr; + if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) + return 0; + + baswap(&bdaddr, &di.bdaddr); + printf("\t%s\t%s\n", di.name, batostr(&bdaddr)); + return 0; +} + +static int conn_list(int dev_id, long arg) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + int i; + + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + perror("Can't get connection list"); + exit(1); + } + + for (i=0; i < cl->conn_num; i++, ci++) { + bdaddr_t bdaddr; + baswap(&bdaddr, &ci->bdaddr); + printf("\t%s %s %s handle %d state %d lm %s\n", + ci->out ? "<" : ">", + ci->type == ACL_LINK ? "ACL" : "SCO", + batostr(&bdaddr), ci->handle, + ci->state, + hci_lmtostr(ci->link_mode)); + } + return 0; +} + +static int find_conn(int dev_id, long arg) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + int i; + + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { + perror("Can't allocate memory"); + exit(1); + } + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + perror("Can't get connection list"); + exit(1); + } + + for (i=0; i < cl->conn_num; i++, ci++) + if (!bacmp((bdaddr_t *)arg, &ci->bdaddr)) + return 1; + return 0; +} + +static void cmd_dev(int dev_id, char **opt, int nopt) +{ + printf("Devices:\n"); + for_each_dev(HCI_UP, dev_info, 0); +} + +static void cmd_inq(int dev_id, char **opt, int nopt) +{ + inquiry_info *info; + int i, num_rsp = 0, length, flags; + bdaddr_t bdaddr; + + if (dev_id < 0) + dev_id = get_route(NULL); + + if (nopt >= 1) + length = atoi(opt[0]); + else + length = 10; /* 10 seconds */ + + flags = 0; + if (nopt >= 2) + flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + + printf("Inquiring ...\n"); + info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); + + if (!info) { + perror("Inquiry failed."); + exit(1); + } + + for (i = 0; i < num_rsp; i++) { + baswap(&bdaddr, &(info+i)->bdaddr); + printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", + batostr(&bdaddr), (info+i)->clock_offset, + (info+i)->dev_class[2], + (info+i)->dev_class[1], + (info+i)->dev_class[0]); + } + free(info); +} + +static void cmd_con(int dev_id, char **opt, int nopt) +{ + printf("Connections:\n"); + if (dev_id < 0) + for_each_dev(HCI_UP, conn_list, 0); + else + conn_list(dev_id, 0); +} + +static void cmd_cc(int dev_id, char **opt, int nopt) +{ + bdaddr_t bdaddr; + int dd, ptype, role; + + if (nopt < 1) + return; + + baswap(&bdaddr, strtoba(opt[0])); + + if (dev_id < 0) { + dev_id = get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (nopt >= 2) + hci_strtoptype(opt[1], &ptype); + else + ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; + + if (nopt >= 3) + role = !strncasecmp("m", opt[2], 1) ? 0 : 1; + else + role = 0; + + hci_create_connection(dd, &bdaddr, ptype, role, 1000); + + hci_close_dev(dd); +} + +static void cmd_dc(int dev_id, char **opt, int nopt) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + int dd; + + if (nopt < 1) + return; + + baswap(&bdaddr, strtoba(*opt)); + + if (dev_id < 0) { + dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + hci_disconnect(dd, cr->conn_info->handle, 0, 100); + + close(dd); + free(cr); +} + +struct { + char *cmd; + void (*func)(int dev_id, char **opt, int nopt); + char *opt; + char *doc; +} command[] = { + { "dev", cmd_dev, 0, "Display local devices" }, + { "inq", cmd_inq, "[lenght] [flush]", "Inquire remote devices" }, + { "con", cmd_con, 0, "Display active connections" }, + { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, + { "dc", cmd_dc, "", "Disconnect from remote device" }, + { NULL, NULL, 0} +}; + +static void usage(void) +{ + int i; + + printf("hcitool - HCI Tool\n"); + printf("Usage:\n" + "\thcitool [-i hciX] [command]\n"); + printf("Commands:\n"); + for (i=0; command[i].cmd; i++) + printf("\t%-4s %-20s\t%s\n", command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); +} + +int main(int argc, char *argv[], char *env[]) +{ + int opt, i, dev_id = -1; + char *dev; + + while ((opt=getopt(argc, argv, "i:h")) != EOF) { + switch(opt) { + case 'i': + dev = strdup(optarg); + dev_id = atoi(dev + 3); + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + if (argc - optind < 1) { + usage(); + exit(0); + } + + /* Open HCI socket */ + if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { + perror("Can't open HCI socket."); + exit(1); + } + + for (i=0; command[i].cmd; i++) { + if (strncmp(command[i].cmd, argv[optind], 3)) + continue; + optind++; + command[i].func(dev_id, argv + optind, argc - optind); + break; + } + + close(ctl); + return 0; +} diff --git a/tools/l2ping.8 b/tools/l2ping.8 new file mode 100644 index 00000000..41becdba --- /dev/null +++ b/tools/l2ping.8 @@ -0,0 +1,49 @@ +.TH L2PING 8 "Jan 22 2002" BlueZ "Linux System Administration" +.SH NAME +l2ping \- Send L2CAP echo request and receive answer +.SH SYNOPSIS +.B l2ping +[ +.I -S source addr +] [ +.I -s size +] [ +.I -c count +] [ +.I -f +] < +.I bd_addr +> +.SH DESCRIPTION +.LP +L2ping sends a L2CAP echo request to the Bluetooth MAC address +.B bd_addr +given in dotted hex notation. +.SH OPTIONS +.TP +.I -S source addr +Select address to be used as source address for the request. +.TP +.I -s size +The +.B size +of the data packets to be sent. +.TP +.I -c count +Send +.B count +number of packets then exit. +.TP +.I -f +Kind of flood ping. Use with care! It reduces the delay time between packets +to 0. +.TP +.I bd_addr +The Bluetooth MAC address to be pinged in dotted hex notation like +.B 01:02:03:ab:cd:ef +or +.B 01:EF:cd:aB:02:03 +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Nils Faerber diff --git a/tools/l2ping.c b/tools/l2ping.c new file mode 100644 index 00000000..9bb8a4d6 --- /dev/null +++ b/tools/l2ping.c @@ -0,0 +1,251 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "bluetooth.h" +#include "l2cap.h" + +/* Defaults */ +bdaddr_t bdaddr; +int size = 20; +int ident = 200; +int delay = 1; +int count = -1; + +/* Stats */ +int sent_pkt = 0, recv_pkt = 0; + +static float tv2fl(struct timeval tv) +{ + return (float)(tv.tv_sec*1000.0) + (float)(tv.tv_usec/1000.0); +} + +static void stat(int sig) +{ + int loss = sent_pkt ? (float)((sent_pkt-recv_pkt)/(sent_pkt/100.0)) : 0; + printf("%d sent, %d received, %d%% loss\n", sent_pkt, recv_pkt, loss); + exit(0); +} + +static void ping(char *svr) +{ + struct sockaddr_l2 addr; + struct sigaction sa; + char buf[2048]; + int s, i, opt, lost; + uint8_t id; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = stat; + sigaction(SIGINT, &sa, NULL); + + if ((s = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) { + perror("Can't create socket."); + exit(1); + } + + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + addr.l2_bdaddr = bdaddr; + if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Can't bind socket."); + exit(1); + } + + baswap(&addr.l2_bdaddr, strtoba(svr)); + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror("Can't connect."); + exit(1); + } + + /* Get local address */ + opt = sizeof(addr); + if( getsockname(s, (struct sockaddr *)&addr, &opt) < 0 ) { + perror("Can't get local address."); + exit(1); + } + baswap(&bdaddr, &addr.l2_bdaddr); + + printf("Ping: %s from %s (data size %d) ...\n", svr, batostr(&bdaddr), size); + + /* Initialize buffer */ + for(i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) + buf[i]=(i%40)+'A'; + + id = ident; + + while( count == -1 || count-- > 0 ){ + struct timeval tv_send, tv_recv, tv_diff; + l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; + + /* Build command header */ + cmd->code = L2CAP_ECHO_REQ; + cmd->ident = id; + cmd->len = __cpu_to_le16(size); + + gettimeofday(&tv_send, NULL); + + /* Send Echo Request */ + if( send(s, buf, size + L2CAP_CMD_HDR_SIZE, 0) <= 0 ){ + perror("Send failed"); + exit(1); + } + + /* Wait for Echo Response */ + lost = 0; + while( 1 ) { + struct pollfd pf[1]; + register int err; + + pf[0].fd = s; pf[0].events = POLLIN; + if( (err = poll(pf, 1, 10*1000)) < 0 ) { + perror("Poll failed"); + exit(1); + } + + if( !err ){ + lost = 1; + break; + } + + if( (err = recv(s, buf, sizeof(buf), 0)) < 0 ) { + perror("Recv failed"); + exit(1); + } + + if( !err ){ + printf("Disconnected\n"); + exit(1); + } + + cmd->len = __le16_to_cpu(cmd->len); + + /* Check for our id */ + if( cmd->ident != id ) + continue; + + /* Check type */ + if( cmd->code == L2CAP_ECHO_RSP ) + break; + if( cmd->code == L2CAP_COMMAND_REJ ){ + printf("Peer doesn't support Echo packets\n"); + exit(1); + } + + } + sent_pkt++; + + if( !lost ){ + recv_pkt++; + + gettimeofday(&tv_recv, NULL); + timersub(&tv_recv, &tv_send, &tv_diff); + + printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id, tv2fl(tv_diff)); + + if( delay ) sleep(delay); + } else { + printf("no response from %s: id %d\n", svr, id); + } + + if( ++id > 254 ) id = ident; + } + stat(0); +} + +static void usage(void) +{ + printf("l2ping - L2CAP ping\n"); + printf("Usage:\n"); + printf("\tl2ping [-S source addr] [-s size] [-c count] [-f] \n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc, char *argv[]) +{ + register int opt; + + /* Default options */ + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt=getopt(argc,argv,"s:c:fS:")) != EOF) { + switch(opt) { + case 'f': + /* Kinda flood ping */ + delay = 0; + break; + + case 'c': + count = atoi(optarg); + break; + + case 's': + size = atoi(optarg); + break; + + case 'S': + baswap(&bdaddr, strtoba(optarg)); + break; + + default: + usage(); + exit(1); + } + } + + if (!(argc - optind)) { + usage(); + exit(1); + } + + ping(argv[optind]); + + return 0; +} diff --git a/tools/l2test.c b/tools/l2test.c new file mode 100644 index 00000000..be0b59e1 --- /dev/null +++ b/tools/l2test.c @@ -0,0 +1,493 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP, + CONNECT +}; + +unsigned char *buf; + +/* Default mtu */ +int imtu = 672; +int omtu = 0; + +/* Default data size */ +long data_size = 672; + +/* Default addr and psm */ +bdaddr_t bdaddr; +unsigned short psm = 10; + +int master = 0; +int auth = 0; +int encrypt = 0; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_l2 rem_addr, loc_addr; + struct l2cap_options opts; + int s, opt; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.l2_family = AF_BLUETOOTH; + loc_addr.l2_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Get default options */ + opt = sizeof(opts); + if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + /* Set new options */ + opts.omtu = omtu; + opts.imtu = imtu; + if( setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0 ) { + syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.l2_family = AF_BLUETOOTH; + baswap(&rem_addr.l2_bdaddr, strtoba(svr)); + rem_addr.l2_psm = htobs(psm); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + return -1; + } + + opt = sizeof(opts); + if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ + syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d]\n", + opts.imtu, opts.omtu, opts.flush_to); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_l2 loc_addr, rem_addr; + struct l2cap_options opts; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.l2_family = AF_BLUETOOTH; + loc_addr.l2_bdaddr = bdaddr; + loc_addr.l2_psm = htobs(psm); + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Get default options */ + opt = sizeof(opts); + if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { + syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Set new options */ + opts.imtu = imtu; + if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { + syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + + /* Set link mode */ + opt = 0; + if (master) + opt |= L2CAP_LM_MASTER; + + if (auth) + opt |= L2CAP_LM_AUTH; + + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + + if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection on psm %d ...", psm); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + opt = sizeof(opts); + if( getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + baswap(&ba, &rem_addr.l2_bdaddr); + syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", + batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO,"Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO,"Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + uint32_t sq; + uint16_t l; + int i,r; + + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + + /* Check sequence */ + sq = btohl(*(uint32_t *)buf); + if (seq != sq) { + syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); + seq = sq; + } + seq++; + + /* Check length */ + l = btohs(*(uint16_t *)(buf+4)); + if (r != l) { + syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); + continue; + } + + /* Verify data */ + for (i=6; i < r; i++) { + if (buf[i] != 0x7f) + syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); + } + + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + } +} + +void send_mode(char *svr) +{ + uint32_t seq; + int s, i; + + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Sending ..."); + + for(i=6; i < data_size; i++) + buf[i]=0x7f; + + seq = 0; + while(1){ + *(uint32_t *)buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if( send(s, buf, data_size, 0) <= 0 ) { + syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + exit(1); + } + } +} + +void reconnect_mode(char *svr) +{ + while(1){ + int s; + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + exit(1); + } + close(s); + + usleep(10); + } +} + +void connect_mode(char *svr) +{ + int s; + if ((s = do_connect(svr)) < 0) { + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", + strerror(errno), errno); + exit(1); + } + sleep(99999999); +} + +void multy_connect_mode(char *svr) +{ + while(1){ + int i, s; + for(i=0; i<10; i++){ + if( fork() ) continue; + + /* Child */ + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + } + close(s); + exit(0); + } + sleep(19); + } +} + +void usage(void) +{ + printf("l2test - L2CAP testing\n" + "Usage:\n"); + printf("\tl2test [-b bytes] [-S bd_addr] [-P psm] [-I imtu] [-O omtu] [-M] [bd_addr]\n"); + printf("Modes:\n" + "\t-d dump (server)\n" + "\t-n silent connect (client)\n" + "\t-c reconnect (client)\n" + "\t-m multiple connects (client)\n" + "\t-r receive (server)\n" + "\t-s send (client)\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + struct sigaction sa; + int opt, mode = RECV; + + while ((opt=getopt(argc,argv,"rdscmnb:P:I:O:S:MAE")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + break; + + case 'n': + mode = CONNECT; + break; + + case 'm': + mode = MULTY; + break; + + case 'b': + data_size = atoi(optarg); + break; + + case 'S': + baswap(&bdaddr, strtoba(optarg)); + break; + + case 'P': + psm = atoi(optarg); + break; + + case 'I': + imtu = atoi(optarg); + break; + + case 'O': + omtu = atoi(optarg); + break; + + case 'M': + master = 1; + break; + + case 'A': + auth = 1; + break; + + case 'E': + encrypt = 1; + break; + + default: + usage(); + exit(1); + } + } + + if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + send_mode(argv[optind]); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multy_connect_mode(argv[optind]); + break; + + case CONNECT: + connect_mode(argv[optind]); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} diff --git a/tools/scotest.c b/tools/scotest.c new file mode 100644 index 00000000..4b56d081 --- /dev/null +++ b/tools/scotest.c @@ -0,0 +1,358 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP +}; + +unsigned char *buf; + +/* Default data size */ +long data_size = 672; + +bdaddr_t bdaddr; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_sco rem_addr, loc_addr; + int s; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.sco_family = AF_BLUETOOTH; + loc_addr.sco_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.sco_family = AF_BLUETOOTH; + baswap(&rem_addr.sco_bdaddr, strtoba(svr)); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + return -1; + } + + syslog(LOG_INFO, "Connected\n"); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_sco loc_addr, rem_addr; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.sco_family = AF_BLUETOOTH; + loc_addr.sco_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection ..."); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + baswap(&ba, &rem_addr.sco_bdaddr); + syslog(LOG_INFO, "Connect from %s\n", batostr(&ba)); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO,"Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO, "Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + int r; + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2fm speed %.2f kb",total, + tv2fl(tv_diff) / 60.0, + (float)( total / tv2fl(tv_diff) ) / 1024.0 ); + } +} + +void send_mode(char *svr) +{ + struct sco_options so; + uint32_t seq; + int s, i, opt; + + if ((s = do_connect(svr)) < 0) { + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", + strerror(errno), errno); + exit(1); + } + + opt = sizeof(so); + if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { + syslog(LOG_ERR, "Can't get SCO options. %s(%d)", + strerror(errno), errno); + exit(1); + } + + + syslog(LOG_INFO,"Sending ..."); + + for (i=6; i < so.mtu; i++) + buf[i]=0x7f; + + seq = 0; + while (1) { + *(uint32_t *)buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, so.mtu, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", + strerror(errno), errno); + exit(1); + } + usleep(1); + } +} + +void reconnect_mode(char *svr) +{ + while(1){ + int s; + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + exit(1); + } + close(s); + + sleep(5); + } +} + +void multy_connect_mode(char *svr) +{ + while(1){ + int i, s; + for(i=0; i<10; i++){ + if( fork() ) continue; + + /* Child */ + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + } + close(s); + exit(0); + } + sleep(19); + } +} + +void usage(void) +{ + printf("scotest - SCO testing\n" + "Usage:\n"); + printf("\tscotest [-b bytes] [bd_addr]\n"); + printf("Modes:\n" + "\t-d dump (server)\n" + "\t-c reconnect (client)\n" + "\t-m multiple connects (client)\n" + "\t-r receive (server)\n" + "\t-s send (client)\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + struct sigaction sa; + int opt, mode = RECV; + + while ((opt=getopt(argc,argv,"rdscmb:")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + break; + + case 'm': + mode = MULTY; + break; + + case 'b': + data_size = atoi(optarg); + break; + + default: + usage(); + exit(1); + } + } + + if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("scotest", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + send_mode(argv[optind]); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multy_connect_mode(argv[optind]); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} -- cgit From 7c424c5ad20ca75f3cbd21318249f558831b29fe Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 8 Mar 2002 21:31:11 +0000 Subject: Update --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7149ba9b..ff460a29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ ver 2.0-pre7: Bluetooth utilities is now a separate package. + New build environment uses automake. + Moved all config files and security data to /etc/bluetooth. + Various cleanups. + + Note: + Please move your /etc/hcid.conf to /etc/bluetooth ver 2.0-pre6: Improved hcitool. -- cgit From d5355b836015bbe6d4bb4b4229c2cc7c8d330d9d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 18 Mar 2002 19:36:42 +0000 Subject: Support for Inventel devices. --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/hciattach.c b/tools/hciattach.c index a4489019..cf882b92 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -544,6 +544,9 @@ struct uart_t uart[] = { /* Sphinx Electronics PICO Card */ { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + /* Inventel BlueBird Module */ + { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { NULL, 0 } }; -- cgit From 50fc3563a46bb0b217b0b3ab941b8b7c012073e1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 18 Mar 2002 19:38:39 +0000 Subject: -a option fixes. Don't try to display name,etc of the down devices. --- tools/hciconfig.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3cbec922..25e91012 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -414,9 +414,11 @@ void print_dev_info(int ctl, struct hci_dev_info *di) print_link_policy(di); print_link_mode(di); - cmd_name(ctl, di->dev_id, NULL); - cmd_class(ctl, di->dev_id, NULL); - cmd_version(ctl, di->dev_id, NULL); + if (di->flags & (1 << HCI_UP)) { + cmd_name(ctl, di->dev_id, NULL); + cmd_class(ctl, di->dev_id, NULL); + cmd_version(ctl, di->dev_id, NULL); + } } printf("\n"); -- cgit From aba9dc216df7ddacbaa10d9e25c7aba05ab28afb Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 18 Mar 2002 19:39:45 +0000 Subject: Don't foget to compile l2test. l2test output nicefication :) --- tools/Makefile.am | 8 ++++++++ tools/Makefile.in | 12 ++++++++++-- tools/l2test.c | 28 +++++++++++++--------------- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index d3133e5f..53e3e21d 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -8,3 +8,11 @@ sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 + +CLEANFILES = l2test.o l2test + + +all-local: l2test + +l2test: l2test.o + $(LINK) l2test.o $(LDFLAGS) $(LIBS) diff --git a/tools/Makefile.in b/tools/Makefile.in index fe838a44..fae41912 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -87,6 +87,8 @@ sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 + +CLEANFILES = l2test.o l2test mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) @@ -368,7 +370,7 @@ install-am: all-am install: install-am uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS uninstall-man uninstall: uninstall-am -all-am: Makefile $(PROGRAMS) $(MANS) +all-am: Makefile $(PROGRAMS) $(MANS) all-local all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install @@ -380,6 +382,7 @@ installdirs: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) @@ -423,11 +426,16 @@ clean-tags maintainer-clean-tags distdir mostlyclean-depend \ distclean-depend clean-depend maintainer-clean-depend info-am info \ dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs \ +uninstall-am uninstall all-local all-redirect all-am all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean +all-local: l2test + +l2test: l2test.o + $(LINK) l2test.o $(LDFLAGS) $(LIBS) + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/tools/l2test.c b/tools/l2test.c index be0b59e1..e527fc60 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -292,10 +292,8 @@ void send_mode(char *svr) uint32_t seq; int s, i; - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + if( (s = do_connect(svr)) < 0 ) exit(1); - } syslog(LOG_INFO,"Sending ..."); @@ -318,10 +316,9 @@ void reconnect_mode(char *svr) { while(1){ int s; - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + if( (s = do_connect(svr)) < 0 ) exit(1); - } + close(s); usleep(10); @@ -331,11 +328,8 @@ void reconnect_mode(char *svr) void connect_mode(char *svr) { int s; - if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", - strerror(errno), errno); + if ((s = do_connect(svr)) < 0) exit(1); - } sleep(99999999); } @@ -347,9 +341,7 @@ void multy_connect_mode(char *svr) if( fork() ) continue; /* Child */ - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); - } + s = do_connect(svr); close(s); exit(0); } @@ -361,14 +353,20 @@ void usage(void) { printf("l2test - L2CAP testing\n" "Usage:\n"); - printf("\tl2test [-b bytes] [-S bd_addr] [-P psm] [-I imtu] [-O omtu] [-M] [bd_addr]\n"); + printf("\tl2test [options] [bdaddr]\n"); printf("Modes:\n" + "\t-r receive (server)\n" "\t-d dump (server)\n" "\t-n silent connect (client)\n" "\t-c reconnect (client)\n" "\t-m multiple connects (client)\n" - "\t-r receive (server)\n" "\t-s send (client)\n"); + printf("Options:\n" + "\t[-b bytes] [-S bdaddr] [-P psm]\n" + "\t[-I imtu] [-O omtu]\n" + "\t[-A] request authentication\n" + "\t[-E] request encryption\n" + "\t[-M] become master\n"); } extern int optind,opterr,optopt; -- cgit -- cgit From eb965f147eaa15028d1abca397a6dc49c55d7868 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 19 Mar 2002 05:37:10 +0000 Subject: COM One PC Card support --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/hciattach.c b/tools/hciattach.c index cf882b92..a7f89e21 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -547,6 +547,9 @@ struct uart_t uart[] = { /* Inventel BlueBird Module */ { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + /* COM One Platinium Bluetooth PC Card */ + { "comone", 0xffff, 0x0101, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { NULL, 0 } }; -- cgit From 30fc590d680e1dddd718316e9a0936e6dfa04be6 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 19 Mar 2002 17:21:12 +0000 Subject: Split initialization. Configure name,class,etc on DEV_UP event. --- hcid/main.c | 111 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/hcid/main.c b/hcid/main.c index 5b3c3d30..835db2df 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -66,65 +66,31 @@ static void usage(void) printf("\thcid [-n not_daemon] [-f config file]\n"); } -static void init_device(int hdev) +static void configure_device(int hdev) { struct hci_dev_req dr; int s; - /* Do initialization in the separate process */ + /* Do configuration in the separate process */ switch (fork()) { case 0: break; case -1: - syslog(LOG_ERR, "Fork failed. Can't init device hci%d. %s(%d)\n", + syslog(LOG_ERR, "Fork failed. Can't init device hci%d. %s(%d)\n", hdev, strerror(errno), errno); default: return; } - set_title("hci%d init", hdev); + set_title("hci%d config", hdev); if ((s = hci_open_dev(hdev)) < 0) { syslog(LOG_ERR, "Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - /* Start HCI device */ - if (ioctl(s, HCIDEVUP, hdev) < 0 && errno != EALREADY) { - syslog(LOG_ERR, "Can't init device hci%d. %s(%d)\n", hdev, - strerror(errno), errno); - exit(1); - } - dr.dev_id = hdev; - /* Set packet type */ - if (devi.pkt_type) { - dr.dev_opt = devi.pkt_type; - if (ioctl(s, HCISETPTYPE, (unsigned long)&dr) < 0) { - syslog(LOG_ERR, "Can't set packet type on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); - } - } - - /* Set link mode */ - if (devi.link_mode) { - dr.dev_opt = devi.link_mode; - if (ioctl(s, HCISETLINKMODE, (unsigned long)&dr) < 0) { - syslog(LOG_ERR, "Can't set link mode on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); - } - } - - /* Set link policy */ - if (devi.link_policy) { - dr.dev_opt = devi.link_policy; - if (ioctl(s, HCISETLINKPOL, (unsigned long)&dr) < 0) { - syslog(LOG_ERR, "Can't set link policy on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); - } - } - /* Set scan mode */ dr.dev_opt = devi.scan; if (ioctl(s, HCISETSCAN, (unsigned long)&dr) < 0) { @@ -176,6 +142,68 @@ static void init_device(int hdev) exit(0); } +static void init_device(int hdev) +{ + struct hci_dev_req dr; + int s; + + /* Do initialization in the separate process */ + switch (fork()) { + case 0: + break; + case -1: + syslog(LOG_ERR, "Fork failed. Can't init device hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + default: + return; + } + + set_title("hci%d init", hdev); + + if ((s = hci_open_dev(hdev)) < 0) { + syslog(LOG_ERR, "Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + dr.dev_id = hdev; + + /* Set packet type */ + if (devi.pkt_type) { + dr.dev_opt = devi.pkt_type; + if (ioctl(s, HCISETPTYPE, (unsigned long)&dr) < 0) { + syslog(LOG_ERR, "Can't set packet type on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + } + } + + /* Set link mode */ + if (devi.link_mode) { + dr.dev_opt = devi.link_mode; + if (ioctl(s, HCISETLINKMODE, (unsigned long)&dr) < 0) { + syslog(LOG_ERR, "Can't set link mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + } + } + + /* Set link policy */ + if (devi.link_policy) { + dr.dev_opt = devi.link_policy; + if (ioctl(s, HCISETLINKPOL, (unsigned long)&dr) < 0) { + syslog(LOG_ERR, "Can't set link policy on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + } + } + + /* Start HCI device */ + if (ioctl(s, HCIDEVUP, hdev) < 0 && errno != EALREADY) { + syslog(LOG_ERR, "Can't init device hci%d. %s(%d)\n", hdev, + strerror(errno), errno); + exit(1); + } + + exit(0); +} + static void init_all_devices(int ctl) { struct hci_dev_list_req *dl; @@ -191,7 +219,7 @@ static void init_all_devices(int ctl) dr = dl->dev_req; if (ioctl(ctl, HCIGETDEVLIST, (void*)dl)) { - syslog(LOG_INFO, "Can't get device list. %s(%d)", + syslog(LOG_INFO, "Can't get device list. %s(%d)", strerror(errno), errno); exit(1); } @@ -200,6 +228,9 @@ static void init_all_devices(int ctl) if (hcid.auto_init) init_device(dr->dev_id); + if (hcid.auto_init && (dr->dev_opt & (1<dev_id); + if (hcid.security && (dr->dev_opt & (1<dev_id); } @@ -258,6 +289,8 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si) case HCI_DEV_UP: syslog(LOG_INFO, "HCI dev %d up", sd->dev_id); + if (hcid.auto_init) + configure_device(sd->dev_id); if (hcid.security) start_security_manager(sd->dev_id); break; -- cgit From 18527eedb9243335fb47c4297e97afcc8722c1c6 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 19 Mar 2002 18:06:30 +0000 Subject: Added inquiry params command --- tools/hciconfig.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 25e91012..779cef0f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -377,6 +376,73 @@ void cmd_version(int ctl, int hdev, char *opt) ver.manufacturer); } +void cmd_inq_parms(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + uint16_t window, interval; + write_inq_activity_cp cp; + + if (sscanf(opt,"%4u/%4u", &window, &interval)!=2) { + printf("Invalid argument format\n"); + exit(1); + } + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQ_ACTIVITY; + rq.cparam = &cp; + rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE; + + cp.window = htobs(window); + cp.interval = htobs(interval); + + if (window < 0x12 || window > 0x1000) + printf("Warning: inquiry window out of range!\n"); + + if (interval < 0x12 || interval > 0x1000) + printf("Warning: inquiry interval out of range!\n"); + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't set inquiry parameters name on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint16_t window, interval; + read_inq_activity_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_INQ_ACTIVITY; + rq.rparam = &rp; + rq.rlen = READ_INQ_ACTIVITY_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read inquiry parameters on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read inquiry parameters on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + + window = btohs(rp.window); + interval = btohs(rp.interval); + printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", + interval, (float)interval * 0.625, window, (float)window * 0.625); + } +} + void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; @@ -447,6 +513,7 @@ struct { { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, + { "inqparms",cmd_inq_parms, "[int/win]","Get/Set device inquiry window and iterval" }, { "version", cmd_version, 0, "Display version information" }, { "features", cmd_features, 0,"Display device features" }, { NULL, NULL, 0} -- cgit From 9738e36a881497bc94d60b273f50dfa27b95030c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 21 Mar 2002 23:23:36 +0000 Subject: Support for company id and more readable version numbers. --- tools/hciconfig.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 779cef0f..3cae9792 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -370,10 +370,11 @@ void cmd_version(int ctl, int hdev, char *opt) } print_dev_hdr(&di); - printf( "\tHCI Ver: 0x%x HCI Rev: 0x%x LMP Ver: 0x%x LMP Subver: 0x%x\n" - "\tManufacturer: %d\n", - ver.hci_ver, ver.hci_rev, ver.lmp_ver, ver.lmp_subver, - ver.manufacturer); + printf( "\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n" + "\tManufacturer: %s (%d)\n", + hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, + lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, + bt_compidtostr(ver.manufacturer), ver.manufacturer); } void cmd_inq_parms(int ctl, int hdev, char *opt) -- cgit From 67230a9bb66546eedfe2a6587c125e3d3c23abf2 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:08:41 +0000 Subject: Fix compiler options and warnings --- configure | 104 ++++++++++++++++++++++++++++-------------------------- configure.in | 2 ++ hcid/Makefile.am | 4 +-- hcid/Makefile.in | 5 +-- tools/hciconfig.c | 6 ++-- 5 files changed, 63 insertions(+), 58 deletions(-) diff --git a/configure b/configure index 8b56bff4..82644521 100755 --- a/configure +++ b/configure @@ -533,6 +533,8 @@ fi +CFLAGS="-Wall -g -O2" + ac_aux_dir= @@ -582,7 +584,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:586: checking host system type" >&5 +echo "configure:588: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -603,7 +605,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:607: checking target system type" >&5 +echo "configure:609: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -621,7 +623,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:625: checking build system type" >&5 +echo "configure:627: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -650,7 +652,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:654: checking host system type" >&5 +echo "configure:656: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -683,7 +685,7 @@ echo "$ac_t""$host" 1>&6 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:687: checking for a BSD compatible install" >&5 +echo "configure:689: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -736,7 +738,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:740: checking whether build environment is sane" >&5 +echo "configure:742: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -793,7 +795,7 @@ test "$program_suffix" != NONE && test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:797: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:799: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -839,7 +841,7 @@ EOF missing_dir=`cd $ac_aux_dir && pwd` echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 -echo "configure:843: checking for working aclocal" >&5 +echo "configure:845: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -852,7 +854,7 @@ else fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:856: checking for working autoconf" >&5 +echo "configure:858: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -865,7 +867,7 @@ else fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 -echo "configure:869: checking for working automake" >&5 +echo "configure:871: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -878,7 +880,7 @@ else fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:882: checking for working autoheader" >&5 +echo "configure:884: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -891,7 +893,7 @@ else fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:895: checking for working makeinfo" >&5 +echo "configure:897: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -908,7 +910,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:912: checking for $ac_word" >&5 +echo "configure:914: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -938,7 +940,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:942: checking for $ac_word" >&5 +echo "configure:944: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -989,7 +991,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:993: checking for $ac_word" >&5 +echo "configure:995: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1021,7 +1023,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1025: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1027: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -1032,12 +1034,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 1036 "configure" +#line 1038 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:1041: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1063,12 +1065,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1067: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1069: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1072: checking whether we are using GNU C" >&5 +echo "configure:1074: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1077,7 +1079,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1081: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1096,7 +1098,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1100: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1102: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1132,7 +1134,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1136: checking for $ac_word" >&5 +echo "configure:1138: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1173,7 +1175,7 @@ done # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1177: checking for a BSD compatible install" >&5 +echo "configure:1179: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1234,7 +1236,7 @@ fi # Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. set dummy ${ac_tool_prefix}ld; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1238: checking for $ac_word" >&5 +echo "configure:1240: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1266,7 +1268,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ld", so it can be a program name with args. set dummy ld; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1270: checking for $ac_word" >&5 +echo "configure:1272: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1301,7 +1303,7 @@ fi # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1305: checking for $ac_word" >&5 +echo "configure:1307: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1333,7 +1335,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1337: checking for $ac_word" >&5 +echo "configure:1339: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1371,7 +1373,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1375: checking for $ac_word" >&5 +echo "configure:1377: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1402,7 +1404,7 @@ done test -n "$YACC" || YACC="yacc" echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1406: checking how to run the C preprocessor" >&5 +echo "configure:1408: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1417,13 +1419,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1427: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1429: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1434,13 +1436,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1444: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1446: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1451,13 +1453,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1461: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1487,7 +1489,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1491: checking for $ac_word" >&5 +echo "configure:1493: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1520,7 +1522,7 @@ test -n "$LEX" || LEX=""$missing_dir/missing flex"" # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1524: checking for $ac_word" >&5 +echo "configure:1526: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1554,7 +1556,7 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:1558: checking for yywrap in -l$ac_lib" >&5 +echo "configure:1560: checking for yywrap in -l$ac_lib" >&5 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1562,7 +1564,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1596,7 +1598,7 @@ fi fi echo $ac_n "checking lex output file root""... $ac_c" 1>&6 -echo "configure:1600: checking lex output file root" >&5 +echo "configure:1602: checking lex output file root" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1617,7 +1619,7 @@ echo "$ac_t""$ac_cv_prog_lex_root" 1>&6 LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6 -echo "configure:1621: checking whether yytext is a pointer" >&5 +echo "configure:1623: checking whether yytext is a pointer" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1629,14 +1631,14 @@ echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c ac_save_LIBS="$LIBS" LIBS="$LIBS $LEXLIB" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1642: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_prog_lex_yytext_pointer=yes else @@ -1676,7 +1678,7 @@ fi echo $ac_n "checking "for bluetooth.h"""... $ac_c" 1>&6 -echo "configure:1680: checking "for bluetooth.h"" >&5 +echo "configure:1682: checking "for bluetooth.h"" >&5 ac_hdr_found=no for p in $BLUEZ_INCDIR; do @@ -1713,7 +1715,7 @@ echo "configure:1680: checking "for bluetooth.h"" >&5 echo $ac_n "checking "for libbluetooth"""... $ac_c" 1>&6 -echo "configure:1717: checking "for libbluetooth"" >&5 +echo "configure:1719: checking "for libbluetooth"" >&5 ac_save_LDFLAGS=$LDFLAGS @@ -1721,7 +1723,7 @@ echo "configure:1717: checking "for libbluetooth"" >&5 for p in $BLUEZ_LIBDIR; do LDFLAGS="-L$p -lbluetooth" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1738: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* LIBS="$LIBS -L$p -lbluetooth" ac_lib_found=yes @@ -1771,7 +1773,7 @@ else # Extract the first word of "glib-config", so it can be a program name with args. set dummy glib-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1775: checking for $ac_word" >&5 +echo "configure:1777: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_GLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1821,7 +1823,7 @@ fi # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1825: checking for a BSD compatible install" >&5 +echo "configure:1827: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 diff --git a/configure.in b/configure.in index 7bcfab76..6de2df29 100644 --- a/configure.in +++ b/configure.in @@ -11,6 +11,8 @@ AC_SUBST(PCMCIA) AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LDFLAGS) +CFLAGS="-Wall -g -O2" + AC_PREFIX_DEFAULT() dnl Guess host type. diff --git a/hcid/Makefile.am b/hcid/Makefile.am index edc4f653..7de921ca 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -7,8 +7,8 @@ sbin_PROGRAMS = hcid hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.y lexer.l kword.c hcid_LDADD = @GLIB_LDFLAGS@ -CFLAGS += @GLIB_CFLAGS@ -YFLAGS += -d +AM_CFLAGS = @GLIB_CFLAGS@ +YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h diff --git a/hcid/Makefile.in b/hcid/Makefile.in index 037379a9..981cfd9f 100644 --- a/hcid/Makefile.in +++ b/hcid/Makefile.in @@ -87,8 +87,8 @@ sbin_PROGRAMS = hcid hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.y lexer.l kword.c hcid_LDADD = @GLIB_LDFLAGS@ -CFLAGS = @GLIB_CFLAGS@ -YFLAGS = -d +AM_CFLAGS = @GLIB_CFLAGS@ +YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h @@ -109,6 +109,7 @@ hcid_DEPENDENCIES = hcid_LDFLAGS = LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LEXLIB = @LEXLIB@ +CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3cae9792..ad576c96 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -389,7 +389,7 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) memset(&rq, 0, sizeof(rq)); if (opt) { - uint16_t window, interval; + unsigned int window, interval; write_inq_activity_cp cp; if (sscanf(opt,"%4u/%4u", &window, &interval)!=2) { @@ -402,8 +402,8 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) rq.cparam = &cp; rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE; - cp.window = htobs(window); - cp.interval = htobs(interval); + cp.window = htobs((uint16_t)window); + cp.interval = htobs((uint16_t)interval); if (window < 0x12 || window > 0x1000) printf("Warning: inquiry window out of range!\n"); -- cgit From 945768a289b2114b26c0139f8875d1471a300c6b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:47:05 +0000 Subject: connect and disconnect fixes. --- tools/hcitool.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 4d6380fb..ed537031 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -219,7 +219,9 @@ static void cmd_con(int dev_id, char **opt, int nopt) static void cmd_cc(int dev_id, char **opt, int nopt) { bdaddr_t bdaddr; - int dd, ptype, role; + int ptype, dd; + uint16_t handle; + uint8_t role; if (nopt < 1) return; @@ -250,7 +252,7 @@ static void cmd_cc(int dev_id, char **opt, int nopt) else role = 0; - hci_create_connection(dd, &bdaddr, ptype, role, 1000); + hci_create_connection(dd, &bdaddr, ptype, role, 0, &handle, 1000); hci_close_dev(dd); } @@ -291,7 +293,7 @@ static void cmd_dc(int dev_id, char **opt, int nopt) exit(1); } - hci_disconnect(dd, cr->conn_info->handle, 0, 100); + hci_disconnect(dd, cr->conn_info->handle, 0x13, 100); close(dd); free(cr); -- cgit From acc7ace68c67f8bd356aaab04ce7b29914962607 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:53:29 +0000 Subject: create_connection fix. --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index ed537031..aa6ac4ac 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -252,7 +252,7 @@ static void cmd_cc(int dev_id, char **opt, int nopt) else role = 0; - hci_create_connection(dd, &bdaddr, ptype, role, 0, &handle, 1000); + hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000); hci_close_dev(dd); } -- cgit From 2f0421e884d8ef73ad71a5f6ffcb8416bc17ad1c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 26 Mar 2002 18:00:16 +0000 Subject: Support for HCISETACLMTU and HCISETSCOMTU ioctls. Minor cleanup. --- tools/hciconfig.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index ad576c96..aca8a29d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -247,6 +247,42 @@ void cmd_lm(int ctl, int hdev, char *opt) } } +void cmd_aclmtu(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr = { dev_id: hdev }; + uint16_t mtu, mpkt; + + if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) + return; + + *((uint16_t *)&dr.dev_opt + 1) = mtu; + *((uint16_t *)&dr.dev_opt + 0) = mpkt; + + if (ioctl(ctl, HCISETACLMTU, (unsigned long)&dr) < 0) { + printf("Can't set ACL mtu on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } +} + +void cmd_scomtu(int ctl, int hdev, char *opt) +{ + struct hci_dev_req dr = { dev_id: hdev }; + uint16_t mtu, mpkt; + + if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) + return; + + *((uint16_t *)&dr.dev_opt + 1) = mtu; + *((uint16_t *)&dr.dev_opt + 0) = mpkt; + + if (ioctl(ctl, HCISETSCOMTU, (unsigned long)&dr) < 0) { + printf("Can't set SCO mtu on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } +} + void cmd_features(int ctl, int hdev, char *opt) { print_dev_hdr(&di); @@ -392,7 +428,7 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) unsigned int window, interval; write_inq_activity_cp cp; - if (sscanf(opt,"%4u/%4u", &window, &interval)!=2) { + if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) { printf("Invalid argument format\n"); exit(1); } @@ -456,9 +492,9 @@ void print_dev_hdr(struct hci_dev_info *di) baswap(&bdaddr, &di->bdaddr); printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); - printf("\tBD Address: %s ACL MTU: %d:%d SCO: MTU %d:%d\n", - batostr(&bdaddr), di->acl_mtu, di->acl_max, - di->sco_mtu, di->sco_max); + printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", + batostr(&bdaddr), di->acl_mtu, di->acl_pkts, + di->sco_mtu, di->sco_pkts); } void print_dev_info(int ctl, struct hci_dev_info *di) @@ -514,7 +550,9 @@ struct { { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, - { "inqparms",cmd_inq_parms, "[int/win]","Get/Set device inquiry window and iterval" }, + { "inqparms",cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, + { "aclmtu", cmd_aclmtu, "","Set ACL MTU and number of packets" }, + { "scomtu", cmd_scomtu, "","Set SCO MTU and number of packets" }, { "version", cmd_version, 0, "Display version information" }, { "features", cmd_features, 0,"Display device features" }, { NULL, NULL, 0} -- cgit From 04c60e71e4b19ca904a5ea158a9e28297855350d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 27 Mar 2002 05:30:35 +0000 Subject: New test modes. --- tools/l2test.c | 63 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/tools/l2test.c b/tools/l2test.c index e527fc60..56adad96 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -52,7 +52,9 @@ enum { RECONNECT, MULTY, DUMP, - CONNECT + CONNECT, + CRECV, + LSEND }; unsigned char *buf; @@ -287,13 +289,10 @@ void recv_mode(int s) } } -void send_mode(char *svr) +void send_mode(int s) { uint32_t seq; - int s, i; - - if( (s = do_connect(svr)) < 0 ) - exit(1); + int i; syslog(LOG_INFO,"Sending ..."); @@ -355,12 +354,15 @@ void usage(void) "Usage:\n"); printf("\tl2test [options] [bdaddr]\n"); printf("Modes:\n" - "\t-r receive (server)\n" - "\t-d dump (server)\n" - "\t-n silent connect (client)\n" - "\t-c reconnect (client)\n" - "\t-m multiple connects (client)\n" - "\t-s send (client)\n"); + "\t-r listen and receive\n" + "\t-w listen and send\n" + "\t-d listen and dump incomming data\n" + "\t-s connect and send\n" + "\t-u connect and receive\n" + "\t-n connect and be silent\n" + "\t-c connect, disconnect, connect, ...\n" + "\t-m multiple connects\n"); + printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" @@ -374,10 +376,12 @@ extern char *optarg; int main(int argc ,char *argv[]) { + int opt, mode, s, need_addr; struct sigaction sa; - int opt, mode = RECV; - while ((opt=getopt(argc,argv,"rdscmnb:P:I:O:S:MAE")) != EOF) { + mode = RECV; need_addr = 0; + + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -385,6 +389,16 @@ int main(int argc ,char *argv[]) case 's': mode = SEND; + need_addr = 1; + break; + + case 'w': + mode = LSEND; + break; + + case 'u': + mode = CRECV; + need_addr = 1; break; case 'd': @@ -393,14 +407,17 @@ int main(int argc ,char *argv[]) case 'c': mode = RECONNECT; + need_addr = 1; break; case 'n': mode = CONNECT; + need_addr = 1; break; case 'm': mode = MULTY; + need_addr = 1; break; case 'b': @@ -441,7 +458,7 @@ int main(int argc ,char *argv[]) } } - if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + if (need_addr && !(argc - optind)) { usage(); exit(1); } @@ -463,12 +480,26 @@ int main(int argc ,char *argv[]) do_listen(recv_mode); break; + case CRECV: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + recv_mode(s); + break; + case DUMP: do_listen(dump_mode); break; case SEND: - send_mode(argv[optind]); + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + send_mode(s); + break; + + case LSEND: + do_listen(send_mode); break; case RECONNECT: -- cgit From 46ee343d9d3f6fe1786089b87402a24fc460144c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 28 Mar 2002 01:32:42 +0000 Subject: Set default inquiry length to 10 seconds. --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index aa6ac4ac..bebdfbd4 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -182,7 +182,7 @@ static void cmd_inq(int dev_id, char **opt, int nopt) if (nopt >= 1) length = atoi(opt[0]); else - length = 10; /* 10 seconds */ + length = 8; /* ~ 10 seconds */ flags = 0; if (nopt >= 2) -- cgit From 3d3b04a31ef6ff0f5c5914834207bdbd2b476e45 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 28 Mar 2002 16:10:16 +0000 Subject: VERSION is defined in Makefile. --- hcid/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hcid/main.c b/hcid/main.c index 835db2df..a1ac60c2 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -49,8 +49,6 @@ #include "hcid.h" #include "lib.h" -#define VERSION "1.1" - struct hcid_opts hcid; struct device_opts devi; -- cgit From 6f47e2dbc18f983f14795b3cd4eff10b61f53f2e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 28 Mar 2002 18:09:56 +0000 Subject: Update --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 08f12162..c4ba1f08 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,7 +15,7 @@ Jean Tourrilhes Thomas Moser Silicon Wave UART initialization. -Marcel Holtmann +Marcel Holtmann Various patches, fixes and other contributions. Nils Faerber -- cgit From 8ba7db9ede6d41211f90c076c6af86bf88600359 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 29 Mar 2002 21:36:21 +0000 Subject: Cleanup --- hcid/Makefile.am | 2 +- hcid/Makefile.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 7de921ca..d20885ac 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -7,7 +7,7 @@ sbin_PROGRAMS = hcid hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.y lexer.l kword.c hcid_LDADD = @GLIB_LDFLAGS@ -AM_CFLAGS = @GLIB_CFLAGS@ +INCLUDES = @GLIB_CFLAGS@ YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h diff --git a/hcid/Makefile.in b/hcid/Makefile.in index 981cfd9f..4f8abc86 100644 --- a/hcid/Makefile.in +++ b/hcid/Makefile.in @@ -87,7 +87,7 @@ sbin_PROGRAMS = hcid hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.y lexer.l kword.c hcid_LDADD = @GLIB_LDFLAGS@ -AM_CFLAGS = @GLIB_CFLAGS@ +INCLUDES = @GLIB_CFLAGS@ YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -- cgit From cce512eea00c814fc3770c438e76d7d24e15c82f Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 2 Apr 2002 01:43:17 +0000 Subject: Update --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index ff460a29..ca404535 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +ver 2.0-pre8: + Additional hciconfig commands. Support for ACL and SCO MTU ioctls. + Support for Inventel and COM1 UART based devices. + Minor hcitool fixes. + Improved l2test. New L2CAP test modes. + Minor cleanup. + ver 2.0-pre7: Bluetooth utilities is now a separate package. New build environment uses automake. -- cgit From 37edbea43464d12dfbe0fb4a4f5114c8fed6fd11 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 5 Apr 2002 21:47:35 +0000 Subject: Socket CF card support --- pcmcia/bluetooth.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index ca48419d..1088d73f 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -24,3 +24,7 @@ device "dtl1_cs" card "Nokia Bluetooth Card DTL-1" version "Nokia Mobile Phones", "DTL-1" bind "dtl1_cs" + +card "Socket CF+ Personal Network Card" + version "Socket", "CF+ Personal Network Card" + bind "dtl1_cs" -- cgit From 06d1825aa28c8d3a6d99cbb9a7cf71cef15af029 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Apr 2002 11:20:50 +0000 Subject: Cleanup and all known cards added --- pcmcia/bluetooth.conf | 56 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 1088d73f..29414bfa 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -1,30 +1,64 @@ -card "Brain Boxes BL-620 Bluetooth Adapter" - version "Brain Boxes", "Bluetooth PC Card" - bind "serial_cs" +device "dtl1_cs" + module "dtl1_cs" + +device "bluecard_cs" + module "bluecard_cs" + +device "bt3c_cs" + module "bt3c_cs" + -card "Xircom CreditCard CBT Bluetooth Adapter" +card "Xircom CreditCard Bluetooth Adapter" version "Xircom", "*", "CBT" bind "serial_cs" -card "3Com Bluetooth PC Card" - version "3COM", "*", "Bluetooth PC Card" +card "Xircom RealPort2 Bluetooth Adapter" + version "Xircom", "*", "R2BT" + bind "serial_cs" + +card "Brain Boxes BL-620 Bluetooth Adapter" + version "Brain Boxes", "Bluetooth PC Card" bind "serial_cs" card "COM One Platinium Bluetooth PC Card" version "COM1 SA", "MC310 CARD" bind "serial_cs" -card "Sphinx PICO Bluetooth Card" +card "AmbiCom BT2000E Bluetooth PC/CF Card" + version "AmbiCom,Inc", "BT2000E" + bind "serial_cs" + +card "Sphinx PICO Card" version "SPHINX", "BT-CARD" bind "serial_cs" -device "dtl1_cs" - module "dtl1_cs" +card "H-Soft blue+Card" + version "H-Soft", "Blue+CARD" + bind "serial_cs" + +card "Compaq iPAQ Bluetooth Sleeve" + version "CF CARD", "GENERIC" + bind "serial_cs" + -card "Nokia Bluetooth Card DTL-1" +card "Nokia Bluetooth Card" version "Nokia Mobile Phones", "DTL-1" bind "dtl1_cs" -card "Socket CF+ Personal Network Card" +card "Socket Bluetooth Card" version "Socket", "CF+ Personal Network Card" bind "dtl1_cs" + + +card "LSE041 Bluetooth PC Card" + version "BlueCard", "LSE041" + bind "bluecard_cs" + +card "LSE039 Bluetooth Compact Flash Card" + version "WSS", "LSE039" + bind "bluecard_cs" + + +card "3Com Bluetooth PC Card" + version "3COM", "*", "Bluetooth PC Card" + bind "bt3c_cs" -- cgit From 4962b360716e1fd17a4f3cbddc7a305b4fd24668 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 9 Apr 2002 18:13:05 +0000 Subject: Added scan and rev commands. --- tools/hcitool.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index bebdfbd4..70e4b56d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -107,6 +107,55 @@ static int dev_info(int dev_id, long arg) return 0; } +static int rev_info(int dev_id, long arg) +{ + struct hci_version ver; + int dd; + + struct hci_request rq; + unsigned char buf[102]; + + + dd = hci_open_dev(dev_id); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", dev_id, strerror(errno), errno); + return -1; + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + printf("Can't read version info hci%d. %s(%d)\n", + dev_id, strerror(errno), errno); + return -1; + } + + printf("hci%d:", dev_id); + switch (ver.manufacturer) { + case 0: + memset(&rq, 0, sizeof(rq)); + rq.ogf = 0x3f; + rq.ocf = 0x000f; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("\n Can't read revision info. %s(%d)\n", + strerror(errno), errno); + return -1; + } + + printf("%s\n", buf + 1); + break; + default: + printf("\n Manufacturer not supported\n"); + break; + } + printf("\n"); + + return 0; +} + static int conn_list(int dev_id, long arg) { struct hci_conn_list_req *cl; @@ -207,6 +256,54 @@ static void cmd_inq(int dev_id, char **opt, int nopt) free(info); } +static void cmd_scan(int dev_id, char **opt, int nopt) +{ + inquiry_info *info; + int i, num_rsp = 0, length, flags; + bdaddr_t bdaddr; + int dd; + char name[248]; + + if (dev_id < 0) + dev_id = get_route(NULL); + + if (nopt >= 1) + length = atoi(opt[0]); + else + length = 8; /* ~ 10 seconds */ + + flags = 0; + if (nopt >= 2) + flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + + printf("Scanning ...\n"); + info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); + + if (!info) { + perror("Inquiry failed."); + exit(1); + } + + for (i = 0; i < num_rsp; i++) { + dd = hci_open_dev(dev_id); + memset(name, 0, sizeof(name)); + if (hci_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + close(dd); + baswap(&bdaddr, &(info+i)->bdaddr); + printf("\t%s\t%s\n", batostr(&bdaddr), name); + } + free(info); +} + +static void cmd_rev(int dev_id, char **opt, int nopt) +{ + if (dev_id < 0) + for_each_dev(HCI_UP, rev_info, 0); + else + rev_info(dev_id, 0); +} + static void cmd_con(int dev_id, char **opt, int nopt) { printf("Connections:\n"); @@ -305,8 +402,10 @@ struct { char *opt; char *doc; } command[] = { - { "dev", cmd_dev, 0, "Display local devices" }, - { "inq", cmd_inq, "[lenght] [flush]", "Inquire remote devices" }, + { "dev", cmd_dev, 0, "Display local devices" }, + { "rev", cmd_rev, 0, "Display revison information" }, + { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, + { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, { "dc", cmd_dc, "", "Disconnect from remote device" }, -- cgit From c7073a0113d641580f49b171b8ece52f59f76e15 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 11 Apr 2002 16:58:54 +0000 Subject: Support for human readble display of device features. --- tools/hciconfig.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index aca8a29d..96d4c7b4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -91,11 +91,16 @@ void print_link_mode(struct hci_dev_info *di) printf("\tLink mode: %s\n", hci_lmtostr(di->link_mode)); } -void print_dev_features(struct hci_dev_info *di) +void print_dev_features(struct hci_dev_info *di, int format) { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + if (!format) { + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", di->features[0], di->features[1], di->features[2], di->features[3] ); + } else { + printf("\tFeatures:\n%s\n", + lmp_featurestostr(di->features, "\t\t", 3)); + } } void cmd_rstat(int ctl, int hdev, char *opt) @@ -286,7 +291,7 @@ void cmd_scomtu(int ctl, int hdev, char *opt) void cmd_features(int ctl, int hdev, char *opt) { print_dev_hdr(&di); - print_dev_features(&di); + print_dev_features(&di, 1); } void cmd_name(int ctl, int hdev, char *opt) @@ -512,7 +517,7 @@ void print_dev_info(int ctl, struct hci_dev_info *di) st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); if (all) { - print_dev_features(di); + print_dev_features(di, 0); print_pkt_type(di); print_link_policy(di); print_link_mode(di); -- cgit From 386647e4e954416f41107db5438223193e8e9167 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 15 Apr 2002 16:53:01 +0000 Subject: Working X display and authentication setting --- scripts/bluepin | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/scripts/bluepin b/scripts/bluepin index db1f8196..a1c51ab2 100755 --- a/scripts/bluepin +++ b/scripts/bluepin @@ -3,28 +3,34 @@ # Bluetooth PIN helper # Written by Maxim Krasnyansky # +import sys, os, string, popen2 -import sys, os, string - -# -# FIXME: -# -# We have to find actual user and proper X display here. And if -# it's not available (no one's logged in) we should lookup some -# file for predefined PINs. -# -# For now we just assume that we have access to local X display -# and whoever is logged in there will get a window pop. +# X Display initialization. +# Find running X Server and parse it's arguments. +# Set enviroment variables DISPLAY and XAUTHORITY +# using info extracted from X Server args. # - -os.environ['DISPLAY'] = ':0' - -# For X Window display access blueping has to find a user and use -# his(her) .Xauthority file. -# os.environ['XAUTHORITY'] = '/home/maxk/.Xauthority' +def set_display(): + disp = ":0" + auth = "" + ps = "/bin/ps -C X --format args --no-headers" + + r,w = popen2.popen2(ps) + arg = string.split(r.read()) + for i in range(1, len(arg)): + if arg[i][0] != '-': + disp = arg[i] + elif arg[i] == "-auth": + auth = arg[i+1] + break + + os.environ['DISPLAY'] = disp + os.environ['XAUTHORITY'] = auth + +# Set X display before initializing GTK +set_display() from gtk import * -#import GdkImlib, GtkExtra # Dialog Class DLG_OK = 1 @@ -113,6 +119,10 @@ def dialog(title, mesg, args, modal = FALSE): return dlg.result def main(*args): + if len(sys.argv) < 2: + print "ERR" + sys.exit() + dir = sys.argv[1] bdaddr = sys.argv[2] -- cgit From 8720383cae063462a97c39f7bccdc5340a58594a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 15 Apr 2002 16:53:32 +0000 Subject: Added "info" command --- tools/hcitool.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 70e4b56d..b30d93d1 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -296,6 +296,64 @@ static void cmd_scan(int dev_id, char **opt, int nopt) free(info); } +static void cmd_info(int dev_id, char **opt, int nopt) +{ + bdaddr_t bdaddr; + uint16_t handle; + int dd; + char name[248]; + unsigned char features[8]; + struct hci_version version; + + if (nopt < 1) + return; + + baswap(&bdaddr, strtoba(opt[0])); + + if (dev_id < 0) { + dev_id = get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + printf("Requesting information ...\n"); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + printf("\tBD Address: %s\n", opt[0]); + + if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { + close(dd); + exit(1); + } + + if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + printf("\tDevice Name: %s\n", name); + + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" + "\tManufacturer: %s (%d)\n", + lmp_vertostr(version.lmp_ver), version.lmp_ver, version.lmp_subver, + bt_compidtostr(version.manufacturer), version.manufacturer); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + printf("\tFeatures:\n%s\n", + lmp_featurestostr(features, "\t\t", 3)); + } + + hci_disconnect(dd, handle, 0x13, 10000); + + close(dd); + +} + static void cmd_rev(int dev_id, char **opt, int nopt) { if (dev_id < 0) @@ -402,13 +460,14 @@ struct { char *opt; char *doc; } command[] = { - { "dev", cmd_dev, 0, "Display local devices" }, - { "rev", cmd_rev, 0, "Display revison information" }, - { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, - { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, - { "con", cmd_con, 0, "Display active connections" }, + { "dev", cmd_dev, 0, "Display local devices" }, + { "rev", cmd_rev, 0, "Display revison information" }, + { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, + { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, + { "info", cmd_info, "", "Get information from remote device" }, + { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, - { "dc", cmd_dc, "", "Disconnect from remote device" }, + { "dc", cmd_dc, "", "Disconnect from remote device" }, { NULL, NULL, 0} }; -- cgit From bcdc3df71560286f08ca6fae865a8aaad1a16ed3 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 16 Apr 2002 22:41:17 +0000 Subject: X server args parsing fix --- scripts/bluepin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bluepin b/scripts/bluepin index a1c51ab2..6246283e 100755 --- a/scripts/bluepin +++ b/scripts/bluepin @@ -18,7 +18,7 @@ def set_display(): r,w = popen2.popen2(ps) arg = string.split(r.read()) for i in range(1, len(arg)): - if arg[i][0] != '-': + if arg[i][0] != '-' and i==1: disp = arg[i] elif arg[i] == "-auth": auth = arg[i+1] -- cgit From c4f18f46436d80592fa3bd500b74737a5e349a56 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 19 Apr 2002 01:26:12 +0000 Subject: Simplified 'cmd' command --- tools/hcitool.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/tools/hcitool.c b/tools/hcitool.c index b30d93d1..b5256300 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -32,12 +32,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -48,6 +50,8 @@ extern char *optarg; static int ctl; +static void usage(void); + static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) { struct hci_dev_list_req *dl; @@ -213,6 +217,23 @@ static int find_conn(int dev_id, long arg) return 0; } +static void hex_dump(char *pref, int width, unsigned char *buf, int len) +{ + register int i,n; + + for (i=0, n=1; i 0x3f) || (htobs(ocf) > 0x3ff)) { + usage(); + return; + } + + for (i = 2, len = 0; i < nopt && len < sizeof(buf); i++, len++) + *ptr++ = (uint8_t) strtol(opt[i], NULL, 16); + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("Device open failed"); + exit(EXIT_FAILURE); + } + + /* Setup filter */ + hci_filter_clear(&flt); + hci_filter_set_ptype(HCI_EVENT_PKT, &flt); + hci_filter_all_events(&flt); + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + perror("HCI filter setup failed"); + exit(EXIT_FAILURE); + } + + printf("< HCI Command: OGF 0x%02x, OCF 0x%04x, plen %d\n", ogf, ocf, len); + hex_dump(" ", 20, buf, len); + fflush(stdout); + + if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { + perror("Send failed"); + exit(EXIT_FAILURE); + } + + len = read(dd, buf, sizeof(buf)); + if (len < 0) { + perror("Read failed"); + exit(EXIT_FAILURE); + } + + hdr = (void *)(buf + 1); + ptr = buf + (1 + HCI_EVENT_HDR_SIZE); + len -= (1 + HCI_EVENT_HDR_SIZE); + + printf("> HCI Event: 0x%02x plen %d:\n", hdr->evt, hdr->plen); + hex_dump(" ", 20, ptr, len); + fflush(stdout); + + return; +} + static void cmd_rev(int dev_id, char **opt, int nopt) { if (dev_id < 0) @@ -465,6 +555,7 @@ struct { { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, { "info", cmd_info, "", "Get information from remote device" }, + { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, { "dc", cmd_dc, "", "Disconnect from remote device" }, -- cgit From ba150fb166ed968105942dd97992be83afd4af50 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 19 Apr 2002 16:45:12 +0000 Subject: cmd_cmd cleanup --- tools/hcitool.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index b5256300..96448533 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -156,7 +156,6 @@ static int rev_info(int dev_id, long arg) break; } printf("\n"); - return 0; } @@ -185,8 +184,7 @@ static int conn_list(int dev_id, long arg) printf("\t%s %s %s handle %d state %d lm %s\n", ci->out ? "<" : ">", ci->type == ACL_LINK ? "ACL" : "SCO", - batostr(&bdaddr), ci->handle, - ci->state, + batostr(&bdaddr), ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } return 0; @@ -237,7 +235,7 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) static void cmd_dev(int dev_id, char **opt, int nopt) { printf("Devices:\n"); - for_each_dev(HCI_UP, dev_info, 0); + for_each_dev(HCI_UP, dev_info, 0); } static void cmd_inq(int dev_id, char **opt, int nopt) @@ -282,8 +280,8 @@ static void cmd_scan(int dev_id, char **opt, int nopt) inquiry_info *info; int i, num_rsp = 0, length, flags; bdaddr_t bdaddr; - int dd; char name[248]; + int dd; if (dev_id < 0) dev_id = get_route(NULL); @@ -372,7 +370,6 @@ static void cmd_info(int dev_id, char **opt, int nopt) hci_disconnect(dd, handle, 0x13, 10000); close(dd); - } static void cmd_cmd(int dev_id, char **opt, int nopt) @@ -380,9 +377,9 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; + int i, len, dd; uint16_t ocf; uint8_t ogf; - int i, len, dd; if (nopt < 2) { usage(); @@ -395,7 +392,7 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) errno = 0; ogf = strtol(opt[0], NULL, 16); ocf = strtol(opt[1], NULL, 16); - if (errno == ERANGE || (ogf > 0x3f) || (htobs(ocf) > 0x3ff)) { + if (errno == ERANGE || (ogf > 0x3f) || (ocf > 0x3ff)) { usage(); return; } @@ -418,9 +415,8 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) exit(EXIT_FAILURE); } - printf("< HCI Command: OGF 0x%02x, OCF 0x%04x, plen %d\n", ogf, ocf, len); - hex_dump(" ", 20, buf, len); - fflush(stdout); + printf("< HCI Command: ogf 0x%02x, ocf 0x%04x, plen %d\n", ogf, ocf, len); + hex_dump(" ", 20, buf, len); fflush(stdout); if (hci_send_cmd(dd, ogf, ocf, len, buf) < 0) { perror("Send failed"); @@ -437,10 +433,10 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); - printf("> HCI Event: 0x%02x plen %d:\n", hdr->evt, hdr->plen); - hex_dump(" ", 20, ptr, len); - fflush(stdout); + printf("> HCI Event: 0x%02x plen %d\n", hdr->evt, hdr->plen); + hex_dump(" ", 20, ptr, len); fflush(stdout); + hci_close_dev(dd); return; } @@ -555,7 +551,7 @@ struct { { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, { "info", cmd_info, "", "Get information from remote device" }, - { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, + { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, { "con", cmd_con, 0, "Display active connections" }, { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, { "dc", cmd_dc, "", "Disconnect from remote device" }, -- cgit From 996b96baf78a1e77e94c08f391e00a8bc7822955 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 19 Apr 2002 20:04:13 +0000 Subject: New improved argument processing. --- tools/hcitool.c | 397 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 313 insertions(+), 84 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 96448533..35509f22 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -48,6 +49,8 @@ extern int optind,opterr,optopt; extern char *optarg; +#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) + static int ctl; static void usage(void); @@ -232,29 +235,79 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) printf("\n"); } -static void cmd_dev(int dev_id, char **opt, int nopt) +/* Display local devices */ + +static struct option dev_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *dev_help = + "Usage:\n" + "\tdev\n"; + +static void cmd_dev(int dev_id, int argc, char **argv) { + int opt; + for_each_opt(opt, dev_options, NULL) { + switch(opt) { + default: + printf(dev_help); + return; + } + } + printf("Devices:\n"); for_each_dev(HCI_UP, dev_info, 0); } -static void cmd_inq(int dev_id, char **opt, int nopt) +/* Inquiry */ + +static struct option inq_options[] = { + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, + {0, 0, 0, 0} +}; + +static char *inq_help = + "Usage:\n" + "\tinq [--length=N] [--numrsp=N] [--flush]\n"; + +static void cmd_inq(int dev_id, int argc, char **argv) { + int num_rsp, length, flags; inquiry_info *info; - int i, num_rsp = 0, length, flags; bdaddr_t bdaddr; - - if (dev_id < 0) - dev_id = get_route(NULL); - - if (nopt >= 1) - length = atoi(opt[0]); - else - length = 8; /* ~ 10 seconds */ + int i, opt; + length = 8; /* ~10 seconds */ + num_rsp = 10; flags = 0; - if (nopt >= 2) - flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + + for_each_opt(opt, inq_options, NULL) { + switch(opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; + + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf(inq_help); + return; + } + } + + if (dev_id < 0) + dev_id = get_route(NULL); printf("Inquiring ...\n"); info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); @@ -275,25 +328,54 @@ static void cmd_inq(int dev_id, char **opt, int nopt) free(info); } -static void cmd_scan(int dev_id, char **opt, int nopt) +/* Device scanning */ + +static struct option scan_options[] = { + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, + {0, 0, 0, 0} +}; + +static char *scan_help = + "Usage:\n" + "\tscan [--length=N] [--numrsp=N] [--flush]\n"; + +static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info; - int i, num_rsp = 0, length, flags; + int num_rsp, length, flags; bdaddr_t bdaddr; char name[248]; - int dd; + int i, opt, dd; - if (dev_id < 0) - dev_id = get_route(NULL); + length = 8; /* ~10 seconds */ + num_rsp = 10; + flags = 0; - if (nopt >= 1) - length = atoi(opt[0]); - else - length = 8; /* ~ 10 seconds */ + for_each_opt(opt, scan_options, NULL) { + switch(opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; - flags = 0; - if (nopt >= 2) - flags |= !strncasecmp("f", opt[1], 1) ? IREQ_CACHE_FLUSH : 0; + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf(scan_help); + return; + } + } + + if (dev_id < 0) + dev_id = get_route(NULL); printf("Scanning ...\n"); info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); @@ -315,19 +397,42 @@ static void cmd_scan(int dev_id, char **opt, int nopt) free(info); } -static void cmd_info(int dev_id, char **opt, int nopt) +/* Info about remote device */ + +static struct option info_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *info_help = + "Usage:\n" + "\tinfo \n"; + +static void cmd_info(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; uint16_t handle; - int dd; char name[248]; unsigned char features[8]; struct hci_version version; + int opt, dd; + + for_each_opt(opt, info_options, NULL) { + switch(opt) { + default: + printf(info_help); + return; + } + } + argc -= optind; + argv += optind; - if (nopt < 1) + if (argc < 1) { + printf(info_help); return; + } - baswap(&bdaddr, strtoba(opt[0])); + baswap(&bdaddr, strtoba(argv[0])); if (dev_id < 0) { dev_id = get_route(&bdaddr); @@ -345,7 +450,7 @@ static void cmd_info(int dev_id, char **opt, int nopt) exit(1); } - printf("\tBD Address: %s\n", opt[0]); + printf("\tBD Address: %s\n", argv[0]); if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { close(dd); @@ -372,17 +477,40 @@ static void cmd_info(int dev_id, char **opt, int nopt) close(dd); } -static void cmd_cmd(int dev_id, char **opt, int nopt) +/* Send arbitrary HCI commands */ + +static struct option cmd_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *cmd_help = + "Usage:\n" + "\tcmd [parameters]\n" + "Example:\n" + "\tcmd 0x03 0x0013 0x41 0x42 0x43 0x44\n"; + +static void cmd_cmd(int dev_id, int argc, char **argv) { char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; - int i, len, dd; + int i, opt, len, dd; uint16_t ocf; uint8_t ogf; - if (nopt < 2) { - usage(); + for_each_opt(opt, cmd_options, NULL) { + switch(opt) { + default: + printf(cmd_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + printf(cmd_help); return; } @@ -390,15 +518,15 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) dev_id = get_route(NULL); errno = 0; - ogf = strtol(opt[0], NULL, 16); - ocf = strtol(opt[1], NULL, 16); + ogf = strtol(argv[0], NULL, 16); + ocf = strtol(argv[1], NULL, 16); if (errno == ERANGE || (ogf > 0x3f) || (ocf > 0x3ff)) { - usage(); + printf(cmd_help); return; } - for (i = 2, len = 0; i < nopt && len < sizeof(buf); i++, len++) - *ptr++ = (uint8_t) strtol(opt[i], NULL, 16); + for (i = 2, len = 0; i < argc && len < sizeof(buf); i++, len++) + *ptr++ = (uint8_t) strtol(argv[i], NULL, 16); dd = hci_open_dev(dev_id); if (dd < 0) { @@ -440,16 +568,58 @@ static void cmd_cmd(int dev_id, char **opt, int nopt) return; } -static void cmd_rev(int dev_id, char **opt, int nopt) +/* Display revision info */ + +static struct option rev_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *rev_help = + "Usage:\n" + "\trev\n"; + +static void cmd_rev(int dev_id, int argc, char **argv) { + int opt; + + for_each_opt(opt, rev_options, NULL) { + switch(opt) { + default: + printf(rev_help); + return; + } + } + if (dev_id < 0) for_each_dev(HCI_UP, rev_info, 0); else rev_info(dev_id, 0); } -static void cmd_con(int dev_id, char **opt, int nopt) +/* Display active connections */ + +static struct option con_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *con_help = + "Usage:\n" + "\tcon\n"; + +static void cmd_con(int dev_id, int argc, char **argv) { + int opt; + + for_each_opt(opt, con_options, NULL) { + switch(opt) { + default: + printf(con_help); + return; + } + } + printf("Connections:\n"); if (dev_id < 0) for_each_dev(HCI_UP, conn_list, 0); @@ -457,17 +627,56 @@ static void cmd_con(int dev_id, char **opt, int nopt) conn_list(dev_id, 0); } -static void cmd_cc(int dev_id, char **opt, int nopt) +/* Create connection */ + +static struct option cc_options[] = { + {"help", 0,0, 'h'}, + {"role", 1,0, 'r'}, + {"ptype", 1,0, 'p'}, + {0, 0, 0, 0} +}; + +static char *cc_help = + "Usage:\n" + "\tcc [--role=m|s] [--ptype=pkt_types] \n" + "Example:\n" + "\tcc --ptype=dm1,dh3,dh5 01:02:03:04:05:06\n" + "\tcc --role=m 01:02:03:04:05:06\n"; + +static void cmd_cc(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; - int ptype, dd; + int opt, ptype, dd; uint16_t handle; uint8_t role; - if (nopt < 1) + role = 0; + ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; + + for_each_opt(opt, cc_options, NULL) { + switch(opt) { + case 'p': + hci_strtoptype(optarg, &ptype); + break; + + case 'r': + role = optarg[0] == 'm' ? 0 : 1; + break; + + default: + printf(cc_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(cc_help); return; + } - baswap(&bdaddr, strtoba(opt[0])); + str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = get_route(&bdaddr); @@ -483,31 +692,43 @@ static void cmd_cc(int dev_id, char **opt, int nopt) exit(1); } - if (nopt >= 2) - hci_strtoptype(opt[1], &ptype); - else - ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; - - if (nopt >= 3) - role = !strncasecmp("m", opt[2], 1) ? 0 : 1; - else - role = 0; - hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000); - hci_close_dev(dd); } -static void cmd_dc(int dev_id, char **opt, int nopt) +/* Close connection */ + +static struct option dc_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *dc_help = + "Usage:\n" + "\tdc \n"; + +static void cmd_dc(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; - int dd; + int opt, dd; + + for_each_opt(opt, dc_options, NULL) { + switch(opt) { + default: + printf(dc_help); + return; + } + } + argc -= optind; + argv += optind; - if (nopt < 1) + if (argc < 1) { + printf(dc_help); return; + } - baswap(&bdaddr, strtoba(*opt)); + str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); @@ -542,19 +763,18 @@ static void cmd_dc(int dev_id, char **opt, int nopt) struct { char *cmd; - void (*func)(int dev_id, char **opt, int nopt); - char *opt; + void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { - { "dev", cmd_dev, 0, "Display local devices" }, - { "rev", cmd_rev, 0, "Display revison information" }, - { "inq", cmd_inq, "[length] [flush]", "Inquire remote devices" }, - { "scan", cmd_scan, "[length] [flush]", "Scan for remote devices" }, - { "info", cmd_info, "", "Get information from remote device" }, - { "cmd", cmd_cmd, " [param]", "Submit arbitrary HCI commands" }, - { "con", cmd_con, 0, "Display active connections" }, - { "cc", cmd_cc, " [pkt type] [role]", "Create connection to remote device" }, - { "dc", cmd_dc, "", "Disconnect from remote device" }, + { "dev", cmd_dev, "Display local devices" }, + { "rev", cmd_rev, "Display revison information" }, + { "inq", cmd_inq, "Inquire remote devices" }, + { "scan", cmd_scan, "Scan for remote devices" }, + { "info", cmd_info, "Get information from remote device" }, + { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, + { "con", cmd_con, "Display active connections" }, + { "cc", cmd_cc, "Create connection to remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, { NULL, NULL, 0} }; @@ -564,24 +784,30 @@ static void usage(void) printf("hcitool - HCI Tool\n"); printf("Usage:\n" - "\thcitool [-i hciX] [command]\n"); + "\thcitool [options] [command parameters]\n"); + printf("Options:\n" + "\t--help\tDisplay help\n" + "\t-i dev\tHCI device\n"); printf("Commands:\n"); for (i=0; command[i].cmd; i++) - printf("\t%-4s %-20s\t%s\n", command[i].cmd, - command[i].opt ? command[i].opt : " ", + printf("\t%-4s\t%s\n", command[i].cmd, command[i].doc); } -int main(int argc, char *argv[], char *env[]) +static struct option main_options[] = { + {"help", 0,0, 'h'}, + {"device", 1,0, 'i'}, + {0, 0, 0, 0} +}; + +int main(int argc, char **argv) { int opt, i, dev_id = -1; - char *dev; - while ((opt=getopt(argc, argv, "i:h")) != EOF) { + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { case 'i': - dev = strdup(optarg); - dev_id = atoi(dev + 3); + dev_id = atoi(optarg + 3); break; case 'h': @@ -591,22 +817,25 @@ int main(int argc, char *argv[], char *env[]) } } - if (argc - optind < 1) { + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { usage(); exit(0); } - /* Open HCI socket */ + /* Open HCI socket */ if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { perror("Can't open HCI socket."); exit(1); } for (i=0; command[i].cmd; i++) { - if (strncmp(command[i].cmd, argv[optind], 3)) + if (strncmp(command[i].cmd, argv[0], 3)) continue; - optind++; - command[i].func(dev_id, argv + optind, argc - optind); + command[i].func(dev_id, argc, argv); break; } -- cgit From 98f6f92be002a098fb4f3b773939ab7c94834a0d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 22 Apr 2002 20:16:27 +0000 Subject: Display feature bytes in hex --- tools/hciconfig.c | 4 +++- tools/hcitool.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 96d4c7b4..21f7bc1c 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -98,7 +98,9 @@ void print_dev_features(struct hci_dev_info *di, int format) di->features[0], di->features[1], di->features[2], di->features[3] ); } else { - printf("\tFeatures:\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + di->features[0], di->features[1], + di->features[2], di->features[3], lmp_featurestostr(di->features, "\t\t", 3)); } } diff --git a/tools/hcitool.c b/tools/hcitool.c index 35509f22..06c426ca 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -468,7 +468,8 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { - printf("\tFeatures:\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + features[0], features[1], features[2], features[3], lmp_featurestostr(features, "\t\t", 3)); } -- cgit From d65d0510cd20a55a08b64f476714b229c5436396 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 22 Apr 2002 20:43:10 +0000 Subject: Argument parsing fixes --- tools/hciconfig.c | 38 +++++++++++++++++++++++++------------- tools/hcitool.c | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 21f7bc1c..4b4844ff 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -580,55 +581,66 @@ void usage(void) command[i].doc); } -int main(int argc, char *argv[], char *env[]) +static struct option main_options[] = { + {"help", 0,0, 'h'}, + {"all", 0,0, 'a'}, + {0, 0, 0, 0} +}; + +int main(int argc, char **argv, char **env) { int opt, ctl, i, cmd=0; - char *dev; - while ((opt=getopt(argc, argv,"ha")) != EOF) { + while ((opt=getopt_long(argc, argv, "ah", main_options, NULL)) != -1) { switch(opt) { case 'a': all = 1; break; + case 'h': + default: usage(); exit(0); } } + argc -= optind; + argv += optind; + optind = 0; + /* Open HCI socket */ if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { perror("Can't open HCI socket."); exit(1); } - if (argc - optind < 1) { + if (argc < 1) { print_dev_list(ctl, 0); exit(0); } - dev = strdup(argv[optind]); - di.dev_id = atoi(argv[optind]+3); - optind++; + di.dev_id = atoi(argv[0] + 3); + argc--; argv++; if (ioctl(ctl, HCIGETDEVINFO, (void*)&di)) { perror("Can't get device info"); exit(1); } - while (optind < argc) { + while (argc > 0) { for (i=0; command[i].cmd; i++) { - if (strncmp(command[i].cmd, argv[optind],4)) + if (strncmp(command[i].cmd, *argv, 4)) continue; - if (command[i].opt) - optind++; + if (command[i].opt) { + argc--; argv++; + } - command[i].func(ctl, di.dev_id, argv[optind]); + command[i].func(ctl, di.dev_id, *argv); cmd = 1; break; } - optind++; + argc--; argv++; } if (!cmd) diff --git a/tools/hcitool.c b/tools/hcitool.c index 06c426ca..8ec564d7 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -783,7 +783,7 @@ static void usage(void) { int i; - printf("hcitool - HCI Tool\n"); + printf("hcitool - HCI Tool ver %s\n", VERSION); printf("Usage:\n" "\thcitool [options] [command parameters]\n"); printf("Options:\n" -- cgit From c050960ed60a1adb9e2b3278490d34c46482bd98 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 1 May 2002 00:38:37 +0000 Subject: update --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index ca404535..b1e6cada 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +ver 2.0-pre9: + Improved bluepin. Working X authentication. + Improved hcitool. New flexible cmd syntax, additional commands. + Human readable display of the device features. + ver 2.0-pre8: Additional hciconfig commands. Support for ACL and SCO MTU ioctls. Support for Inventel and COM1 UART based devices. -- cgit From 095e2ef25275e4682b9c1a51d6f9f233f0360d18 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 2 May 2002 20:54:47 +0000 Subject: Added "name" command. --- tools/hcitool.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tools/hcitool.c b/tools/hcitool.c index 8ec564d7..f6a98610 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -397,6 +397,61 @@ static void cmd_scan(int dev_id, int argc, char **argv) free(info); } +/* Remote name */ + +static struct option name_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *name_help = + "Usage:\n" + "\tname \n"; + +static void cmd_name(int dev_id, int argc, char **argv) +{ + bdaddr_t bdaddr; + char name[248]; + int opt, dd; + + for_each_opt(opt, name_options, NULL) { + switch(opt) { + default: + printf(name_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(name_help); + return; + } + + baswap(&bdaddr, strtoba(argv[0])); + + if (dev_id < 0) { + dev_id = get_route(&bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Device is not available.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + printf("%s\n", name); + + close(dd); + +} + /* Info about remote device */ static struct option info_options[] = { @@ -771,6 +826,7 @@ struct { { "rev", cmd_rev, "Display revison information" }, { "inq", cmd_inq, "Inquire remote devices" }, { "scan", cmd_scan, "Scan for remote devices" }, + { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, -- cgit From 79095069d348e61dc26c6fa6e35428c5d90887ff Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 3 May 2002 22:15:02 +0000 Subject: Bluetooth rc script for Debian distro. --- scripts/Makefile.am | 2 +- scripts/Makefile.in | 2 +- scripts/bluetooth.rc.deb | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100755 scripts/bluetooth.rc.deb diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 12f32c78..117c3186 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -15,4 +15,4 @@ redhat: debian: $(mkinstalldirs) $(DESTDIR)/etc/init.d - $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)/etc/init.d/bluetooth + $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.deb $(DESTDIR)/etc/init.d/bluetooth diff --git a/scripts/Makefile.in b/scripts/Makefile.in index d750a69c..ccc6f79f 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -220,7 +220,7 @@ redhat: debian: $(mkinstalldirs) $(DESTDIR)/etc/init.d - $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)/etc/init.d/bluetooth + $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.deb $(DESTDIR)/etc/init.d/bluetooth # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/scripts/bluetooth.rc.deb b/scripts/bluetooth.rc.deb new file mode 100755 index 00000000..36892187 --- /dev/null +++ b/scripts/bluetooth.rc.deb @@ -0,0 +1,60 @@ +#! /bin/sh +# +# bluetooth Bluetooth subsystem starting and stopping +# +# Edd Dumbill + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +DAEMON=/sbin/hcid +HCIATTACH=/sbin/hciattach +UART_CONF=/etc/bluetooth/uart +NAME=hcid +DESC=bluez-utils + +test -f $DAEMON || exit 0 +test -f $HCIATTACH || exit 0 + +set -e + +start_uarts() +{ + [ -f $HCIATTACH -a -f $UART_CONF ] || return + grep -v '^#' $UART_CONF | while read i; do + $HCIATTACH $i + done +} + +stop_uarts() +{ + killall hciattach > /dev/null 2>&1 || true +} + +case "$1" in + start) + echo -n "Starting $DESC: " + $DAEMON + echo "$NAME." + start_uarts || true + ;; + stop) + echo -n "Stopping $DESC: " + killall $NAME || true + echo "$NAME." + stop_uarts + ;; + restart|force-reload) + echo -n "Restarting $DESC: " + killall $NAME || true + sleep 1 + $DAEMON + echo "$NAME." + ;; + *) + N=/etc/init.d/bluez-utils + # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $N {start|stop|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 -- cgit From 6446efe312e0410efc4c45dc68f5d980755f0666 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 8 May 2002 17:00:05 +0000 Subject: Use hci_test_bit instead of (1<flags & (1 << HCI_UP)) { + if (hci_test_bit(HCI_UP, &di->flags)) { cmd_name(ctl, di->dev_id, NULL); cmd_class(ctl, di->dev_id, NULL); cmd_version(ctl, di->dev_id, NULL); diff --git a/tools/hcitool.c b/tools/hcitool.c index f6a98610..68d4aa7a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -78,7 +78,7 @@ static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) return -1; for (i=0; i < dl->dev_num; i++, dr++) { - if (dr->dev_opt & (1<dev_opt)) { if (!func || func(dr->dev_id, arg)) return dr->dev_id; } -- cgit From c1df5fbb4f48cfdd3cd4a566a0836889aa6e8458 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 8 May 2002 17:41:10 +0000 Subject: RSSI support. --- tools/hcitool.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tools/hcitool.c b/tools/hcitool.c index 68d4aa7a..5ac90657 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -817,6 +817,91 @@ static void cmd_dc(int dev_id, int argc, char **argv) free(cr); } +/* Read RSSI */ + +static struct option rssi_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *rssi_help = + "Usage:\n" + "\trssi \n"; + +static void cmd_rssi(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_rssi_rp rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, rssi_options, NULL) { + switch(opt) { + default: + printf(rssi_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(rssi_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_RSSI_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + printf("Can't read RSSI hci%d. %s(%d)\n", + dd, strerror(errno), errno); + exit(1); + } + + if (rp.status) { + printf("Read RSSI on hci%d returned (error) status 0x%2.2X\n", + dd, rp.status); + exit(1); + } + printf( "\tRSSI return value: %d\n", rp.rssi); + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -832,6 +917,7 @@ struct { { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, + { "rssi", cmd_rssi, "Display connection RSSI" }, { NULL, NULL, 0} }; -- cgit From 6524a7f07a5b73e2b34a5b8feeb8b4c4ff1fd385 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 9 May 2002 16:31:11 +0000 Subject: Add XFree86 to the list X servers that we look for. --- scripts/bluepin | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/bluepin b/scripts/bluepin index 6246283e..aa1a0f3c 100755 --- a/scripts/bluepin +++ b/scripts/bluepin @@ -11,9 +11,10 @@ import sys, os, string, popen2 # using info extracted from X Server args. # def set_display(): - disp = ":0" + disp = ":0" auth = "" - ps = "/bin/ps -C X --format args --no-headers" + proc = "-C X -C XFree86" + ps = "/bin/ps " + proc + " --format args --no-headers" r,w = popen2.popen2(ps) arg = string.split(r.read()) -- cgit From 7ef138d4d8d5042f9feaae9fb3bb3a4a947d8582 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 13 May 2002 18:45:11 +0000 Subject: make file cleanup --- configure | 115 +++++++++++++++++++++++++++++------------------------- configure.in | 9 +++-- tools/Makefile.am | 8 +--- tools/Makefile.in | 67 +++++++++++++++++++++---------- 4 files changed, 115 insertions(+), 84 deletions(-) diff --git a/configure b/configure index 82644521..fa0617ec 100755 --- a/configure +++ b/configure @@ -16,6 +16,8 @@ ac_help="$ac_help --with-bluez-libs=DIR BlueZ libraries and header files" ac_help="$ac_help --with-glib=DIR GLib libraries and header files" +ac_help="$ac_help +--enable-pcmcia Always install PCMCIA support files" # Initialize some variables set by options. # The variables have the same names as the options, with @@ -584,7 +586,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:588: checking host system type" >&5 +echo "configure:590: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -605,7 +607,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:609: checking target system type" >&5 +echo "configure:611: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -623,7 +625,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:627: checking build system type" >&5 +echo "configure:629: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -652,7 +654,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:656: checking host system type" >&5 +echo "configure:658: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -685,7 +687,7 @@ echo "$ac_t""$host" 1>&6 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:689: checking for a BSD compatible install" >&5 +echo "configure:691: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -738,7 +740,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:742: checking whether build environment is sane" >&5 +echo "configure:744: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -795,7 +797,7 @@ test "$program_suffix" != NONE && test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:799: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:801: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -841,7 +843,7 @@ EOF missing_dir=`cd $ac_aux_dir && pwd` echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 -echo "configure:845: checking for working aclocal" >&5 +echo "configure:847: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -854,7 +856,7 @@ else fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:858: checking for working autoconf" >&5 +echo "configure:860: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -867,7 +869,7 @@ else fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 -echo "configure:871: checking for working automake" >&5 +echo "configure:873: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -880,7 +882,7 @@ else fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:884: checking for working autoheader" >&5 +echo "configure:886: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -893,7 +895,7 @@ else fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:897: checking for working makeinfo" >&5 +echo "configure:899: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -910,7 +912,7 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:914: checking for $ac_word" >&5 +echo "configure:916: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -940,7 +942,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:944: checking for $ac_word" >&5 +echo "configure:946: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -991,7 +993,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:995: checking for $ac_word" >&5 +echo "configure:997: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1023,7 +1025,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1027: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1029: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -1034,12 +1036,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 1038 "configure" +#line 1040 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:1043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1065,12 +1067,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1069: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1071: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1074: checking whether we are using GNU C" >&5 +echo "configure:1076: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1079,7 +1081,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1085: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1098,7 +1100,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1102: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1104: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1134,7 +1136,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1138: checking for $ac_word" >&5 +echo "configure:1140: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1175,7 +1177,7 @@ done # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1179: checking for a BSD compatible install" >&5 +echo "configure:1181: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1236,7 +1238,7 @@ fi # Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. set dummy ${ac_tool_prefix}ld; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1240: checking for $ac_word" >&5 +echo "configure:1242: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1268,7 +1270,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ld", so it can be a program name with args. set dummy ld; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1272: checking for $ac_word" >&5 +echo "configure:1274: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1303,7 +1305,7 @@ fi # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1307: checking for $ac_word" >&5 +echo "configure:1309: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1335,7 +1337,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1339: checking for $ac_word" >&5 +echo "configure:1341: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1373,7 +1375,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1377: checking for $ac_word" >&5 +echo "configure:1379: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1404,7 +1406,7 @@ done test -n "$YACC" || YACC="yacc" echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1408: checking how to run the C preprocessor" >&5 +echo "configure:1410: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1419,13 +1421,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1429: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1431: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1436,13 +1438,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1446: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1448: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1453,13 +1455,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1465: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1489,7 +1491,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1493: checking for $ac_word" >&5 +echo "configure:1495: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1522,7 +1524,7 @@ test -n "$LEX" || LEX=""$missing_dir/missing flex"" # Extract the first word of "flex", so it can be a program name with args. set dummy flex; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1526: checking for $ac_word" >&5 +echo "configure:1528: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1556,7 +1558,7 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:1560: checking for yywrap in -l$ac_lib" >&5 +echo "configure:1562: checking for yywrap in -l$ac_lib" >&5 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1564,7 +1566,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1598,7 +1600,7 @@ fi fi echo $ac_n "checking lex output file root""... $ac_c" 1>&6 -echo "configure:1602: checking lex output file root" >&5 +echo "configure:1604: checking lex output file root" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1619,7 +1621,7 @@ echo "$ac_t""$ac_cv_prog_lex_root" 1>&6 LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6 -echo "configure:1623: checking whether yytext is a pointer" >&5 +echo "configure:1625: checking whether yytext is a pointer" >&5 if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1631,14 +1633,14 @@ echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c ac_save_LIBS="$LIBS" LIBS="$LIBS $LEXLIB" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_prog_lex_yytext_pointer=yes else @@ -1678,7 +1680,7 @@ fi echo $ac_n "checking "for bluetooth.h"""... $ac_c" 1>&6 -echo "configure:1682: checking "for bluetooth.h"" >&5 +echo "configure:1684: checking "for bluetooth.h"" >&5 ac_hdr_found=no for p in $BLUEZ_INCDIR; do @@ -1715,7 +1717,7 @@ echo "configure:1682: checking "for bluetooth.h"" >&5 echo $ac_n "checking "for libbluetooth"""... $ac_c" 1>&6 -echo "configure:1719: checking "for libbluetooth"" >&5 +echo "configure:1721: checking "for libbluetooth"" >&5 ac_save_LDFLAGS=$LDFLAGS @@ -1723,7 +1725,7 @@ echo "configure:1719: checking "for libbluetooth"" >&5 for p in $BLUEZ_LIBDIR; do LDFLAGS="-L$p -lbluetooth" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* LIBS="$LIBS -L$p -lbluetooth" ac_lib_found=yes @@ -1773,7 +1775,7 @@ else # Extract the first word of "glib-config", so it can be a program name with args. set dummy glib-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1777: checking for $ac_word" >&5 +echo "configure:1779: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_GLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1823,7 +1825,7 @@ fi # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1827: checking for a BSD compatible install" >&5 +echo "configure:1829: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1902,17 +1904,24 @@ if test "$cross_compiling" != yes; then fi -if test "$cross_compiling" != yes; then - +# Check whether --enable-pcmcia or --disable-pcmcia was given. +if test "${enable_pcmcia+set}" = set; then + enableval="$enable_pcmcia" + PCMCIA=pcmcia +else + if test "$cross_compiling" != yes; then + if test -d /etc/pcmcia; then PCMCIA=pcmcia else PCMCIA= fi + fi fi + for i in CFLAGS CPPFLAGS LDFLAGS LIBS; do eval o=\$$i o=`echo $o | sed 's#.\.\./#&../#g'` diff --git a/configure.in b/configure.in index 6de2df29..21515cbd 100644 --- a/configure.in +++ b/configure.in @@ -82,9 +82,12 @@ if test "$cross_compiling" != yes; then fi dnl Check for PCMCIA -if test "$cross_compiling" != yes; then - AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=) -fi +AC_ARG_ENABLE(pcmcia, + --enable-pcmcia Always install PCMCIA support files, + [PCMCIA=pcmcia], + [ if test "$cross_compiling" != yes; then + AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=) + fi ]) AC_ADD_DIRLEVEL(CFLAGS CPPFLAGS LDFLAGS LIBS) diff --git a/tools/Makefile.am b/tools/Makefile.am index 53e3e21d..f8312834 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -9,10 +9,4 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -CLEANFILES = l2test.o l2test - - -all-local: l2test - -l2test: l2test.o - $(LINK) l2test.o $(LDFLAGS) $(LIBS) +noinst_PROGRAMS = l2test scotest diff --git a/tools/Makefile.in b/tools/Makefile.in index fae41912..9070c880 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -88,10 +88,10 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -CLEANFILES = l2test.o l2test +noinst_PROGRAMS = l2test scotest mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = -PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) DEFS = @DEFS@ -I. -I$(srcdir) @@ -108,6 +108,16 @@ l2ping_OBJECTS = l2ping.o l2ping_LDADD = $(LDADD) l2ping_DEPENDENCIES = l2ping_LDFLAGS = +l2test_SOURCES = l2test.c +l2test_OBJECTS = l2test.o +l2test_LDADD = $(LDADD) +l2test_DEPENDENCIES = +l2test_LDFLAGS = +scotest_SOURCES = scotest.c +scotest_OBJECTS = scotest.o +scotest_LDADD = $(LDADD) +scotest_DEPENDENCIES = +scotest_LDFLAGS = hciattach_SOURCES = hciattach.c hciattach_OBJECTS = hciattach.o hciattach_LDADD = $(LDADD) @@ -134,9 +144,9 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = gtar GZIP_ENV = --best DEP_FILES = .deps/hciattach.P .deps/hciconfig.P .deps/hcitool.P \ -.deps/l2ping.P -SOURCES = hcitool.c l2ping.c hciattach.c hciconfig.c -OBJECTS = hcitool.o l2ping.o hciattach.o hciconfig.o +.deps/l2ping.P .deps/l2test.P .deps/scotest.P +SOURCES = hcitool.c l2ping.c l2test.c scotest.c hciattach.c hciconfig.c +OBJECTS = hcitool.o l2ping.o l2test.o scotest.o hciattach.o hciconfig.o all: all-redirect .SUFFIXES: @@ -174,6 +184,15 @@ uninstall-binPROGRAMS: rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done +mostlyclean-noinstPROGRAMS: + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +distclean-noinstPROGRAMS: + +maintainer-clean-noinstPROGRAMS: + mostlyclean-sbinPROGRAMS: clean-sbinPROGRAMS: @@ -223,6 +242,14 @@ l2ping: $(l2ping_OBJECTS) $(l2ping_DEPENDENCIES) @rm -f l2ping $(LINK) $(l2ping_LDFLAGS) $(l2ping_OBJECTS) $(l2ping_LDADD) $(LIBS) +l2test: $(l2test_OBJECTS) $(l2test_DEPENDENCIES) + @rm -f l2test + $(LINK) $(l2test_LDFLAGS) $(l2test_OBJECTS) $(l2test_LDADD) $(LIBS) + +scotest: $(scotest_OBJECTS) $(scotest_DEPENDENCIES) + @rm -f scotest + $(LINK) $(scotest_LDFLAGS) $(scotest_OBJECTS) $(scotest_LDADD) $(LIBS) + hciattach: $(hciattach_OBJECTS) $(hciattach_DEPENDENCIES) @rm -f hciattach $(LINK) $(hciattach_LDFLAGS) $(hciattach_OBJECTS) $(hciattach_LDADD) $(LIBS) @@ -370,7 +397,7 @@ install-am: all-am install: install-am uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS uninstall-man uninstall: uninstall-am -all-am: Makefile $(PROGRAMS) $(MANS) all-local +all-am: Makefile $(PROGRAMS) $(MANS) all-redirect: all-am install-strip: $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install @@ -382,31 +409,32 @@ installdirs: mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -rm -f Makefile $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log stamp-h stamp-h[0-9]* maintainer-clean-generic: -mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-sbinPROGRAMS \ - mostlyclean-compile mostlyclean-tags mostlyclean-depend \ - mostlyclean-generic +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \ + mostlyclean-sbinPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-depend mostlyclean-generic mostlyclean: mostlyclean-am -clean-am: clean-binPROGRAMS clean-sbinPROGRAMS clean-compile clean-tags \ - clean-depend clean-generic mostlyclean-am +clean-am: clean-binPROGRAMS clean-noinstPROGRAMS clean-sbinPROGRAMS \ + clean-compile clean-tags clean-depend clean-generic \ + mostlyclean-am clean: clean-am -distclean-am: distclean-binPROGRAMS distclean-sbinPROGRAMS \ - distclean-compile distclean-tags distclean-depend \ - distclean-generic clean-am +distclean-am: distclean-binPROGRAMS distclean-noinstPROGRAMS \ + distclean-sbinPROGRAMS distclean-compile distclean-tags \ + distclean-depend distclean-generic clean-am distclean: distclean-am maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-noinstPROGRAMS \ maintainer-clean-sbinPROGRAMS maintainer-clean-compile \ maintainer-clean-tags maintainer-clean-depend \ maintainer-clean-generic distclean-am @@ -417,6 +445,8 @@ maintainer-clean: maintainer-clean-am .PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ +clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS clean-sbinPROGRAMS \ maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ install-sbinPROGRAMS mostlyclean-compile distclean-compile \ @@ -426,16 +456,11 @@ clean-tags maintainer-clean-tags distdir mostlyclean-depend \ distclean-depend clean-depend maintainer-clean-depend info-am info \ dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-local all-redirect all-am all installdirs \ +uninstall-am uninstall all-redirect all-am all installdirs \ mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean -all-local: l2test - -l2test: l2test.o - $(LINK) l2test.o $(LDFLAGS) $(LIBS) - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: -- cgit From 8f32a0237d9eae5ab56916424bb1e7580be28db1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 13 May 2002 18:55:25 +0000 Subject: usage clarification --- tools/hcitool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/hcitool.c b/tools/hcitool.c index 5ac90657..67cd7987 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -935,6 +935,9 @@ static void usage(void) for (i=0; command[i].cmd; i++) printf("\t%-4s\t%s\n", command[i].cmd, command[i].doc); + printf("\n" + "For more information on the usage of each command use:\n" + "\thcitool --help\n" ); } static struct option main_options[] = { -- cgit From f7ab1ef143abdee16036e23e8cdf19d999d84916 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 13 May 2002 18:58:04 +0000 Subject: update --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index c4ba1f08..a918375f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -20,3 +20,6 @@ Marcel Holtmann Nils Faerber Man pages. + +Martin Leopold + Various patches and fixes. -- cgit From cbc274c6e3ce3b2135c21c101d19271d66d3215e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 17 May 2002 00:42:43 +0000 Subject: First bring device up then init everything else. --- hcid/main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hcid/main.c b/hcid/main.c index a1ac60c2..8f6ec8bc 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -163,6 +163,13 @@ static void init_device(int hdev) exit(1); } + /* Start HCI device */ + if (ioctl(s, HCIDEVUP, hdev) < 0 && errno != EALREADY) { + syslog(LOG_ERR, "Can't init device hci%d. %s(%d)\n", hdev, + strerror(errno), errno); + exit(1); + } + dr.dev_id = hdev; /* Set packet type */ @@ -192,13 +199,6 @@ static void init_device(int hdev) } } - /* Start HCI device */ - if (ioctl(s, HCIDEVUP, hdev) < 0 && errno != EALREADY) { - syslog(LOG_ERR, "Can't init device hci%d. %s(%d)\n", hdev, - strerror(errno), errno); - exit(1); - } - exit(0); } @@ -226,10 +226,10 @@ static void init_all_devices(int ctl) if (hcid.auto_init) init_device(dr->dev_id); - if (hcid.auto_init && (dr->dev_opt & (1<dev_opt)) configure_device(dr->dev_id); - if (hcid.security && (dr->dev_opt & (1<dev_opt)) start_security_manager(dr->dev_id); } -- cgit From c7057958d5fbf7fa82745b5ab75844723def24ab Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 17 May 2002 01:01:13 +0000 Subject: Fix "make dist". --- Makefile.am | 2 +- Makefile.in | 2 +- configure | 54 ++++++++++++++++++++++++++--------------------------- configure.in | 12 ++++++------ hcid/Makefile.am | 2 +- hcid/Makefile.in | 2 +- pcmcia/Makefile.am | 4 +++- pcmcia/Makefile.in | 2 ++ scripts/Makefile.am | 2 ++ scripts/Makefile.in | 2 ++ tools/Makefile.am | 2 ++ tools/Makefile.in | 2 ++ 12 files changed, 50 insertions(+), 38 deletions(-) diff --git a/Makefile.am b/Makefile.am index 17255ef5..4c73270a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,6 +2,6 @@ # $Id$ # -EXTRA_DIST = ChangeLog README CREDITS +EXTRA_DIST = ChangeLog README SUBDIRS = hcid tools scripts pcmcia diff --git a/Makefile.in b/Makefile.in index 03dcae4e..b9a21653 100644 --- a/Makefile.in +++ b/Makefile.in @@ -82,7 +82,7 @@ PCMCIA = @PCMCIA@ VERSION = @VERSION@ YACC = @YACC@ -EXTRA_DIST = ChangeLog README CREDITS +EXTRA_DIST = ChangeLog README SUBDIRS = hcid tools scripts pcmcia ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 diff --git a/configure b/configure index fa0617ec..cb27f9a2 100755 --- a/configure +++ b/configure @@ -529,16 +529,6 @@ fi - - - - - - -CFLAGS="-Wall -g -O2" - - - ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then @@ -586,7 +576,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:590: checking host system type" >&5 +echo "configure:580: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -607,7 +597,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:611: checking target system type" >&5 +echo "configure:601: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -625,7 +615,7 @@ target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:629: checking build system type" >&5 +echo "configure:619: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -654,7 +644,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:658: checking host system type" >&5 +echo "configure:648: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -687,7 +677,7 @@ echo "$ac_t""$host" 1>&6 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:691: checking for a BSD compatible install" >&5 +echo "configure:681: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -740,7 +730,7 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:744: checking whether build environment is sane" >&5 +echo "configure:734: checking whether build environment is sane" >&5 # Just in case sleep 1 echo timestamp > conftestfile @@ -797,7 +787,7 @@ test "$program_suffix" != NONE && test "$program_transform_name" = "" && program_transform_name="s,x,x," echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:801: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:791: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -826,7 +816,7 @@ fi PACKAGE=bluez-utils -VERSION=1.0 +VERSION=2.0 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } @@ -843,7 +833,7 @@ EOF missing_dir=`cd $ac_aux_dir && pwd` echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 -echo "configure:847: checking for working aclocal" >&5 +echo "configure:837: checking for working aclocal" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -856,7 +846,7 @@ else fi echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:860: checking for working autoconf" >&5 +echo "configure:850: checking for working autoconf" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -869,7 +859,7 @@ else fi echo $ac_n "checking for working automake""... $ac_c" 1>&6 -echo "configure:873: checking for working automake" >&5 +echo "configure:863: checking for working automake" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -882,7 +872,7 @@ else fi echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:886: checking for working autoheader" >&5 +echo "configure:876: checking for working autoheader" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -895,7 +885,7 @@ else fi echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:899: checking for working makeinfo" >&5 +echo "configure:889: checking for working makeinfo" >&5 # Run test in a subshell; some versions of sh will print an error if # an executable is not found, even if stderr is redirected. # Redirect stdin to placate older versions of autoconf. Sigh. @@ -909,6 +899,16 @@ fi + + + + + + +CFLAGS="-Wall -g -O2" + + + # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 @@ -2074,10 +2074,6 @@ s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g -s%@DISTRO@%$DISTRO%g -s%@PCMCIA@%$PCMCIA%g -s%@GLIB_CFLAGS@%$GLIB_CFLAGS%g -s%@GLIB_LDFLAGS@%$GLIB_LDFLAGS%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g @@ -2104,6 +2100,10 @@ s%@AUTOMAKE@%$AUTOMAKE%g s%@AUTOHEADER@%$AUTOHEADER%g s%@MAKEINFO@%$MAKEINFO%g s%@SET_MAKE@%$SET_MAKE%g +s%@DISTRO@%$DISTRO%g +s%@PCMCIA@%$PCMCIA%g +s%@GLIB_CFLAGS@%$GLIB_CFLAGS%g +s%@GLIB_LDFLAGS@%$GLIB_LDFLAGS%g s%@CC@%$CC%g s%@AWK@%$AWK%g s%@LD@%$LD%g diff --git a/configure.in b/configure.in index 21515cbd..27330f61 100644 --- a/configure.in +++ b/configure.in @@ -5,6 +5,12 @@ dnl Process this file with autoconf to produce a configure script. dnl AC_INIT() +dnl Guess host type. +AC_CANONICAL_SYSTEM +AC_CANONICAL_HOST + +AM_INIT_AUTOMAKE(bluez-utils, 2.0) + AC_SUBST(DISTRO) AC_SUBST(PCMCIA) @@ -15,12 +21,6 @@ CFLAGS="-Wall -g -O2" AC_PREFIX_DEFAULT() -dnl Guess host type. -AC_CANONICAL_SYSTEM -AC_CANONICAL_HOST - -AM_INIT_AUTOMAKE(bluez-utils, 1.0) - dnl Check for programs. AC_PROG_CC AC_PROG_AWK diff --git a/hcid/Makefile.am b/hcid/Makefile.am index d20885ac..59358cec 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -4,7 +4,7 @@ sbin_PROGRAMS = hcid -hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.y lexer.l kword.c +hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c hcid_LDADD = @GLIB_LDFLAGS@ INCLUDES = @GLIB_CFLAGS@ diff --git a/hcid/Makefile.in b/hcid/Makefile.in index 4f8abc86..f21d31b8 100644 --- a/hcid/Makefile.in +++ b/hcid/Makefile.in @@ -84,7 +84,7 @@ YACC = @YACC@ sbin_PROGRAMS = hcid -hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.y lexer.l kword.c +hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c hcid_LDADD = @GLIB_LDFLAGS@ INCLUDES = @GLIB_CFLAGS@ diff --git a/pcmcia/Makefile.am b/pcmcia/Makefile.am index 3664b3e7..485bb06b 100644 --- a/pcmcia/Makefile.am +++ b/pcmcia/Makefile.am @@ -2,7 +2,9 @@ # $Id$ # -pcmciadir = /etc/pcmcia +pcmciadir = /etc/pcmcia + +EXTRA_DIST = bluetooth bluetooth.conf install-data-local: @PCMCIA@ diff --git a/pcmcia/Makefile.in b/pcmcia/Makefile.in index ed120814..d8fbc707 100644 --- a/pcmcia/Makefile.in +++ b/pcmcia/Makefile.in @@ -83,6 +83,8 @@ VERSION = @VERSION@ YACC = @YACC@ pcmciadir = /etc/pcmcia + +EXTRA_DIST = bluetooth bluetooth.conf mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = DIST_COMMON = Makefile.am Makefile.in diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 117c3186..4d86094a 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -4,6 +4,8 @@ bin_SCRIPTS = bluepin +EXTRA_DIST = bluepin bluetooth.rc.rh bluetooth.rc.deb + install-data-local: @DISTRO@ unknown: diff --git a/scripts/Makefile.in b/scripts/Makefile.in index ccc6f79f..a6e9f552 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -83,6 +83,8 @@ VERSION = @VERSION@ YACC = @YACC@ bin_SCRIPTS = bluepin + +EXTRA_DIST = bluepin bluetooth.rc.rh bluetooth.rc.deb mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = SCRIPTS = $(bin_SCRIPTS) diff --git a/tools/Makefile.am b/tools/Makefile.am index f8312834..c1a82d7f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -10,3 +10,5 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 noinst_PROGRAMS = l2test scotest + +EXTRA_DIST = $(man_MANS) diff --git a/tools/Makefile.in b/tools/Makefile.in index 9070c880..794cfeca 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -89,6 +89,8 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 noinst_PROGRAMS = l2test scotest + +EXTRA_DIST = $(man_MANS) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) -- cgit From b9d072d8c187426e925356dc5fdc143f6a19d4bb Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 18 May 2002 00:50:26 +0000 Subject: Change connection packet type support. --- tools/hcitool.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 5 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 67cd7987..7f7cf1de 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -878,6 +878,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; rq.cparam = &cr->conn_info->handle; @@ -886,22 +887,101 @@ static void cmd_rssi(int dev_id, int argc, char **argv) rq.rlen = READ_RSSI_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { - printf("Can't read RSSI hci%d. %s(%d)\n", - dd, strerror(errno), errno); + perror("Read RSSI failed"); exit(1); } if (rp.status) { - printf("Read RSSI on hci%d returned (error) status 0x%2.2X\n", - dd, rp.status); + printf("Read RSSI returned (error) status 0x%2.2X\n", rp.status); exit(1); } - printf( "\tRSSI return value: %d\n", rp.rssi); + printf("\tRSSI return value: %d\n", rp.rssi); close(dd); free(cr); } +/* Set connection packet type */ + +static struct option cpt_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *cpt_help = + "Usage:\n" + "\tcpt \n"; + +static void cmd_cpt(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + set_conn_ptype_cp cp; + bdaddr_t bdaddr; + int opt, dd, ptype; + + for_each_opt(opt, cpt_options, NULL) { + switch(opt) { + default: + printf(cpt_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + printf(cpt_help); + return; + } + + str2ba(argv[0], &bdaddr); + hci_strtoptype(argv[1], &ptype); + + if (dev_id < 0) { + dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = cr->conn_info->handle; + cp.pkt_type = ptype; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; + rq.cparam = &cp; + rq.clen = SET_CONN_PTYPE_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("Packet type change failed"); + exit(1); + } + + close(dd); + free(cr); +} + + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -917,6 +997,7 @@ struct { { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, + { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { NULL, NULL, 0} }; -- cgit From d8ab2999e595a6cf7e853c881d1716c7262fe74a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 23 May 2002 20:56:51 +0000 Subject: help output improvements --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 7f7cf1de..8ce64ed6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -273,7 +273,9 @@ static struct option inq_options[] = { static char *inq_help = "Usage:\n" - "\tinq [--length=N] [--numrsp=N] [--flush]\n"; + "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" + "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--flush] flush the inquiry cache\n"; static void cmd_inq(int dev_id, int argc, char **argv) { -- cgit From e4108aa9ba79bc6e898fa1581e2c4a56a68ad10d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 23 May 2002 20:57:19 +0000 Subject: Build env cleanup. Remove auto generated files from CVS. Working 'make distcheck'. --- Makefile.in | 342 -------- acinclude.m4 | 11 +- aclocal.m4 | 11 +- bootstrap | 2 + configure | 2228 --------------------------------------------------- hcid/Makefile.am | 13 +- hcid/Makefile.in | 363 --------- pcmcia/Makefile.in | 200 ----- scripts/Makefile.in | 229 ------ tools/Makefile.in | 468 ----------- 10 files changed, 30 insertions(+), 3837 deletions(-) delete mode 100644 Makefile.in create mode 100755 bootstrap delete mode 100755 configure delete mode 100644 hcid/Makefile.in delete mode 100644 pcmcia/Makefile.in delete mode 100644 scripts/Makefile.in delete mode 100644 tools/Makefile.in diff --git a/Makefile.in b/Makefile.in deleted file mode 100644 index b9a21653..00000000 --- a/Makefile.in +++ /dev/null @@ -1,342 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in 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. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# -# $Id$ -# - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = . - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_alias = @build_alias@ -build_triplet = @build@ -host_alias = @host_alias@ -host_triplet = @host@ -target_alias = @target_alias@ -target_triplet = @target@ -AR = @AR@ -AWK = @AWK@ -CC = @CC@ -DISTRO = @DISTRO@ -GLIB = @GLIB@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_LDFLAGS = @GLIB_LDFLAGS@ -LD = @LD@ -LEX = @LEX@ -MAKEINFO = @MAKEINFO@ -PACKAGE = @PACKAGE@ -PCMCIA = @PCMCIA@ -VERSION = @VERSION@ -YACC = @YACC@ - -EXTRA_DIST = ChangeLog README - -SUBDIRS = hcid tools scripts pcmcia -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ -Makefile.in NEWS acinclude.m4 aclocal.m4 config.guess config.sub \ -configure configure.in install-sh missing mkinstalldirs - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -all: all-redirect -.SUFFIXES: -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) - cd $(top_builddir) \ - && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status - -$(ACLOCAL_M4): configure.in acinclude.m4 - cd $(srcdir) && $(ACLOCAL) - -config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck -$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) - cd $(srcdir) && $(AUTOCONF) - -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. - -@SET_MAKE@ - -all-recursive install-data-recursive install-exec-recursive \ -installdirs-recursive install-recursive uninstall-recursive \ -check-recursive installcheck-recursive info-recursive dvi-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ - rev="$$subdir $$rev"; \ - test "$$subdir" != "." || dot_seen=yes; \ - done; \ - test "$$dot_seen" = "no" && rev=". $$rev"; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) - -mostlyclean-tags: - -clean-tags: - -distclean-tags: - -rm -f TAGS ID - -maintainer-clean-tags: - -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - -rm -rf $(distdir) - GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz - mkdir $(distdir)/=build - mkdir $(distdir)/=inst - dc_install_base=`cd $(distdir)/=inst && pwd`; \ - cd $(distdir)/=build \ - && ../configure --srcdir=.. --prefix=$$dc_install_base \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) dist - -rm -rf $(distdir) - @banner="$(distdir).tar.gz is ready for distribution"; \ - dashes=`echo "$$banner" | sed s/./=/g`; \ - echo "$$dashes"; \ - echo "$$banner"; \ - echo "$$dashes" -dist: distdir - -chmod -R a+r $(distdir) - GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) - -rm -rf $(distdir) -dist-all: distdir - -chmod -R a+r $(distdir) - GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) - -rm -rf $(distdir) -distdir: $(DISTFILES) - -rm -rf $(distdir) - mkdir $(distdir) - -chmod 777 $(distdir) - here=`cd $(top_builddir) && pwd`; \ - top_distdir=`cd $(distdir) && pwd`; \ - distdir=`cd $(distdir) && pwd`; \ - cd $(top_srcdir) \ - && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done - for subdir in $(SUBDIRS); do \ - if test "$$subdir" = .; then :; else \ - test -d $(distdir)/$$subdir \ - || mkdir $(distdir)/$$subdir \ - || exit 1; \ - chmod 777 $(distdir)/$$subdir; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ - || exit 1; \ - fi; \ - done -info-am: -info: info-recursive -dvi-am: -dvi: dvi-recursive -check-am: all-am -check: check-recursive -installcheck-am: -installcheck: installcheck-recursive -install-exec-am: -install-exec: install-exec-recursive - -install-data-am: -install-data: install-data-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-recursive -uninstall-am: -uninstall: uninstall-recursive -all-am: Makefile -all-redirect: all-recursive -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: installdirs-recursive -installdirs-am: - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-tags mostlyclean-generic - -mostlyclean: mostlyclean-recursive - -clean-am: clean-tags clean-generic mostlyclean-am - -clean: clean-recursive - -distclean-am: distclean-tags distclean-generic clean-am - -distclean: distclean-recursive - -rm -f config.status - -maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ - distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-recursive - -rm -f config.status - -.PHONY: install-data-recursive uninstall-data-recursive \ -install-exec-recursive uninstall-exec-recursive installdirs-recursive \ -uninstalldirs-recursive all-recursive check-recursive \ -installcheck-recursive info-recursive dvi-recursive \ -mostlyclean-recursive distclean-recursive clean-recursive \ -maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ -distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ -dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ -install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs-am \ -installdirs mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/acinclude.m4 b/acinclude.m4 index 1dc30479..96c9617a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -78,7 +78,16 @@ AC_DEFUN( AC_SEARCH_LIB, ac_lib_found=no for p in $3; do - LDFLAGS="-L$p -l$1" + test -d $p || continue; + + # Check for libtool library + if test -f $p/lib$1.la; then + path=$p/.libs + else + path=$p + fi + + LDFLAGS="-L$path -l$1" AC_TRY_LINK_FUNC($2, [ LIBS="$LIBS -L$p -l$1" diff --git a/aclocal.m4 b/aclocal.m4 index 7b89b4b2..fadd44eb 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -90,7 +90,16 @@ AC_DEFUN( AC_SEARCH_LIB, ac_lib_found=no for p in $3; do - LDFLAGS="-L$p -l$1" + test -d $p || continue; + + # Check for libtool library + if test -f $p/lib$1.la; then + path=$p/.libs + else + path=$p + fi + + LDFLAGS="-L$path -l$1" AC_TRY_LINK_FUNC($2, [ LIBS="$LIBS -L$p -l$1" diff --git a/bootstrap b/bootstrap new file mode 100755 index 00000000..019a160f --- /dev/null +++ b/bootstrap @@ -0,0 +1,2 @@ +#! /bin/sh +aclocal && automake --copy --add-missing && autoconf diff --git a/configure b/configure deleted file mode 100755 index cb27f9a2..00000000 --- a/configure +++ /dev/null @@ -1,2228 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.13 -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: -ac_default_prefix= -ac_help="$ac_help ---with-bluez-libs=DIR BlueZ libraries and header files" -ac_help="$ac_help ---with-glib=DIR GLib libraries and header files" -ac_help="$ac_help ---enable-pcmcia Always install PCMCIA support files" - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} -# Maximum number of lines to put in a shell here document. -ac_max_here_lines=12 - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.13" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set these to C if already set. These must not be set unconditionally -# because not all systems understand e.g. LANG=C (notably SCO). -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! -# Non-C LC_CTYPE values break the ctype check. -if test "${LANG+set}" = set; then LANG=C; export LANG; fi -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi -if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file= - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -ac_exeext= -ac_objext=o -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - - -ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } -fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. - - -# Do some error checking and defaulting for the host and target type. -# The inputs are: -# configure --host=HOST --target=TARGET --build=BUILD NONOPT -# -# The rules are: -# 1. You are not allowed to specify --host, --target, and nonopt at the -# same time. -# 2. Host defaults to nonopt. -# 3. If nonopt is not specified, then host defaults to the current host, -# as determined by config.guess. -# 4. Target and build default to nonopt. -# 5. If nonopt is not specified, then target and build default to host. - -# The aliases save the names the user supplied, while $host etc. -# will get canonicalized. -case $host---$target---$nonopt in -NONE---*---* | *---NONE---* | *---*---NONE) ;; -*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;; -esac - - -# Make sure we can run config.sub. -if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : -else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } -fi - -echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:580: checking host system type" >&5 - -host_alias=$host -case "$host_alias" in -NONE) - case $nonopt in - NONE) - if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : - else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } - fi ;; - *) host_alias=$nonopt ;; - esac ;; -esac - -host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` -host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -echo "$ac_t""$host" 1>&6 - -echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:601: checking target system type" >&5 - -target_alias=$target -case "$target_alias" in -NONE) - case $nonopt in - NONE) target_alias=$host_alias ;; - *) target_alias=$nonopt ;; - esac ;; -esac - -target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` -target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -echo "$ac_t""$target" 1>&6 - -echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:619: checking build system type" >&5 - -build_alias=$build -case "$build_alias" in -NONE) - case $nonopt in - NONE) build_alias=$host_alias ;; - *) build_alias=$nonopt ;; - esac ;; -esac - -build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` -build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -echo "$ac_t""$build" 1>&6 - -test "$host_alias" != "$target_alias" && - test "$program_prefix$program_suffix$program_transform_name" = \ - NONENONEs,x,x, && - program_prefix=${target_alias}- - - -# Make sure we can run config.sub. -if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : -else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } -fi - -echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:648: checking host system type" >&5 - -host_alias=$host -case "$host_alias" in -NONE) - case $nonopt in - NONE) - if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : - else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } - fi ;; - *) host_alias=$nonopt ;; - esac ;; -esac - -host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` -host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -echo "$ac_t""$host" 1>&6 - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:681: checking for a BSD compatible install" >&5 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_IFS" - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL="$ac_install_sh" - fi -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:734: checking whether build environment is sane" >&5 -# Just in case -sleep 1 -echo timestamp > conftestfile -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftestfile` - fi - if test "$*" != "X $srcdir/configure conftestfile" \ - && test "$*" != "X conftestfile $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - { echo "configure: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" 1>&2; exit 1; } - fi - - test "$2" = conftestfile - ) -then - # Ok. - : -else - { echo "configure: error: newly created file is older than distributed files! -Check your system clock" 1>&2; exit 1; } -fi -rm -f conftest* -echo "$ac_t""yes" 1>&6 -if test "$program_transform_name" = s,x,x,; then - program_transform_name= -else - # Double any \ or $. echo might interpret backslashes. - cat <<\EOF_SED > conftestsed -s,\\,\\\\,g; s,\$,$$,g -EOF_SED - program_transform_name="`echo $program_transform_name|sed -f conftestsed`" - rm -f conftestsed -fi -test "$program_prefix" != NONE && - program_transform_name="s,^,${program_prefix},; $program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" - -# sed with no file args requires a program. -test "$program_transform_name" = "" && program_transform_name="s,x,x," - -echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:791: checking whether ${MAKE-make} sets \${MAKE}" >&5 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftestmake <<\EOF -all: - @echo 'ac_maketemp="${MAKE}"' -EOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` -if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes -else - eval ac_cv_prog_make_${ac_make}_set=no -fi -rm -f conftestmake -fi -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$ac_t""yes" 1>&6 - SET_MAKE= -else - echo "$ac_t""no" 1>&6 - SET_MAKE="MAKE=${MAKE-make}" -fi - - -PACKAGE=bluez-utils - -VERSION=2.0 - -if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then - { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } -fi -cat >> confdefs.h <> confdefs.h <&6 -echo "configure:837: checking for working aclocal" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (aclocal --version) < /dev/null > /dev/null 2>&1; then - ACLOCAL=aclocal - echo "$ac_t""found" 1>&6 -else - ACLOCAL="$missing_dir/missing aclocal" - echo "$ac_t""missing" 1>&6 -fi - -echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:850: checking for working autoconf" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (autoconf --version) < /dev/null > /dev/null 2>&1; then - AUTOCONF=autoconf - echo "$ac_t""found" 1>&6 -else - AUTOCONF="$missing_dir/missing autoconf" - echo "$ac_t""missing" 1>&6 -fi - -echo $ac_n "checking for working automake""... $ac_c" 1>&6 -echo "configure:863: checking for working automake" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (automake --version) < /dev/null > /dev/null 2>&1; then - AUTOMAKE=automake - echo "$ac_t""found" 1>&6 -else - AUTOMAKE="$missing_dir/missing automake" - echo "$ac_t""missing" 1>&6 -fi - -echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:876: checking for working autoheader" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (autoheader --version) < /dev/null > /dev/null 2>&1; then - AUTOHEADER=autoheader - echo "$ac_t""found" 1>&6 -else - AUTOHEADER="$missing_dir/missing autoheader" - echo "$ac_t""missing" 1>&6 -fi - -echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:889: checking for working makeinfo" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (makeinfo --version) < /dev/null > /dev/null 2>&1; then - MAKEINFO=makeinfo - echo "$ac_t""found" 1>&6 -else - MAKEINFO="$missing_dir/missing makeinfo" - echo "$ac_t""missing" 1>&6 -fi - - - - - - - - - -CFLAGS="-Wall -g -O2" - - - -# Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:916: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:946: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_prog_rejected=no - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - break - fi - done - IFS="$ac_save_ifs" -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$ac_dir/$ac_word" "$@" - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - if test -z "$CC"; then - case "`uname -s`" in - *win32* | *WIN32*) - # Extract the first word of "cl", so it can be a program name with args. -set dummy cl; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:997: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="cl" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - ;; - esac - fi - test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -fi - -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1029: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -cat > conftest.$ac_ext << EOF - -#line 1040 "configure" -#include "confdefs.h" - -main(){return(0);} -EOF -if { (eval echo configure:1045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cc_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then - ac_cv_prog_cc_cross=no - else - ac_cv_prog_cc_cross=yes - fi -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_prog_cc_works=no -fi -rm -fr conftest* -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 -if test $ac_cv_prog_cc_works = no; then - { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } -fi -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1071: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 -echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 -cross_compiling=$ac_cv_prog_cc_cross - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1076: checking whether we are using GNU C" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 - -if test $ac_cv_prog_gcc = yes; then - GCC=yes -else - GCC= -fi - -ac_test_CFLAGS="${CFLAGS+set}" -ac_save_CFLAGS="$CFLAGS" -CFLAGS= -echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1104: checking whether ${CC-cc} accepts -g" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_cc_g=yes -else - ac_cv_prog_cc_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi - -for ac_prog in gawk mawk nawk awk -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1140: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_AWK="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -AWK="$ac_cv_prog_AWK" -if test -n "$AWK"; then - echo "$ac_t""$AWK" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$AWK" && break -done - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1181: checking for a BSD compatible install" >&5 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_IFS" - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL="$ac_install_sh" - fi -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -if test $host != $build; then - ac_tool_prefix=${host_alias}- -else - ac_tool_prefix= -fi - -# Extract the first word of "${ac_tool_prefix}ld", so it can be a program name with args. -set dummy ${ac_tool_prefix}ld; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1242: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$LD"; then - ac_cv_prog_LD="$LD" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_LD="${ac_tool_prefix}ld" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -LD="$ac_cv_prog_LD" -if test -n "$LD"; then - echo "$ac_t""$LD" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - -if test -z "$ac_cv_prog_LD"; then -if test -n "$ac_tool_prefix"; then - # Extract the first word of "ld", so it can be a program name with args. -set dummy ld; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1274: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$LD"; then - ac_cv_prog_LD="$LD" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_LD="ld" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_LD" && ac_cv_prog_LD="ld" -fi -fi -LD="$ac_cv_prog_LD" -if test -n "$LD"; then - echo "$ac_t""$LD" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -else - LD="ld" -fi -fi - -# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1309: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_AR="${ac_tool_prefix}ar" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -AR="$ac_cv_prog_AR" -if test -n "$AR"; then - echo "$ac_t""$AR" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - -if test -z "$ac_cv_prog_AR"; then -if test -n "$ac_tool_prefix"; then - # Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1341: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_AR="ar" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" -fi -fi -AR="$ac_cv_prog_AR" -if test -n "$AR"; then - echo "$ac_t""$AR" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -else - AR="ar" -fi -fi - - -for ac_prog in 'bison -y' byacc -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1379: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$YACC"; then - ac_cv_prog_YACC="$YACC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_YACC="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -YACC="$ac_cv_prog_YACC" -if test -n "$YACC"; then - echo "$ac_t""$YACC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$YACC" && break -done -test -n "$YACC" || YACC="yacc" - -echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1410: checking how to run the C preprocessor" >&5 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then -if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # This must be in double quotes, not single quotes, because CPP may get - # substituted into the Makefile and "${CC-cc}" will confuse make. - CPP="${CC-cc} -E" - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1431: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP="${CC-cc} -E -traditional-cpp" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1448: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP="${CC-cc} -nologo -E" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1465: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP=/lib/cpp -fi -rm -f conftest* -fi -rm -f conftest* -fi -rm -f conftest* - ac_cv_prog_CPP="$CPP" -fi - CPP="$ac_cv_prog_CPP" -else - ac_cv_prog_CPP="$CPP" -fi -echo "$ac_t""$CPP" 1>&6 - -missing_dir=`cd $ac_aux_dir && pwd` -for ac_prog in flex lex -do -# Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1495: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$LEX"; then - ac_cv_prog_LEX="$LEX" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_LEX="$ac_prog" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -LEX="$ac_cv_prog_LEX" -if test -n "$LEX"; then - echo "$ac_t""$LEX" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -test -n "$LEX" && break -done -test -n "$LEX" || LEX=""$missing_dir/missing flex"" - -# Extract the first word of "flex", so it can be a program name with args. -set dummy flex; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1528: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$LEX"; then - ac_cv_prog_LEX="$LEX" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_LEX="flex" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex" -fi -fi -LEX="$ac_cv_prog_LEX" -if test -n "$LEX"; then - echo "$ac_t""$LEX" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$LEXLIB" -then - case "$LEX" in - flex*) ac_lib=fl ;; - *) ac_lib=l ;; - esac - echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:1562: checking for yywrap in -l$ac_lib" >&5 -ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-l$ac_lib $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - LEXLIB="-l$ac_lib" -else - echo "$ac_t""no" 1>&6 -fi - -fi - -echo $ac_n "checking lex output file root""... $ac_c" 1>&6 -echo "configure:1604: checking lex output file root" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_lex_root'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # The minimal lex program is just a single line: %%. But some broken lexes -# (Solaris, I think it was) want two %% lines, so accommodate them. -echo '%% -%%' | $LEX -if test -f lex.yy.c; then - ac_cv_prog_lex_root=lex.yy -elif test -f lexyy.c; then - ac_cv_prog_lex_root=lexyy -else - { echo "configure: error: cannot find output from $LEX; giving up" 1>&2; exit 1; } -fi -fi - -echo "$ac_t""$ac_cv_prog_lex_root" 1>&6 -LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root - -echo $ac_n "checking whether yytext is a pointer""... $ac_c" 1>&6 -echo "configure:1625: checking whether yytext is a pointer" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_lex_yytext_pointer'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # POSIX says lex can declare yytext either as a pointer or an array; the -# default is implementation-dependent. Figure out which it is, since -# not all implementations provide the %pointer and %array declarations. -ac_cv_prog_lex_yytext_pointer=no -echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c -ac_save_LIBS="$LIBS" -LIBS="$LIBS $LEXLIB" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - ac_cv_prog_lex_yytext_pointer=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 -fi -rm -f conftest* -LIBS="$ac_save_LIBS" -rm -f "${LEX_OUTPUT_ROOT}.c" - -fi - -echo "$ac_t""$ac_cv_prog_lex_yytext_pointer" 1>&6 -if test $ac_cv_prog_lex_yytext_pointer = yes; then - cat >> confdefs.h <<\EOF -#define YYTEXT_POINTER 1 -EOF - -fi - - -# Check whether --with-bluez-libs or --without-bluez-libs was given. -if test "${with_bluez_libs+set}" = set; then - withval="$with_bluez_libs" - - BLUEZ_INCDIR="$withval"/include - BLUEZ_LIBDIR="$withval"/src/.libs - -else - - BLUEZ_INCDIR='../libs/include ../bluez-libs*/include /usr/include/bluetooth' - BLUEZ_LIBDIR='../libs/src/.libs ../bluez-libs*/src/.libs /usr/lib' - - -fi - - - - echo $ac_n "checking "for bluetooth.h"""... $ac_c" 1>&6 -echo "configure:1684: checking "for bluetooth.h"" >&5 - ac_hdr_found=no - for p in $BLUEZ_INCDIR; do - - ac_file_found=yes - for f in bluetooth.h; do - if test ! -f $p/$f; then - ac_file_found=no - break; - fi - done - - if test "$ac_file_found" = "yes" ; then - - ac_hdr_found=yes - break - - - else - : - fi - - done - if test "$ac_hdr_found" = "yes" ; then - CPPFLAGS="$CPPFLAGS -I$p" - echo "$ac_t""($p) yes " 1>&6 - : - else - echo "$ac_t"""no"" 1>&6 - { echo "configure: error: Bluetooth headers not found. - Please install bluez-libs package." 1>&2; exit 1; } - - fi - - - - echo $ac_n "checking "for libbluetooth"""... $ac_c" 1>&6 -echo "configure:1721: checking "for libbluetooth"" >&5 - - ac_save_LDFLAGS=$LDFLAGS - - ac_lib_found=no - for p in $BLUEZ_LIBDIR; do - LDFLAGS="-L$p -lbluetooth" - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - LIBS="$LIBS -L$p -lbluetooth" - ac_lib_found=yes - break - - -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 -fi -rm -f conftest* - done - if test "$ac_lib_found" = "yes" ; then - echo "$ac_t""($p) yes " 1>&6 - : - else - echo "$ac_t"""no"" 1>&6 - { echo "configure: error: Bluetooth library not found. - Please compile and install bluez-libs package." 1>&2; exit 1; } - - fi - - LDFLAGS=$ac_save_LDFLAGS - - -# Check whether --with-glib or --without-glib was given. -if test "${with_glib+set}" = set; then - withval="$with_glib" - - GLIB_CFLAGS="-I$withval" - GLIB_LDFLAGS="-L$withval/.libs -lglib" - -else - - echo "$ac_t"""checking for GLib ..."" 1>&6 - # Extract the first word of "glib-config", so it can be a program name with args. -set dummy glib-config; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1779: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_GLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$GLIB"; then - ac_cv_prog_GLIB="$GLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_GLIB="yes" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_GLIB" && ac_cv_prog_GLIB="not found" -fi -fi -GLIB="$ac_cv_prog_GLIB" -if test -n "$GLIB"; then - echo "$ac_t""$GLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - if test "$GLIB" = "yes"; then - GLIB_CFLAGS="`glib-config --cflags`" - GLIB_LDFLAGS="`glib-config --libs`" - else - { echo "configure: error: GLib not found" 1>&2; exit 1; } - fi - - -fi - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1829: checking for a BSD compatible install" >&5 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_IFS" - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL="$ac_install_sh" - fi -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - -DISTRO=unknown - -if test "$cross_compiling" != yes; then - - if test -f /etc/redhat-release; then - DISTRO=redhat - else - : - fi - - - if test -f /etc/mandrake-release; then - DISTRO=redhat - else - : - fi - - - if test -f /etc/debian_version; then - DISTRO=debian - else - : - fi - -fi - -# Check whether --enable-pcmcia or --disable-pcmcia was given. -if test "${enable_pcmcia+set}" = set; then - enableval="$enable_pcmcia" - PCMCIA=pcmcia -else - if test "$cross_compiling" != yes; then - - if test -d /etc/pcmcia; then - PCMCIA=pcmcia - else - PCMCIA= - fi - - fi -fi - - - - for i in CFLAGS CPPFLAGS LDFLAGS LIBS; do - eval o=\$$i - o=`echo $o | sed 's#.\.\./#&../#g'` - eval $i=\$o - done - - -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g -s%\[%\\&%g -s%\]%\\&%g -s%\$%$$%g -EOF -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` -rm -f conftest.defs - - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS </dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.13" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir -ac_given_INSTALL="$INSTALL" - -trap 'rm -fr `echo "Makefile hcid/Makefile tools/Makefile scripts/Makefile pcmcia/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 -EOF -cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@SHELL@%$SHELL%g -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@FFLAGS@%$FFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@host@%$host%g -s%@host_alias@%$host_alias%g -s%@host_cpu@%$host_cpu%g -s%@host_vendor@%$host_vendor%g -s%@host_os@%$host_os%g -s%@target@%$target%g -s%@target_alias@%$target_alias%g -s%@target_cpu@%$target_cpu%g -s%@target_vendor@%$target_vendor%g -s%@target_os@%$target_os%g -s%@build@%$build%g -s%@build_alias@%$build_alias%g -s%@build_cpu@%$build_cpu%g -s%@build_vendor@%$build_vendor%g -s%@build_os@%$build_os%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@PACKAGE@%$PACKAGE%g -s%@VERSION@%$VERSION%g -s%@ACLOCAL@%$ACLOCAL%g -s%@AUTOCONF@%$AUTOCONF%g -s%@AUTOMAKE@%$AUTOMAKE%g -s%@AUTOHEADER@%$AUTOHEADER%g -s%@MAKEINFO@%$MAKEINFO%g -s%@SET_MAKE@%$SET_MAKE%g -s%@DISTRO@%$DISTRO%g -s%@PCMCIA@%$PCMCIA%g -s%@GLIB_CFLAGS@%$GLIB_CFLAGS%g -s%@GLIB_LDFLAGS@%$GLIB_LDFLAGS%g -s%@CC@%$CC%g -s%@AWK@%$AWK%g -s%@LD@%$LD%g -s%@AR@%$AR%g -s%@YACC@%$YACC%g -s%@LEX@%$LEX%g -s%@LEXLIB@%$LEXLIB%g -s%@CPP@%$CPP%g -s%@LEX_OUTPUT_ROOT@%$LEX_OUTPUT_ROOT%g -s%@GLIB@%$GLIB%g - -CEOF -EOF - -cat >> $CONFIG_STATUS <<\EOF - -# Split the substitutions into bite-sized pieces for seds with -# small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. -ac_file=1 # Number of current file. -ac_beg=1 # First line for current file. -ac_end=$ac_max_sed_cmds # Line after last line for current file. -ac_more_lines=: -ac_sed_cmds="" -while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file - else - sed "${ac_end}q" conftest.subs > conftest.s$ac_file - fi - if test ! -s conftest.s$ac_file; then - ac_more_lines=false - rm -f conftest.s$ac_file - else - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f conftest.s$ac_file" - else - ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" - fi - ac_file=`expr $ac_file + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_cmds` - fi -done -if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat -fi -EOF - -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - case "$ac_given_INSTALL" in - [/$]*) INSTALL="$ac_given_INSTALL" ;; - *) INSTALL="$ac_dots$ac_given_INSTALL" ;; - esac - - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -s%@INSTALL@%$INSTALL%g -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file -fi; done -rm -f conftest.s* - -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF - -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 59358cec..49386a93 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -5,24 +5,27 @@ sbin_PROGRAMS = hcid hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c +hcid_CONFIG = hcid.conf hcid_LDADD = @GLIB_LDFLAGS@ INCLUDES = @GLIB_CFLAGS@ -YFLAGS = -d +YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -confdir = $(prefix)/etc/bluetooth -conf_FILE = $(confdir)/hcid.conf -pin_FILE = $(confdir)/pin +EXTRA_DIST = $(hcid_CONFIG) # # Install configuration files # +confdir = $(prefix)/etc/bluetooth +conf_FILE = $(confdir)/$(hcid_CONFIG) +pin_FILE = $(confdir)/pin + install-data-local: $(mkinstalldirs) $(DESTDIR)$(confdir) [ -f $(DESTDIR)$(conf_FILE) ] || \ - $(INSTALL_DATA) $(srcdir)/hcid.conf $(DESTDIR)$(conf_FILE) + $(INSTALL_DATA) $(srcdir)/$(hcid_CONFIG) $(DESTDIR)$(conf_FILE) [ -f $(DESTDIR)$(pin_FILE) ] || \ echo "BlueZ" > $(DESTDIR)$(pin_FILE); \ chmod 600 $(DESTDIR)$(pin_FILE) diff --git a/hcid/Makefile.in b/hcid/Makefile.in deleted file mode 100644 index f21d31b8..00000000 --- a/hcid/Makefile.in +++ /dev/null @@ -1,363 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in 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. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# -# $Id$ -# - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_alias = @build_alias@ -build_triplet = @build@ -host_alias = @host_alias@ -host_triplet = @host@ -target_alias = @target_alias@ -target_triplet = @target@ -AR = @AR@ -AWK = @AWK@ -CC = @CC@ -DISTRO = @DISTRO@ -GLIB = @GLIB@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_LDFLAGS = @GLIB_LDFLAGS@ -LD = @LD@ -LEX = @LEX@ -MAKEINFO = @MAKEINFO@ -PACKAGE = @PACKAGE@ -PCMCIA = @PCMCIA@ -VERSION = @VERSION@ -YACC = @YACC@ - -sbin_PROGRAMS = hcid - -hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c -hcid_LDADD = @GLIB_LDFLAGS@ - -INCLUDES = @GLIB_CFLAGS@ -YFLAGS = -d - -CLEANFILES = lexer.c parser.c parser.h - -confdir = $(prefix)/etc/bluetooth -conf_FILE = $(confdir)/hcid.conf -pin_FILE = $(confdir)/pin -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -PROGRAMS = $(sbin_PROGRAMS) - - -DEFS = @DEFS@ -I. -I$(srcdir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -hcid_OBJECTS = main.o security.o lib.o parser.o lexer.o kword.o -hcid_DEPENDENCIES = -hcid_LDFLAGS = -LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LEXLIB = @LEXLIB@ -CFLAGS = @CFLAGS@ -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -DIST_COMMON = Makefile.am Makefile.in lexer.c parser.c - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -DEP_FILES = .deps/kword.P .deps/lexer.P .deps/lib.P .deps/main.P \ -.deps/parser.P .deps/security.P -SOURCES = $(hcid_SOURCES) -OBJECTS = $(hcid_OBJECTS) - -all: all-redirect -.SUFFIXES: -.SUFFIXES: .S .c .l .o .s .y -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu hcid/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - - -mostlyclean-sbinPROGRAMS: - -clean-sbinPROGRAMS: - -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) - -distclean-sbinPROGRAMS: - -maintainer-clean-sbinPROGRAMS: - -install-sbinPROGRAMS: $(sbin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(sbindir) - @list='$(sbin_PROGRAMS)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - else :; fi; \ - done - -uninstall-sbinPROGRAMS: - @$(NORMAL_UNINSTALL) - list='$(sbin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - done - -.s.o: - $(COMPILE) -c $< - -.S.o: - $(COMPILE) -c $< - -mostlyclean-compile: - -rm -f *.o core *.core - -clean-compile: - -distclean-compile: - -rm -f *.tab.c - -maintainer-clean-compile: - -hcid: $(hcid_OBJECTS) $(hcid_DEPENDENCIES) - @rm -f hcid - $(LINK) $(hcid_LDFLAGS) $(hcid_OBJECTS) $(hcid_LDADD) $(LIBS) -.l.c: - $(LEX) $(AM_LFLAGS) $(LFLAGS) $< && mv $(LEX_OUTPUT_ROOT).c $@ -.y.c: - $(YACC) $(AM_YFLAGS) $(YFLAGS) $< && mv y.tab.c $*.c - if test -f y.tab.h; then \ - if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \ - else :; fi -parser.h: parser.c - - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) - -mostlyclean-tags: - -clean-tags: - -distclean-tags: - -rm -f TAGS ID - -maintainer-clean-tags: - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -subdir = hcid - -distdir: $(DISTFILES) - here=`cd $(top_builddir) && pwd`; \ - top_distdir=`cd $(top_distdir) && pwd`; \ - distdir=`cd $(distdir) && pwd`; \ - cd $(top_srcdir) \ - && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu hcid/Makefile - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done - -DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) - --include $(DEP_FILES) - -mostlyclean-depend: - -clean-depend: - -distclean-depend: - -rm -rf .deps - -maintainer-clean-depend: - -%.o: %.c - @echo '$(COMPILE) -c $<'; \ - $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< - @-cp .deps/$(*F).pp .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm .deps/$(*F).pp - -%.lo: %.c - @echo '$(LTCOMPILE) -c $<'; \ - $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< - @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ - < .deps/$(*F).pp > .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm -f .deps/$(*F).pp -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: all-am -check: check-am -installcheck-am: -installcheck: installcheck-am -install-exec-am: install-sbinPROGRAMS -install-exec: install-exec-am - -install-data-am: install-data-local -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: uninstall-sbinPROGRAMS -uninstall: uninstall-am -all-am: Makefile $(PROGRAMS) -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - $(mkinstalldirs) $(DESTDIR)$(sbindir) - - -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: - -test -z "lexerlparserhparserc" || rm -f lexerl parserh parserc -mostlyclean-am: mostlyclean-sbinPROGRAMS mostlyclean-compile \ - mostlyclean-tags mostlyclean-depend mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-sbinPROGRAMS clean-compile clean-tags clean-depend \ - clean-generic mostlyclean-am - -clean: clean-am - -distclean-am: distclean-sbinPROGRAMS distclean-compile distclean-tags \ - distclean-depend distclean-generic clean-am - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-sbinPROGRAMS \ - maintainer-clean-compile maintainer-clean-tags \ - maintainer-clean-depend maintainer-clean-generic \ - distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS \ -clean-sbinPROGRAMS maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ -install-sbinPROGRAMS mostlyclean-compile distclean-compile \ -clean-compile maintainer-clean-compile tags mostlyclean-tags \ -distclean-tags clean-tags maintainer-clean-tags distdir \ -mostlyclean-depend distclean-depend clean-depend \ -maintainer-clean-depend info-am info dvi-am dvi check check-am \ -installcheck-am installcheck install-exec-am install-exec \ -install-data-local install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs \ -mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -# -# Install configuration files -# -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(confdir) - [ -f $(DESTDIR)$(conf_FILE) ] || \ - $(INSTALL_DATA) $(srcdir)/hcid.conf $(DESTDIR)$(conf_FILE) - [ -f $(DESTDIR)$(pin_FILE) ] || \ - echo "BlueZ" > $(DESTDIR)$(pin_FILE); \ - chmod 600 $(DESTDIR)$(pin_FILE) - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/pcmcia/Makefile.in b/pcmcia/Makefile.in deleted file mode 100644 index d8fbc707..00000000 --- a/pcmcia/Makefile.in +++ /dev/null @@ -1,200 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in 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. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# -# $Id$ -# - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_alias = @build_alias@ -build_triplet = @build@ -host_alias = @host_alias@ -host_triplet = @host@ -target_alias = @target_alias@ -target_triplet = @target@ -AR = @AR@ -AWK = @AWK@ -CC = @CC@ -DISTRO = @DISTRO@ -GLIB = @GLIB@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_LDFLAGS = @GLIB_LDFLAGS@ -LD = @LD@ -LEX = @LEX@ -MAKEINFO = @MAKEINFO@ -PACKAGE = @PACKAGE@ -PCMCIA = @PCMCIA@ -VERSION = @VERSION@ -YACC = @YACC@ - -pcmciadir = /etc/pcmcia - -EXTRA_DIST = bluetooth bluetooth.conf -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -DIST_COMMON = Makefile.am Makefile.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -all: all-redirect -.SUFFIXES: -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu pcmcia/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - -tags: TAGS -TAGS: - - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -subdir = pcmcia - -distdir: $(DISTFILES) - here=`cd $(top_builddir) && pwd`; \ - top_distdir=`cd $(top_distdir) && pwd`; \ - distdir=`cd $(distdir) && pwd`; \ - cd $(top_srcdir) \ - && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu pcmcia/Makefile - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: all-am -check: check-am -installcheck-am: -installcheck: installcheck-am -install-exec-am: -install-exec: install-exec-am - -install-data-am: install-data-local -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: -uninstall: uninstall-am -all-am: Makefile -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-generic mostlyclean-am - -clean: clean-am - -distclean-am: distclean-generic clean-am - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: tags distdir info-am info dvi-am dvi check check-am \ -installcheck-am installcheck install-exec-am install-exec \ -install-data-local install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs \ -mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -install-data-local: @PCMCIA@ - -pcmcia: - $(mkinstalldirs) $(DESTDIR)$(pcmciadir) - $(INSTALL) -m 755 $(srcdir)/bluetooth $(DESTDIR)$(pcmciadir) - $(INSTALL) -m 644 $(srcdir)/bluetooth.conf $(DESTDIR)$(pcmciadir) - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/scripts/Makefile.in b/scripts/Makefile.in deleted file mode 100644 index a6e9f552..00000000 --- a/scripts/Makefile.in +++ /dev/null @@ -1,229 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in 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. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# -# $Id$ -# - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_alias = @build_alias@ -build_triplet = @build@ -host_alias = @host_alias@ -host_triplet = @host@ -target_alias = @target_alias@ -target_triplet = @target@ -AR = @AR@ -AWK = @AWK@ -CC = @CC@ -DISTRO = @DISTRO@ -GLIB = @GLIB@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_LDFLAGS = @GLIB_LDFLAGS@ -LD = @LD@ -LEX = @LEX@ -MAKEINFO = @MAKEINFO@ -PACKAGE = @PACKAGE@ -PCMCIA = @PCMCIA@ -VERSION = @VERSION@ -YACC = @YACC@ - -bin_SCRIPTS = bluepin - -EXTRA_DIST = bluepin bluetooth.rc.rh bluetooth.rc.deb -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -SCRIPTS = $(bin_SCRIPTS) - -DIST_COMMON = Makefile.am Makefile.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -all: all-redirect -.SUFFIXES: -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - - -install-binSCRIPTS: $(bin_SCRIPTS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) - @list='$(bin_SCRIPTS)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - $(INSTALL_SCRIPT) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ - else if test -f $(srcdir)/$$p; then \ - echo " $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`"; \ - $(INSTALL_SCRIPT) $(srcdir)/$$p $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ - else :; fi; fi; \ - done - -uninstall-binSCRIPTS: - @$(NORMAL_UNINSTALL) - list='$(bin_SCRIPTS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`; \ - done -tags: TAGS -TAGS: - - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -subdir = scripts - -distdir: $(DISTFILES) - here=`cd $(top_builddir) && pwd`; \ - top_distdir=`cd $(top_distdir) && pwd`; \ - distdir=`cd $(distdir) && pwd`; \ - cd $(top_srcdir) \ - && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu scripts/Makefile - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: all-am -check: check-am -installcheck-am: -installcheck: installcheck-am -install-exec-am: install-binSCRIPTS -install-exec: install-exec-am - -install-data-am: install-data-local -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: uninstall-binSCRIPTS -uninstall: uninstall-am -all-am: Makefile $(SCRIPTS) -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - $(mkinstalldirs) $(DESTDIR)$(bindir) - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-generic mostlyclean-am - -clean: clean-am - -distclean-am: distclean-generic clean-am - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: uninstall-binSCRIPTS install-binSCRIPTS tags distdir info-am \ -info dvi-am dvi check check-am installcheck-am installcheck \ -install-exec-am install-exec install-data-local install-data-am \ -install-data install-am install uninstall-am uninstall all-redirect \ -all-am all installdirs mostlyclean-generic distclean-generic \ -clean-generic maintainer-clean-generic clean mostlyclean distclean \ -maintainer-clean - - -install-data-local: @DISTRO@ - -unknown: - -echo Unknown distribution - -redhat: - $(mkinstalldirs) $(DESTDIR)/etc/rc.d/init.d - $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)/etc/rc.d/init.d/bluetooth - -debian: - $(mkinstalldirs) $(DESTDIR)/etc/init.d - $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.deb $(DESTDIR)/etc/init.d/bluetooth - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/tools/Makefile.in b/tools/Makefile.in deleted file mode 100644 index 794cfeca..00000000 --- a/tools/Makefile.in +++ /dev/null @@ -1,468 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in 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. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# -# $Id$ -# - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_alias = @build_alias@ -build_triplet = @build@ -host_alias = @host_alias@ -host_triplet = @host@ -target_alias = @target_alias@ -target_triplet = @target@ -AR = @AR@ -AWK = @AWK@ -CC = @CC@ -DISTRO = @DISTRO@ -GLIB = @GLIB@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_LDFLAGS = @GLIB_LDFLAGS@ -LD = @LD@ -LEX = @LEX@ -MAKEINFO = @MAKEINFO@ -PACKAGE = @PACKAGE@ -PCMCIA = @PCMCIA@ -VERSION = @VERSION@ -YACC = @YACC@ - -mandir = $(prefix)/usr/share/man - -sbin_PROGRAMS = hciattach hciconfig -bin_PROGRAMS = hcitool l2ping - -man_MANS = hciattach.8 l2ping.8 - -noinst_PROGRAMS = l2test scotest - -EXTRA_DIST = $(man_MANS) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) - - -DEFS = @DEFS@ -I. -I$(srcdir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -hcitool_SOURCES = hcitool.c -hcitool_OBJECTS = hcitool.o -hcitool_LDADD = $(LDADD) -hcitool_DEPENDENCIES = -hcitool_LDFLAGS = -l2ping_SOURCES = l2ping.c -l2ping_OBJECTS = l2ping.o -l2ping_LDADD = $(LDADD) -l2ping_DEPENDENCIES = -l2ping_LDFLAGS = -l2test_SOURCES = l2test.c -l2test_OBJECTS = l2test.o -l2test_LDADD = $(LDADD) -l2test_DEPENDENCIES = -l2test_LDFLAGS = -scotest_SOURCES = scotest.c -scotest_OBJECTS = scotest.o -scotest_LDADD = $(LDADD) -scotest_DEPENDENCIES = -scotest_LDFLAGS = -hciattach_SOURCES = hciattach.c -hciattach_OBJECTS = hciattach.o -hciattach_LDADD = $(LDADD) -hciattach_DEPENDENCIES = -hciattach_LDFLAGS = -hciconfig_SOURCES = hciconfig.c -hciconfig_OBJECTS = hciconfig.o -hciconfig_LDADD = $(LDADD) -hciconfig_DEPENDENCIES = -hciconfig_LDFLAGS = -CFLAGS = @CFLAGS@ -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -man8dir = $(mandir)/man8 -MANS = $(man_MANS) - -NROFF = nroff -DIST_COMMON = Makefile.am Makefile.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -DEP_FILES = .deps/hciattach.P .deps/hciconfig.P .deps/hcitool.P \ -.deps/l2ping.P .deps/l2test.P .deps/scotest.P -SOURCES = hcitool.c l2ping.c l2test.c scotest.c hciattach.c hciconfig.c -OBJECTS = hcitool.o l2ping.o l2test.o scotest.o hciattach.o hciconfig.o - -all: all-redirect -.SUFFIXES: -.SUFFIXES: .S .c .o .s -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - - -mostlyclean-binPROGRAMS: - -clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) - -distclean-binPROGRAMS: - -maintainer-clean-binPROGRAMS: - -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(bindir) - @list='$(bin_PROGRAMS)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - else :; fi; \ - done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - list='$(bin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - done - -mostlyclean-noinstPROGRAMS: - -clean-noinstPROGRAMS: - -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) - -distclean-noinstPROGRAMS: - -maintainer-clean-noinstPROGRAMS: - -mostlyclean-sbinPROGRAMS: - -clean-sbinPROGRAMS: - -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) - -distclean-sbinPROGRAMS: - -maintainer-clean-sbinPROGRAMS: - -install-sbinPROGRAMS: $(sbin_PROGRAMS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(sbindir) - @list='$(sbin_PROGRAMS)'; for p in $$list; do \ - if test -f $$p; then \ - echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ - $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - else :; fi; \ - done - -uninstall-sbinPROGRAMS: - @$(NORMAL_UNINSTALL) - list='$(sbin_PROGRAMS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ - done - -.s.o: - $(COMPILE) -c $< - -.S.o: - $(COMPILE) -c $< - -mostlyclean-compile: - -rm -f *.o core *.core - -clean-compile: - -distclean-compile: - -rm -f *.tab.c - -maintainer-clean-compile: - -hcitool: $(hcitool_OBJECTS) $(hcitool_DEPENDENCIES) - @rm -f hcitool - $(LINK) $(hcitool_LDFLAGS) $(hcitool_OBJECTS) $(hcitool_LDADD) $(LIBS) - -l2ping: $(l2ping_OBJECTS) $(l2ping_DEPENDENCIES) - @rm -f l2ping - $(LINK) $(l2ping_LDFLAGS) $(l2ping_OBJECTS) $(l2ping_LDADD) $(LIBS) - -l2test: $(l2test_OBJECTS) $(l2test_DEPENDENCIES) - @rm -f l2test - $(LINK) $(l2test_LDFLAGS) $(l2test_OBJECTS) $(l2test_LDADD) $(LIBS) - -scotest: $(scotest_OBJECTS) $(scotest_DEPENDENCIES) - @rm -f scotest - $(LINK) $(scotest_LDFLAGS) $(scotest_OBJECTS) $(scotest_LDADD) $(LIBS) - -hciattach: $(hciattach_OBJECTS) $(hciattach_DEPENDENCIES) - @rm -f hciattach - $(LINK) $(hciattach_LDFLAGS) $(hciattach_OBJECTS) $(hciattach_LDADD) $(LIBS) - -hciconfig: $(hciconfig_OBJECTS) $(hciconfig_DEPENDENCIES) - @rm -f hciconfig - $(LINK) $(hciconfig_LDFLAGS) $(hciconfig_OBJECTS) $(hciconfig_LDADD) $(LIBS) - -install-man8: - $(mkinstalldirs) $(DESTDIR)$(man8dir) - @list='$(man8_MANS)'; \ - l2='$(man_MANS)'; for i in $$l2; do \ - case "$$i" in \ - *.8*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ - done - -uninstall-man8: - @list='$(man8_MANS)'; \ - l2='$(man_MANS)'; for i in $$l2; do \ - case "$$i" in \ - *.8*) list="$$list $$i" ;; \ - esac; \ - done; \ - for i in $$list; do \ - ext=`echo $$i | sed -e 's/^.*\\.//'`; \ - inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ - inst=`echo $$inst | sed '$(transform)'`.$$ext; \ - echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ - rm -f $(DESTDIR)$(man8dir)/$$inst; \ - done -install-man: $(MANS) - @$(NORMAL_INSTALL) - $(MAKE) $(AM_MAKEFLAGS) install-man8 -uninstall-man: - @$(NORMAL_UNINSTALL) - $(MAKE) $(AM_MAKEFLAGS) uninstall-man8 - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) - -mostlyclean-tags: - -clean-tags: - -distclean-tags: - -rm -f TAGS ID - -maintainer-clean-tags: - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -subdir = tools - -distdir: $(DISTFILES) - here=`cd $(top_builddir) && pwd`; \ - top_distdir=`cd $(top_distdir) && pwd`; \ - distdir=`cd $(distdir) && pwd`; \ - cd $(top_srcdir) \ - && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu tools/Makefile - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done - -DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) - --include $(DEP_FILES) - -mostlyclean-depend: - -clean-depend: - -distclean-depend: - -rm -rf .deps - -maintainer-clean-depend: - -%.o: %.c - @echo '$(COMPILE) -c $<'; \ - $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< - @-cp .deps/$(*F).pp .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm .deps/$(*F).pp - -%.lo: %.c - @echo '$(LTCOMPILE) -c $<'; \ - $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< - @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ - < .deps/$(*F).pp > .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm -f .deps/$(*F).pp -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: all-am -check: check-am -installcheck-am: -installcheck: installcheck-am -install-exec-am: install-binPROGRAMS install-sbinPROGRAMS -install-exec: install-exec-am - -install-data-am: install-man -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS uninstall-man -uninstall: uninstall-am -all-am: Makefile $(PROGRAMS) $(MANS) -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(sbindir) \ - $(DESTDIR)$(mandir)/man8 - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \ - mostlyclean-sbinPROGRAMS mostlyclean-compile \ - mostlyclean-tags mostlyclean-depend mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-binPROGRAMS clean-noinstPROGRAMS clean-sbinPROGRAMS \ - clean-compile clean-tags clean-depend clean-generic \ - mostlyclean-am - -clean: clean-am - -distclean-am: distclean-binPROGRAMS distclean-noinstPROGRAMS \ - distclean-sbinPROGRAMS distclean-compile distclean-tags \ - distclean-depend distclean-generic clean-am - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-binPROGRAMS \ - maintainer-clean-noinstPROGRAMS \ - maintainer-clean-sbinPROGRAMS maintainer-clean-compile \ - maintainer-clean-tags maintainer-clean-depend \ - maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ -maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ -mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \ -clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \ -mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS clean-sbinPROGRAMS \ -maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \ -install-sbinPROGRAMS mostlyclean-compile distclean-compile \ -clean-compile maintainer-clean-compile install-man8 uninstall-man8 \ -install-man uninstall-man tags mostlyclean-tags distclean-tags \ -clean-tags maintainer-clean-tags distdir mostlyclean-depend \ -distclean-depend clean-depend maintainer-clean-depend info-am info \ -dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ -install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs \ -mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: -- cgit From bcf196f0baf80fdb51b2df27e3d47a98291023ae Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 24 May 2002 23:37:55 +0000 Subject: Get rid of .libs in default lib path --- acinclude.m4 | 2 +- aclocal.m4 | 2 +- configure.in | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 96c9617a..4395841f 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -90,7 +90,7 @@ AC_DEFUN( AC_SEARCH_LIB, LDFLAGS="-L$path -l$1" AC_TRY_LINK_FUNC($2, [ - LIBS="$LIBS -L$p -l$1" + LIBS="$LIBS -L$path -l$1" ac_lib_found=yes break ] diff --git a/aclocal.m4 b/aclocal.m4 index fadd44eb..39d3c08f 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -102,7 +102,7 @@ AC_DEFUN( AC_SEARCH_LIB, LDFLAGS="-L$path -l$1" AC_TRY_LINK_FUNC($2, [ - LIBS="$LIBS -L$p -l$1" + LIBS="$LIBS -L$path -l$1" ac_lib_found=yes break ] diff --git a/configure.in b/configure.in index 27330f61..295594af 100644 --- a/configure.in +++ b/configure.in @@ -35,10 +35,10 @@ AC_ARG_WITH(bluez-libs, --with-bluez-libs=DIR BlueZ libraries and header files, [ BLUEZ_INCDIR="$withval"/include - BLUEZ_LIBDIR="$withval"/src/.libs + BLUEZ_LIBDIR="$withval"/src ],[ BLUEZ_INCDIR='../libs/include ../bluez-libs*/include /usr/include/bluetooth' - BLUEZ_LIBDIR='../libs/src/.libs ../bluez-libs*/src/.libs /usr/lib' + BLUEZ_LIBDIR='../libs/src ../bluez-libs*/src /usr/lib' ] ) -- cgit From ce0f133679d1536162c8223ea12eb582bbcafa85 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 27 May 2002 02:25:33 +0000 Subject: Libtoolize and fix top level build. Make cleanup. --- Makefile.am | 4 +- acinclude.m4 | 15 +- aclocal.m4 | 3339 ++++++++++++++++++++++++++++++++++++++- config.guess | 894 ++++++++--- config.sub | 535 ++++++- configure.in | 13 +- ltmain.sh | 4946 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 9412 insertions(+), 334 deletions(-) create mode 100644 ltmain.sh diff --git a/Makefile.am b/Makefile.am index 4c73270a..6c007cbd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,6 +2,4 @@ # $Id$ # -EXTRA_DIST = ChangeLog README - -SUBDIRS = hcid tools scripts pcmcia +SUBDIRS := hcid tools scripts pcmcia diff --git a/acinclude.m4 b/acinclude.m4 index 4395841f..33dbbcd2 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,13 +1,3 @@ -dnl Add directory level -AC_DEFUN( AC_ADD_DIRLEVEL, -[ - for i in $1; do - eval o=\$$i - o=`echo $o | sed 's#.\.\./#&../#g'` - eval $i=\$o - done -]) - dnl Test file AC_DEFUN( AC_TEST_FILE, [ @@ -52,6 +42,8 @@ AC_DEFUN( AC_SEARCH_HEADERS, AC_MSG_CHECKING("for $1") ac_hdr_found=no for p in $2; do + test -d $p || continue; + p=`cd $p && pwd` AC_TEST_FILES($1, $p, [ ac_hdr_found=yes @@ -79,6 +71,7 @@ AC_DEFUN( AC_SEARCH_LIB, ac_lib_found=no for p in $3; do test -d $p || continue; + p=`cd $p && pwd` # Check for libtool library if test -f $p/lib$1.la; then @@ -90,7 +83,7 @@ AC_DEFUN( AC_SEARCH_LIB, LDFLAGS="-L$path -l$1" AC_TRY_LINK_FUNC($2, [ - LIBS="$LIBS -L$path -l$1" + LIBS="$LIBS -L$p -l$1" ac_lib_found=yes break ] diff --git a/aclocal.m4 b/aclocal.m4 index 39d3c08f..62d31720 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -10,16 +10,6 @@ dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A dnl PARTICULAR PURPOSE. -dnl Add directory level -AC_DEFUN( AC_ADD_DIRLEVEL, -[ - for i in $1; do - eval o=\$$i - o=`echo $o | sed 's#.\.\./#&../#g'` - eval $i=\$o - done -]) - dnl Test file AC_DEFUN( AC_TEST_FILE, [ @@ -64,6 +54,8 @@ AC_DEFUN( AC_SEARCH_HEADERS, AC_MSG_CHECKING("for $1") ac_hdr_found=no for p in $2; do + test -d $p || continue; + p=`cd $p && pwd` AC_TEST_FILES($1, $p, [ ac_hdr_found=yes @@ -91,6 +83,7 @@ AC_DEFUN( AC_SEARCH_LIB, ac_lib_found=no for p in $3; do test -d $p || continue; + p=`cd $p && pwd` # Check for libtool library if test -f $p/lib$1.la; then @@ -102,7 +95,7 @@ AC_DEFUN( AC_SEARCH_LIB, LDFLAGS="-L$path -l$1" AC_TRY_LINK_FUNC($2, [ - LIBS="$LIBS -L$path -l$1" + LIBS="$LIBS -L$p -l$1" ac_lib_found=yes break ] @@ -220,3 +213,3327 @@ AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex") AC_PROG_LEX AC_DECL_YYTEXT]) +# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- + +# serial 46 AC_PROG_LIBTOOL +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +]) + +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +_LT_AC_PROG_ECHO_BACKSLASH +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_RESTORE]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one + AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, + [AC_TRY_LINK([], + [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); + DllMain (0, 0, 0);], + [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) + + case $host/$CC in + *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) + # old mingw systems require "-dll" to link a DLL, while more recent ones + # require "-mdll" + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -mdll" + AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, + [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) + CFLAGS="$SAVE_CFLAGS" ;; + *-*-cygwin* | *-*-pw32*) + # cygwin systems need to pass --dll to the linker, and not link + # crt.o which will require a WinMain@16 definition. + lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; + esac + ;; + ]) +esac + +_LT_AC_LTCONFIG_HACK + +]) + +# _LT_AC_CHECK_DLFCN +# -------------------- +AC_DEFUN(_LT_AC_CHECK_DLFCN, +[AC_CHECK_HEADERS(dlfcn.h) +])# _LT_AC_CHECK_DLFCN + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +[symcode='[BCDEGRST]'] + +# Regexp to match symbols that can be accessed directly from C. +[sympat='\([_A-Za-z][_A-Za-z0-9]*\)'] + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Define system-specific variables. +case $host_os in +aix*) + [symcode='[BCDT]'] + ;; +cygwin* | mingw* | pw32*) + [symcode='[ABCDGISTW]'] + ;; +hpux*) # Its linker distinguishes data from code symbols + lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + ;; +irix*) + [symcode='[BCDEGRST]'] + ;; +solaris* | sysv5*) + [symcode='[BDT]'] + ;; +sysv4) + [symcode='[DFNSTU]'] + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $host_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + [symcode='[ABCDGISTW]'] +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. +[lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"] + + # Check to see that the pipe works correctly. + pipe_works=no + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +[lt_preloaded_symbols[] =] +{ +EOF + sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if AC_TRY_EVAL(ac_link) && test -s conftest; then + pipe_works=yes + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AC_FD_CC + fi + else + echo "cannot find nm_test_var in $nlist" >&AC_FD_CC + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC + fi + else + echo "$progname: failed program was:" >&AC_FD_CC + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" +if test -z "$lt_cv_sys_global_symbol_pipe"; then + global_symbol_to_cdecl= +else + global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" +fi +if test -z "$global_symbol_pipe$global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + +# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR +# --------------------------------- +AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR], +[# Find the correct PATH separator. Usually this is `:', but +# DJGPP uses `;' like DOS. +if test "X${PATH_SEPARATOR+set}" != Xset; then + UNAME=${UNAME-`uname 2>/dev/null`} + case X$UNAME in + *-DOS) lt_cv_sys_path_separator=';' ;; + *) lt_cv_sys_path_separator=':' ;; + esac +fi +])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn;t interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +AC_DIVERT_POP +])# _LT_AC_PROG_ECHO_BACKSLASH + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ------------------------------------------------------------------ +AC_DEFUN(_LT_AC_TRY_DLOPEN_SELF, +[if test "$cross_compiling" = yes; then : + [$4] +else + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_unknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + +# AC_LIBTOOL_DLOPEN_SELF +# ------------------- +AC_DEFUN(AC_LIBTOOL_DLOPEN_SELF, +[if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + cygwin* | mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + *) + AC_CHECK_LIB(dl, dlopen, [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_FUNC(dlopen, lt_cv_dlopen="dlopen", + [AC_CHECK_FUNC(shl_load, lt_cv_dlopen="shl_load", + [AC_CHECK_LIB(svld, dlopen, + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB(dld, shl_load, + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + LDFLAGS="$LDFLAGS $link_static_flag" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + +AC_DEFUN([_LT_AC_LTCONFIG_HACK], +[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" +need_locks="$enable_libtool_lock" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +if test x"$host" != x"$build"; then + ac_tool_prefix=${host_alias}- +else + ac_tool_prefix= +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case $host_os in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="[$]2" + +AC_MSG_CHECKING([for objdir]) +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +AC_MSG_RESULT($objdir) + + +AC_ARG_WITH(pic, +[ --with-pic try to use only PIC/non-PIC objects [default=use both]], +pic_mode="$withval", pic_mode=default) +test -z "$pic_mode" && pic_mode=default + +# We assume here that the value for lt_cv_prog_cc_pic will not be cached +# in isolation, and that seeing it set (from the cache) indicates that +# the associated values are set (in the cache) correctly too. +AC_MSG_CHECKING([for $compiler option to produce PIC]) +AC_CACHE_VAL(lt_cv_prog_cc_pic, +[ lt_cv_prog_cc_pic= + lt_cv_prog_cc_shlib= + lt_cv_prog_cc_wl= + lt_cv_prog_cc_static= + lt_cv_prog_cc_no_builtin= + lt_cv_prog_cc_can_build_shared=$can_build_shared + + if test "$GCC" = yes; then + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-static' + + case $host_os in + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # we not sure about C++ programs. + lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | irix5* | irix6* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_cv_prog_cc_pic='-fno-common' + ;; + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_cv_prog_cc_pic=-Kconform_pic + fi + ;; + *) + lt_cv_prog_cc_pic='-fPIC' + ;; + esac + else + # PORTME Check for PIC flags for the system compiler. + case $host_os in + aix3* | aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + else + lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better lt_cv_prog_cc_static that works with the bundled CC? + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" + lt_cv_prog_cc_pic='+Z' + ;; + + irix5* | irix6*) + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_cv_prog_cc_pic='-DDLL_EXPORT' + ;; + + newsos6) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + ;; + + osf3* | osf4* | osf5*) + # All OSF/1 code is PIC. + lt_cv_prog_cc_wl='-Wl,' + lt_cv_prog_cc_static='-non_shared' + ;; + + sco3.2v5*) + lt_cv_prog_cc_pic='-Kpic' + lt_cv_prog_cc_static='-dn' + lt_cv_prog_cc_shlib='-belf' + ;; + + solaris*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Wl,' + ;; + + sunos4*) + lt_cv_prog_cc_pic='-PIC' + lt_cv_prog_cc_static='-Bstatic' + lt_cv_prog_cc_wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + lt_cv_prog_cc_pic='-KPIC' + lt_cv_prog_cc_static='-Bstatic' + if test "x$host_vendor" = xsni; then + lt_cv_prog_cc_wl='-LD' + else + lt_cv_prog_cc_wl='-Wl,' + fi + ;; + + uts4*) + lt_cv_prog_cc_pic='-pic' + lt_cv_prog_cc_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_cv_prog_cc_pic='-Kconform_pic' + lt_cv_prog_cc_static='-Bstatic' + fi + ;; + + *) + lt_cv_prog_cc_can_build_shared=no + ;; + esac + fi +]) +if test -z "$lt_cv_prog_cc_pic"; then + AC_MSG_RESULT([none]) +else + AC_MSG_RESULT([$lt_cv_prog_cc_pic]) + + # Check to make sure the pic_flag actually works. + AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works]) + AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" + AC_TRY_COMPILE([], [], [dnl + case $host_os in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then + # they create non-PIC objects. So, if there were any warnings, we + # assume that PIC is not supported. + if test -s conftest.err; then + lt_cv_prog_cc_pic_works=no + else + lt_cv_prog_cc_pic_works=yes + fi + ;; + *) + lt_cv_prog_cc_pic_works=yes + ;; + esac + ], [dnl + lt_cv_prog_cc_pic_works=no + ]) + CFLAGS="$save_CFLAGS" + ]) + + if test "X$lt_cv_prog_cc_pic_works" = Xno; then + lt_cv_prog_cc_pic= + lt_cv_prog_cc_can_build_shared=no + else + lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" + fi + + AC_MSG_RESULT([$lt_cv_prog_cc_pic_works]) +fi + +# Check for any special shared library compilation flags. +if test -n "$lt_cv_prog_cc_shlib"; then + AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries]) + if echo "$old_CC $old_CFLAGS " | [egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]"] >/dev/null; then : + else + AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure]) + lt_cv_prog_cc_can_build_shared=no + fi +fi + +AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works]) +AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl + lt_cv_prog_cc_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" + AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes]) + LDFLAGS="$save_LDFLAGS" +]) + +# Belt *and* braces to stop my trousers falling down: +test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= +AC_MSG_RESULT([$lt_cv_prog_cc_static_works]) + +pic_flag="$lt_cv_prog_cc_pic" +special_shlib_compile_flags="$lt_cv_prog_cc_shlib" +wl="$lt_cv_prog_cc_wl" +link_static_flag="$lt_cv_prog_cc_static" +no_builtin_flag="$lt_cv_prog_cc_no_builtin" +can_build_shared="$lt_cv_prog_cc_can_build_shared" + + +# Check to see if options -o and -c are simultaneously supported by compiler +AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext]) +AC_CACHE_VAL([lt_cv_compiler_c_o], [ +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +echo "int some_variable = 0;" > conftest.$ac_ext +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" +compiler_c_o=no +if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + lt_cv_compiler_c_o=no + else + lt_cv_compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&AC_FD_CC + lt_cv_compiler_c_o=no +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null +]) +compiler_c_o=$lt_cv_compiler_c_o +AC_MSG_RESULT([$compiler_c_o]) + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + AC_MSG_CHECKING([if $compiler supports -c -o file.lo]) + AC_CACHE_VAL([lt_cv_compiler_o_lo], [ + lt_cv_compiler_o_lo=no + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + lt_cv_compiler_o_lo=no + else + lt_cv_compiler_o_lo=yes + fi + ]) + CFLAGS="$save_CFLAGS" + ]) + compiler_o_lo=$lt_cv_compiler_o_lo + AC_MSG_RESULT([$compiler_o_lo]) +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi + +if test "$GCC" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions]) + echo "int some_variable = 0;" > conftest.$ac_ext + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" + compiler_rtti_exceptions=no + AC_TRY_COMPILE([], [int some_variable = 0;], [dnl + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + compiler_rtti_exceptions=no + else + compiler_rtti_exceptions=yes + fi + ]) + CFLAGS="$save_CFLAGS" + AC_MSG_RESULT([$compiler_rtti_exceptions]) + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi +fi + +# See if the linker supports building shared libraries. +AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries]) + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +old_archive_from_expsyms_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_into_libs=no +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +link_all_deplibs=unknown +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. +extract_expsyms_cmds= + +case $host_os in +cygwin* | mingw* | pw32* ) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX, the GNU linker is very broken + # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ + sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ + test -f $output_objdir/impgen.exe || (cd $output_objdir && \ + if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ + else $CC -o impgen impgen.c ; fi)~ + $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' + + old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' + + # cygwin and mingw dlls have different entry points and sets of symbols + # to exclude. + # FIXME: what about values for MSVC? + dll_entry=__cygwin_dll_entry@12 + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ + case $host_os in + mingw*) + # mingw values + dll_entry=_DllMainCRTStartup@12 + dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ + ;; + esac + + # mingw and cygwin differ, and it's simplest to just exclude the union + # of the two symbol sets. + dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 + + # recent cygwin and mingw systems supply a stub DllMain which the user + # can override, but on older systems we have to supply one (in ltdll.c) + if test "x$lt_cv_need_dllmain" = "xyes"; then + ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " + ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < [$]0 > $output_objdir/$soname-ltdll.c~ + test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' + else + ltdll_obj= + ltdll_cmds= + fi + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + # Be careful not to strip the DATA tag left be newer dlltools. + export_symbols_cmds="$ltdll_cmds"' + $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ + [sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//"] < $output_objdir/$soname-def > $export_symbols' + + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is. + # If DATA tags from a recent dlltool are present, honour them! + archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname-def; + else + echo EXPORTS > $output_objdir/$soname-def; + _lt_hint=1; + cat $export_symbols | while read symbol; do + set dummy \$symbol; + case \[$]# in + 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; + *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; + esac; + _lt_hint=`expr 1 + \$_lt_hint`; + done; + fi~ + '"$ltdll_cmds"' + $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ + $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ + $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris* | sysv5*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw* | pw32*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4* | aix5*) + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + shared_flag='-shared' + else + if test "$host_cpu" = ia64; then + shared_flag='-G' + else + shared_flag='${wl}-bM:SRE' + fi + hardcode_direct=yes + fi + + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # Test if we are trying to use run time linking, or normal AIX style linking. + # If -brtl is somewhere in LDFLAGS, we need to do run time linking. + aix_use_runtimelinking=no + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl" ); then + aix_use_runtimelinking=yes + break + fi + done + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + # It seems that -bexpall can do strange things, so it is better to + # generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' + allow_undefined_flag=' -Wl,-G' + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-znodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + else + hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' + # Warning - without using the other run time loading flags, -berok will + # link without error, but may produce a broken library. + allow_undefined_flag='${wl}-berok' + # This is a bit strange, but is similar to how AIX traditionally builds + # it's shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' + fi + fi + ;; + + amigaos*) + archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + fix_srcfile_path='`cygpath -w "$srcfile"`' + ;; + + darwin* | rhapsody*) + allow_undefined_flag='-undefined suppress' + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + archive_cmds='$CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linkopts -install_name $rpath/$soname $(test -n "$verstring" -a x$verstring != x0.0 && echo $verstring)' + # We need to add '_' to the symbols in $export_symbols first + #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' + hardcode_direct=yes + hardcode_shlibpath_var=no + whole_archive_flag_spec='-all_load $convenience' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case $host_os in + hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + link_all_deplibs=yes + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + openbsd*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' + + #Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag=' -z defs' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + [solaris2.[0-5] | solaris2.[0-5].*]) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + if test "x$host_vendor" = xsno; then + archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_direct=yes # is this really true??? + else + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv5*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + hardcode_libdir_flag_spec= + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4.2uw2*) + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=no + hardcode_shlibpath_var=no + hardcode_runpath_var=yes + runpath_var=LD_RUN_PATH + ;; + + sysv5uw7* | unixware7*) + no_undefined_flag='${wl}-z ${wl}text' + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac +fi +AC_MSG_RESULT([$ld_shlibs]) +test "$ld_shlibs" = no && can_build_shared=no + +# Check hardcoding attributes. +AC_MSG_CHECKING([how to hardcode library paths into programs]) +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +AC_MSG_RESULT([$hardcode_action]) + +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +reload_cmds='$LD$reload_flag -o $output$reload_objs' +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +# PORTME Fill in your ld.so characteristics +AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4* | aix5*) + version_type=linux + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + [ aix4 | aix4.[01] | aix4.[01].*)] + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so instead of + # lib.a to let people know that these are not typical AIX shared libraries. + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}.so$major' + fi + shlibpath_var=LIBPATH + deplibs_check_method=pass_all + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | [$Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\'']`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi4*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + export_dynamic_flag_spec=-rdynamic + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + need_version=no + need_lib_prefix=no + case $GCC,$host_os in + yes,cygwin*) + library_names_spec='$libname.dll.a' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll' + postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog .libs/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + ;; + yes,mingw*) + library_names_spec='${libname}`echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"` + ;; + yes,pw32*) + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' + ;; + *) + library_names_spec='${libname}`echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + # FIXME: Relying on posixy $() will cause problems for + # cross-compilation, but unfortunately the echo tests do not + # yet detect zsh echo's removal of \ escapes. + library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' + soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + *) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6*) + version_type=irix + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' + case $host_os in + irix5*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + need_version=no + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +AC_LIBTOOL_DLOPEN_SELF + +if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + AC_CACHE_VAL([lt_cv_archive_cmds_need_lc], + [$rm conftest* + echo 'static int dummy;' > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile); then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_cv_prog_cc_wl + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi]) + AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc]) + ;; + esac +fi +need_lc=${lt_cv_archive_cmds_need_lc-yes} + +# The second clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + : +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + test -f Makefile && make "$ltmain" +fi + +if test -f "$ltmain"; then + trap "$rm \"${ofile}T\"; exit 1" 1 2 15 + $rm -f "${ofile}T" + + echo creating $ofile + + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS \ + AR AR_FLAGS CC LD LN_S NM SHELL \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ + postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ + old_striplib striplib file_magic_cmd export_symbols_cmds \ + deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case $var in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + cat <<__EOF__ > "${ofile}T" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996-2000 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi + +# ### BEGIN LIBTOOL CONFIG + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$need_lc + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# The default C compiler. +CC=$lt_CC + +# Is the compiler the GNU C compiler? +with_gcc=$GCC + +# The linker used to build libraries. +LD=$lt_LD + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_wl + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_pic_flag +pic_mode=$pic_mode + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$lt_compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_old_archive_cmds +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_global_symbol_to_cdecl + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# ### END LIBTOOL CONFIG + +__EOF__ + + case $host_os in + aix3*) + cat <<\EOF >> "${ofile}T" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + case $host_os in + cygwin* | mingw* | pw32* | os2*) + cat <<'EOF' >> "${ofile}T" + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# /* O_BINARY isn't required (or even defined sometimes) under Unix */ +# #ifndef O_BINARY +# #define O_BINARY 0 +# #endif +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (dll < 1) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) + + mv -f "${ofile}T" "$ofile" || \ + (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") + chmod +x "$ofile" +fi + +])# _LT_AC_LTCONFIG_HACK + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[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. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[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. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[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. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_LIBTOOL_PICMODE - implement the --with-pic flag +# Usage: AC_LIBTOOL_PICMODE[(MODE)] +# Where MODE is either `yes' or `no'. If omitted, it defaults to +# `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default)]) + + +# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in + /*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; + ?:/*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. + ;; + *) + ac_save_MAGIC_CMD="$MAGIC_CMD" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$ac_save_ifs" + MAGIC_CMD="$ac_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +]) + + +# AC_PATH_MAGIC - find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl +AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) + else + MAGIC_CMD=: + fi +fi +]) + + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +# AC_PROG_LD_GNU - +AC_DEFUN([AC_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + lt_cv_prog_gnu_ld=yes +else + lt_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$lt_cv_prog_gnu_ld +]) + +# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, +[lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +test -n "$reload_flag" && reload_flag=" $reload_flag" +]) + +# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependant libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# ['file_magic [regex]'] -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi4*) + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'] + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin* | mingw* | pw32*) + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' + lt_cv_file_magic_cmd='/usr/bin/file -L' + case "$host_os" in + rhapsody* | darwin1.[012]) + lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` + ;; + *) # Darwin 1.3 on + lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' + ;; + esac + ;; + +freebsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + [lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20*|hpux11*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + +irix5* | irix6*) + case $host_os in + irix5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + [lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"] + ;; + esac + lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux-gnu*) + case $host_cpu in + alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | s390* ) + lt_cv_deplibs_check_method=pass_all ;; + *) + # glibc up to 2.1.1 does not perform some relocations on ARM + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;] + esac + lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'] + else + [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'] + fi + ;; + +newos6*) + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'] + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +osf3* | osf4* | osf5*) + # this will be overridden with pass_all, but let us keep it just in case + lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' + lt_cv_file_magic_test_file=/shlib/libc.so + lt_cv_deplibs_check_method=pass_all + ;; + +sco3.2v5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + lt_cv_file_magic_test_file=/lib/libc.so + ;; + +[sysv5uw[78]* | sysv4*uw2*)] + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + case $host_vendor in + motorola) + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'] + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'] + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + [lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"] + lt_cv_file_magic_test_file=/lib/libc.so + ;; + esac + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +]) + + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/${ac_tool_prefix}nm + if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then + lt_cv_path_NM="$tmp_nm -B" + break + elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + lt_cv_path_NM="$tmp_nm -p" + break + else + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and INCLTDL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and INCLTDL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + diff --git a/config.guess b/config.guess index 2960d6e0..ba661651 100755 --- a/config.guess +++ b/config.guess @@ -1,7 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. -# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. + +timestamp='2001-04-20' + # This file 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 @@ -22,18 +25,92 @@ # the same distribution terms that you use for the rest of that program. # Written by Per Bothner . -# The master version of this file is at the FSF in /home/gd/gnu/lib. +# Please send patches to . # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you -# don't specify an explicit system type (host/target name). -# -# Only a few systems have been added to this list; please add others -# (but try to keep the structure clean). -# +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c + for c in cc gcc c89 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break + fi + done + rm -f $dummy.c $dummy.o $dummy.rel + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 8/24/94.) @@ -43,14 +120,57 @@ fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 - # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-unknown ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE}" in + i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` @@ -59,56 +179,69 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - cat <dummy.s + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text .globl main + .align 4 .ent main main: - .frame \$30,0,\$26,0 - .prologue 0 - .long 0x47e03d80 # implver $0 - lda \$2,259 - .long 0x47e20c21 # amask $2,$1 - srl \$1,8,\$2 - sll \$2,2,\$2 - sll \$0,3,\$0 - addl \$1,\$0,\$0 - addl \$2,\$0,\$0 - ret \$31,(\$26),1 + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit .end main EOF - ${CC-cc} dummy.s -o dummy 2>/dev/null + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then - ./dummy - case "$?" in - 7) + case `./$dummy` in + 0-0) UNAME_MACHINE="alpha" ;; - 15) + 1-0) UNAME_MACHINE="alphaev5" ;; - 14) + 1-1) UNAME_MACHINE="alphaev56" ;; - 10) + 1-101) UNAME_MACHINE="alphapca56" ;; - 16) + 2-303) UNAME_MACHINE="alphaev6" ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; esac fi - rm -f dummy.s dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]` + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit 0 ;; Amiga*:UNIX_System_V:4.0:*) - echo m68k-cbm-sysv4 + echo m68k-unknown-sysv4 exit 0;; - amiga:NetBSD:*:*) - echo m68k-cbm-netbsd${UNAME_RELEASE} - exit 0 ;; amiga:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; @@ -133,16 +266,16 @@ EOF wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit 0;; - arm32:NetBSD:*:*) - echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - exit 0 ;; - SR2?01:HI-UX/MPP:*:*) + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit 0;; - Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*) + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 @@ -150,7 +283,7 @@ EOF echo pyramid-pyramid-bsd fi exit 0 ;; - NILE:*:*:dcosx) + NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4H:SunOS:5.*:*) @@ -195,21 +328,38 @@ EOF aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit 0 ;; - atari*:NetBSD:*:*) - echo m68k-atari-netbsd${UNAME_RELEASE} - exit 0 ;; atari*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; - sun3*:NetBSD:*:*) - echo m68k-sun-netbsd${UNAME_RELEASE} + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; sun3*:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; - mac68k:NetBSD:*:*) - echo m68k-apple-netbsd${UNAME_RELEASE} - exit 0 ;; mac68k:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; @@ -222,9 +372,6 @@ EOF powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit 0 ;; - macppc:NetBSD:*:*) - echo powerpc-apple-netbsd${UNAME_RELEASE} - exit 0 ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit 0 ;; @@ -234,12 +381,17 @@ EOF VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; - 2020:CLIX:*:*) + 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit 0 ;; mips:*:*:UMIPS | mips:*:*:RISCos) - sed 's/^ //' << EOF >dummy.c - int main (argc, argv) int argc; char **argv; { + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); @@ -254,12 +406,15 @@ EOF exit (-1); } EOF - ${CC-cc} dummy.c -o dummy \ - && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo mips-mips-riscos${UNAME_RELEASE} exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit 0 ;; @@ -275,15 +430,18 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ - -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then echo m88k-dg-dgux${UNAME_RELEASE} - else + else echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} fi - else echo i586-dg-dgux${UNAME_RELEASE} - fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 @@ -304,12 +462,20 @@ EOF ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i?86:AIX:*:*) + i*86:AIX:*:*) echo i386-ibm-aix exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - sed 's/^ //' << EOF >dummy.c + sed 's/^ //' << EOF >$dummy.c #include main() @@ -320,8 +486,8 @@ EOF exit(0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo rs6000-ibm-aix3.2.5 elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 @@ -329,9 +495,9 @@ EOF echo rs6000-ibm-aix3.2 fi exit 0 ;; - *:AIX:*:4) + *:AIX:*:[45]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` - if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -339,7 +505,7 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=4.${UNAME_RELEASE} + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit 0 ;; @@ -349,7 +515,7 @@ EOF ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) @@ -365,28 +531,48 @@ EOF echo m68k-hp-bsd4.4 exit 0 ;; 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 ) - sed 's/^ //' << EOF >dummy.c + 9000/[678][0-9][0-9]) + case "${HPUX_REV}" in + 11.[0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + esac ;; + esac + fi ;; + esac + if [ "${HP_ARCH}" = "" ]; then + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE #include #include - + int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); - #endif + #endif long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) + + switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: + case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) - switch (bits) + switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; @@ -394,20 +580,25 @@ EOF } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; - #endif + #endif default: puts ("hppa1.0"); break; } exit (0); } EOF - (${CC-cc} dummy.c -o dummy 2>/dev/null ) && HP_ARCH=`./dummy` - rm -f dummy.c dummy + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; esac - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; 3050*:HI-UX:*:*) - sed 's/^ //' << EOF >dummy.c + sed 's/^ //' << EOF >$dummy.c #include int main () @@ -432,8 +623,8 @@ EOF exit (0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy echo unknown-hitachi-hiuxwe2 exit 0 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) @@ -442,13 +633,16 @@ EOF 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit 0 ;; - i?86:OSF1:*:*) + i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else @@ -458,6 +652,9 @@ EOF parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; @@ -488,37 +685,41 @@ EOF -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit 0 ;; CRAY-2:*:*:*) echo cray2-cray-unicos exit 0 ;; - F300:UNIX_System_V:*:*) - FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit 0 ;; - F301:UNIX_System_V:*:*) - echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` - exit 0 ;; - hp3[0-9][05]:NetBSD:*:*) - echo m68k-hp-netbsd${UNAME_RELEASE} - exit 0 ;; hp300:OpenBSD:*:*) echo m68k-unknown-openbsd${UNAME_RELEASE} exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; - i?86:BSD/386:*:* | *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit 0 ;; *:FreeBSD:*:*) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit 0 ;; - *:NetBSD:*:*) - echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - exit 0 ;; *:OpenBSD:*:*) echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` exit 0 ;; @@ -528,6 +729,18 @@ EOF i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; @@ -537,85 +750,26 @@ EOF *:GNU:*:*) echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit 0 ;; - *:Linux:*:*) - # uname on the ARM produces all sorts of strangeness, and we need to - # filter it out. - case "$UNAME_MACHINE" in - arm* | sa110*) UNAME_MACHINE="arm" ;; - esac - - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. - ld_help_string=`ld --help 2>&1` - ld_supported_emulations=`echo $ld_help_string \ - | sed -ne '/supported emulations:/!d - s/[ ][ ]*/ /g - s/.*supported emulations: *// - s/ .*// - p'` - case "$ld_supported_emulations" in - i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; - i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; - sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; - armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; - m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; - elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;; - esac - - if test "${UNAME_MACHINE}" = "alpha" ; then - sed 's/^ //' <dummy.s - .globl main - .ent main - main: - .frame \$30,0,\$26,0 - .prologue 0 - .long 0x47e03d80 # implver $0 - lda \$2,259 - .long 0x47e20c21 # amask $2,$1 - srl \$1,8,\$2 - sll \$2,2,\$2 - sll \$0,3,\$0 - addl \$1,\$0,\$0 - addl \$2,\$0,\$0 - ret \$31,(\$26),1 - .end main -EOF - LIBC="" - ${CC-cc} dummy.s -o dummy 2>/dev/null - if test "$?" = 0 ; then - ./dummy - case "$?" in - 7) - UNAME_MACHINE="alpha" - ;; - 15) - UNAME_MACHINE="alphaev5" - ;; - 14) - UNAME_MACHINE="alphaev56" - ;; - 10) - UNAME_MACHINE="alphapca56" - ;; - 16) - UNAME_MACHINE="alphaev6" - ;; - esac - - objdump --private-headers dummy | \ - grep ld.so.1 > /dev/null - if test "$?" = 0 ; then - LIBC="libc1" - fi - fi - rm -f dummy.s dummy - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 - elif test "${UNAME_MACHINE}" = "mips" ; then - cat >dummy.c <$dummy.c < /* for printf() prototype */ +int main (int argc, char *argv[]) { +#else +int main (argc, argv) int argc; char *argv[]; { +#endif #ifdef __MIPSEB__ printf ("%s-unknown-linux-gnu\n", argv[1]); #endif @@ -625,32 +779,152 @@ main(argc, argv) return 0; } EOF - ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy - else - # Either a pre-BFD a.out linker (linux-gnuoldld) - # or one that does not give us useful --help. - # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. - # If ld does not provide *any* "supported emulations:" - # that means it is gnuoldld. - echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" - test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 - - case "${UNAME_MACHINE}" in - i?86) - VENDOR=pc; - ;; - *) - VENDOR=unknown; - ;; - esac - # Determine whether the default compiler is a.out or elf - cat >dummy.c </dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + ;; + ppc:Linux:*:*) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif main(argc, argv) int argc; char *argv[]; { +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unknown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then LIBC="libc1" ; fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 ;; + alpha:Linux:*:*) + cat <$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) UNAME_MACHINE="alpha" ;; + 1-0) UNAME_MACHINE="alphaev5" ;; + 1-1) UNAME_MACHINE="alphaev56" ;; + 1-101) UNAME_MACHINE="alphapca56" ;; + 2-303) UNAME_MACHINE="alphaev6" ;; + 2-307) UNAME_MACHINE="alphaev67" ;; + esac + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_supported_emulations=`cd /; ld --help 2>&1 \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i*86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i*86) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + i*86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + esac + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + test -z "$ld_supported_emulations" && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + case "${UNAME_MACHINE}" in + i*86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 @@ -667,15 +941,16 @@ main(argc, argv) return 0; } EOF - ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy - fi ;; + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # are messed up and put the nodename in both sysname and nodename. - i?86:DYNIX/ptx:4*:*) + i*86:DYNIX/ptx:4*:*) echo i386-sequent-sysv4 exit 0 ;; - i?86:UNIX_SV:4.2MP:2.*) + i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, @@ -683,14 +958,24 @@ EOF # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; - i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; - i?86:*:3.2:*) + i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit 0 ;; - i?86:UnixWare:*:*) - if /bin/uname -X 2>/dev/null >/dev/null ; then - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - fi - echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION} + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; pc:*:*:*) + # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i386. echo i386-pc-msdosdjgpp @@ -735,7 +1021,7 @@ EOF exit 0 ;; M68*:*:R3V[567]*:*) test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` @@ -746,24 +1032,30 @@ EOF 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:*) + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit 0 ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; - i?86:LynxOS:2.*:*) + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit 0 ;; - rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; @@ -791,10 +1083,10 @@ EOF mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit 0 ;; - news*:NEWS-OS:*:6*) + news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit 0 ;; - R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*) + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else @@ -810,12 +1102,82 @@ EOF BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[KW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 -cat >dummy.c <$dummy.c < # include @@ -853,7 +1215,10 @@ main () #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif @@ -898,11 +1263,24 @@ main () #endif #if defined (vax) -#if !defined (ultrix) - printf ("vax-dec-bsd\n"); exit (0); -#else - printf ("vax-dec-ultrix\n"); exit (0); -#endif +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif #endif #if defined (alliant) && defined (i860) @@ -913,8 +1291,8 @@ main () } EOF -${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 -rm -f dummy.c dummy +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy # Apollos put the system type in the environment. @@ -946,6 +1324,48 @@ then esac fi -#echo '(Unable to guess system type)' 1>&2 +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub index 00bea6e6..a06a480a 100755 --- a/config.sub +++ b/config.sub @@ -1,6 +1,10 @@ #! /bin/sh -# Configuration validation subroutine script, version 1.1. -# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc. +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. + +timestamp='2001-04-20' + # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. @@ -25,6 +29,8 @@ # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. +# Please send patches to . +# # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. @@ -45,30 +51,73 @@ # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -if [ x$1 = x ] -then - echo Configuration name missing. 1>&2 - echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 - echo "or $0 ALIAS" 1>&2 - echo where ALIAS is a recognized configuration type. 1>&2 - exit 1 -fi +me=`echo "$0" | sed -e 's,.*/,,'` -# First pass through any local machine types. -case $1 in - *local*) - echo $1 - exit 0 - ;; - *) - ;; +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - linux-gnu*) + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -94,15 +143,25 @@ case $os in -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple) + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; -hiux*) os=-hiuxwe2 ;; -sco5) - os=sco3.2v5 + os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) @@ -121,6 +180,9 @@ case $os in os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -143,26 +205,50 @@ case $os in -psos*) os=-psos ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. - tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ - | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ - | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \ - | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \ - | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \ - | mips64 | mipsel | mips64el | mips64orion | mips64orionel \ - | mipstx39 | mipstx39el \ - | sparc | sparclet | sparclite | sparc64 | v850) + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \ + | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \ + | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | sh[34] \ + | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp10 | pdp11 \ + | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \ + | v850 | c4x \ + | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \ + | pj | pjl | h8500) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | w65) ;; + # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. - i[34567]86) + i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. @@ -171,27 +257,52 @@ case $basic_machine in exit 1 ;; # Recognize the basic CPU types with company name. - vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ - | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \ + | arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ - | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \ - | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \ - | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \ - | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \ - | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ - | sparc64-* | mips64-* | mipsel-* \ - | mips64el-* | mips64orion-* | mips64orionel-* \ - | mipstx39-* | mipstx39el-* \ - | f301-*) + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp10-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \ + | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \ + | [cjt]90-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \ + | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; alliant | fx80) basic_machine=fx80-alliant ;; @@ -207,20 +318,24 @@ case $basic_machine in os=-sysv ;; amiga | amiga-*) - basic_machine=m68k-cbm + basic_machine=m68k-unknown ;; amigaos | amigados) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) - basic_machine=m68k-cbm + basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; aux) basic_machine=m68k-apple os=-aux @@ -257,13 +372,16 @@ case $basic_machine in basic_machine=cray2-cray os=-unicos ;; - [ctj]90-cray) - basic_machine=c90-cray + [cjt]90) + basic_machine=${basic_machine}-cray os=-unicos ;; crds | unos) basic_machine=m68k-crds ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; da30 | da30-*) basic_machine=m68k-da30 ;; @@ -297,6 +415,10 @@ case $basic_machine in encore | umax | mmax) basic_machine=ns32k-encore ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; fx2800) basic_machine=i860-alliant ;; @@ -307,6 +429,10 @@ case $basic_machine in basic_machine=tron-gmicro os=-sysv ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 @@ -315,6 +441,14 @@ case $basic_machine in basic_machine=h8300-hitachi os=-hms ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; harris) basic_machine=m88k-harris os=-sysv3 @@ -330,13 +464,30 @@ case $basic_machine in basic_machine=m68k-hp os=-hpux ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; - hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) @@ -345,27 +496,42 @@ case $basic_machine in hppa-next) os=-nextstep3 ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; i370-ibm* | ibm*) basic_machine=i370-ibm - os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? - i[34567]86v32) + i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; - i[34567]86v4*) + i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; - i[34567]86v) + i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; - i[34567]86sol2) + i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; iris | iris4d) basic_machine=mips-sgi case $os in @@ -391,9 +557,17 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; miniframe) basic_machine=m68000-convergent ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; mipsel*-linux*) basic_machine=mipsel-unknown os=-linux-gnu @@ -408,10 +582,34 @@ case $basic_machine in mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos @@ -424,6 +622,10 @@ case $basic_machine in basic_machine=mips-sony os=-newsos ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; next | m*-next ) basic_machine=m68k-next case $os in @@ -449,9 +651,32 @@ case $basic_machine in basic_machine=i960-intel os=-nindy ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; np1) basic_machine=np1-gould ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 @@ -469,28 +694,28 @@ case $basic_machine in pc532 | pc532-*) basic_machine=ns32k-pc532 ;; - pentium | p5 | k5 | nexen) + pentium | p5 | k5 | k6 | nexgen) basic_machine=i586-pc ;; - pentiumpro | p6 | k6 | 6x86) + pentiumpro | p6 | 6x86 | athlon) basic_machine=i686-pc ;; pentiumii | pentium2) - basic_machine=i786-pc + basic_machine=i686-pc ;; - pentium-* | p5-* | k5-* | nexen-*) + pentium-* | p5-* | k5-* | k6-* | nexgen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - pentiumpro-* | p6-* | k6-* | 6x86-*) + pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; - power) basic_machine=rs6000-ibm + power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; @@ -505,12 +730,24 @@ case $basic_machine in ps2) basic_machine=i386-ibm ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; sequent) basic_machine=i386-sequent ;; @@ -518,6 +755,10 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; sps7) basic_machine=m68k-bull os=-sysv2 @@ -525,6 +766,13 @@ case $basic_machine in spur) basic_machine=spur-unknown ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; sun2) basic_machine=m68000-sun ;; @@ -565,10 +813,22 @@ case $basic_machine in sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; symmetry) basic_machine=i386-sequent os=-dynix ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; tx39) basic_machine=mipstx39-unknown ;; @@ -586,6 +846,10 @@ case $basic_machine in basic_machine=a29k-nyu os=-sym1 ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; vaxv) basic_machine=vax-dec os=-sysv @@ -609,6 +873,14 @@ case $basic_machine in basic_machine=a29k-wrs os=-vxworks ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; xmp) basic_machine=xmp-cray os=-unicos @@ -616,6 +888,10 @@ case $basic_machine in xps | xps100) basic_machine=xps100-honeywell ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -623,6 +899,15 @@ case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; mips) if [ x$os = x-linux-gnu ]; then basic_machine=mips-unknown @@ -639,13 +924,20 @@ case $basic_machine in vax) basic_machine=vax-dec ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; - sparc) + sh3 | sh4) + basic_machine=sh-unknown + ;; + sparc | sparcv9 | sparcv9b) basic_machine=sparc-sun ;; cydra) @@ -657,6 +949,19 @@ case $basic_machine in orion105) basic_machine=clipper-highlevel ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 @@ -710,13 +1015,35 @@ case $os in | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos*) + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*) # Remember, each alternative MUST END IN *, to match a version number. ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; @@ -726,6 +1053,12 @@ case $os in -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; -osfrose*) os=-osfrose ;; @@ -741,12 +1074,18 @@ case $os in -acis*) os=-aos ;; + -386bsd) + os=-bsd + ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; + -nsk*) + os=-nsk + ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` @@ -772,9 +1111,18 @@ case $os in # This must come after -sysvr4. -sysv*) ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; -xenix) os=-xenix ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; -none) ;; *) @@ -800,9 +1148,15 @@ case $basic_machine in *-acorn) os=-riscix1.2 ;; + arm*-rebel) + os=-linux + ;; arm*-semi) os=-aout ;; + pdp10-*) + os=-tops20 + ;; pdp11-*) os=-none ;; @@ -821,6 +1175,15 @@ case $basic_machine in # default. # os=-sunos4 ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; @@ -833,6 +1196,15 @@ case $basic_machine in *-ibm) os=-aix ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; *-hp) os=-hpux ;; @@ -893,9 +1265,21 @@ case $basic_machine in *-masscomp) os=-rtu ;; - f301-fujitsu) + f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; *) os=-none ;; @@ -917,9 +1301,15 @@ case $basic_machine in -aix*) vendor=ibm ;; + -beos*) + vendor=be + ;; -hpux*) vendor=hp ;; + -mpeix*) + vendor=hp + ;; -hiux*) vendor=hitachi ;; @@ -935,7 +1325,7 @@ case $basic_machine in -genix*) vendor=ns ;; - -mvs*) + -mvs* | -opened*) vendor=ibm ;; -ptx*) @@ -947,9 +1337,26 @@ case $basic_machine in -aux*) vendor=apple ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure.in b/configure.in index 295594af..5cc2f263 100644 --- a/configure.in +++ b/configure.in @@ -27,18 +27,20 @@ AC_PROG_AWK AC_PROG_INSTALL AC_CHECK_TOOL(LD, ld, ld) AC_CHECK_TOOL(AR, ar, ar) - +AC_PROG_INSTALL AC_PROG_YACC AM_PROG_LEX +AM_PROG_LIBTOOL + AC_ARG_WITH(bluez-libs, --with-bluez-libs=DIR BlueZ libraries and header files, [ BLUEZ_INCDIR="$withval"/include BLUEZ_LIBDIR="$withval"/src ],[ - BLUEZ_INCDIR='../libs/include ../bluez-libs*/include /usr/include/bluetooth' - BLUEZ_LIBDIR='../libs/src ../bluez-libs*/src /usr/lib' + BLUEZ_INCDIR='../libs/include /usr/include/bluetooth' + BLUEZ_LIBDIR='../libs/src /usr/lib' ] ) @@ -69,9 +71,6 @@ AC_ARG_WITH(glib, ] ) -dnl Check for programs. -AC_PROG_INSTALL - dnl Check for distro type. DISTRO=unknown @@ -89,6 +88,4 @@ AC_ARG_ENABLE(pcmcia, AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=) fi ]) -AC_ADD_DIRLEVEL(CFLAGS CPPFLAGS LDFLAGS LIBS) - AC_OUTPUT(Makefile hcid/Makefile tools/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/ltmain.sh b/ltmain.sh new file mode 100644 index 00000000..2393e14d --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,4946 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun configure. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case $arg in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + execute_dlfiles) + execute_dlfiles="$execute_dlfiles $arg" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case $arg in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + sed -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case $nonopt in + *cc | *++ | gcc* | *-gcc*) + mode=link + for arg + do + case $arg in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case $mode in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + prev= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + case $prev in + "") ;; + xcompiler) + # Aesthetically quote the previous argument. + prev= + lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + + case $arg in + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + # Accept any command-line options. + case $arg in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` + lastarg= + IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + lastarg="$lastarg $arg" + done + IFS="$save_ifs" + lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` + + # Add the arguments to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + continue + ;; + esac + + case $user_target in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + case $lastarg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case $user_target in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case $libobj in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case $libobj in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $libobj" + else + removelist="$libobj" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $run ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + else + # Don't build PIC code + command="$base_compile $srcfile" + fi + if test "$build_old_libs" = yes; then + lo_libobj="$libobj" + dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$libobj"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + + if test -d "$dir"; then + $show "$rm $libobj" + $run $rm $libobj + else + $show "$mkdir $dir" + $run $mkdir $dir + status=$? + if test $status -ne 0 && test ! -d $dir; then + exit $status + fi + fi + fi + if test "$compiler_o_lo" = yes; then + output_obj="$libobj" + command="$command -o $output_obj" + elif test "$compiler_c_o" = yes; then + output_obj="$obj" + command="$command -o $output_obj" + fi + + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test x"$output_obj" != x"$libobj"; then + $show "$mv $output_obj $libobj" + if $run $mv $output_obj $libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # If we have no pic_flag, then copy the object into place and finish. + if (test -z "$pic_flag" || test "$pic_mode" != default) && + test "$build_old_libs" = yes; then + # Rename the .lo from within objdir to obj + if test -f $obj; then + $show $rm $obj + $run $rm $obj + fi + + $show "$mv $libobj $obj" + if $run $mv $libobj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` + libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + # Now arrange that obj and lo_libobj become the same file + $show "(cd $xdir && $LN_S $baseobj $libobj)" + if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then + exit 0 + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $srcfile" + else + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $srcfile $pic_flag -DPIC" + fi + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + output_obj="$obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test x"$output_obj" != x"$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + else + # Move the .lo from within objdir + $show "$mv $libobj $lo_libobj" + if $run $mv $libobj $lo_libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + fi + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $run $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link | relink) + modename="$modename: link" + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invokation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args="$nonopt" + compile_command="$nonopt" + finalize_command="$nonopt" + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + + avoid_version=no + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -all-static | -static) + if test "X$arg" = "X-all-static"; then + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + shift + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test + ;; + *) qarg=$arg ;; + esac + libtool_args="$libtool_args $qarg" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case $prev in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + xcompiler) + compiler_flags="$compiler_flags $qarg" + prev= + compile_command="$compile_command $qarg" + finalize_command="$finalize_command $qarg" + continue + ;; + xlinker) + linker_flags="$linker_flags $qarg" + compiler_flags="$compiler_flags $wl$qarg" + prev= + compile_command="$compile_command $wl$qarg" + finalize_command="$finalize_command $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n $prev + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: more than one -exported-symbols argument is not allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix*) + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + ;; + esac + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 + exit 1 + fi + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "*) ;; + *) + deplibs="$deplibs -L$dir" + lib_search_path="$lib_search_path $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$dir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-pw32* | *-*-beos*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-mingw* | *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + esac + fi + deplibs="$deplibs $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + # The PATH hackery in wrapper scripts is required on Windows + # in order for the loader to find any dlls it needs. + $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 + $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -Wc,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` + arg= + IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Wl,*) + args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` + arg= + IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + case $flag in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + flag="\"$flag\"" + ;; + esac + arg="$arg $wl$flag" + compiler_flags="$compiler_flags $wl$flag" + linker_flags="$linker_flags $flag" + done + IFS="$save_ifs" + arg=`$echo "X$arg" | $Xsed -e "s/^ //"` + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + + *.lo | *.$objext) + # A library or standard object. + if test "$prev" = dlfiles; then + # This file was specified with -dlopen. + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + dlfiles="$dlfiles $arg" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` + prev= + else + case $arg in + *.lo) libobjs="$libobjs $arg" ;; + *) objs="$objs $arg" ;; + esac + fi + ;; + + *.$libext) + # An archive. + deplibs="$deplibs $arg" + old_deplibs="$old_deplibs $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + dlfiles="$dlfiles $arg" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + dlprefiles="$dlprefiles $arg" + prev= + else + deplibs="$deplibs $arg" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + arg="\"$arg\"" + ;; + esac + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done # argument parsing loop + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + # Create the object directory. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Determine the type of output + case $output in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + case "$libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + libs="$libs $deplib" + done + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + case $linkmode in + lib) + passes="conv link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 + exit 1 + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + for pass in $passes; do + if test "$linkmode" = prog; then + # Determine which files to process + case $pass in + dlopen) + libs="$dlfiles" + save_deplibs="$deplibs" # Collect dlpreopened libraries + deplibs= + ;; + dlpreopen) libs="$dlprefiles" ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + for deplib in $libs; do + lib= + found=no + case $deplib in + -l*) + if test "$linkmode" = oldlib && test "$linkmode" = obj; then + $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 + continue + fi + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` + for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do + # Search the libtool library + lib="$searchdir/lib${name}.la" + if test -f "$lib"; then + found=yes + break + fi + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + ;; + *) + $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) lib="$deplib" ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + if test "$deplibs_check_method" != pass_all; then + echo + echo "*** Warning: This library needs some functionality provided by $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + else + echo + echo "*** Warning: Linking the shared library $output against the" + echo "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + newdlprefiles="$newdlprefiles $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + newdlfiles="$newdlfiles $deplib" + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + if test $found = yes || test -f "$lib"; then : + else + $echo "$modename: cannot find the library \`$lib'" 1>&2 + exit 1 + fi + + # Check to see that this really is a libtool archive. + if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + + ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` + test "X$ladir" = "X$lib" && ladir="." + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" = oldlib && test "$linkmode" = obj; }; then + # Add dl[pre]opened files of deplib + test -n "$dlopen" && dlfiles="$dlfiles $dlopen" + test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $ladir/$objdir/$old_library" + old_convenience="$old_convenience $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + tmp_libs="$tmp_libs $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + $echo "$modename: \`$lib' is not a convenience library" 1>&2 + exit 1 + fi + continue + fi # $pass = conv + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 + exit 1 + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. + dlprefiles="$dlprefiles $lib" + else + newdlfiles="$newdlfiles $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + abs_ladir="$ladir" + fi + ;; + esac + laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + $echo "$modename: warning: library \`$lib' was moved." 1>&2 + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$libdir" + absdir="$libdir" + fi + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + notinst_path="$notinst_path $abs_ladir" + fi # $installed = yes + name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir"; then + $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 + exit 1 + fi + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + newdlprefiles="$newdlprefiles $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + newdlprefiles="$newdlprefiles $dir/$dlname" + else + newdlprefiles="$newdlprefiles $dir/$linklib" + fi + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" + fi + continue + fi + + if test "$linkmode" = prog && test "$pass" != link; then + newlib_search_path="$newlib_search_path $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test + esac + # Need to link against all dependency_libs? + if test $linkalldeplibs = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + tmp_libs="$tmp_libs $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + link_static=no # Whether the deplib will be linked statically + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + # Link against this shared library + + if test "$linkmode,$pass" = "prog,link" || + { test "$linkmode" = lib && test "$hardcode_into_libs" = yes; }; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + if test "$linkmode" = prog; then + # We need to hardcode the library path + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *" $absdir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + fi + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + if test "$installed" = no; then + notinst_deplibs="$notinst_deplibs $lib" + need_relink=yes + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + realname="$2" + shift; shift + libname=`eval \\$echo \"$libname_spec\"` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin*) + major=`expr $current - $age` + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + soname=`echo $soroot | sed -e 's/^.*\///'` + newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a" + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + $show "extracting exported symbol list from \`$soname'" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + eval cmds=\"$extract_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + $show "generating import library for \`$soname'" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + eval cmds=\"$old_archive_from_expsyms_cmds\" + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n $old_archive_from_expsyms_cmds + + if test "$linkmode" = prog || test "$mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && \ + test "$hardcode_minus_L" != yes && \ + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; + esac + add="-l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + + # Try to link the static library + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + echo "*** Warning: This library needs some functionality provided by $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** Therefore, libtool will create a static module, that should work " + echo "*** as long as the dlopening application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || test $build_old_libs = yes || + test $link_static = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + *) temp_deplibs="$temp_deplibs $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + newlib_search_path="$newlib_search_path $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case "$tmp_libs " in + *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; + esac + tmp_libs="$tmp_libs $deplib" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + case $deplib in + -L*) path="$deplib" ;; + *.la) + dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$deplib" && dir="." + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + absdir="$dir" + fi + ;; + esac + if grep "^installed=no" $deplib > /dev/null; then + path="-L$absdir/$objdir" + else + eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + if test "$absdir" != "$libdir"; then + $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 + fi + path="-L$absdir" + fi + ;; + *) continue ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$deplibs $path" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + test "$pass" != scan && dependency_libs="$newdependency_libs" + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + *) + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + ;; + *) tmp_libs="$tmp_libs $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + if test "$pass" = "conv" && + { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then + libs="$deplibs" # reset libs + deplibs= + fi + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + objs="$objs$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 + exit 1 + else + echo + echo "*** Warning: Linking the shared library $output against the non-libtool" + echo "*** objects $objs is not portable!" + libobjs="$libobjs $objs" + fi + fi + + if test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + libext=al + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case $current in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $revision in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case $age in + 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + minor_current=`expr $current + 1` + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + irix) + major=`expr $current - $age + 1` + verstring="sgi$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="sgi$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + major=`expr $current - $age` + versuffix="-$major" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + fi + + if test "$mode" != relink; then + # Remove our outputs. + $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" + $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + for path in $notinst_path; do + lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'` + deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'` + dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'` + done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + if test $hardcode_into_libs != yes || test $build_old_libs = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) dlfiles="$dlfiles $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) dlprefiles="$dlprefiles $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + deplibs="$deplibs -framework System" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + deplibs="$deplibs -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | sed 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | sed 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: This library needs some functionality provided by $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method + match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` + for a_deplib in $deplibs; do + name="`expr $a_deplib : '-l\(.*\)'`" + # If $name is empty we are operating on a -L argument. + if test -n "$name" && test "$name" != "0"; then + libname=`eval \\$echo \"$libname_spec\"` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + if eval echo \"$potent_lib\" 2>/dev/null \ + | sed 10q \ + | egrep "$match_pattern_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: This library needs some functionality provided by $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test $allow_undefined = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + dep_rpath="$dep_rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval dep_rpath=\"$hardcode_libdir_flag_spec\" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + test -z "$dlname" && dlname=$soname + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Ensure that we have .o objects for linkers which dislike .lo + # (e.g. aix) in case we are running --disable-static + for obj in $libobjs; do + xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$obj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + if test ! -f $xdir/$oldobj; then + $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" + $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? + fi + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linker_flags="$linker_flags $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$mode" = relink; then + $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? + exit 0 + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case $output in + *.lo) + if test -n "$objs$old_deplibs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show $rm $libobj + $run $rm $libobj + xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$libobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` + $show "(cd $xdir && $LN_S $oldobj $baseobj)" + $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + prog) + case $host in + *cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;; + esac + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` + ;; + esac + + compile_command="$compile_command $compile_deplibs" + finalize_command="$finalize_command $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) + case :$dllsearchpath: in + *":$libdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$libdir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case $dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | sed -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{\ +" + + sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \ + -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \ + < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr_t) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac;; + *-*-hpux*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test $need_relink = no || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $run $rm $output + # Link the executable and exit + $show "$link_command" + $run eval "$link_command" || exit $? + exit 0 + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + relink_command="cd `pwd`; $relink_command" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case $0 in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|sed 's,.exe$,,'` ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) exeext=.exe ;; + *) exeext= ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if (eval \$relink_command); then : + else + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + # win32 systems need to use the prog path for dll + # lookup to work + *-*-cygwin* | *-*-pw32*) + $echo >> $output "\ + exec \$progdir/\$program \${1+\"\$@\"} +" + ;; + + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2*) + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case $xlib in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + # Ensure that we have .o objects in place in case we decided + # not to build a shared library, and have fallen back to building + # static libs even though --disable-static was passed! + for oldobj in $oldobjs; do + if test ! -f $oldobj; then + xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$xdir" = "X$oldobj"; then + xdir="." + else + xdir="$xdir" + fi + baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` + obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` + $show "(cd $xdir && ${LN_S} $obj $baseobj)" + $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` + relink_command="$var=\"$var_value\"; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="cd `pwd`; $SHELL $0 --mode=relink $libtool_args" + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` + eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + if test -z "$libdir"; then + $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdependency_libs="$newdependency_libs $libdir/$name" + ;; + *) newdependency_libs="$newdependency_libs $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + for lib in $dlfiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlfiles="$newdlfiles $libdir/$name" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` + eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + if test -z "$libdir"; then + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + exit 1 + fi + newdlprefiles="$newdlprefiles $libdir/$name" + done + dlprefiles="$newdlprefiles" + fi + $rm $output + # place dlname in correct position for cygwin + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; + esac + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test $need_relink = yes; then + $echo >> $output "\ +relink_command=\"$relink_command\"" + fi + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case $arg in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + if test -n "$relink_command"; then + $echo "$modename: warning: relinking \`$file'" 1>&2 + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + continue + fi + fi + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$srcname $destdir/$realname" + $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? + if test -n "$stripme" && test -n "$striplib"; then + $show "$striplib $destdir/$realname" + $run eval "$striplib $destdir/$realname" || exit $? + fi + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + notinst_deplibs= + relink_command= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Check the variables that should have been set. + if test -z "$notinst_deplibs"; then + $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case $lib in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + relink_command= + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyways + case $install_prog,$host in + /usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + destfile=`echo $destfile | sed -e 's,.exe$,,'` + ;; + esac + ;; + esac + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + if test -n "$stripme" && test -n "$striplib"; then + $show "$old_striplib $oldlib" + $run eval "$old_striplib $oldlib" || exit $? + fi + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec $SHELL $0 --finish$current_libdirs + exit 1 + fi + + exit 0 + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = ":" && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case $file in + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case $file in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now actually exec the command. + eval "exec \$cmd$args" + + $echo "$modename: cannot exec \$cmd$args" + exit 1 + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + fi + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool clean and uninstall mode + clean | uninstall) + modename="$modename: $mode" + rm="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) rm="$rm $arg"; rmforce=yes ;; + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + rmdirs= + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$file"; then + dir=. + objdir="$objdir" + else + objdir="$dir/$objdir" + fi + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + test $mode = uninstall && objdir="$dir" + + # Remember objdir for removal later, being careful to avoid duplicates + if test $mode = clean; then + case " $rmdirs " in + *" $objdir "*) ;; + *) rmdirs="$rmdirs $objdir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if (test -L "$file") >/dev/null 2>&1 \ + || (test -h "$file") >/dev/null 2>&1 \ + || test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $objdir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" + test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" + + if test $mode = uninstall; then + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + if test $? != 0 && test "$rmforce" != yes; then + exit_status=1 + fi + done + IFS="$save_ifs" + fi + # FIXME: should reinstall the best remaining shared library. + fi + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + ;; + + *) + # Do a test to see if this is a libtool program. + if test $mode = clean && + (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + relink_command= + . $dir/$file + + rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + rmfiles="$rmfiles $objdir/lt-$name" + fi + fi + ;; + esac + $show "$rm $rmfiles" + $run $rm $rmfiles || exit_status=1 + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + $show "rmdir $dir" + $run rmdir $dir >/dev/null 2>&1 + fi + done + + exit $exit_status + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 +fi # test -z "$show_help" + +# We need to display help for each of the modes. +case $mode in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +clean) + $echo \ +"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -prefer-pic try to building PIC objects only + -prefer-non-pic try to building non-PIC objects only + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: -- cgit From 940d830204a87da484eec5e84f18281476c9a505 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 31 May 2002 17:14:39 +0000 Subject: -p print pid option --- tools/hciattach.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index a7f89e21..9668460c 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -647,30 +647,36 @@ extern char *optarg; int main(int argc, char *argv[]) { struct uart_t *u = NULL; - int detach, opt, i, n; + int detach, printpid, opt, i, n; int to = 5; + pid_t pid; struct sigaction sa; char dev[20]; detach = 1; + printpid = 0; - while ((opt=getopt(argc, argv, "nt:l")) != EOF) { + while ((opt=getopt(argc, argv, "npt:l")) != EOF) { switch(opt) { case 'n': detach = 0; break; - + + case 'p': + printpid = 1; + break; + case 't': to = atoi(optarg); break; - + case 'l': for (i = 0; uart[i].type; i++) { printf("%-10s0x%04x,0x%04x\n", uart[i].type, uart[i].m_id, uart[i].p_id); } exit(0); - + default: usage(); exit(1); @@ -747,7 +753,11 @@ int main(int argc, char *argv[]) alarm(0); if (detach) { - if (fork()) return 0; + if ((pid = fork())) { + if (printpid) + printf("%d\n", pid); + return 0; + } for (i=0; i<20; i++) if (i != n) close(i); } -- cgit From 8ee2371d4b948a541a71fce00e1cfde01ed364d8 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 16:48:50 +0000 Subject: Use library functions hci_for_each_dev and hci_get_route. Use new hci_inquiry function syntax. --- tools/hcitool.c | 125 +++++++++++++++----------------------------------------- 1 file changed, 33 insertions(+), 92 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 8ce64ed6..c2ad6186 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -51,62 +51,13 @@ extern char *optarg; #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) -static int ctl; - static void usage(void); -static int for_each_dev(int flag, int(*func)(int d, long arg), long arg) -{ - struct hci_dev_list_req *dl; - struct hci_dev_req *dr; - int i; - - dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); - if (!dl) { - perror("Can't allocate memory"); - return -1; - } - dl->dev_num = HCI_MAX_DEV; - dr = dl->dev_req; - - if (ioctl(ctl, HCIGETDEVLIST, (void*)dl)) { - perror("Can't get device list"); - return -1; - } - - if (!dl->dev_num) - return -1; - - for (i=0; i < dl->dev_num; i++, dr++) { - if (hci_test_bit(flag, &dr->dev_opt)) { - if (!func || func(dr->dev_id, arg)) - return dr->dev_id; - } - } - return -1; -} - -static int other_bdaddr(int dev_id, long arg) -{ - struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) - return 0; - return bacmp((bdaddr_t *)arg, &di.bdaddr); -} - -static int get_route(bdaddr_t *bdaddr) -{ - if (bdaddr) - return for_each_dev(HCI_UP, other_bdaddr, (long) bdaddr); - else - return for_each_dev(HCI_UP, NULL, 0); -} - -static int dev_info(int dev_id, long arg) +static int dev_info(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; bdaddr_t bdaddr; - if (ioctl(ctl, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) return 0; baswap(&bdaddr, &di.bdaddr); @@ -114,14 +65,17 @@ static int dev_info(int dev_id, long arg) return 0; } -static int rev_info(int dev_id, long arg) +static int rev_info(int s, int dev_id, long arg) { struct hci_version ver; + int id = arg; int dd; struct hci_request rq; unsigned char buf[102]; + if (id != -1 && dev_id != id) + return 0; dd = hci_open_dev(dev_id); if (dd < 0) { @@ -162,12 +116,16 @@ static int rev_info(int dev_id, long arg) return 0; } -static int conn_list(int dev_id, long arg) +static int conn_list(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; + int id = arg; int i; + if (id != -1 && dev_id != id) + return 0; + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { perror("Can't allocate memory"); exit(1); @@ -176,7 +134,7 @@ static int conn_list(int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { perror("Can't get connection list"); exit(1); } @@ -193,7 +151,7 @@ static int conn_list(int dev_id, long arg) return 0; } -static int find_conn(int dev_id, long arg) +static int find_conn(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; @@ -207,7 +165,7 @@ static int find_conn(int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(ctl, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { perror("Can't get connection list"); exit(1); } @@ -258,7 +216,7 @@ static void cmd_dev(int dev_id, int argc, char **argv) } printf("Devices:\n"); - for_each_dev(HCI_UP, dev_info, 0); + hci_for_each_dev(HCI_UP, dev_info, 0); } /* Inquiry */ @@ -280,7 +238,7 @@ static char *inq_help = static void cmd_inq(int dev_id, int argc, char **argv) { int num_rsp, length, flags; - inquiry_info *info; + inquiry_info *info = NULL; bdaddr_t bdaddr; int i, opt; @@ -308,13 +266,9 @@ static void cmd_inq(int dev_id, int argc, char **argv) } } - if (dev_id < 0) - dev_id = get_route(NULL); - printf("Inquiring ...\n"); - info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); - - if (!info) { + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + if (num_rsp < 0) { perror("Inquiry failed."); exit(1); } @@ -346,7 +300,7 @@ static char *scan_help = static void cmd_scan(int dev_id, int argc, char **argv) { - inquiry_info *info; + inquiry_info *info = NULL; int num_rsp, length, flags; bdaddr_t bdaddr; char name[248]; @@ -376,13 +330,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } - if (dev_id < 0) - dev_id = get_route(NULL); - printf("Scanning ...\n"); - info = hci_inquiry(dev_id, length, &num_rsp, NULL, flags); - - if (!info) { + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + if (num_rsp < 0) { perror("Inquiry failed."); exit(1); } @@ -434,7 +384,7 @@ static void cmd_name(int dev_id, int argc, char **argv) baswap(&bdaddr, strtoba(argv[0])); if (dev_id < 0) { - dev_id = get_route(&bdaddr); + dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr, "Device is not available.\n"); exit(1); @@ -492,7 +442,7 @@ static void cmd_info(int dev_id, int argc, char **argv) baswap(&bdaddr, strtoba(argv[0])); if (dev_id < 0) { - dev_id = get_route(&bdaddr); + dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr, "Device is not available.\n"); exit(1); @@ -573,7 +523,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) } if (dev_id < 0) - dev_id = get_route(NULL); + dev_id = hci_get_route(NULL); errno = 0; ogf = strtol(argv[0], NULL, 16); @@ -648,11 +598,7 @@ static void cmd_rev(int dev_id, int argc, char **argv) return; } } - - if (dev_id < 0) - for_each_dev(HCI_UP, rev_info, 0); - else - rev_info(dev_id, 0); + hci_for_each_dev(HCI_UP, rev_info, dev_id); } /* Display active connections */ @@ -679,10 +625,7 @@ static void cmd_con(int dev_id, int argc, char **argv) } printf("Connections:\n"); - if (dev_id < 0) - for_each_dev(HCI_UP, conn_list, 0); - else - conn_list(dev_id, 0); + hci_for_each_dev(HCI_UP, conn_list, dev_id); } /* Create connection */ @@ -737,7 +680,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) str2ba(argv[0], &bdaddr); if (dev_id < 0) { - dev_id = get_route(&bdaddr); + dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { fprintf(stderr, "Device is not available.\n"); exit(1); @@ -789,7 +732,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) str2ba(argv[0], &bdaddr); if (dev_id < 0) { - dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -856,7 +799,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) str2ba(argv[0], &bdaddr); if (dev_id < 0) { - dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -941,7 +884,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) hci_strtoptype(argv[1], &ptype); if (dev_id < 0) { - dev_id = for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -1032,6 +975,7 @@ static struct option main_options[] = { int main(int argc, char **argv) { int opt, i, dev_id = -1; + bdaddr_t ba; while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { @@ -1055,9 +999,8 @@ int main(int argc, char **argv) exit(0); } - /* Open HCI socket */ - if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { - perror("Can't open HCI socket."); + if (dev_id != -1 && hci_devba(dev_id, &ba) < 0) { + perror("Device is not available"); exit(1); } @@ -1067,7 +1010,5 @@ int main(int argc, char **argv) command[i].func(dev_id, argc, argv); break; } - - close(ctl); return 0; } -- cgit From 002edf82ee25e3161bb00e6c976aefcb11062ba1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 18:33:43 +0000 Subject: use hci_devid --- tools/hcitool.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index c2ad6186..96348342 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -980,7 +980,11 @@ int main(int argc, char **argv) while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { case 'i': - dev_id = atoi(optarg + 3); + dev_id = hci_devid(optarg); + if (dev_id < 0) { + perror("Invalid device"); + exit(1); + } break; case 'h': -- cgit From c02c1c574229696436c8d25bf578eecb2ca584ed Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 20:38:27 +0000 Subject: remove extra spaces. --- acinclude.m4 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 33dbbcd2..a2fa7784 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,5 +1,5 @@ dnl Test file -AC_DEFUN( AC_TEST_FILE, +AC_DEFUN([AC_TEST_FILE], [ if test -f $1; then ifelse([$2], , :,[$2]) @@ -9,7 +9,7 @@ AC_DEFUN( AC_TEST_FILE, ]) dnl Test dir -AC_DEFUN( AC_TEST_DIR, +AC_DEFUN([AC_TEST_DIR], [ if test -d $1; then ifelse([$2], , :,[$2]) @@ -19,7 +19,7 @@ AC_DEFUN( AC_TEST_DIR, ]) dnl Test files -AC_DEFUN( AC_TEST_FILES, +AC_DEFUN([AC_TEST_FILES], [ ac_file_found=yes for f in $1; do @@ -37,7 +37,7 @@ AC_DEFUN( AC_TEST_FILES, ]) dnl Search for headers, add path to CPPFLAGS if found -AC_DEFUN( AC_SEARCH_HEADERS, +AC_DEFUN([AC_SEARCH_HEADERS], [ AC_MSG_CHECKING("for $1") ac_hdr_found=no @@ -62,7 +62,7 @@ AC_DEFUN( AC_SEARCH_HEADERS, ]) dnl Search for library, add path to LIBS if found -AC_DEFUN( AC_SEARCH_LIB, +AC_DEFUN([AC_SEARCH_LIB], [ AC_MSG_CHECKING("for lib$1") -- cgit From 296ddcd87894b3fb9cf6c4140c6d199945091c3d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 20:39:47 +0000 Subject: update --- aclocal.m4 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/aclocal.m4 b/aclocal.m4 index 62d31720..ae6daf9d 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -11,7 +11,7 @@ dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A dnl PARTICULAR PURPOSE. dnl Test file -AC_DEFUN( AC_TEST_FILE, +AC_DEFUN([AC_TEST_FILE], [ if test -f $1; then ifelse([$2], , :,[$2]) @@ -21,7 +21,7 @@ AC_DEFUN( AC_TEST_FILE, ]) dnl Test dir -AC_DEFUN( AC_TEST_DIR, +AC_DEFUN([AC_TEST_DIR], [ if test -d $1; then ifelse([$2], , :,[$2]) @@ -31,7 +31,7 @@ AC_DEFUN( AC_TEST_DIR, ]) dnl Test files -AC_DEFUN( AC_TEST_FILES, +AC_DEFUN([AC_TEST_FILES], [ ac_file_found=yes for f in $1; do @@ -49,7 +49,7 @@ AC_DEFUN( AC_TEST_FILES, ]) dnl Search for headers, add path to CPPFLAGS if found -AC_DEFUN( AC_SEARCH_HEADERS, +AC_DEFUN([AC_SEARCH_HEADERS], [ AC_MSG_CHECKING("for $1") ac_hdr_found=no @@ -74,7 +74,7 @@ AC_DEFUN( AC_SEARCH_HEADERS, ]) dnl Search for library, add path to LIBS if found -AC_DEFUN( AC_SEARCH_LIB, +AC_DEFUN([AC_SEARCH_LIB], [ AC_MSG_CHECKING("for lib$1") -- cgit From f3e80c3e7a1d99badf8b1b0d59bc06caa055eb08 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 20:50:41 +0000 Subject: update --- ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index b1e6cada..2b39260c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +ver 2.0-pre10: + Support for reading RSSI, remote name and changing + connection type (hcitool). + Device initialization fixes (hcid). + Other minor fixes and improvements. + Build environment cleanup and fixes. + ver 2.0-pre9: Improved bluepin. Working X authentication. Improved hcitool. New flexible cmd syntax, additional commands. -- cgit From 7e8f6ce3e2783f5fdd9682983c6c8e1979989d0a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 20:51:09 +0000 Subject: Bump version number --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 5cc2f263..bdf0ddd8 100644 --- a/configure.in +++ b/configure.in @@ -9,7 +9,7 @@ dnl Guess host type. AC_CANONICAL_SYSTEM AC_CANONICAL_HOST -AM_INIT_AUTOMAKE(bluez-utils, 2.0) +AM_INIT_AUTOMAKE(bluez-utils, 2.0-pre10) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) -- cgit From 596c0840d5682ccae5f1805f92f32391608bfac8 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Jun 2002 00:24:30 +0000 Subject: scan command works again. --- tools/hcitool.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 96348342..ae03ee96 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -330,6 +330,14 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } + if (dev_id < 0) { + dev_id = hci_get_route(&bdaddr); + if (dev_id < 0) { + perror("Device is not available."); + exit(1); + } + } + printf("Scanning ...\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { @@ -337,15 +345,22 @@ static void cmd_scan(int dev_id, int argc, char **argv) exit(1); } + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + free(info); + exit(1); + } + for (i = 0; i < num_rsp; i++) { - dd = hci_open_dev(dev_id); memset(name, 0, sizeof(name)); if (hci_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - close(dd); baswap(&bdaddr, &(info+i)->bdaddr); - printf("\t%s\t%s\n", batostr(&bdaddr), name); + printf("\t%s\t%s\n", batostr(&bdaddr), name); } + + close(dd); free(info); } -- cgit From c7e67f2e3d1512db597270a03cf07f7ed6ab3eb1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Jun 2002 00:49:38 +0000 Subject: autogenerated by bootstrap --- aclocal.m4 | 3539 ------------------------------------------------------------ 1 file changed, 3539 deletions(-) delete mode 100644 aclocal.m4 diff --git a/aclocal.m4 b/aclocal.m4 deleted file mode 100644 index ae6daf9d..00000000 --- a/aclocal.m4 +++ /dev/null @@ -1,3539 +0,0 @@ -dnl aclocal.m4 generated automatically by aclocal 1.4-p5 - -dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl This program is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without -dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A -dnl PARTICULAR PURPOSE. - -dnl Test file -AC_DEFUN([AC_TEST_FILE], -[ - if test -f $1; then - ifelse([$2], , :,[$2]) - else - ifelse([$3], , :,[$3]) - fi -]) - -dnl Test dir -AC_DEFUN([AC_TEST_DIR], -[ - if test -d $1; then - ifelse([$2], , :,[$2]) - else - ifelse([$3], , :,[$3]) - fi -]) - -dnl Test files -AC_DEFUN([AC_TEST_FILES], -[ - ac_file_found=yes - for f in $1; do - if test ! -f $2/$f; then - ac_file_found=no - break; - fi - done - - if test "$ac_file_found" = "yes" ; then - ifelse([$3], , :,[$3]) - else - ifelse([$4], , :,[$4]) - fi -]) - -dnl Search for headers, add path to CPPFLAGS if found -AC_DEFUN([AC_SEARCH_HEADERS], -[ - AC_MSG_CHECKING("for $1") - ac_hdr_found=no - for p in $2; do - test -d $p || continue; - p=`cd $p && pwd` - AC_TEST_FILES($1, $p, - [ - ac_hdr_found=yes - break - ] - ) - done - if test "$ac_hdr_found" = "yes" ; then - CPPFLAGS="$CPPFLAGS -I$p" - AC_MSG_RESULT( [($p) yes] ) - ifelse([$3], , :,[$3]) - else - AC_MSG_RESULT("no") - ifelse([$4], , :,[$4]) - fi -]) - -dnl Search for library, add path to LIBS if found -AC_DEFUN([AC_SEARCH_LIB], -[ - AC_MSG_CHECKING("for lib$1") - - ac_save_LDFLAGS=$LDFLAGS - - ac_lib_found=no - for p in $3; do - test -d $p || continue; - p=`cd $p && pwd` - - # Check for libtool library - if test -f $p/lib$1.la; then - path=$p/.libs - else - path=$p - fi - - LDFLAGS="-L$path -l$1" - AC_TRY_LINK_FUNC($2, - [ - LIBS="$LIBS -L$p -l$1" - ac_lib_found=yes - break - ] - ) - done - if test "$ac_lib_found" = "yes" ; then - AC_MSG_RESULT( [($p) yes] ) - ifelse([$4], , :,[$4]) - else - AC_MSG_RESULT("no") - ifelse([$5], , :,[$5]) - fi - - LDFLAGS=$ac_save_LDFLAGS -]) - -# Do all the work for Automake. This macro actually does too much -- -# some checks are only needed if your package does certain things. -# But this isn't really a big deal. - -# serial 1 - -dnl Usage: -dnl AM_INIT_AUTOMAKE(package,version, [no-define]) - -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_REQUIRE([AC_PROG_INSTALL]) -PACKAGE=[$1] -AC_SUBST(PACKAGE) -VERSION=[$2] -AC_SUBST(VERSION) -dnl test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) -fi -ifelse([$3],, -AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) -AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) -AC_REQUIRE([AM_SANITY_CHECK]) -AC_REQUIRE([AC_ARG_PROGRAM]) -dnl FIXME This is truly gross. -missing_dir=`cd $ac_aux_dir && pwd` -AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) -AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) -AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) -AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) -AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) -AC_REQUIRE([AC_PROG_MAKE_SET])]) - -# -# Check to make sure that the build environment is sane. -# - -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftestfile -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` - if test "[$]*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftestfile` - fi - if test "[$]*" != "X $srcdir/configure conftestfile" \ - && test "[$]*" != "X conftestfile $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "[$]2" = conftestfile - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -rm -f conftest* -AC_MSG_RESULT(yes)]) - -dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) -dnl The program must properly implement --version. -AC_DEFUN([AM_MISSING_PROG], -[AC_MSG_CHECKING(for working $2) -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if ($2 --version) < /dev/null > /dev/null 2>&1; then - $1=$2 - AC_MSG_RESULT(found) -else - $1="$3/missing $2" - AC_MSG_RESULT(missing) -fi -AC_SUBST($1)]) - - -dnl AM_PROG_LEX -dnl Look for flex, lex or missing, then run AC_PROG_LEX and AC_DECL_YYTEXT -AC_DEFUN([AM_PROG_LEX], -[missing_dir=ifelse([$1],,`cd $ac_aux_dir && pwd`,$1) -AC_CHECK_PROGS(LEX, flex lex, "$missing_dir/missing flex") -AC_PROG_LEX -AC_DECL_YYTEXT]) - -# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- - -# serial 46 AC_PROG_LIBTOOL -AC_DEFUN([AC_PROG_LIBTOOL], -[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -# Prevent multiple expansion -define([AC_PROG_LIBTOOL], []) -]) - -AC_DEFUN([AC_LIBTOOL_SETUP], -[AC_PREREQ(2.13)dnl -AC_REQUIRE([AC_ENABLE_SHARED])dnl -AC_REQUIRE([AC_ENABLE_STATIC])dnl -AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_LD])dnl -AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl -AC_REQUIRE([AC_PROG_NM])dnl -AC_REQUIRE([AC_PROG_LN_S])dnl -AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl -AC_REQUIRE([AC_OBJEXT])dnl -AC_REQUIRE([AC_EXEEXT])dnl -dnl - -_LT_AC_PROG_ECHO_BACKSLASH -# Only perform the check for file, if the check method requires it -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - AC_PATH_MAGIC - fi - ;; -esac - -AC_CHECK_TOOL(RANLIB, ranlib, :) -AC_CHECK_TOOL(STRIP, strip, :) - -ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) -ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], -enable_win32_dll=yes, enable_win32_dll=no) - -AC_ARG_ENABLE(libtool-lock, - [ --disable-libtool-lock avoid locking (might break parallel builds)]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_SAVE - AC_LANG_C - AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_RESTORE]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; - -ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], -[*-*-cygwin* | *-*-mingw* | *-*-pw32*) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - - # recent cygwin and mingw systems supply a stub DllMain which the user - # can override, but on older systems we have to supply one - AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, - [AC_TRY_LINK([], - [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); - DllMain (0, 0, 0);], - [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) - - case $host/$CC in - *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) - # old mingw systems require "-dll" to link a DLL, while more recent ones - # require "-mdll" - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -mdll" - AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, - [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) - CFLAGS="$SAVE_CFLAGS" ;; - *-*-cygwin* | *-*-pw32*) - # cygwin systems need to pass --dll to the linker, and not link - # crt.o which will require a WinMain@16 definition. - lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; - esac - ;; - ]) -esac - -_LT_AC_LTCONFIG_HACK - -]) - -# _LT_AC_CHECK_DLFCN -# -------------------- -AC_DEFUN(_LT_AC_CHECK_DLFCN, -[AC_CHECK_HEADERS(dlfcn.h) -])# _LT_AC_CHECK_DLFCN - -# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE -# --------------------------------- -AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], -[AC_REQUIRE([AC_CANONICAL_HOST]) -AC_REQUIRE([AC_PROG_NM]) -AC_REQUIRE([AC_OBJEXT]) -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -[symcode='[BCDEGRST]'] - -# Regexp to match symbols that can be accessed directly from C. -[sympat='\([_A-Za-z][_A-Za-z0-9]*\)'] - -# Transform the above into a raw symbol and a C symbol. -symxfrm='\1 \2\3 \3' - -# Transform an extracted symbol line into a proper C declaration -lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" - -# Define system-specific variables. -case $host_os in -aix*) - [symcode='[BCDT]'] - ;; -cygwin* | mingw* | pw32*) - [symcode='[ABCDGISTW]'] - ;; -hpux*) # Its linker distinguishes data from code symbols - lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - ;; -irix*) - [symcode='[BCDEGRST]'] - ;; -solaris* | sysv5*) - [symcode='[BDT]'] - ;; -sysv4) - [symcode='[DFNSTU]'] - ;; -esac - -# Handle CRLF in mingw tool chain -opt_cr= -case $host_os in -mingw*) - opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then - [symcode='[ABCDGISTW]'] -fi - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Write the raw and C identifiers. -[lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"] - - # Check to see that the pipe works correctly. - pipe_works=no - rm -f conftest* - cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if egrep ' nm_test_var$' "$nlist" >/dev/null; then - if egrep ' nm_test_func$' "$nlist" >/dev/null; then - cat < conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' - - cat <> conftest.$ac_ext -#if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * -#else -# define lt_ptr_t char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr_t address; -} -[lt_preloaded_symbols[] =] -{ -EOF - sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" >> conftest.$ac_ext - cat <<\EOF >> conftest.$ac_ext - {0, (lt_ptr_t) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$no_builtin_flag" - if AC_TRY_EVAL(ac_link) && test -s conftest; then - pipe_works=yes - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&AC_FD_CC - fi - else - echo "cannot find nm_test_var in $nlist" >&AC_FD_CC - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC - fi - else - echo "$progname: failed program was:" >&AC_FD_CC - cat conftest.$ac_ext >&5 - fi - rm -f conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" -if test -z "$lt_cv_sys_global_symbol_pipe"; then - global_symbol_to_cdecl= -else - global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" -fi -if test -z "$global_symbol_pipe$global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi -]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE - -# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR -# --------------------------------- -AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR], -[# Find the correct PATH separator. Usually this is `:', but -# DJGPP uses `;' like DOS. -if test "X${PATH_SEPARATOR+set}" != Xset; then - UNAME=${UNAME-`uname 2>/dev/null`} - case X$UNAME in - *-DOS) lt_cv_sys_path_separator=';' ;; - *) lt_cv_sys_path_separator=':' ;; - esac -fi -])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR - -# _LT_AC_PROG_ECHO_BACKSLASH -# -------------------------- -# Add some code to the start of the generated configure script which -# will find an echo command which doesn;t interpret backslashes. -AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], -[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], - [AC_DIVERT_PUSH(NOTICE)]) -_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR - -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` - ;; -esac - -echo=${ECHO-echo} -if test "X[$]1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X[$]1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} -fi - -if test "X[$]1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null && - echo_test_string="`eval $cmd`" && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null - then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : -else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" - for dir in $PATH /usr/ucb; do - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} - else - # Try using printf. - echo='printf %s\n' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL [$]0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$CONFIG_SHELL [$]0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "[$]0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -ECHO=$echo -if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then - ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" -fi - -AC_SUBST(ECHO) -AC_DIVERT_POP -])# _LT_AC_PROG_ECHO_BACKSLASH - -# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ------------------------------------------------------------------ -AC_DEFUN(_LT_AC_TRY_DLOPEN_SELF, -[if test "$cross_compiling" = yes; then : - [$4] -else - AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -}] -EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_unknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_AC_TRY_DLOPEN_SELF - -# AC_LIBTOOL_DLOPEN_SELF -# ------------------- -AC_DEFUN(AC_LIBTOOL_DLOPEN_SELF, -[if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - cygwin* | mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - *) - AC_CHECK_LIB(dl, dlopen, [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_FUNC(dlopen, lt_cv_dlopen="dlopen", - [AC_CHECK_FUNC(shl_load, lt_cv_dlopen="shl_load", - [AC_CHECK_LIB(svld, dlopen, - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB(dld, shl_load, - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -])# AC_LIBTOOL_DLOPEN_SELF - -AC_DEFUN([_LT_AC_LTCONFIG_HACK], -[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e s/^X//' -[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] - -# Same as above, but do not quote variable references. -[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Constants: -rm="rm -f" - -# Global variables: -default_ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -libext=a -ltmain="$ac_aux_dir/ltmain.sh" -ofile="$default_ofile" -with_gnu_ld="$lt_cv_prog_gnu_ld" -need_locks="$enable_libtool_lock" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -test -z "$AS" && AS=as -test -z "$CC" && CC=cc -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$LD" && LD=ld -test -z "$LN_S" && LN_S="ln -s" -test -z "$MAGIC_CMD" && MAGIC_CMD=file -test -z "$NM" && NM=nm -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$RANLIB" && RANLIB=: -test -z "$STRIP" && STRIP=: -test -z "$ac_objext" && ac_objext=o - -if test x"$host" != x"$build"; then - ac_tool_prefix=${host_alias}- -else - ac_tool_prefix= -fi - -# Transform linux* to *-*-linux-gnu*, to support old configure scripts. -case $host_os in -linux-gnu*) ;; -linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` -esac - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" -fi - -# Allow CC to be a program name with arguments. -set dummy $CC -compiler="[$]2" - -AC_MSG_CHECKING([for objdir]) -rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - objdir=_libs -fi -rmdir .libs 2>/dev/null -AC_MSG_RESULT($objdir) - - -AC_ARG_WITH(pic, -[ --with-pic try to use only PIC/non-PIC objects [default=use both]], -pic_mode="$withval", pic_mode=default) -test -z "$pic_mode" && pic_mode=default - -# We assume here that the value for lt_cv_prog_cc_pic will not be cached -# in isolation, and that seeing it set (from the cache) indicates that -# the associated values are set (in the cache) correctly too. -AC_MSG_CHECKING([for $compiler option to produce PIC]) -AC_CACHE_VAL(lt_cv_prog_cc_pic, -[ lt_cv_prog_cc_pic= - lt_cv_prog_cc_shlib= - lt_cv_prog_cc_wl= - lt_cv_prog_cc_static= - lt_cv_prog_cc_no_builtin= - lt_cv_prog_cc_can_build_shared=$can_build_shared - - if test "$GCC" = yes; then - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static='-static' - - case $host_os in - aix*) - # Below there is a dirty hack to force normal static linking with -ldl - # The problem is because libdl dynamically linked with both libc and - # libC (AIX C++ library), which obviously doesn't included in libraries - # list by gcc. This cause undefined symbols with -static flags. - # This hack allows C programs to be linked with "-static -ldl", but - # we not sure about C++ programs. - lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' - ;; - beos* | irix5* | irix6* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_cv_prog_cc_pic='-fno-common' - ;; - cygwin* | mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_cv_prog_cc_pic='-DDLL_EXPORT' - ;; - sysv4*MP*) - if test -d /usr/nec; then - lt_cv_prog_cc_pic=-Kconform_pic - fi - ;; - *) - lt_cv_prog_cc_pic='-fPIC' - ;; - esac - else - # PORTME Check for PIC flags for the system compiler. - case $host_os in - aix3* | aix4* | aix5*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_cv_prog_cc_static='-Bstatic' - lt_cv_prog_cc_wl='-Wl,' - else - lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - hpux9* | hpux10* | hpux11*) - # Is there a better lt_cv_prog_cc_static that works with the bundled CC? - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" - lt_cv_prog_cc_pic='+Z' - ;; - - irix5* | irix6*) - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static='-non_shared' - # PIC (with -KPIC) is the default. - ;; - - cygwin* | mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_cv_prog_cc_pic='-DDLL_EXPORT' - ;; - - newsos6) - lt_cv_prog_cc_pic='-KPIC' - lt_cv_prog_cc_static='-Bstatic' - ;; - - osf3* | osf4* | osf5*) - # All OSF/1 code is PIC. - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static='-non_shared' - ;; - - sco3.2v5*) - lt_cv_prog_cc_pic='-Kpic' - lt_cv_prog_cc_static='-dn' - lt_cv_prog_cc_shlib='-belf' - ;; - - solaris*) - lt_cv_prog_cc_pic='-KPIC' - lt_cv_prog_cc_static='-Bstatic' - lt_cv_prog_cc_wl='-Wl,' - ;; - - sunos4*) - lt_cv_prog_cc_pic='-PIC' - lt_cv_prog_cc_static='-Bstatic' - lt_cv_prog_cc_wl='-Qoption ld ' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - lt_cv_prog_cc_pic='-KPIC' - lt_cv_prog_cc_static='-Bstatic' - if test "x$host_vendor" = xsni; then - lt_cv_prog_cc_wl='-LD' - else - lt_cv_prog_cc_wl='-Wl,' - fi - ;; - - uts4*) - lt_cv_prog_cc_pic='-pic' - lt_cv_prog_cc_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_cv_prog_cc_pic='-Kconform_pic' - lt_cv_prog_cc_static='-Bstatic' - fi - ;; - - *) - lt_cv_prog_cc_can_build_shared=no - ;; - esac - fi -]) -if test -z "$lt_cv_prog_cc_pic"; then - AC_MSG_RESULT([none]) -else - AC_MSG_RESULT([$lt_cv_prog_cc_pic]) - - # Check to make sure the pic_flag actually works. - AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works]) - AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" - AC_TRY_COMPILE([], [], [dnl - case $host_os in - hpux9* | hpux10* | hpux11*) - # On HP-UX, both CC and GCC only warn that PIC is supported... then - # they create non-PIC objects. So, if there were any warnings, we - # assume that PIC is not supported. - if test -s conftest.err; then - lt_cv_prog_cc_pic_works=no - else - lt_cv_prog_cc_pic_works=yes - fi - ;; - *) - lt_cv_prog_cc_pic_works=yes - ;; - esac - ], [dnl - lt_cv_prog_cc_pic_works=no - ]) - CFLAGS="$save_CFLAGS" - ]) - - if test "X$lt_cv_prog_cc_pic_works" = Xno; then - lt_cv_prog_cc_pic= - lt_cv_prog_cc_can_build_shared=no - else - lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" - fi - - AC_MSG_RESULT([$lt_cv_prog_cc_pic_works]) -fi - -# Check for any special shared library compilation flags. -if test -n "$lt_cv_prog_cc_shlib"; then - AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries]) - if echo "$old_CC $old_CFLAGS " | [egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]"] >/dev/null; then : - else - AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure]) - lt_cv_prog_cc_can_build_shared=no - fi -fi - -AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works]) -AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl - lt_cv_prog_cc_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" - AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes]) - LDFLAGS="$save_LDFLAGS" -]) - -# Belt *and* braces to stop my trousers falling down: -test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= -AC_MSG_RESULT([$lt_cv_prog_cc_static_works]) - -pic_flag="$lt_cv_prog_cc_pic" -special_shlib_compile_flags="$lt_cv_prog_cc_shlib" -wl="$lt_cv_prog_cc_wl" -link_static_flag="$lt_cv_prog_cc_static" -no_builtin_flag="$lt_cv_prog_cc_no_builtin" -can_build_shared="$lt_cv_prog_cc_can_build_shared" - - -# Check to see if options -o and -c are simultaneously supported by compiler -AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext]) -AC_CACHE_VAL([lt_cv_compiler_c_o], [ -$rm -r conftest 2>/dev/null -mkdir conftest -cd conftest -echo "int some_variable = 0;" > conftest.$ac_ext -mkdir out -# According to Tom Tromey, Ian Lance Taylor reported there are C compilers -# that will create temporary files in the current directory regardless of -# the output directory. Thus, making CWD read-only will cause this test -# to fail, enabling locking or at least warning the user not to do parallel -# builds. -chmod -w . -save_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" -compiler_c_o=no -if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s out/conftest.err; then - lt_cv_compiler_c_o=no - else - lt_cv_compiler_c_o=yes - fi -else - # Append any errors to the config.log. - cat out/conftest.err 1>&AC_FD_CC - lt_cv_compiler_c_o=no -fi -CFLAGS="$save_CFLAGS" -chmod u+w . -$rm conftest* out/* -rmdir out -cd .. -rmdir conftest -$rm -r conftest 2>/dev/null -]) -compiler_c_o=$lt_cv_compiler_c_o -AC_MSG_RESULT([$compiler_c_o]) - -if test x"$compiler_c_o" = x"yes"; then - # Check to see if we can write to a .lo - AC_MSG_CHECKING([if $compiler supports -c -o file.lo]) - AC_CACHE_VAL([lt_cv_compiler_o_lo], [ - lt_cv_compiler_o_lo=no - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -c -o conftest.lo" - AC_TRY_COMPILE([], [int some_variable = 0;], [dnl - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - lt_cv_compiler_o_lo=no - else - lt_cv_compiler_o_lo=yes - fi - ]) - CFLAGS="$save_CFLAGS" - ]) - compiler_o_lo=$lt_cv_compiler_o_lo - AC_MSG_RESULT([$compiler_o_lo]) -else - compiler_o_lo=no -fi - -# Check to see if we can do hard links to lock some files if needed -hard_links="nottested" -if test "$compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi - -if test "$GCC" = yes; then - # Check to see if options -fno-rtti -fno-exceptions are supported by compiler - AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions]) - echo "int some_variable = 0;" > conftest.$ac_ext - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" - compiler_rtti_exceptions=no - AC_TRY_COMPILE([], [int some_variable = 0;], [dnl - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - compiler_rtti_exceptions=no - else - compiler_rtti_exceptions=yes - fi - ]) - CFLAGS="$save_CFLAGS" - AC_MSG_RESULT([$compiler_rtti_exceptions]) - - if test "$compiler_rtti_exceptions" = "yes"; then - no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' - else - no_builtin_flag=' -fno-builtin' - fi -fi - -# See if the linker supports building shared libraries. -AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries]) - -allow_undefined_flag= -no_undefined_flag= -need_lib_prefix=unknown -need_version=unknown -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -archive_cmds= -archive_expsym_cmds= -old_archive_from_new_cmds= -old_archive_from_expsyms_cmds= -export_dynamic_flag_spec= -whole_archive_flag_spec= -thread_safe_flag_spec= -hardcode_into_libs=no -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no -hardcode_shlibpath_var=unsupported -runpath_var= -link_all_deplibs=unknown -always_export_symbols=no -export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' -# include_expsyms should be a list of space-separated symbols to be *always* -# included in the symbol list -include_expsyms= -# exclude_expsyms can be an egrep regular expression of symbols to exclude -# it will be wrapped by ` (' and `)$', so one must not match beginning or -# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', -# as well as any symbol that contains `d'. -exclude_expsyms="_GLOBAL_OFFSET_TABLE_" -# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out -# platforms (ab)use it in PIC code, but their linkers get confused if -# the symbol is explicitly referenced. Since portable code cannot -# rely on this symbol name, it's probably fine to never include it in -# preloaded symbol tables. -extract_expsyms_cmds= - -case $host_os in -cygwin* | mingw* | pw32* ) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX, the GNU linker is very broken - # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. - ld_shlibs=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can use - # them. - ld_shlibs=no - ;; - - beos*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - allow_undefined_flag=unsupported - always_export_symbols=yes - - extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ - sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ - test -f $output_objdir/impgen.exe || (cd $output_objdir && \ - if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ - else $CC -o impgen impgen.c ; fi)~ - $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' - - old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' - - # cygwin and mingw dlls have different entry points and sets of symbols - # to exclude. - # FIXME: what about values for MSVC? - dll_entry=__cygwin_dll_entry@12 - dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ - case $host_os in - mingw*) - # mingw values - dll_entry=_DllMainCRTStartup@12 - dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ - ;; - esac - - # mingw and cygwin differ, and it's simplest to just exclude the union - # of the two symbol sets. - dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 - - # recent cygwin and mingw systems supply a stub DllMain which the user - # can override, but on older systems we have to supply one (in ltdll.c) - if test "x$lt_cv_need_dllmain" = "xyes"; then - ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " - ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < [$]0 > $output_objdir/$soname-ltdll.c~ - test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' - else - ltdll_obj= - ltdll_cmds= - fi - - # Extract the symbol export list from an `--export-all' def file, - # then regenerate the def file from the symbol export list, so that - # the compiled dll only exports the symbol export list. - # Be careful not to strip the DATA tag left be newer dlltools. - export_symbols_cmds="$ltdll_cmds"' - $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ - [sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//"] < $output_objdir/$soname-def > $export_symbols' - - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is. - # If DATA tags from a recent dlltool are present, honour them! - archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname-def; - else - echo EXPORTS > $output_objdir/$soname-def; - _lt_hint=1; - cat $export_symbols | while read symbol; do - set dummy \$symbol; - case \[$]# in - 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; - *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; - esac; - _lt_hint=`expr 1 + \$_lt_hint`; - done; - fi~ - '"$ltdll_cmds"' - $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ - $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ - $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - case $host_os in - cygwin* | mingw* | pw32*) - # dlltool doesn't understand --whole-archive et. al. - whole_archive_flag_spec= - ;; - *) - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - ;; - esac - fi -else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix4* | aix5*) - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_libdir_separator=':' - if test "$GCC" = yes; then - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - shared_flag='-shared' - else - if test "$host_cpu" = ia64; then - shared_flag='-G' - else - shared_flag='${wl}-bM:SRE' - fi - hardcode_direct=yes - fi - - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # Test if we are trying to use run time linking, or normal AIX style linking. - # If -brtl is somewhere in LDFLAGS, we need to do run time linking. - aix_use_runtimelinking=no - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl" ); then - aix_use_runtimelinking=yes - break - fi - done - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - # It seems that -bexpall can do strange things, so it is better to - # generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' - allow_undefined_flag=' -Wl,-G' - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-znodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' - # Warning - without using the other run time loading flags, -berok will - # link without error, but may produce a broken library. - allow_undefined_flag='${wl}-berok' - # This is a bit strange, but is similar to how AIX traditionally builds - # it's shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' - fi - fi - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - ;; - - darwin* | rhapsody*) - allow_undefined_flag='-undefined suppress' - # FIXME: Relying on posixy $() will cause problems for - # cross-compilation, but unfortunately the echo tests do not - # yet detect zsh echo's removal of \ escapes. - archive_cmds='$CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linkopts -install_name $rpath/$soname $(test -n "$verstring" -a x$verstring != x0.0 && echo $verstring)' - # We need to add '_' to the symbols in $export_symbols first - #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' - hardcode_direct=yes - hardcode_shlibpath_var=no - whole_archive_flag_spec='-all_load $convenience' - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd*) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9* | hpux10* | hpux11*) - case $host_os in - hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; - *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; - esac - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_minus_L=yes # Not in the search PATH, but as the default - # location of the library. - export_dynamic_flag_spec='${wl}-E' - ;; - - irix5* | irix6*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - link_all_deplibs=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - openbsd*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' - - #Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - - sco3.2v5*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - no_undefined_flag=' -z defs' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - [solaris2.[0-5] | solaris2.[0-5].*]) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - if test "x$host_vendor" = xsno; then - archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linkopts' - hardcode_direct=yes # is this really true??? - else - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv5*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec= - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=no - hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5uw7* | unixware7*) - no_undefined_flag='${wl}-z ${wl}text' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac -fi -AC_MSG_RESULT([$ld_shlibs]) -test "$ld_shlibs" = no && can_build_shared=no - -# Check hardcoding attributes. -AC_MSG_CHECKING([how to hardcode library paths into programs]) -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || \ - test -n "$runpath_var"; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$hardcode_shlibpath_var" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -AC_MSG_RESULT([$hardcode_action]) - -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -reload_cmds='$LD$reload_flag -o $output$reload_objs' -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -# PORTME Fill in your ld.so characteristics -AC_MSG_CHECKING([dynamic linker characteristics]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}.so$major' - ;; - -aix4* | aix5*) - version_type=linux - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - [ aix4 | aix4.[01] | aix4.[01].*)] - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so instead of - # lib.a to let people know that these are not typical AIX shared libraries. - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}.so$major' - fi - shlibpath_var=LIBPATH - deplibs_check_method=pass_all - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | [$Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\'']`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}.so' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - export_dynamic_flag_spec=-rdynamic - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - need_version=no - need_lib_prefix=no - case $GCC,$host_os in - yes,cygwin*) - library_names_spec='$libname.dll.a' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll' - postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog .libs/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - ;; - yes,mingw*) - library_names_spec='${libname}`echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"` - ;; - yes,pw32*) - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' - ;; - *) - library_names_spec='${libname}`echo ${release} | [sed -e 's/[.]/-/g']`${versuffix}.dll $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - # FIXME: Relying on posixy $() will cause problems for - # cross-compilation, but unfortunately the echo tests do not - # yet detect zsh echo's removal of \ escapes. - library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' - soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - *) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - dynamic_linker="$host_os dld.sl" - version_type=sunos - need_lib_prefix=no - need_version=no - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' - soname_spec='${libname}${release}.sl$major' - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6*) - version_type=irix - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' - case $host_os in - irix5*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux-gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' - soname_spec='${libname}${release}.so$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - need_version=no - fi - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - ;; - -os2*) - libname_spec='$name' - need_lib_prefix=no - library_names_spec='$libname.dll $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_version=no - soname_spec='${libname}${release}.so' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' - soname_spec='$libname.so.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -# Report the final consequences. -AC_MSG_CHECKING([if libtool supports shared libraries]) -AC_MSG_RESULT([$can_build_shared]) - -if test "$hardcode_action" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -AC_LIBTOOL_DLOPEN_SELF - -if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_MSG_CHECKING([whether -lc should be explicitly linked in]) - AC_CACHE_VAL([lt_cv_archive_cmds_need_lc], - [$rm conftest* - echo 'static int dummy;' > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile); then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_cv_prog_cc_wl - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) - then - lt_cv_archive_cmds_need_lc=no - else - lt_cv_archive_cmds_need_lc=yes - fi - allow_undefined_flag=$save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi]) - AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc]) - ;; - esac -fi -need_lc=${lt_cv_archive_cmds_need_lc-yes} - -# The second clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - : -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - test -f Makefile && make "$ltmain" -fi - -if test -f "$ltmain"; then - trap "$rm \"${ofile}T\"; exit 1" 1 2 15 - $rm -f "${ofile}T" - - echo creating $ofile - - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS \ - AR AR_FLAGS CC LD LN_S NM SHELL \ - reload_flag reload_cmds wl \ - pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ - thread_safe_flag_spec whole_archive_flag_spec libname_spec \ - library_names_spec soname_spec \ - RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ - old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ - postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ - old_striplib striplib file_magic_cmd export_symbols_cmds \ - deplibs_check_method allow_undefined_flag no_undefined_flag \ - finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ - hardcode_libdir_flag_spec hardcode_libdir_separator \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do - - case $var in - reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ - extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - cat <<__EOF__ > "${ofile}T" -#! $SHELL - -# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996-2000 Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="sed -e s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -# ### BEGIN LIBTOOL CONFIG - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$need_lc - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# The default C compiler. -CC=$lt_CC - -# Is the compiler the GNU C compiler? -with_gcc=$GCC - -# The linker used to build libraries. -LD=$lt_LD - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_wl - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_pic_flag -pic_mode=$pic_mode - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_compiler_c_o - -# Can we write directly to a .lo ? -compiler_o_lo=$lt_compiler_o_lo - -# Must we lock files when doing compilation ? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_link_static_flag - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_no_builtin_flag - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_global_symbol_to_cdecl - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# ### END LIBTOOL CONFIG - -__EOF__ - - case $host_os in - aix3*) - cat <<\EOF >> "${ofile}T" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - case $host_os in - cygwin* | mingw* | pw32* | os2*) - cat <<'EOF' >> "${ofile}T" - # This is a source program that is used to create dlls on Windows - # Don't remove nor modify the starting and closing comments -# /* ltdll.c starts here */ -# #define WIN32_LEAN_AND_MEAN -# #include -# #undef WIN32_LEAN_AND_MEAN -# #include -# -# #ifndef __CYGWIN__ -# # ifdef __CYGWIN32__ -# # define __CYGWIN__ __CYGWIN32__ -# # endif -# #endif -# -# #ifdef __cplusplus -# extern "C" { -# #endif -# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); -# #ifdef __cplusplus -# } -# #endif -# -# #ifdef __CYGWIN__ -# #include -# DECLARE_CYGWIN_DLL( DllMain ); -# #endif -# HINSTANCE __hDllInstance_base; -# -# BOOL APIENTRY -# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) -# { -# __hDllInstance_base = hInst; -# return TRUE; -# } -# /* ltdll.c ends here */ - # This is a source program that is used to create import libraries - # on Windows for dlls which lack them. Don't remove nor modify the - # starting and closing comments -# /* impgen.c starts here */ -# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. -# -# This file is part of GNU libtool. -# -# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# */ -# -# #include /* for printf() */ -# #include /* for open(), lseek(), read() */ -# #include /* for O_RDONLY, O_BINARY */ -# #include /* for strdup() */ -# -# /* O_BINARY isn't required (or even defined sometimes) under Unix */ -# #ifndef O_BINARY -# #define O_BINARY 0 -# #endif -# -# static unsigned int -# pe_get16 (fd, offset) -# int fd; -# int offset; -# { -# unsigned char b[2]; -# lseek (fd, offset, SEEK_SET); -# read (fd, b, 2); -# return b[0] + (b[1]<<8); -# } -# -# static unsigned int -# pe_get32 (fd, offset) -# int fd; -# int offset; -# { -# unsigned char b[4]; -# lseek (fd, offset, SEEK_SET); -# read (fd, b, 4); -# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); -# } -# -# static unsigned int -# pe_as32 (ptr) -# void *ptr; -# { -# unsigned char *b = ptr; -# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); -# } -# -# int -# main (argc, argv) -# int argc; -# char *argv[]; -# { -# int dll; -# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; -# unsigned long export_rva, export_size, nsections, secptr, expptr; -# unsigned long name_rvas, nexp; -# unsigned char *expdata, *erva; -# char *filename, *dll_name; -# -# filename = argv[1]; -# -# dll = open(filename, O_RDONLY|O_BINARY); -# if (dll < 1) -# return 1; -# -# dll_name = filename; -# -# for (i=0; filename[i]; i++) -# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') -# dll_name = filename + i +1; -# -# pe_header_offset = pe_get32 (dll, 0x3c); -# opthdr_ofs = pe_header_offset + 4 + 20; -# num_entries = pe_get32 (dll, opthdr_ofs + 92); -# -# if (num_entries < 1) /* no exports */ -# return 1; -# -# export_rva = pe_get32 (dll, opthdr_ofs + 96); -# export_size = pe_get32 (dll, opthdr_ofs + 100); -# nsections = pe_get16 (dll, pe_header_offset + 4 +2); -# secptr = (pe_header_offset + 4 + 20 + -# pe_get16 (dll, pe_header_offset + 4 + 16)); -# -# expptr = 0; -# for (i = 0; i < nsections; i++) -# { -# char sname[8]; -# unsigned long secptr1 = secptr + 40 * i; -# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); -# unsigned long vsize = pe_get32 (dll, secptr1 + 16); -# unsigned long fptr = pe_get32 (dll, secptr1 + 20); -# lseek(dll, secptr1, SEEK_SET); -# read(dll, sname, 8); -# if (vaddr <= export_rva && vaddr+vsize > export_rva) -# { -# expptr = fptr + (export_rva - vaddr); -# if (export_rva + export_size > vaddr + vsize) -# export_size = vsize - (export_rva - vaddr); -# break; -# } -# } -# -# expdata = (unsigned char*)malloc(export_size); -# lseek (dll, expptr, SEEK_SET); -# read (dll, expdata, export_size); -# erva = expdata - export_rva; -# -# nexp = pe_as32 (expdata+24); -# name_rvas = pe_as32 (expdata+32); -# -# printf ("EXPORTS\n"); -# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) - - mv -f "${ofile}T" "$ofile" || \ - (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") - chmod +x "$ofile" -fi - -])# _LT_AC_LTCONFIG_HACK - -# AC_LIBTOOL_DLOPEN - enable checks for dlopen support -AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) - -# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's -AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) - -# AC_ENABLE_SHARED - implement the --enable-shared flag -# Usage: AC_ENABLE_SHARED[(DEFAULT)] -# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to -# `yes'. -AC_DEFUN([AC_ENABLE_SHARED], -[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE(shared, -changequote(<<, >>)dnl -<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], -changequote([, ])dnl -[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. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac], -enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl -]) - -# AC_DISABLE_SHARED - set the default shared flag to --disable-shared -AC_DEFUN([AC_DISABLE_SHARED], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_SHARED(no)]) - -# AC_ENABLE_STATIC - implement the --enable-static flag -# Usage: AC_ENABLE_STATIC[(DEFAULT)] -# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to -# `yes'. -AC_DEFUN([AC_ENABLE_STATIC], -[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE(static, -changequote(<<, >>)dnl -<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], -changequote([, ])dnl -[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. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac], -enable_static=AC_ENABLE_STATIC_DEFAULT)dnl -]) - -# AC_DISABLE_STATIC - set the default static flag to --disable-static -AC_DEFUN([AC_DISABLE_STATIC], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_STATIC(no)]) - - -# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag -# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] -# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to -# `yes'. -AC_DEFUN([AC_ENABLE_FAST_INSTALL], -[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE(fast-install, -changequote(<<, >>)dnl -<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], -changequote([, ])dnl -[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. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac], -enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl -]) - -# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install -AC_DEFUN([AC_DISABLE_FAST_INSTALL], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_FAST_INSTALL(no)]) - -# AC_LIBTOOL_PICMODE - implement the --with-pic flag -# Usage: AC_LIBTOOL_PICMODE[(MODE)] -# Where MODE is either `yes' or `no'. If omitted, it defaults to -# `both'. -AC_DEFUN([AC_LIBTOOL_PICMODE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -pic_mode=ifelse($#,1,$1,default)]) - - -# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library -AC_DEFUN([AC_PATH_TOOL_PREFIX], -[AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in - /*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; - ?:/*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. - ;; - *) - ac_save_MAGIC_CMD="$MAGIC_CMD" - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="ifelse([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - egrep "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$ac_save_ifs" - MAGIC_CMD="$ac_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -]) - - -# AC_PATH_MAGIC - find a file program which can recognise a shared library -AC_DEFUN([AC_PATH_MAGIC], -[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl -AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) - else - MAGIC_CMD=: - fi -fi -]) - - -# AC_PROG_LD - find the path to the GNU or non-GNU linker -AC_DEFUN([AC_PROG_LD], -[AC_ARG_WITH(gnu-ld, -[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], -test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by GCC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]* | [A-Za-z]:[\\/]*)] - [re_direlt='/[^/][^/]*/\.\./'] - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - lt_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$lt_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_PROG_LD_GNU -]) - -# AC_PROG_LD_GNU - -AC_DEFUN([AC_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 &5; then - lt_cv_prog_gnu_ld=yes -else - lt_cv_prog_gnu_ld=no -fi]) -with_gnu_ld=$lt_cv_prog_gnu_ld -]) - -# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker -# -- PORTME Some linkers may need a different reload flag. -AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], -[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, -[lt_cv_ld_reload_flag='-r']) -reload_flag=$lt_cv_ld_reload_flag -test -n "$reload_flag" && reload_flag=" $reload_flag" -]) - -# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies -# -- PORTME fill in with the dynamic library characteristics -AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], -[AC_CACHE_CHECK([how to recognise dependant libraries], -lt_cv_deplibs_check_method, -[lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# ['file_magic [regex]'] -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given egrep regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix4* | aix5*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi4*) - [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'] - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin* | mingw* | pw32*) - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' - lt_cv_file_magic_cmd='/usr/bin/file -L' - case "$host_os" in - rhapsody* | darwin1.[012]) - lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` - ;; - *) # Darwin 1.3 on - lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' - ;; - esac - ;; - -freebsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - [lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'] - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20*|hpux11*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'] - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - -irix5* | irix6*) - case $host_os in - irix5*) - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" - ;; - *) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - # this will be overridden with pass_all, but let us keep it just in case - [lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"] - ;; - esac - lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux-gnu*) - case $host_cpu in - alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | s390* ) - lt_cv_deplibs_check_method=pass_all ;; - *) - # glibc up to 2.1.1 does not perform some relocations on ARM - [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;] - esac - lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'] - else - [lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'] - fi - ;; - -newos6*) - [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'] - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -osf3* | osf4* | osf5*) - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' - lt_cv_file_magic_test_file=/shlib/libc.so - lt_cv_deplibs_check_method=pass_all - ;; - -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - lt_cv_file_magic_test_file=/lib/libc.so - ;; - -[sysv5uw[78]* | sysv4*uw2*)] - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - case $host_vendor in - motorola) - [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'] - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - [lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'] - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - [lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"] - lt_cv_file_magic_test_file=/lib/libc.so - ;; - esac - ;; -esac -]) -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -]) - - -# AC_PROG_NM - find the path to a BSD-compatible name lister -AC_DEFUN([AC_PROG_NM], -[AC_MSG_CHECKING([for BSD-compatible nm]) -AC_CACHE_VAL(lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - test -z "$ac_dir" && ac_dir=. - tmp_nm=$ac_dir/${ac_tool_prefix}nm - if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then - lt_cv_path_NM="$tmp_nm -B" - break - elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - lt_cv_path_NM="$tmp_nm -p" - break - else - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - fi - fi - done - IFS="$ac_save_ifs" - test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm -fi]) -NM="$lt_cv_path_NM" -AC_MSG_RESULT([$NM]) -]) - -# AC_CHECK_LIBM - check for math library -AC_DEFUN([AC_CHECK_LIBM], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cygwin* | *-*-pw32*) - # These system don't have libm - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, main, LIBM="-lm") - ;; -esac -]) - -# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for -# the libltdl convenience library and INCLTDL to the include flags for -# the libltdl header and adds --enable-ltdl-convenience to the -# configure arguments. Note that LIBLTDL and INCLTDL are not -# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not -# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed -# with '${top_builddir}/' and INCLTDL will be prefixed with -# '${top_srcdir}/' (note the single quotes!). If your package is not -# flat and you're not using automake, define top_builddir and -# top_srcdir appropriately in the Makefiles. -AC_DEFUN([AC_LIBLTDL_CONVENIENCE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - case $enable_ltdl_convenience in - no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; - "") enable_ltdl_convenience=yes - ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; - esac - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la - INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) -]) - -# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for -# the libltdl installable library and INCLTDL to the include flags for -# the libltdl header and adds --enable-ltdl-install to the configure -# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is -# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed -# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will -# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed -# with '${top_srcdir}/' (note the single quotes!). If your package is -# not flat and you're not using automake, define top_builddir and -# top_srcdir appropriately in the Makefiles. -# In the future, this macro may have to be called after AC_PROG_LIBTOOL. -AC_DEFUN([AC_LIBLTDL_INSTALLABLE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - AC_CHECK_LIB(ltdl, main, - [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], - [if test x"$enable_ltdl_install" = xno; then - AC_MSG_WARN([libltdl not installed, but installation disabled]) - else - enable_ltdl_install=yes - fi - ]) - if test x"$enable_ltdl_install" = x"yes"; then - ac_configure_args="$ac_configure_args --enable-ltdl-install" - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la - INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - else - ac_configure_args="$ac_configure_args --enable-ltdl-install=no" - LIBLTDL="-lltdl" - INCLTDL= - fi -]) - -# old names -AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) -AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) -AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) -AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) -AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) - -# This is just to silence aclocal about the macro not being used -ifelse([AC_DISABLE_FAST_INSTALL]) - -- cgit From 7ad5aedae37fb54d064844e30bc6c26ab626e869 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Jun 2002 04:28:23 +0000 Subject: Improved link key handling. More verbose logging. --- hcid/main.c | 5 ++--- hcid/security.c | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/hcid/main.c b/hcid/main.c index 8f6ec8bc..6b0a4067 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -249,15 +249,12 @@ static void init_defaults(void) static void sig_usr1(int sig) { - syslog(LOG_INFO, "Flushing link keys"); flush_link_keys(); } static void sig_term(int sig) { - syslog(LOG_INFO, "Terminating"); g_main_quit(event_loop); - save_link_keys(); } static void sig_hup(int sig) @@ -456,6 +453,8 @@ int main(int argc, char *argv[], char *env[]) /* Start event processor */ g_main_run(event_loop); + save_link_keys(); + syslog(LOG_INFO, "Exit."); return 0; } diff --git a/hcid/security.c b/hcid/security.c index bca27805..f87fca5f 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -57,6 +57,8 @@ void save_link_keys(void) { int n, f; + syslog(LOG_INFO, "Saving link key database"); + umask(0077); if (!(f = open(hcid.key_file, O_WRONLY | O_CREAT | O_TRUNC, 0))) { syslog(LOG_ERR, "Can't save key database %s. %s(%d)", @@ -78,6 +80,9 @@ void save_link_keys(void) void flush_link_keys(void) { int n; + + syslog(LOG_INFO, "Flushing link key database"); + for (n=0; n < hcid.key_num; n++) { if (hcid.link_key[n]) { free(hcid.link_key[n]); @@ -300,24 +305,42 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) evt_link_key_notify *evt = ptr; bdaddr_t *dba = &evt->bdaddr; struct link_key *key; - time_t tm = time(0); - int n, k = -1; + time_t tm, td, ot; + int n, k = -1, ek = -1; - /* Find a slot */ + tm = time(0); ot = HCID_KEY_TTL; + + /* Find an empty slot or the oldest key */ for (n=0; n < hcid.key_num; n++) { key = hcid.link_key[n]; - if (!key || (!bacmp(&key->sba, sba) && !bacmp(&key->dba, dba)) || - (tm - key->time) > HCID_KEY_TTL) { + if (!key || (!bacmp(&key->sba, sba) && !bacmp(&key->dba, dba))) { k = n; break; } + + td = tm - key->time; + if (td > ot) { + ot = td; + ek = n; + } } + if (k == -1 && ek != -1) + k = ek; + if (k != -1) { + char sa[40], da[40]; + /* Update link key */ key = hcid.link_key[k]; - if (!key && !(key = malloc(sizeof(*key)))) + if (!key && !(key = malloc(sizeof(*key)))) { + syslog(LOG_ERR, "Can't allocate link key memory. %s(%d)", + strerror(errno), errno); return; + } + + ba2str(sba, sa); ba2str(dba, da); + syslog(LOG_INFO, "Storing link key %s %s", sa, da); bacpy(&key->sba, sba); bacpy(&key->dba, dba); @@ -326,7 +349,9 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) key->time = tm; hcid.link_key[k] = key; - } + } else + syslog(LOG_ERR, "No slot available for a link key."); + } gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) -- cgit From 4ee1ce8bb3026e5f144d38ff626d475883c9cafb Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Jun 2002 05:22:28 +0000 Subject: update --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2b39260c..9a462e96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +ver 2.0-pre11: + Improved link key managment and more verbose logging (hcid). + Fixed scan command (hcitool). + ver 2.0-pre10: Support for reading RSSI, remote name and changing connection type (hcitool). -- cgit From 917527a5cc61d76032060aeca74deecac58da2a1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Jun 2002 05:23:44 +0000 Subject: Increase version number --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index bdf0ddd8..335b2b0d 100644 --- a/configure.in +++ b/configure.in @@ -9,7 +9,7 @@ dnl Guess host type. AC_CANONICAL_SYSTEM AC_CANONICAL_HOST -AM_INIT_AUTOMAKE(bluez-utils, 2.0-pre10) +AM_INIT_AUTOMAKE(bluez-utils, 2.0-pre11) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) -- cgit From f79b2c879c633667916d1fb17870c54597294d8e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 24 Jun 2002 02:38:01 +0000 Subject: Link key handling rewrite. Remove max link key limit. Keep key database updated. Minor cleanup. --- hcid/hcid.conf | 2 +- hcid/hcid.h | 65 +++++++------- hcid/kword.c | 40 ++++----- hcid/lexer.l | 40 ++++----- hcid/lib.c | 42 ++++----- hcid/lib.h | 86 +++++++++--------- hcid/main.c | 53 ++++++----- hcid/parser.y | 40 ++++----- hcid/security.c | 266 ++++++++++++++++++++++---------------------------------- 9 files changed, 285 insertions(+), 349 deletions(-) diff --git a/hcid/hcid.conf b/hcid/hcid.conf index cfd06e5f..784e1d97 100644 --- a/hcid/hcid.conf +++ b/hcid/hcid.conf @@ -31,7 +31,7 @@ device { class 0x100; # Default packet type - pkt_type DH1,DM1,HV1; + #pkt_type DH1,DM1,HV1; # Inquiry and Page scan iscan enable; pscan enable; diff --git a/hcid/hcid.h b/hcid/hcid.h index 677a02dd..40dc6ad0 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -1,24 +1,24 @@ /* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ /* * $Id$ @@ -34,8 +34,6 @@ #define HCID_PIN_FILE "/etc/bluetooth/pin" #define HCID_KEY_FILE "/etc/bluetooth/link_key" #define HCID_PIN_HELPER "/bin/bluepin" -#define HCID_KEY_NUM 20 -#define HCID_KEY_TTL 172800 /* 2 days */ struct device_opts { char *name; @@ -58,22 +56,20 @@ struct link_key { }; struct hcid_opts { - char *host_name; - int auto_init; - int security; + char *host_name; + int auto_init; + int security; - char *config_file; + char *config_file; - uint8_t pin_code[16]; - int pin_len; - char *pin_helper; - char *pin_file; + uint8_t pin_code[16]; + int pin_len; + char *pin_helper; + char *pin_file; - struct link_key **link_key; - int key_num; - char *key_file; + char *key_file; - int sock; + int sock; }; extern struct hcid_opts hcid; @@ -88,5 +84,4 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data); void start_security_manager(int hdev); void stop_security_manager(int hdev); -void save_link_keys(void); void flush_link_keys(void); diff --git a/hcid/kword.c b/hcid/kword.c index a496591f..cc69db39 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -1,24 +1,24 @@ /* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ /* * $Id$ diff --git a/hcid/lexer.l b/hcid/lexer.l index a7af9c63..85cd5780 100644 --- a/hcid/lexer.l +++ b/hcid/lexer.l @@ -1,25 +1,25 @@ %{ /* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ /* diff --git a/hcid/lib.c b/hcid/lib.c index ac47603d..2e310012 100644 --- a/hcid/lib.c +++ b/hcid/lib.c @@ -1,24 +1,24 @@ /* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ /* * $Id$ @@ -95,7 +95,7 @@ char * expand_name(char *dst, char *str, int dev_id) } /* Returns current host name */ -char * get_host_name(void) +char *get_host_name(void) { char name[40]; diff --git a/hcid/lib.h b/hcid/lib.h index 4683c0ff..17f21a71 100644 --- a/hcid/lib.h +++ b/hcid/lib.h @@ -1,24 +1,24 @@ /* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ /* * $Id$ @@ -26,9 +26,9 @@ #include -char * expand_name(char *dst, char *str, int dev_id); +char *expand_name(char *dst, char *str, int dev_id); -char * get_host_name(void); +char *get_host_name(void); void init_title(int argc, char *argv[], char *env[], const char *name); void set_title(const char *ftm, ...); @@ -49,36 +49,40 @@ static inline void io_cancel(void) /* Read exactly len bytes (Signal safe)*/ static inline int read_n(int fd, void *buf, int len) { - register int t=0, w; + register int t = 0, w; while (!__io_canceled && len > 0) { - if( (w = read(fd, buf, len)) < 0 ){ - if( errno == EINTR || errno == EAGAIN ) - continue; - return -1; - } - if( !w ) - return 0; - len -= w; buf += w; t += w; + if ((w = read(fd, buf, len)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!w) + return 0; + len -= w; + buf += w; + t += w; } return t; -} +} /* Write exactly len bytes (Signal safe)*/ static inline int write_n(int fd, void *buf, int len) { - register int t=0, w; + register int t = 0, w; while (!__io_canceled && len > 0) { - if( (w = write(fd, buf, len)) < 0 ){ - if( errno == EINTR || errno == EAGAIN ) - continue; - return -1; - } - if( !w ) - return 0; - len -= w; buf += w; t += w; + if ((w = write(fd, buf, len)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!w) + return 0; + len -= w; + buf += w; + t += w; } return t; diff --git a/hcid/main.c b/hcid/main.c index 6b0a4067..1f2537fb 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -1,24 +1,24 @@ /* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ /* * $Id$ @@ -38,11 +38,11 @@ #include #include #include -#include +#include -#include -#include -#include +#include +#include +#include #include @@ -359,7 +359,6 @@ int main(int argc, char *argv[], char *env[]) hcid.pin_file = strdup(HCID_PIN_FILE); hcid.pin_helper = strdup(HCID_PIN_HELPER); hcid.key_file = strdup(HCID_KEY_FILE); - hcid.key_num = HCID_KEY_NUM; init_defaults(); @@ -393,6 +392,8 @@ int main(int argc, char *argv[], char *env[]) chdir("/"); } + umask(0077); + init_title(argc, argv, env, "hcid: "); set_title("initializing"); @@ -453,8 +454,6 @@ int main(int argc, char *argv[], char *env[]) /* Start event processor */ g_main_run(event_loop); - save_link_keys(); - syslog(LOG_INFO, "Exit."); return 0; } diff --git a/hcid/parser.y b/hcid/parser.y index e8be6c99..ff2cd1c6 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -1,25 +1,25 @@ %{ /* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ /* diff --git a/hcid/security.c b/hcid/security.c index f87fca5f..a980b500 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -1,24 +1,24 @@ /* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ /* * $Id$ @@ -42,9 +42,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include @@ -53,75 +53,104 @@ static GIOChannel *io_chan[HCI_MAX_DEV]; -void save_link_keys(void) +/* Link Key handling */ + +void flush_link_keys(void) { - int n, f; + syslog(LOG_INFO, "Flushing link key database"); + truncate(hcid.key_file, 0); +} - syslog(LOG_INFO, "Saving link key database"); +/* This function is not reentrable */ +static struct link_key *get_link_key(bdaddr_t *sba, bdaddr_t *dba) +{ + static struct link_key k; + struct link_key *key = NULL; + int f, r; - umask(0077); - if (!(f = open(hcid.key_file, O_WRONLY | O_CREAT | O_TRUNC, 0))) { - syslog(LOG_ERR, "Can't save key database %s. %s(%d)", - hcid.key_file, strerror(errno), errno); - return; + f = open(hcid.key_file, O_RDONLY); + if (f < 0) { + if (errno != ENOENT) + syslog(LOG_ERR, "Link key database open failed. %s(%d)", + strerror(errno), errno); + return NULL; } - for (n = 0; n < hcid.key_num; n++) { - if (!hcid.link_key[n]) - continue; + while ((r = read_n(f, &k, sizeof(k)))) { + if (r < 0) { + syslog(LOG_ERR, "Link key database read failed. %s(%d)", + strerror(errno), errno); + break; + } - if (write_n(f, hcid.link_key[n], sizeof(struct link_key)) < 0) + if (!bacmp(&k.sba, sba) && !bacmp(&k.dba, dba)) { + key = &k; break; + } } close(f); + return key; } -void flush_link_keys(void) +static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) { - int n; - - syslog(LOG_INFO, "Flushing link key database"); + struct link_key *key = get_link_key(sba, dba); - for (n=0; n < hcid.key_num; n++) { - if (hcid.link_key[n]) { - free(hcid.link_key[n]); - hcid.link_key[n] = NULL; - } + if (key) { + /* Link key found */ + link_key_reply_cp lr; + memcpy(lr.link_key, key->key, 16); + bacpy(&lr.bdaddr, dba); + hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, + LINK_KEY_REPLY_CP_SIZE, &lr); + key->time = time(0); + } else { + /* Link key not found */ + hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba); } } -int read_link_keys(void) +static void save_link_key(struct link_key *key) { - int f, n = 0; + char sa[40], da[40]; + int f; - if (!(f = open(hcid.key_file, O_RDONLY))) { - syslog(LOG_ERR, "Can't open key database %s. %s(%d)", - hcid.key_file, strerror(errno), errno); - return -1; + f = open(hcid.key_file, O_WRONLY | O_CREAT | O_APPEND, 0); + if (f < 0) { + syslog(LOG_ERR, "Link key database open failed. %s(%d)", + strerror(errno), errno); + return; } - while (n < hcid.key_num) { - struct link_key *key; - int r; + if (write_n(f, key, sizeof(*key)) < 0) { + syslog(LOG_ERR, "Link key database write failed. %s(%d)", + strerror(errno), errno); + } - key = malloc(sizeof(*key)); - if (!key) - continue; + close(f); - r = read_n(f, key, sizeof(*key)); - if (r <= 0) { - free(key); - break; - } + ba2str(&key->sba, sa); ba2str(&key->dba, da); + syslog(LOG_INFO, "Saving link key %s %s", sa, da); +} - hcid.link_key[n++] = key; - } +static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) +{ + evt_link_key_notify *evt = ptr; + bdaddr_t *dba = &evt->bdaddr; + struct link_key key; - close(f); - return n; + memcpy(key.key, evt->link_key, 16); + bacpy(&key.sba, sba); + bacpy(&key.dba, dba); + key.type = evt->key_type; + key.time = time(0); + + save_link_key(&key); } +/* PIN code handling */ + int read_pin_code(void) { char buf[17]; @@ -225,36 +254,6 @@ reject: exit(0); } -static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) -{ - struct link_key *key = NULL; - int n; - - /* Find the key */ - for (n=0; n < hcid.key_num; n++) { - if (!hcid.link_key[n]) - continue; - if (!bacmp(&hcid.link_key[n]->sba, sba) && - !bacmp(&hcid.link_key[n]->dba, dba)) { - key = hcid.link_key[n]; - break; - } - } - - if (key) { - /* Link key found */ - link_key_reply_cp lr; - memcpy(lr.link_key, key->key, 16); - bacpy(&lr.bdaddr, dba); - hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, - LINK_KEY_REPLY_CP_SIZE, &lr); - key->time = time(0); - } else { - /* Link key not found */ - hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba); - } -} - static void pin_code_request(int dev, bdaddr_t *ba) { struct hci_conn_info_req *cr; @@ -300,60 +299,6 @@ static void pin_code_request(int dev, bdaddr_t *ba) free(cr); } -static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) -{ - evt_link_key_notify *evt = ptr; - bdaddr_t *dba = &evt->bdaddr; - struct link_key *key; - time_t tm, td, ot; - int n, k = -1, ek = -1; - - tm = time(0); ot = HCID_KEY_TTL; - - /* Find an empty slot or the oldest key */ - for (n=0; n < hcid.key_num; n++) { - key = hcid.link_key[n]; - if (!key || (!bacmp(&key->sba, sba) && !bacmp(&key->dba, dba))) { - k = n; - break; - } - - td = tm - key->time; - if (td > ot) { - ot = td; - ek = n; - } - } - - if (k == -1 && ek != -1) - k = ek; - - if (k != -1) { - char sa[40], da[40]; - - /* Update link key */ - key = hcid.link_key[k]; - if (!key && !(key = malloc(sizeof(*key)))) { - syslog(LOG_ERR, "Can't allocate link key memory. %s(%d)", - strerror(errno), errno); - return; - } - - ba2str(sba, sa); ba2str(dba, da); - syslog(LOG_INFO, "Storing link key %s %s", sa, da); - - bacpy(&key->sba, sba); - bacpy(&key->dba, dba); - memcpy(key->key, evt->link_key, 16); - key->type = evt->key_type; - key->time = tm; - - hcid.link_key[k] = key; - } else - syslog(LOG_ERR, "No slot available for a link key."); - -} - gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) { char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; @@ -407,19 +352,14 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) return TRUE; } -int init_security_data(void) +static void init_security_data(void) { - void *buf; - - buf = calloc(hcid.key_num, sizeof(void*)); - if (!buf) { - syslog(LOG_ERR, "Can't allocate link key database. %s(%d)", - strerror(errno), errno); - return -1; - } - hcid.link_key = buf; - read_link_keys(); + static int initialized = 0; + if (initialized) + return; + initialized = 1; + /* Set local PIN code */ if (hcid.security == HCID_SEC_AUTO) { if (read_pin_code() < 0) { @@ -427,8 +367,7 @@ int init_security_data(void) hcid.pin_len = 5; } } - - return 0; + return; } void start_security_manager(int hdev) @@ -443,8 +382,7 @@ void start_security_manager(int hdev) syslog(LOG_INFO, "Starting security manager %d", hdev); - if (!hcid.link_key && init_security_data()) - return; + init_security_data(); if ((dev = hci_open_dev(hdev)) < 0) { syslog(LOG_ERR, "Can't open device hci%d. %s(%d)", -- cgit From ccb0bf6ad34beb532176a49731537f09fe01875c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 24 Jun 2002 02:52:27 +0000 Subject: Reload PIN code on SIGHUP. More cleanups. --- hcid/hcid.h | 1 + hcid/main.c | 22 +++++++++++++--------- hcid/security.c | 30 ++++++++++-------------------- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index 40dc6ad0..0715db28 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -82,6 +82,7 @@ int read_config(char *file); gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data); gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data); +void init_security_data(void); void start_security_manager(int hdev); void stop_security_manager(int hdev); void flush_link_keys(void); diff --git a/hcid/main.c b/hcid/main.c index 1f2537fb..37e6cf65 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -264,6 +264,8 @@ static void sig_hup(int sig) if (read_config(hcid.config_file) < 0) syslog(LOG_ERR, "Config reload failed"); + init_security_data(); + init_all_devices(hcid.sock); } @@ -364,17 +366,17 @@ int main(int argc, char *argv[], char *env[]) while ((opt=getopt(argc,argv,"f:n")) != EOF) { switch(opt) { - case 'n': - daemon = 0; - break; + case 'n': + daemon = 0; + break; - case 'f': - hcid.config_file = strdup(optarg); - break; + case 'f': + hcid.config_file = strdup(optarg); + break; - default: - usage(); - exit(1); + default: + usage(); + exit(1); } } @@ -440,6 +442,8 @@ int main(int argc, char *argv[], char *env[]) if (read_config(hcid.config_file) < 0) syslog(LOG_ERR, "Config load failed"); + init_security_data(); + /* Create event loop */ event_loop = g_main_new(FALSE); diff --git a/hcid/security.c b/hcid/security.c index a980b500..75e44421 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -352,24 +352,6 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) return TRUE; } -static void init_security_data(void) -{ - static int initialized = 0; - - if (initialized) - return; - initialized = 1; - - /* Set local PIN code */ - if (hcid.security == HCID_SEC_AUTO) { - if (read_pin_code() < 0) { - strcpy(hcid.pin_code, "bluez"); - hcid.pin_len = 5; - } - } - return; -} - void start_security_manager(int hdev) { GIOChannel *chan = io_chan[hdev]; @@ -382,8 +364,6 @@ void start_security_manager(int hdev) syslog(LOG_INFO, "Starting security manager %d", hdev); - init_security_data(); - if ((dev = hci_open_dev(hdev)) < 0) { syslog(LOG_ERR, "Can't open device hci%d. %s(%d)", hdev, strerror(errno), errno); @@ -438,3 +418,13 @@ void stop_security_manager(int hdev) close(g_io_channel_unix_get_fd(chan)); io_chan[hdev] = NULL; } + +void init_security_data(void) +{ + /* Set local PIN code */ + if (read_pin_code() < 0) { + strcpy(hcid.pin_code, "BlueZ"); + hcid.pin_len = 5; + } + return; +} -- cgit From 00b80c5e59ee6375af4a06b41f181d2d90402ad8 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 24 Jun 2002 03:11:13 +0000 Subject: Start sdpd, if installed. --- scripts/bluetooth.rc.rh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/bluetooth.rc.rh b/scripts/bluetooth.rc.rh index f0586788..95ae4222 100755 --- a/scripts/bluetooth.rc.rh +++ b/scripts/bluetooth.rc.rh @@ -16,7 +16,7 @@ prog="Bluetooth" UART_CONF="/etc/bluetooth/uart" -start_uarts() +start_uarts() { [ -f /sbin/hciattach -a -f $UART_CONF ] || return grep -v '^#' $UART_CONF | while read i; do @@ -33,16 +33,26 @@ start() { echo -n $"Starting $prog: " daemon /sbin/hcid + + if [ -x /usr/sbin/sdpd ]; then + daemon /usr/sbin/sdpd + fi + start_uarts - touch /var/lock/subsys/bluetooth + touch /var/lock/subsys/bluetooth echo } stop() { echo -n $"Shutting down $prog: " - stop_uarts killproc hcid + + if [ -x /usr/sbin/sdpd ]; then + killproc sdpd + fi + + stop_uarts rm -f /var/lock/subsys/bluetooth echo } -- cgit From 408650cbb8de03f650f6343953eac715608e4757 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 24 Jun 2002 03:22:55 +0000 Subject: update --- ChangeLog | 8 +++++++- configure.in | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9a462e96..ce192952 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ +ver 2.0-pre12: + Removed max link key limit. Keys never expire. + Link key database is always updated. Reread PIN on SIGHUP (hcid). + Bluetooth script starts SDPd, if installed. + Other minor fixes. + ver 2.0-pre11: - Improved link key managment and more verbose logging (hcid). + Improved link key management and more verbose logging (hcid). Fixed scan command (hcitool). ver 2.0-pre10: diff --git a/configure.in b/configure.in index 335b2b0d..9aaad200 100644 --- a/configure.in +++ b/configure.in @@ -9,7 +9,7 @@ dnl Guess host type. AC_CANONICAL_SYSTEM AC_CANONICAL_HOST -AM_INIT_AUTOMAKE(bluez-utils, 2.0-pre11) +AM_INIT_AUTOMAKE(bluez-utils, 2.0-pre12) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) -- cgit From cd7dd46bb4c182c1ea81c123eb1820d738ea03e6 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 25 Jun 2002 04:15:33 +0000 Subject: Page params commands --- tools/hciconfig.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 1efdecca..9d52dcf3 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -488,6 +488,135 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) } } +void cmd_page_parms(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + unsigned int window, interval; + write_page_activity_cp cp; + + if (sscanf(opt,"%4u:%4u", &window, &interval) != 2) { + printf("Invalid argument format\n"); + exit(1); + } + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_PAGE_ACTIVITY; + rq.cparam = &cp; + rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE; + + cp.window = htobs((uint16_t)window); + cp.interval = htobs((uint16_t)interval); + + if (window < 0x12 || window > 0x1000) + printf("Warning: page window out of range!\n"); + + if (interval < 0x12 || interval > 0x1000) + printf("Warning: page interval out of range!\n"); + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't set page parameters name on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint16_t window, interval; + read_page_activity_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_PAGE_ACTIVITY; + rq.rparam = &rp; + rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read page parameters on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read page parameters on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + + window = btohs(rp.window); + interval = btohs(rp.interval); + printf("\tPage interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", + interval, (float)interval * 0.625, window, (float)window * 0.625); + } +} + +void cmd_page_to(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int s; + if ((s = hci_open_dev(hdev)) < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + unsigned int timeout; + write_page_timeout_cp cp; + + if (sscanf(opt,"%4u", &timeout) != 1) { + printf("Invalid argument format\n"); + exit(1); + } + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_PAGE_TIMEOUT; + rq.cparam = &cp; + rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE; + + cp.timeout = htobs((uint16_t)timeout); + + if (timeout < 0x01 || timeout > 0xFFFF) + printf("Warning: page timeout out of range!\n"); + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't set page timeout on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint16_t timeout; + read_page_timeout_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_PAGE_TIMEOUT; + rq.rparam = &rp; + rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE; + + if (hci_send_req(s, &rq, 1000) < 0) { + printf("Can't read page timeout on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read page timeout on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + print_dev_hdr(&di); + + timeout = btohs(rp.timeout); + printf("\tPage timeout: %u slots (%.2f ms)\n", + timeout, (float)timeout * 0.625); + } +} + void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; @@ -559,6 +688,8 @@ struct { { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, { "inqparms",cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, + { "pageparms",cmd_page_parms, "[win:int]","Get/Set page scan window and interval" }, + { "ptimeo", cmd_page_to, "[to]", "Get/Set page timeout" }, { "aclmtu", cmd_aclmtu, "","Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "","Set SCO MTU and number of packets" }, { "version", cmd_version, 0, "Display version information" }, -- cgit From aaa64a3108d3bb8eba3e49f2b58d3909627bbca0 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 25 Jun 2002 04:36:09 +0000 Subject: Move revision command to hciconfig. --- tools/hciconfig.c | 57 ++++++++++++++++++++++++++++++++++++---- tools/hcitool.c | 77 ------------------------------------------------------- 2 files changed, 52 insertions(+), 82 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 9d52dcf3..093c3100 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -617,6 +617,52 @@ void cmd_page_to(int ctl, int hdev, char *opt) } } +static void cmd_revision(int ctl, int hdev, char *opt) +{ + struct hci_version ver; + struct hci_request rq; + unsigned char buf[102]; + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + return; + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + printf("Can't read version info hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + return; + } + + print_dev_hdr(&di); + switch (ver.manufacturer) { + case 0: + memset(&rq, 0, sizeof(rq)); + rq.ogf = 0x3f; + rq.ocf = 0x000f; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("\n Can't read revision info. %s(%d)\n", + strerror(errno), errno); + return; + } + + printf("\t%s\n", buf + 1); + break; + + default: + printf("\tUnsuported manufacturer\n"); + break; + } + return; +} + void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; @@ -687,13 +733,14 @@ struct { { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, - { "inqparms",cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, - { "pageparms",cmd_page_parms, "[win:int]","Get/Set page scan window and interval" }, - { "ptimeo", cmd_page_to, "[to]", "Get/Set page timeout" }, + { "inqparms", cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, + { "pageparms", cmd_page_parms, "[win:int]","Get/Set page scan window and interval" }, + { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, { "aclmtu", cmd_aclmtu, "","Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "","Set SCO MTU and number of packets" }, - { "version", cmd_version, 0, "Display version information" }, - { "features", cmd_features, 0,"Display device features" }, + { "features", cmd_features, 0, "Display device features" }, + { "version", cmd_version, 0, "Display version information" }, + { "revision", cmd_revision, 0, "Display revision information" }, { NULL, NULL, 0} }; diff --git a/tools/hcitool.c b/tools/hcitool.c index ae03ee96..8eaa2cc2 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -65,57 +65,6 @@ static int dev_info(int s, int dev_id, long arg) return 0; } -static int rev_info(int s, int dev_id, long arg) -{ - struct hci_version ver; - int id = arg; - int dd; - - struct hci_request rq; - unsigned char buf[102]; - - if (id != -1 && dev_id != id) - return 0; - - dd = hci_open_dev(dev_id); - if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", dev_id, strerror(errno), errno); - return -1; - } - - if (hci_read_local_version(dd, &ver, 1000) < 0) { - printf("Can't read version info hci%d. %s(%d)\n", - dev_id, strerror(errno), errno); - return -1; - } - - printf("hci%d:", dev_id); - switch (ver.manufacturer) { - case 0: - memset(&rq, 0, sizeof(rq)); - rq.ogf = 0x3f; - rq.ocf = 0x000f; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &buf; - rq.rlen = sizeof(buf); - - if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\n Can't read revision info. %s(%d)\n", - strerror(errno), errno); - return -1; - } - - printf("%s\n", buf + 1); - break; - default: - printf("\n Manufacturer not supported\n"); - break; - } - printf("\n"); - return 0; -} - static int conn_list(int s, int dev_id, long arg) { struct hci_conn_list_req *cl; @@ -591,31 +540,6 @@ static void cmd_cmd(int dev_id, int argc, char **argv) return; } -/* Display revision info */ - -static struct option rev_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} -}; - -static char *rev_help = - "Usage:\n" - "\trev\n"; - -static void cmd_rev(int dev_id, int argc, char **argv) -{ - int opt; - - for_each_opt(opt, rev_options, NULL) { - switch(opt) { - default: - printf(rev_help); - return; - } - } - hci_for_each_dev(HCI_UP, rev_info, dev_id); -} - /* Display active connections */ static struct option con_options[] = { @@ -948,7 +872,6 @@ struct { char *doc; } command[] = { { "dev", cmd_dev, "Display local devices" }, - { "rev", cmd_rev, "Display revison information" }, { "inq", cmd_inq, "Inquire remote devices" }, { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, -- cgit From 8bf4e7762d7839c00dec331b32b8674190e98be7 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 25 Jun 2002 18:31:56 +0000 Subject: Command parsing fix. --- tools/hciconfig.c | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 093c3100..a247e29d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -716,32 +716,32 @@ struct { char *opt; char *doc; } command[] = { - { "up", cmd_up, 0, "Open and initialize HCI device" }, - { "down", cmd_down, 0, "Close HCI device" }, - { "reset", cmd_reset, 0, "Reset HCI device" }, - { "rstat", cmd_rstat, 0, "Reset statistic counters" }, - { "auth", cmd_auth, 0, "Enable Authentication" }, - { "noauth", cmd_auth, 0, "Disable Authentication" }, - { "encrypt",cmd_encrypt,0, "Enable Encryption" }, - { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, - { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, - { "noscan", cmd_scan, 0, "Disable scan" }, - { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, - { "pscan", cmd_scan, 0, "Enable Page scan" }, - { "ptype", cmd_ptype, "[type]", "Get/Set default packet type" }, - { "lm", cmd_lm, "[mode]", "Get/Set default link mode" }, - { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, - { "name", cmd_name, "[name]", "Get/Set local name" }, - { "class", cmd_class, "[class]", "Get/Set class of device" }, - { "inqparms", cmd_inq_parms, "[win:int]","Get/Set inquiry scan window and interval" }, - { "pageparms", cmd_page_parms, "[win:int]","Get/Set page scan window and interval" }, - { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, - { "aclmtu", cmd_aclmtu, "","Set ACL MTU and number of packets" }, - { "scomtu", cmd_scomtu, "","Set SCO MTU and number of packets" }, - { "features", cmd_features, 0, "Display device features" }, - { "version", cmd_version, 0, "Display version information" }, - { "revision", cmd_revision, 0, "Display revision information" }, - { NULL, NULL, 0} + { "up", cmd_up, 0, "Open and initialize HCI device" }, + { "down", cmd_down, 0, "Close HCI device" }, + { "reset", cmd_reset, 0, "Reset HCI device" }, + { "rstat", cmd_rstat, 0, "Reset statistic counters" }, + { "auth", cmd_auth, 0, "Enable Authentication" }, + { "noauth", cmd_auth, 0, "Disable Authentication" }, + { "encrypt", cmd_encrypt, 0, "Enable Encryption" }, + { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, + { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, + { "noscan", cmd_scan, 0, "Disable scan" }, + { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, + { "pscan", cmd_scan, 0, "Enable Page scan" }, + { "ptype", cmd_ptype, "[type]", "Get/Set default packet type" }, + { "lm", cmd_lm, "[mode]", "Get/Set default link mode" }, + { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, + { "name", cmd_name, "[name]", "Get/Set local name" }, + { "class", cmd_class, "[class]", "Get/Set class of device" }, + { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, + { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, + { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, + { "aclmtu", cmd_aclmtu, "", "Set ACL MTU and number of packets" }, + { "scomtu", cmd_scomtu, "", "Set SCO MTU and number of packets" }, + { "features", cmd_features, 0, "Display device features" }, + { "version", cmd_version, 0, "Display version information" }, + { "revision", cmd_revision, 0, "Display revision information" }, + { NULL, NULL, 0 } }; void usage(void) @@ -807,7 +807,7 @@ int main(int argc, char **argv, char **env) while (argc > 0) { for (i=0; command[i].cmd; i++) { - if (strncmp(command[i].cmd, *argv, 4)) + if (strncmp(command[i].cmd, *argv, 5)) continue; if (command[i].opt) { -- cgit From 1ab78899d1ca28e0ea56cb68c73c04b7128d233f Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 9 Jul 2002 18:54:46 +0000 Subject: Timeout can be 5 digits. --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index a247e29d..6f9dc4ca 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -570,7 +570,7 @@ void cmd_page_to(int ctl, int hdev, char *opt) unsigned int timeout; write_page_timeout_cp cp; - if (sscanf(opt,"%4u", &timeout) != 1) { + if (sscanf(opt,"%5u", &timeout) != 1) { printf("Invalid argument format\n"); exit(1); } -- cgit From eb23734ec801339282844c2548ec415303e36455 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 9 Jul 2002 19:10:01 +0000 Subject: Display device class in human readable format. --- tools/hciconfig.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 6f9dc4ca..baa1d97b 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -344,8 +344,157 @@ void cmd_name(int ctl, int hdev, char *opt) } } +/* + * see http://www.bluetooth.org/assigned-numbers/baseband.htm --- all + * strings are reproduced verbatim + */ +static char *get_minor_device_name(int major, int minor) +{ + switch(major) { + case 0:/* misc */ + return ""; + case 1:/* computer */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Desktop workstation"; + case 2: + return "Server"; + case 3: + return "Laptop"; + case 4: + return "Handheld"; + case 5: + return "Palm"; + case 6: + return "Wearable"; + } + break; + case 2:/* phone */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Cellular"; + case 2: + return "Cordless"; + case 3: + return "Smart phone"; + case 4: + return "Wired modem or voice gateway"; + case 5: + return "Common ISDN Access"; + case 6: + return "Sim Card Reader"; + } + break; + case 3:/* lan access */ + if (minor == 0) + return "Uncategorized"; + switch(minor / 8) { + case 0: + return "Fully available"; + case 1: + return "1-17% utilized"; + case 2: + return "17-33% utilized"; + case 3: + return "33-50% utilized"; + case 4: + return "50-67% utilized"; + case 5: + return "67-83% utilized"; + case 6: + return "83-99% utilized"; + case 7: + return "No service available"; + } + break; + case 4:/* audio/video */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Device conforms to the Headset profile"; + case 2: + return "Hands-free"; + /* 3 is reserved */ + case 4: + return "Microphone"; + case 5: + return "Loudspeaker"; + case 6: + return "Headphones"; + case 7: + return "Portable Audio"; + case 8: + return "Car Audio"; + case 9: + return "Set-top box"; + case 10: + return "HiFi Audio Device"; + case 11: + return "VCR"; + case 12: + return "Video Camera"; + case 13: + return "Camcorder"; + case 14: + return "Video Monitor"; + case 15: + return "Video Display and Loudspeaker"; + case 16: + return "Video Conferencing"; + /* 17 is reserved */ + case 18: + return "Gaming/Toy"; + } + break; + case 5:/* peripheral */ + switch(minor) { + case 16: + return "Keyboard"; + case 32: + return "Pointing device"; + case 64: + return "Combo keyboard/pointing device"; + } + break; + case 6:/* imaging */ + if (minor & 4) + return "Display"; + if (minor & 8) + return "Camera"; + if (minor & 16) + return "Scanner"; + if (minor & 32) + return "Printer"; + break; + case 63:/* uncategorised */ + return ""; + } + return "Unknown (reserved) minor device class"; +} + void cmd_class(int ctl, int hdev, char *opt) { + static char *services[] = { "Positioning", + "Networking", + "Rendering", + "Capturing", + "Object Transfer", + "Audio", + "Telephony", + "Information" }; + static char *major_devices[] = { "Miscellaneous", + "Computer", + "Phone", + "LAN Access", + "Audio/Video", + "Peripheral", + "Imaging", + "Uncategorized" }; struct hci_request rq; int s; @@ -393,6 +542,25 @@ void cmd_class(int ctl, int hdev, char *opt) print_dev_hdr(&di); printf("\tClass: 0x%02x%02x%02x\n", rp.dev_class[2], rp.dev_class[1], rp.dev_class[0]); + printf("\tService Classes: "); + if (rp.dev_class[2]) { + int first = 1; + for(s=0; s < 8; s++) + if (rp.dev_class[2] & (2 << s)) { + if (!first) + printf(", "); + printf(services[s]); + first = 0; + } + } else + printf("Unspecified"); + printf("\n\tDevice Class: "); + if (rp.dev_class[1] > sizeof(major_devices)) + printf("Invalid Device Class!\n"); + else + printf("%s/%s\n", major_devices[rp.dev_class[1]], + get_minor_device_name(rp.dev_class[1], + rp.dev_class[0] / 4)); } } -- cgit From e60ae4dbe6877e5aec39e73db73acac63975fc85 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 12 Jul 2002 00:19:06 +0000 Subject: Minor fixes for dev class handling. --- tools/hciconfig.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index baa1d97b..6ea30a5d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -545,8 +545,8 @@ void cmd_class(int ctl, int hdev, char *opt) printf("\tService Classes: "); if (rp.dev_class[2]) { int first = 1; - for(s=0; s < 8; s++) - if (rp.dev_class[2] & (2 << s)) { + for(s=0; s < sizeof(services); s++) + if (rp.dev_class[2] & (1 << s)) { if (!first) printf(", "); printf(services[s]); @@ -558,7 +558,7 @@ void cmd_class(int ctl, int hdev, char *opt) if (rp.dev_class[1] > sizeof(major_devices)) printf("Invalid Device Class!\n"); else - printf("%s/%s\n", major_devices[rp.dev_class[1]], + printf("%s, %s\n", major_devices[rp.dev_class[1]], get_minor_device_name(rp.dev_class[1], rp.dev_class[0] / 4)); } -- cgit From c8680c123311875ff82b1c11b032e300c0e87219 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 12 Jul 2002 00:21:43 +0000 Subject: update --- AUTHORS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS b/AUTHORS index a918375f..d0e84f45 100644 --- a/AUTHORS +++ b/AUTHORS @@ -23,3 +23,6 @@ Nils Faerber Martin Leopold Various patches and fixes. + +Stephen Crane + Support for human readable class of device display. -- cgit From 99148a336433ac48bd8dc1fb23f4dc7cbf8c812e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 18 Jul 2002 01:54:04 +0000 Subject: Improved PCMCIA init script --- pcmcia/bluetooth | 65 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/pcmcia/bluetooth b/pcmcia/bluetooth index ea22ce40..b21ff04d 100755 --- a/pcmcia/bluetooth +++ b/pcmcia/bluetooth @@ -2,33 +2,58 @@ # # bluetooth # -# Initialize a PCMCIA Bluetooth device +# PCMCIA Bluetooth device initialization # Written by Maxim Krasnyanskiy # -# $1 - socket -# $2 - device -# +# This script requires new cardmgr and expects following +# environment variables FUNCTION, VENDORID, CARDNAME +# -LOG="/usr/bin/logger -i -t bluetooth -p daemon.notice" +# +# $Id$ +# -IDENT="/sbin/cardctl ident $1" +if [ -r ./shared ]; then . ./shared ; else . /etc/pcmcia/shared ; fi -# Check if card is really a Bluetooth card -if ! $IDENT | grep -i 'bluetooth' > /dev/null 2>&1; then - $LOG "$2 is not a Bluetooth device" - exit -fi +# Get device attributes +get_info $DEVICE -ID=`$IDENT | awk '/.*id/{print $2 $3}'` -TYPE=`$IDENT | awk '/.*func/{print $2}'` +# +# Serial devices +# +start_serial() { + /sbin/hciattach $DEVICE $VENDORID +} +stop_serial() { + return +} +suspend_serial() { + do_fuser -k -HUP /dev/$DEVICE > /dev/null +} +resume_serial() { + start_serial +} + +start= +stop= +suspend= +resume= +check= +cksum= -$LOG "Bluetooth device id $ID type $TYPE $2" +case "$FUNCTION" in +2) # Serial + if ! echo $CARDNAME | grep -i 'bluetooth' > /dev/null 2>&1; then + exit + fi -case "$TYPE" in - # Serial device - 2) - /sbin/hciattach $DEVICE $ID - ;; + start=start_serial + stop=stop_serial + suspend=suspend_serial + resume=resume_serial + ;; esac -unset LOG IDENT ID TYPE +eval \$$ACTION + +exit 0 -- cgit From c5dca08e234386563667e8f790b4e1122c364c5d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 18 Jul 2002 18:12:46 +0000 Subject: Support for multiple pairing modes. Link key replacement. --- hcid/hcid.conf | 16 ++++++--- hcid/hcid.h | 7 +++- hcid/kword.c | 8 +++++ hcid/kword.h | 1 + hcid/main.c | 11 +++++- hcid/parser.y | 20 +++++++++-- hcid/security.c | 105 ++++++++++++++++++++++++++++++++++++++++---------------- 7 files changed, 129 insertions(+), 39 deletions(-) diff --git a/hcid/hcid.conf b/hcid/hcid.conf index 784e1d97..89645993 100644 --- a/hcid/hcid.conf +++ b/hcid/hcid.conf @@ -6,16 +6,22 @@ # HCId options options { - # Automaticaly initialize new devices + # Automatically initialize new devices autoinit yes; # Security Manager mode # none - Security manager disabled - # auto - Use local PIN for incomming connections + # auto - Use local PIN for incoming connections # user - Always ask user for a PIN # security auto; + # Pairing mode + # none - Pairing disabled + # multi - Allow pairing with already paired devices + # once - Pair once and deny successive attempts + pairing multi; + # PIN helper pin_helper /bin/bluepin; } @@ -38,9 +44,9 @@ device { # Default link mode # none - no specific policy - # accept - always accept incomming connections - # master - become master on incomming connections, - # deny role switch on outgoint connections + # accept - always accept incoming connections + # master - become master on incoming connections, + # deny role switch on outgoing connections # #lm accept,master; # diff --git a/hcid/hcid.h b/hcid/hcid.h index 0715db28..cfc034e4 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -59,6 +59,7 @@ struct hcid_opts { char *host_name; int auto_init; int security; + int pairing; char *config_file; @@ -77,6 +78,10 @@ extern struct hcid_opts hcid; #define HCID_SEC_AUTO 1 #define HCID_SEC_USER 2 +#define HCID_PAIRING_NONE 0 +#define HCID_PAIRING_MULTI 1 +#define HCID_PAIRING_ONCE 2 + int read_config(char *file); gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data); @@ -85,4 +90,4 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data); void init_security_data(void); void start_security_manager(int hdev); void stop_security_manager(int hdev); -void flush_link_keys(void); +void toggle_pairing(int enable); diff --git a/hcid/kword.c b/hcid/kword.c index cc69db39..0486f21b 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -37,6 +37,7 @@ struct kword cfg_keyword[] = { { "device", K_DEVICE }, { "autoinit", K_AUTOINIT }, { "security", K_SECURITY }, + { "pairing", K_PAIRING }, { "pkt_type", K_PTYPE }, { "lm", K_LM }, { "lp", K_LP }, @@ -62,6 +63,13 @@ struct kword sec_param[] = { { NULL , 0 } }; +struct kword pair_param[] = { + { "none", HCID_PAIRING_NONE }, + { "multi", HCID_PAIRING_MULTI }, + { "once", HCID_PAIRING_ONCE }, + { NULL , 0 } +}; + int lineno; int find_keyword(struct kword *kw, char *str) diff --git a/hcid/kword.h b/hcid/kword.h index 854c91d0..10c54493 100644 --- a/hcid/kword.h +++ b/hcid/kword.h @@ -32,5 +32,6 @@ extern int lineno; extern struct kword cfg_keyword[]; extern struct kword sec_param[]; +extern struct kword pair_param[]; int find_keyword(struct kword *kw, char *str); diff --git a/hcid/main.c b/hcid/main.c index 37e6cf65..8a5371e5 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -249,7 +249,12 @@ static void init_defaults(void) static void sig_usr1(int sig) { - flush_link_keys(); + toggle_pairing(0); +} + +static void sig_usr2(int sig) +{ + toggle_pairing(1); } static void sig_term(int sig) @@ -357,6 +362,8 @@ int main(int argc, char *argv[], char *env[]) /* Default HCId settings */ hcid.config_file = HCID_CONFIG_FILE; hcid.host_name = get_host_name(); + hcid.security = HCID_SEC_AUTO; + hcid.pairing = HCID_PAIRING_MULTI; hcid.pin_file = strdup(HCID_PIN_FILE); hcid.pin_helper = strdup(HCID_PIN_HELPER); @@ -412,6 +419,8 @@ int main(int argc, char *argv[], char *env[]) sigaction(SIGHUP, &sa, NULL); sa.sa_handler = sig_usr1; sigaction(SIGUSR1, &sa, NULL); + sa.sa_handler = sig_usr2; + sigaction(SIGUSR2, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); diff --git a/hcid/parser.y b/hcid/parser.y index ff2cd1c6..b7614f85 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -56,7 +56,7 @@ int yyerror(char *s); } %token K_OPTIONS K_DEVICE -%token K_AUTOINIT K_SECURITY +%token K_AUTOINIT K_SECURITY K_PAIRING %token K_PTYPE K_NAME K_CLASS K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN %token K_PINHELP %token K_YES K_NO @@ -64,7 +64,7 @@ int yyerror(char *s); %token WORD PATH STRING LIST %token NUM -%type bool pkt_type link_mode link_policy sec_mode +%type bool pkt_type link_mode link_policy sec_mode pair_mode %type dev_name %% @@ -93,6 +93,10 @@ hcid_opt: hcid.security = $2; } + | K_PAIRING pair_mode { + hcid.pairing = $2; + } + | K_PINHELP PATH { if (hcid.pin_helper) free(hcid.pin_helper); @@ -117,6 +121,18 @@ sec_mode: | K_NO { $$ = HCID_SEC_NONE; } ; +pair_mode: + WORD { + int opt = find_keyword(pair_param, $1); + if (opt < 0) { + cfg_error("Unknown pairing mode '%s'", $1); + $$ = 0; + } else + $$ = opt; + } + ; + + device_options: '{' device_opts '}' device_opts: | device_opt ';' | error ';' | device_opts device_opt ';'; device_opt: diff --git a/hcid/security.c b/hcid/security.c index 75e44421..b7839c4c 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -53,29 +53,27 @@ static GIOChannel *io_chan[HCI_MAX_DEV]; -/* Link Key handling */ +static int pairing; -void flush_link_keys(void) +void toggle_pairing(int enable) { - syslog(LOG_INFO, "Flushing link key database"); - truncate(hcid.key_file, 0); + if (enable) + pairing = hcid.pairing; + else + pairing = 0; + + syslog(LOG_INFO, "Pairing %s", pairing ? "enabled" : "disabled"); } +/* Link Key handling */ + /* This function is not reentrable */ -static struct link_key *get_link_key(bdaddr_t *sba, bdaddr_t *dba) +static struct link_key *__get_link_key(int f, bdaddr_t *sba, bdaddr_t *dba) { static struct link_key k; struct link_key *key = NULL; - int f, r; - - f = open(hcid.key_file, O_RDONLY); - if (f < 0) { - if (errno != ENOENT) - syslog(LOG_ERR, "Link key database open failed. %s(%d)", - strerror(errno), errno); - return NULL; - } - + int r; + while ((r = read_n(f, &k, sizeof(k)))) { if (r < 0) { syslog(LOG_ERR, "Link key database read failed. %s(%d)", @@ -88,7 +86,20 @@ static struct link_key *get_link_key(bdaddr_t *sba, bdaddr_t *dba) break; } } - + return key; +} + +static struct link_key *get_link_key(bdaddr_t *sba, bdaddr_t *dba) +{ + struct link_key *key = NULL; + int f; + + f = open(hcid.key_file, O_RDONLY); + if (f >= 0) + key = __get_link_key(f, sba, dba); + else if (errno != ENOENT) + syslog(LOG_ERR, "Link key database open failed. %s(%d)", + strerror(errno), errno); close(f); return key; } @@ -114,24 +125,43 @@ static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) static void save_link_key(struct link_key *key) { char sa[40], da[40]; - int f; + struct link_key *exist; + int f, err; - f = open(hcid.key_file, O_WRONLY | O_CREAT | O_APPEND, 0); + f = open(hcid.key_file, O_RDWR | O_CREAT, 0); if (f < 0) { syslog(LOG_ERR, "Link key database open failed. %s(%d)", strerror(errno), errno); return; } + /* Check if key already exist */ + exist = __get_link_key(f, &key->sba, &key->dba); + + err = 0; + + if (exist) { + off_t o = lseek(f, 0, SEEK_CUR); + err = lseek(f, o - sizeof(*key), SEEK_SET); + } else + err = fcntl(f, F_SETFL, O_APPEND); + + if (err < 0) { + syslog(LOG_ERR, "Link key database seek failed. %s(%d)", + strerror(errno), errno); + goto failed; + } + if (write_n(f, key, sizeof(*key)) < 0) { syslog(LOG_ERR, "Link key database write failed. %s(%d)", strerror(errno), errno); } - close(f); - ba2str(&key->sba, sa); ba2str(&key->dba, da); - syslog(LOG_INFO, "Saving link key %s %s", sa, da); + syslog(LOG_INFO, "%s link key %s %s", exist ? "Replacing" : "Saving", sa, da); + +failed: + close(f); } static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) @@ -254,7 +284,7 @@ reject: exit(0); } -static void pin_code_request(int dev, bdaddr_t *ba) +static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) { struct hci_conn_info_req *cr; struct hci_conn_info *ci; @@ -263,25 +293,32 @@ static void pin_code_request(int dev, bdaddr_t *ba) if (!cr) return; - bacpy(&cr->bdaddr, ba); + bacpy(&cr->bdaddr, dba); cr->type = ACL_LINK; if (ioctl(dev, HCIGETCONNINFO, (unsigned long) cr) < 0) { syslog(LOG_ERR, "Can't get conn info %s(%d)", strerror(errno), errno); - /* Reject PIN */ - hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, ba); - - free(cr); - return; + goto reject; } ci = cr->conn_info; + if (pairing == HCID_PAIRING_ONCE) { + struct link_key *key = get_link_key(sba, dba); + if (key) { + char ba[40]; + ba2str(dba, ba); + syslog(LOG_WARNING, "PIN code request for already paired device %s", ba); + goto reject; + } + } else if (pairing == HCID_PAIRING_NONE) + goto reject; + if (hcid.security == HCID_SEC_AUTO) { if (!ci->out) { /* Incomming connection */ pin_code_reply_cp pr; memset(&pr, 0, sizeof(pr)); - bacpy(&pr.bdaddr, ba); + bacpy(&pr.bdaddr, dba); memcpy(pr.pin_code, hcid.pin_code, hcid.pin_len); pr.pin_len = hcid.pin_len; hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, @@ -297,6 +334,12 @@ static void pin_code_request(int dev, bdaddr_t *ba) call_pin_helper(dev, ci); } free(cr); + return; + +reject: + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); + free(cr); + return; } gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) @@ -337,7 +380,7 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) switch (eh->evt) { case EVT_PIN_CODE_REQ: - pin_code_request(dev, (bdaddr_t *) ptr); + pin_code_request(dev, &di->bdaddr, (bdaddr_t *) ptr); break; case EVT_LINK_KEY_REQ: @@ -426,5 +469,7 @@ void init_security_data(void) strcpy(hcid.pin_code, "BlueZ"); hcid.pin_len = 5; } + + pairing = hcid.pairing; return; } -- cgit From 70516886fef2e6c208d3e48332cc2c6c4b4d964c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 20 Jul 2002 18:53:27 +0000 Subject: Support for connectionless channels (datagram sockets). --- tools/l2test.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/tools/l2test.c b/tools/l2test.c index 56adad96..985a7500 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -73,6 +73,7 @@ unsigned short psm = 10; int master = 0; int auth = 0; int encrypt = 0; +int socktype = SOCK_SEQPACKET; float tv2fl(struct timeval tv) { @@ -85,7 +86,7 @@ int do_connect(char *svr) struct l2cap_options opts; int s, opt; - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0 ) { + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); return -1; } @@ -141,7 +142,7 @@ void do_listen( void (*handler)(int sk) ) int s, s1, opt; bdaddr_t ba; - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0 ) { + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -154,8 +155,19 @@ void do_listen( void (*handler)(int sk) ) exit(1); } - if( listen(s, 10) ) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + /* Set link mode */ + opt = 0; + if (master) + opt |= L2CAP_LM_MASTER; + + if (auth) + opt |= L2CAP_LM_AUTH; + + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + + if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); exit(1); } @@ -173,20 +185,13 @@ void do_listen( void (*handler)(int sk) ) exit(1); } + if (socktype == SOCK_DGRAM) { + handler(s); + return; + } - /* Set link mode */ - opt = 0; - if (master) - opt |= L2CAP_LM_MASTER; - - if (auth) - opt |= L2CAP_LM_AUTH; - - if (encrypt) - opt |= L2CAP_LM_ENCRYPT; - - if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -228,7 +233,7 @@ void dump_mode(int s) { int len; - syslog(LOG_INFO,"Receiving ..."); + syslog(LOG_INFO, "Receiving ..."); while ((len = read(s, buf, data_size)) > 0) syslog(LOG_INFO, "Recevied %d bytes\n", len); } @@ -366,7 +371,8 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" - "\t[-A] request authentication\n" + "\t[-D] use connectionless channel (datagram)\n" + "\t[-E] request encryption\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); } @@ -381,7 +387,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAED")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -452,6 +458,10 @@ int main(int argc ,char *argv[]) encrypt = 1; break; + case 'D': + socktype = SOCK_DGRAM; + break; + default: usage(); exit(1); -- cgit From 6c76db6269147a21a0df57ba3a669e33614bf810 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sun, 21 Jul 2002 19:30:22 +0000 Subject: GLIB searching fixes. --- configure.in | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/configure.in b/configure.in index 9aaad200..b1e3f3b9 100644 --- a/configure.in +++ b/configure.in @@ -54,22 +54,18 @@ AC_SEARCH_LIB(bluetooth, hci_open_dev, $BLUEZ_LIBDIR,, Please compile and install bluez-libs package.) ) -AC_ARG_WITH(glib, - --with-glib=DIR GLib libraries and header files, - [ - GLIB_CFLAGS="-I$withval" - GLIB_LDFLAGS="-L$withval/.libs -lglib" - ],[ - AC_MSG_RESULT("checking for GLib ...") - AC_CHECK_PROG(GLIB, glib-config, yes, [not found]) - if test "$GLIB" = "yes"; then - GLIB_CFLAGS="`glib-config --cflags`" - GLIB_LDFLAGS="`glib-config --libs`" - else - AC_MSG_ERROR(GLib not found) - fi - ] +AC_ARG_WITH(glib-config, + --with-glib-config=program glib-config location, + GLIB_CONFIG="$withval", + [ + AC_PATH_PROGS(GLIB_CONFIG, glib-config, no) + if test "$GLIB_CONFIG" = "no"; then + AC_MSG_ERROR(GLib not found) + fi + ] ) +GLIB_CFLAGS="`$GLIB_CONFIG --cflags`" +GLIB_LDFLAGS="`$GLIB_CONFIG --libs`" dnl Check for distro type. DISTRO=unknown -- cgit From 89d41e2e6c81aa5c30f2fa699cc4654eb174627c Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 23 Jul 2002 19:51:11 +0000 Subject: Don't exit from reconnect mode if connection was denied. --- tools/l2test.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/tools/l2test.c b/tools/l2test.c index 985a7500..1fd20932 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -120,12 +120,14 @@ int do_connect(char *svr) rem_addr.l2_psm = htobs(psm); if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + close(s); return -1; } opt = sizeof(opts); if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + close(s); return -1; } @@ -305,11 +307,11 @@ void send_mode(int s) buf[i]=0x7f; seq = 0; - while(1){ - *(uint32_t *)buf = htobl(seq++); + while (1) { + *(uint32_t *) buf = htobl(seq++); *(uint16_t *)(buf+4) = htobs(data_size); - if( send(s, buf, data_size, 0) <= 0 ) { + if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); exit(1); } @@ -318,14 +320,9 @@ void send_mode(int s) void reconnect_mode(char *svr) { - while(1){ - int s; - if( (s = do_connect(svr)) < 0 ) - exit(1); - + while(1) { + int s = do_connect(svr); close(s); - - usleep(10); } } @@ -337,19 +334,20 @@ void connect_mode(char *svr) sleep(99999999); } -void multy_connect_mode(char *svr) +void multi_connect_mode(char *svr) { - while(1){ + while (1) { int i, s; - for(i=0; i<10; i++){ - if( fork() ) continue; + for (i=0; i<10; i++) { + if (fork()) continue; /* Child */ s = do_connect(svr); + usleep(500); close(s); exit(0); } - sleep(19); + sleep(2); } } @@ -517,7 +515,7 @@ int main(int argc ,char *argv[]) break; case MULTY: - multy_connect_mode(argv[optind]); + multi_connect_mode(argv[optind]); break; case CONNECT: -- cgit From 671854ad5a6f8b40adb397d30aa93ff66efa1376 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sun, 4 Aug 2002 22:13:31 +0000 Subject: BCSP inti support. --- tools/hciattach.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 9668460c..b24f33ab 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -228,6 +228,26 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) return 0; } +/* + * BCSP specific initialization + */ +static int bcsp(int fd, struct uart_t *u, struct termios *ti) +{ + ti->c_cflag &= ~CBAUD; + ti->c_cflag |= B115200 | CS8 | CLOCAL | PARENB; + ti->c_cflag &= ~(PARODD|CRTSCTS); + + ti->c_oflag = 0; /* turn off output processing */ + ti->c_lflag = 0; /* no local modes */ + + if (tcsetattr(fd, TCSANOW, ti) < 0) { + perror("Can't set port settings"); + return -1; + } + + return 0; +} + /* * CSR specific initialization * Inspired strongly by code in OpenBT and experimentations with Brainboxes @@ -525,30 +545,32 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) } struct uart_t uart[] = { - { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, - { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, - { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, + { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, + { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, + + { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 0, bcsp }, /* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */ - { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, FLOW_CTL, NULL }, /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ - { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, csr }, + { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, csr }, /* BrainBoxes PCMCIA card (BL620) */ - { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 460800, FLOW_CTL, csr }, + { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 460800, FLOW_CTL, csr }, /* Silicon Wave kits */ - { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, swave }, + { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, swave }, /* Sphinx Electronics PICO Card */ - { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, /* Inventel BlueBird Module */ - { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, /* COM One Platinium Bluetooth PC Card */ - { "comone", 0xffff, 0x0101, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 0, bcsp }, { NULL, 0 } }; -- cgit From 2b2b06022138ea2c000b8a5e19c247f74ea9655b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 5 Aug 2002 02:00:11 +0000 Subject: update --- ChangeLog | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ChangeLog b/ChangeLog index ce192952..4c40f80e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +ver 2.0: + BCSP initialization (hciattach). + Minor hciconfig fixes. + +ver 2.0-pre13: + Support for multiple pairing modes. + Link key database handling fixes. + ver 2.0-pre12: Removed max link key limit. Keys never expire. Link key database is always updated. Reread PIN on SIGHUP (hcid). -- cgit From d9fa0038d3d6ce2377ede3965d237606b21ed542 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 5 Aug 2002 02:04:14 +0000 Subject: update version --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index b1e3f3b9..f857e0f8 100644 --- a/configure.in +++ b/configure.in @@ -9,7 +9,7 @@ dnl Guess host type. AC_CANONICAL_SYSTEM AC_CANONICAL_HOST -AM_INIT_AUTOMAKE(bluez-utils, 2.0-pre12) +AM_INIT_AUTOMAKE(bluez-utils, 2.0) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) -- cgit From dbf3acbbd59cc75fe68a8e6895c8afd623f835ee Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 9 Aug 2002 16:54:45 +0000 Subject: configure fixes --- acinclude.m4 | 2 -- configure.in | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index a2fa7784..cca660ee 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -76,8 +76,6 @@ AC_DEFUN([AC_SEARCH_LIB], # Check for libtool library if test -f $p/lib$1.la; then path=$p/.libs - else - path=$p fi LDFLAGS="-L$path -l$1" diff --git a/configure.in b/configure.in index f857e0f8..fef17598 100644 --- a/configure.in +++ b/configure.in @@ -39,14 +39,14 @@ AC_ARG_WITH(bluez-libs, BLUEZ_INCDIR="$withval"/include BLUEZ_LIBDIR="$withval"/src ],[ - BLUEZ_INCDIR='../libs/include /usr/include/bluetooth' + BLUEZ_INCDIR='../libs/include /usr/include' BLUEZ_LIBDIR='../libs/src /usr/lib' ] ) -AC_SEARCH_HEADERS(bluetooth.h, $BLUEZ_INCDIR,, +AC_SEARCH_HEADERS(bluetooth/bluetooth.h, $BLUEZ_INCDIR,, AC_MSG_ERROR(Bluetooth headers not found. - Please install bluez-libs package.) + Please compile and install bluez-libs package.) ) AC_SEARCH_LIB(bluetooth, hci_open_dev, $BLUEZ_LIBDIR,, -- cgit From 87c1d9f203e4ff13948ed8bf6802b21b7020d155 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 19 Aug 2002 16:51:48 +0000 Subject: RFCOMM test tool --- tools/Makefile.am | 2 +- tools/rctest.c | 470 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 471 insertions(+), 1 deletion(-) create mode 100644 tools/rctest.c diff --git a/tools/Makefile.am b/tools/Makefile.am index c1a82d7f..281be99e 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -9,6 +9,6 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -noinst_PROGRAMS = l2test scotest +noinst_PROGRAMS = l2test scotest rctest EXTRA_DIST = $(man_MANS) diff --git a/tools/rctest.c b/tools/rctest.c new file mode 100644 index 00000000..3789fe8b --- /dev/null +++ b/tools/rctest.c @@ -0,0 +1,470 @@ +/* + RFCOMM test tool + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP, + CONNECT, + CRECV, + LSEND +}; + +unsigned char *buf; + +/* Default mtu */ +int imtu = 672; +int omtu = 0; + +/* Default data size */ +long data_size = 127; + +/* Default addr and port */ +bdaddr_t bdaddr; +unsigned short port = 10; + +int master = 0; +int auth = 0; +int encrypt = 0; +int socktype = SOCK_STREAM; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_rc rem_addr, loc_addr; + int s; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.rc_family = AF_BLUETOOTH; + loc_addr.rc_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.rc_family = AF_BLUETOOTH; + baswap(&rem_addr.rc_bdaddr, strtoba(svr)); + rem_addr.rc_port = htobs(port); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + syslog(LOG_INFO, "Connected"); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_rc loc_addr, rem_addr; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.rc_family = AF_BLUETOOTH; + loc_addr.rc_bdaddr = bdaddr; + loc_addr.rc_port = htobs(port); + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + +#if 0 + /* Set link mode */ + opt = 0; + if (master) + opt |= L2CAP_LM_MASTER; + + if (auth) + opt |= L2CAP_LM_AUTH; + + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + + if (setsockopt(s, SOL_RFCOMM, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } +#endif + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection on port %d ...", port); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + baswap(&ba, &rem_addr.rc_bdaddr); + syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO, "Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO,"Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + uint32_t sq; + uint16_t l; + int i,r; + + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + + /* Check sequence */ + sq = btohl(*(uint32_t *)buf); + if (seq != sq) { + syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); + seq = sq; + } + seq++; + + /* Check length */ + l = btohs(*(uint16_t *)(buf+4)); + if (r != l) { + syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); + continue; + } + + /* Verify data */ + for (i=6; i < r; i++) { + if (buf[i] != 0x7f) + syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); + } + + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + } +} + +void send_mode(int s) +{ + uint32_t seq; + int i; + + syslog(LOG_INFO,"Sending ..."); + + for(i=6; i < data_size; i++) + buf[i]=0x7f; + + seq = 0; + while (1) { + *(uint32_t *) buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, data_size, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + exit(1); + } + } +} + +void reconnect_mode(char *svr) +{ + while(1) { + int s = do_connect(svr); + close(s); + } +} + +void multi_connect_mode(char *svr) +{ + while (1) { + int i, s; + for (i=0; i<10; i++) { + if (fork()) continue; + + /* Child */ + s = do_connect(svr); + usleep(500); + close(s); + exit(0); + } + sleep(2); + } +} + +void usage(void) +{ + printf("l2test - L2CAP testing\n" + "Usage:\n"); + printf("\tl2test [options] [bdaddr]\n"); + printf("Modes:\n" + "\t-r listen and receive\n" + "\t-w listen and send\n" + "\t-d listen and dump incomming data\n" + "\t-s connect and send\n" + "\t-u connect and receive\n" + "\t-n connect and be silent\n" + "\t-c connect, disconnect, connect, ...\n" + "\t-m multiple connects\n"); + + printf("Options:\n" + "\t[-b bytes] [-S bdaddr] [-P port]\n" + "\t[-I imtu] [-O omtu]\n" + "\t[-D] use connectionless channel (datagram)\n" + "\t[-E] request encryption\n" + "\t[-E] request encryption\n" + "\t[-M] become master\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + int opt, mode, s, need_addr; + struct sigaction sa; + + mode = RECV; need_addr = 0; + + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + need_addr = 1; + break; + + case 'w': + mode = LSEND; + break; + + case 'u': + mode = CRECV; + need_addr = 1; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + need_addr = 1; + break; + + case 'n': + mode = CONNECT; + need_addr = 1; + break; + + case 'm': + mode = MULTY; + need_addr = 1; + break; + + case 'b': + data_size = atoi(optarg); + break; + + case 'S': + baswap(&bdaddr, strtoba(optarg)); + break; + + case 'P': + port = atoi(optarg); + break; + + case 'I': + imtu = atoi(optarg); + break; + + case 'O': + omtu = atoi(optarg); + break; + + case 'M': + master = 1; + break; + + case 'A': + auth = 1; + break; + + case 'E': + encrypt = 1; + break; + + default: + usage(); + exit(1); + } + } + + if (need_addr && !(argc - optind)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case CRECV: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + recv_mode(s); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + send_mode(s); + break; + + case LSEND: + do_listen(send_mode); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multi_connect_mode(argv[optind]); + break; + + case CONNECT: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + dump_mode(s); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} -- cgit From 04c8ddd5a5d720e75144755d071e2331c979d1ed Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 20 Aug 2002 04:39:54 +0000 Subject: Add 'bluetooth/' to includes --- hcid/hcid.h | 2 +- hcid/parser.y | 6 +++--- tools/hciattach.c | 8 ++++---- tools/hciconfig.c | 6 +++--- tools/hcitool.c | 6 +++--- tools/l2ping.c | 4 ++-- tools/l2test.c | 4 ++-- tools/rctest.c | 4 ++-- tools/scotest.c | 4 ++-- 9 files changed, 22 insertions(+), 22 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index cfc034e4..3e7838b4 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -28,7 +28,7 @@ #include -#include +#include #define HCID_CONFIG_FILE "/etc/bluetooth/hcid.conf" #define HCID_PIN_FILE "/etc/bluetooth/pin" diff --git a/hcid/parser.y b/hcid/parser.y index b7614f85..96bcf023 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -35,9 +35,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include "hcid.h" #include "kword.h" diff --git a/tools/hciattach.c b/tools/hciattach.c index b24f33ab..ca81117b 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -41,10 +41,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include struct uart_t { char *type; diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 6ea30a5d..3c213ba4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -39,9 +39,9 @@ #include #include -#include -#include -#include +#include +#include +#include extern int optind,opterr,optopt; extern char *optarg; diff --git a/tools/hcitool.c b/tools/hcitool.c index 8eaa2cc2..7d3772bb 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -42,9 +42,9 @@ #include #include -#include -#include -#include +#include +#include +#include extern int optind,opterr,optopt; extern char *optarg; diff --git a/tools/l2ping.c b/tools/l2ping.c index 9bb8a4d6..310ba86b 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -47,8 +47,8 @@ #include #include -#include "bluetooth.h" -#include "l2cap.h" +#include +#include /* Defaults */ bdaddr_t bdaddr; diff --git a/tools/l2test.c b/tools/l2test.c index 1fd20932..b08b2d34 100644 --- a/tools/l2test.c +++ b/tools/l2test.c @@ -42,8 +42,8 @@ #include #include -#include -#include +#include +#include /* Test modes */ enum { diff --git a/tools/rctest.c b/tools/rctest.c index 3789fe8b..bcb3516c 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -40,8 +40,8 @@ #include #include -#include -#include +#include +#include /* Test modes */ enum { diff --git a/tools/scotest.c b/tools/scotest.c index 4b56d081..dcb1acdf 100644 --- a/tools/scotest.c +++ b/tools/scotest.c @@ -42,8 +42,8 @@ #include #include -#include -#include +#include +#include /* Test modes */ enum { -- cgit From 8c46235a8972c0d1ced79d467de494e5842444be Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 20 Aug 2002 18:42:12 +0000 Subject: Syntax fix. --- hcid/parser.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hcid/parser.y b/hcid/parser.y index 96bcf023..f0aafbd3 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -82,7 +82,7 @@ statement: } ; -hcid_options: '{' hcid_opts '}' +hcid_options: '{' hcid_opts '}'; hcid_opts: | hcid_opt ';' | error ';' | hcid_opts hcid_opt ';'; hcid_opt: K_AUTOINIT bool { @@ -133,7 +133,7 @@ pair_mode: ; -device_options: '{' device_opts '}' +device_options: '{' device_opts '}'; device_opts: | device_opt ';' | error ';' | device_opts device_opt ';'; device_opt: K_PTYPE pkt_type { -- cgit From 41577e502830106f479fd9a17e08a797d671256b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 20 Aug 2002 19:53:37 +0000 Subject: port -> channel --- tools/rctest.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/rctest.c b/tools/rctest.c index bcb3516c..24699b23 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -64,9 +64,9 @@ int omtu = 0; /* Default data size */ long data_size = 127; -/* Default addr and port */ +/* Default addr and channel */ bdaddr_t bdaddr; -unsigned short port = 10; +unsigned short channel = 10; int master = 0; int auth = 0; @@ -99,7 +99,7 @@ int do_connect(char *svr) memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.rc_family = AF_BLUETOOTH; baswap(&rem_addr.rc_bdaddr, strtoba(svr)); - rem_addr.rc_port = htobs(port); + rem_addr.rc_channel = htobs(channel); if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); close(s); @@ -124,7 +124,7 @@ void do_listen( void (*handler)(int sk) ) loc_addr.rc_family = AF_BLUETOOTH; loc_addr.rc_bdaddr = bdaddr; - loc_addr.rc_port = htobs(port); + loc_addr.rc_channel = htobs(channel); if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); @@ -153,7 +153,7 @@ void do_listen( void (*handler)(int sk) ) exit(1); } - syslog(LOG_INFO,"Waiting for connection on port %d ...", port); + syslog(LOG_INFO,"Waiting for connection on channel %d ...", channel); while(1) { opt = sizeof(rem_addr); @@ -308,7 +308,7 @@ void usage(void) "\t-m multiple connects\n"); printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P port]\n" + "\t[-b bytes] [-S bdaddr] [-P channel]\n" "\t[-I imtu] [-O omtu]\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-E] request encryption\n" @@ -374,7 +374,7 @@ int main(int argc ,char *argv[]) break; case 'P': - port = atoi(optarg); + channel = atoi(optarg); break; case 'I': -- cgit From d10423ecaa32884c2c382756d502f615349c400b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2002 10:06:55 +0000 Subject: use hci lib --- tools/hciconfig.c | 84 ++++++++++++------------------------------------------- tools/hcitool.c | 6 ++-- 2 files changed, 21 insertions(+), 69 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3c213ba4..bbc61d0e 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -299,48 +299,26 @@ void cmd_features(int ctl, int hdev, char *opt) void cmd_name(int ctl, int hdev, char *opt) { - struct hci_request rq; - int s; - if ((s = hci_open_dev(hdev)) < 0) { + int s = hci_open_dev(hdev); + if (s < 0) { printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - - memset(&rq, 0, sizeof(rq)); - if (opt) { - change_local_name_cp cp; - strcpy(cp.name, opt); - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_CHANGE_LOCAL_NAME; - rq.cparam = &cp; - rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; - - if (hci_send_req(s, &rq, 1000) < 0) { + if (hci_write_local_name(s, opt, 1000) < 0) { printf("Can't change local name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { - read_local_name_rp rp; - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LOCAL_NAME; - rq.rparam = &rp; - rq.rlen = READ_LOCAL_NAME_RP_SIZE; - - if (hci_send_req(s, &rq, 1000) < 0) { + char name[248]; + if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { printf("Can't read local name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - if (rp.status) { - printf("Read local name on hci%d returned status %d\n", hdev, rp.status); - exit(1); - } print_dev_hdr(&di); - printf("\tName: '%s'\n", rp.name); + printf("\tName: '%s'\n", name); } } @@ -495,58 +473,33 @@ void cmd_class(int ctl, int hdev, char *opt) "Peripheral", "Imaging", "Uncategorized" }; - struct hci_request rq; - int s; + int s = hci_open_dev(hdev); - if ((s = hci_open_dev(hdev)) < 0) { + if (s < 0) { printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - - memset(&rq, 0, sizeof(rq)); if (opt) { uint32_t cod = htobl(strtoul(opt, NULL, 16)); - write_class_of_dev_cp cp; - - memcpy(cp.dev_class, &cod, 3); - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CLASS_OF_DEV; - rq.cparam = &cp; - rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; - - if (hci_send_req(s, &rq, 1000) < 0) { + if (0 > hci_write_class_of_dev(s, cod, 1000)) { printf("Can't write local class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { - read_class_of_dev_rp rp; - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_CLASS_OF_DEV; - rq.rparam = &rp; - rq.rlen = READ_CLASS_OF_DEV_RP_SIZE; - - if (hci_send_req(s, &rq, 1000) < 0) { + uint8_t cls[3]; + if (0 > hci_read_class_of_dev(s, cls, 1000)) { printf("Can't read class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - - if (rp.status) { - printf("Read class of device on hci%d returned status %d\n", - hdev, rp.status); - exit(1); - } print_dev_hdr(&di); - printf("\tClass: 0x%02x%02x%02x\n", - rp.dev_class[2], rp.dev_class[1], rp.dev_class[0]); + printf("\tClass: 0x%02x%02x%02x\n", cls[2], cls[1], cls[0]); printf("\tService Classes: "); - if (rp.dev_class[2]) { + if (cls[2]) { int first = 1; for(s=0; s < sizeof(services); s++) - if (rp.dev_class[2] & (1 << s)) { + if (cls[2] & (1 << s)) { if (!first) printf(", "); printf(services[s]); @@ -555,12 +508,11 @@ void cmd_class(int ctl, int hdev, char *opt) } else printf("Unspecified"); printf("\n\tDevice Class: "); - if (rp.dev_class[1] > sizeof(major_devices)) + if (cls[1] > sizeof(major_devices)) printf("Invalid Device Class!\n"); else - printf("%s, %s\n", major_devices[rp.dev_class[1]], - get_minor_device_name(rp.dev_class[1], - rp.dev_class[0] / 4)); + printf("%s, %s\n", major_devices[cls[1]], + get_minor_device_name(cls[1], cls[0] / 4)); } } @@ -653,7 +605,7 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) interval = btohs(rp.interval); printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", interval, (float)interval * 0.625, window, (float)window * 0.625); - } + } } void cmd_page_parms(int ctl, int hdev, char *opt) diff --git a/tools/hcitool.c b/tools/hcitool.c index 7d3772bb..34a9f5a4 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -303,7 +303,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - if (hci_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) + if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); baswap(&bdaddr, &(info+i)->bdaddr); printf("\t%s\t%s\n", batostr(&bdaddr), name); @@ -361,7 +361,7 @@ static void cmd_name(int dev_id, int argc, char **argv) exit(1); } - if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("%s\n", name); close(dd); @@ -428,7 +428,7 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } - if (hci_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { -- cgit From 331ea4b4af4b8e147aacdd6c8fcf7352198f2151 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 23 Aug 2002 20:22:54 +0000 Subject: Improved PCMCIA support. --- pcmcia/bluetooth | 14 ++++++-------- pcmcia/bluetooth.conf | 17 ++++++++--------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/pcmcia/bluetooth b/pcmcia/bluetooth index b21ff04d..220adc72 100755 --- a/pcmcia/bluetooth +++ b/pcmcia/bluetooth @@ -5,8 +5,7 @@ # PCMCIA Bluetooth device initialization # Written by Maxim Krasnyanskiy # -# This script requires new cardmgr and expects following -# environment variables FUNCTION, VENDORID, CARDNAME +# This script requires cardmgr 3.2.1 or later # # @@ -22,7 +21,10 @@ get_info $DEVICE # Serial devices # start_serial() { - /sbin/hciattach $DEVICE $VENDORID + IRQ=`setserial /dev/$DEVICE | sed -e 's/.*IRQ: //'` + setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ + + /sbin/hciattach $DEVICE $MANFID } stop_serial() { return @@ -41,12 +43,8 @@ resume= check= cksum= -case "$FUNCTION" in +case "$FUNCID" in 2) # Serial - if ! echo $CARDNAME | grep -i 'bluetooth' > /dev/null 2>&1; then - exit - fi - start=start_serial stop=stop_serial suspend=suspend_serial diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 29414bfa..e451a6a2 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -7,38 +7,37 @@ device "bluecard_cs" device "bt3c_cs" module "bt3c_cs" - card "Xircom CreditCard Bluetooth Adapter" version "Xircom", "*", "CBT" - bind "serial_cs" + bind "serial_cs" class "bluetooth" card "Xircom RealPort2 Bluetooth Adapter" version "Xircom", "*", "R2BT" - bind "serial_cs" + bind "serial_cs" class "bluetooth" card "Brain Boxes BL-620 Bluetooth Adapter" version "Brain Boxes", "Bluetooth PC Card" - bind "serial_cs" + bind "serial_cs" class "bluetooth" card "COM One Platinium Bluetooth PC Card" version "COM1 SA", "MC310 CARD" - bind "serial_cs" + bind "serial_cs" class "bluetooth" card "AmbiCom BT2000E Bluetooth PC/CF Card" version "AmbiCom,Inc", "BT2000E" - bind "serial_cs" + bind "serial_cs" class "bluetooth" card "Sphinx PICO Card" version "SPHINX", "BT-CARD" - bind "serial_cs" + bind "serial_cs" class "bluetooth" card "H-Soft blue+Card" version "H-Soft", "Blue+CARD" - bind "serial_cs" + bind "serial_cs" class "bluetooth" card "Compaq iPAQ Bluetooth Sleeve" version "CF CARD", "GENERIC" - bind "serial_cs" + bind "serial_cs" class "bluetooth" card "Nokia Bluetooth Card" -- cgit From e8ff1fd108ac4d6192d48446815b83cf41589af7 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 24 Aug 2002 15:57:12 +0000 Subject: Kill hciattach on unplug --- pcmcia/bluetooth | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pcmcia/bluetooth b/pcmcia/bluetooth index 220adc72..503484d9 100755 --- a/pcmcia/bluetooth +++ b/pcmcia/bluetooth @@ -5,7 +5,8 @@ # PCMCIA Bluetooth device initialization # Written by Maxim Krasnyanskiy # -# This script requires cardmgr 3.2.1 or later +# This script requires new cardmgr and expects following +# environment variables FUNCTION, VENDORID, CARDNAME # # @@ -24,13 +25,13 @@ start_serial() { IRQ=`setserial /dev/$DEVICE | sed -e 's/.*IRQ: //'` setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ - /sbin/hciattach $DEVICE $MANFID + /sbin/hciattach $DEVICE $MANFID > /tmp/pcmcia } stop_serial() { - return + do_fuser -k -HUP /dev/$DEVICE > /dev/null } suspend_serial() { - do_fuser -k -HUP /dev/$DEVICE > /dev/null + stop_serial } resume_serial() { start_serial -- cgit From 2d21a950915b17c9bc284a0bd703fd58ba8ac760 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 1 Sep 2002 10:49:22 +0000 Subject: Cleanup --- tools/rctest.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/rctest.c b/tools/rctest.c index 24699b23..af34b3f7 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -294,9 +294,9 @@ void multi_connect_mode(char *svr) void usage(void) { - printf("l2test - L2CAP testing\n" + printf("rctest - RFCOMM testing\n" "Usage:\n"); - printf("\tl2test [options] [bdaddr]\n"); + printf("\trctest [options] [bdaddr]\n"); printf("Modes:\n" "\t-r listen and receive\n" "\t-w listen and send\n" @@ -310,7 +310,6 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P channel]\n" "\t[-I imtu] [-O omtu]\n" - "\t[-D] use connectionless channel (datagram)\n" "\t[-E] request encryption\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); @@ -418,7 +417,7 @@ int main(int argc ,char *argv[]) sa.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &sa, NULL); - openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); + openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0); switch( mode ){ case RECV: -- cgit From 74ec9c1b4330e9faf5e922e1b1821e4d658fd02e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 6 Sep 2002 17:35:26 +0000 Subject: rfcomm needs different error detection code. --- tools/rctest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/rctest.c b/tools/rctest.c index af34b3f7..a3eefd6f 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -212,7 +212,7 @@ void recv_mode(int s) strerror(errno), errno); return; } - +#if 0 /* Check sequence */ sq = btohl(*(uint32_t *)buf); if (seq != sq) { @@ -233,7 +233,7 @@ void recv_mode(int s) if (buf[i] != 0x7f) syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); } - +#endif total += r; } gettimeofday(&tv_end,NULL); -- cgit From f93bdd3e8438c165bc3ba98dc1730d2701f98bfc Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 9 Sep 2002 16:27:39 +0000 Subject: BCSP fixes --- tools/hciattach.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index ca81117b..cee27e46 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -77,6 +77,8 @@ static int uart_speed(int s) return B460800; case 921600: return B921600; + case 1000000: + return B1000000; default: return B57600; } @@ -233,18 +235,88 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) */ static int bcsp(int fd, struct uart_t *u, struct termios *ti) { - ti->c_cflag &= ~CBAUD; - ti->c_cflag |= B115200 | CS8 | CLOCAL | PARENB; - ti->c_cflag &= ~(PARODD|CRTSCTS); + unsigned char byte, bcsph[4], bcspp[4], + bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0}, + bcsp_sync_resp_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xac,0xaf,0xef,0xee,0xc0}, + bcsp_conf_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xad,0xef,0xac,0xed,0xc0}, + bcsp_conf_resp_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xde,0xad,0xd0,0xd0,0xc0}, + bcspsync[4] = {0xda, 0xdc, 0xed, 0xed}, + bcspsyncresp[4] = {0xac,0xaf,0xef,0xee}, + bcspconf[4] = {0xad,0xef,0xac,0xed}, + bcspconfresp[4] = {0xde,0xad,0xd0,0xd0}; + int sync_sent = 0; + + if (set_speed(fd, ti, u->speed) < 0) { + perror("Can't set default baud rate"); + return -1; + } - ti->c_oflag = 0; /* turn off output processing */ - ti->c_lflag = 0; /* no local modes */ + ti->c_cflag |= PARENB; + ti->c_cflag &= ~(PARODD); if (tcsetattr(fd, TCSANOW, ti) < 0) { perror("Can't set port settings"); return -1; } + /* State = shy */ + + while (1) { + do { + read(fd, &byte, 1); + } while(byte != 0xC0); + + do { + read(fd, &bcsph[0], 1); + } while(bcsph[0] == 0xC0); + + read(fd, &bcsph[1], 3); + if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) + continue; + if (bcsph[1] != 0x41 || bcsph[2] != 0x00) + continue; + + read(fd, &bcspp, 4); + if (!memcmp(bcspp, bcspsync, 4)) { + write(fd, &bcsp_sync_resp_pkt,10); + if (!sync_sent) { + write(fd, &bcsp_sync_pkt, 10); /* muzzled = false */ + sync_sent = 1; + } + } else if (!memcmp(bcspp, bcspsyncresp, 4)) + break; + } + + /* State = curious */ + + write(fd, &bcsp_conf_pkt, 10); + while (1) { + do { + read(fd, &byte, 1); + } while(byte != 0xC0); + + do { + read(fd, &bcsph[0], 1); + } while(bcsph[0] == 0xC0); + + read(fd, &bcsph[1], 3); + if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) + continue; + + if (bcsph[1] != 0x41 || bcsph[2] != 0x00) + continue; + + read(fd, &bcspp, 4); + if (!memcmp(bcspp, bcspsync, 4)) + write(fd, &bcsp_sync_resp_pkt, 10); + else if (!memcmp(bcspp, bcspconf, 4)) + write(fd, &bcsp_conf_resp_pkt, 10); + else if (!memcmp(bcspp, bcspconfresp, 4)) + break; + } + + /* State = garrulous */ + return 0; } @@ -763,7 +835,7 @@ int main(int argc, char *argv[]) sa.sa_handler = sig_alarm; sigaction(SIGALRM, &sa, NULL); - /* 5 seconds should be enought for intialization */ + /* 5 seconds should be enough for intialization */ alarm(to); n = init_uart(dev, u); -- cgit From 068ed1258ab388bfa6d554da9376375ecc673686 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 12 Sep 2002 02:00:37 +0000 Subject: channel must be uint8 --- tools/rctest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/rctest.c b/tools/rctest.c index a3eefd6f..388195a7 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -66,7 +66,7 @@ long data_size = 127; /* Default addr and channel */ bdaddr_t bdaddr; -unsigned short channel = 10; +uint8_t channel = 10; int master = 0; int auth = 0; @@ -99,7 +99,7 @@ int do_connect(char *svr) memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.rc_family = AF_BLUETOOTH; baswap(&rem_addr.rc_bdaddr, strtoba(svr)); - rem_addr.rc_channel = htobs(channel); + rem_addr.rc_channel = channel; if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); close(s); @@ -124,7 +124,7 @@ void do_listen( void (*handler)(int sk) ) loc_addr.rc_family = AF_BLUETOOTH; loc_addr.rc_bdaddr = bdaddr; - loc_addr.rc_channel = htobs(channel); + loc_addr.rc_channel = channel; if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); -- cgit From 8f511c20f7f6b0b59316bdb84ff444ccbc918242 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sun, 15 Sep 2002 17:13:40 +0000 Subject: get link quality support --- tools/hcitool.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 34a9f5a4..730605db 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -785,6 +785,91 @@ static void cmd_rssi(int dev_id, int argc, char **argv) free(cr); } +/* Get Link Quality */ + +static struct option link_quality_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *link_quality_help = + "Usage:\n" + "\tlq \n"; + +static void cmd_link_quality(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + get_link_quality_rp rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, link_quality_options, NULL) { + switch(opt) { + default: + printf(link_quality_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(link_quality_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_GET_LINK_QUALITY; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = GET_LINK_QUALITY_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI get_link_quality request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", + rp.status); + exit(1); + } + printf("Link quality: %d\n", rp.link_quality); + + close(dd); + free(cr); +} + /* Set connection packet type */ static struct option cpt_options[] = { @@ -865,7 +950,6 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } - struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -882,6 +966,7 @@ struct { { "dc", cmd_dc, "Disconnect from remote device" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, + { "lq", cmd_link_quality, "Display link quality" }, { NULL, NULL, 0} }; -- cgit From 2af38a90ac802ab706ed984b3105ada22d6f060d Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 26 Sep 2002 05:13:23 +0000 Subject: BCSP initialization improvements --- tools/hciattach.c | 134 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 25 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index cee27e46..78deb53b 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -230,21 +230,67 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) return 0; } +static int read_check(int fd, void *buf, int count) +{ + int res; + + do{ + res = read(fd, buf, count); + if (res != -1) { + buf += res; count -= res; + } + } while (count && (errno == 0 || errno == EINTR)); + + if (count) + return -1; + + return 0; +} + /* * BCSP specific initialization */ +int serial_fd; + +static void bcsp_tshy_sig_alarm(int sig) +{ + static int retries=0; + unsigned char bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0}; + + if (retries < 10) { + retries++; + write(serial_fd, &bcsp_sync_pkt, 10); + alarm(1); + return; + } + fprintf(stderr, "BCSP initialization timed out\n"); + exit(1); +} + +static void bcsp_tconf_sig_alarm(int sig) +{ + static int retries=0; + unsigned char bcsp_conf_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xad,0xef,0xac,0xed,0xc0}; + if (retries < 10){ + retries++; + write(serial_fd, &bcsp_conf_pkt, 10); + alarm(1); + return; + } + fprintf(stderr, "BCSP initialization timed out\n"); + exit(1); +} + static int bcsp(int fd, struct uart_t *u, struct termios *ti) { unsigned char byte, bcsph[4], bcspp[4], - bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0}, bcsp_sync_resp_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xac,0xaf,0xef,0xee,0xc0}, - bcsp_conf_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xad,0xef,0xac,0xed,0xc0}, bcsp_conf_resp_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xde,0xad,0xd0,0xd0,0xc0}, - bcspsync[4] = {0xda, 0xdc, 0xed, 0xed}, + bcspsync[4] = {0xda, 0xdc, 0xed, 0xed}, bcspsyncresp[4] = {0xac,0xaf,0xef,0xee}, - bcspconf[4] = {0xad,0xef,0xac,0xed}, + bcspconf[4] = {0xad,0xef,0xac,0xed}, bcspconfresp[4] = {0xde,0xad,0xd0,0xd0}; - int sync_sent = 0; + struct sigaction sa; if (set_speed(fd, ti, u->speed) < 0) { perror("Can't set default baud rate"); @@ -259,54 +305,92 @@ static int bcsp(int fd, struct uart_t *u, struct termios *ti) return -1; } + alarm(0); + + serial_fd = fd; + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = bcsp_tshy_sig_alarm; + sigaction(SIGALRM, &sa, NULL); + /* State = shy */ + bcsp_tshy_sig_alarm(0); while (1) { do { - read(fd, &byte, 1); - } while(byte != 0xC0); + if (read_check(fd, &byte, 1) == -1){ + perror("Failed to read"); + return -1; + } + } while (byte != 0xC0); do { - read(fd, &bcsph[0], 1); - } while(bcsph[0] == 0xC0); + if ( read_check(fd, &bcsph[0], 1) == -1){ + perror("Failed to read"); + return -1; + } + + } while (bcsph[0] == 0xC0); + + if ( read_check(fd, &bcsph[1], 3) == -1){ + perror("Failed to read"); + return -1; + } - read(fd, &bcsph[1], 3); if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) - continue; + continue; if (bcsph[1] != 0x41 || bcsph[2] != 0x00) - continue; - - read(fd, &bcspp, 4); + continue; + + if (read_check(fd, &bcspp, 4) == -1){ + perror("Failed to read"); + return -1; + } + if (!memcmp(bcspp, bcspsync, 4)) { write(fd, &bcsp_sync_resp_pkt,10); - if (!sync_sent) { - write(fd, &bcsp_sync_pkt, 10); /* muzzled = false */ - sync_sent = 1; - } } else if (!memcmp(bcspp, bcspsyncresp, 4)) break; } /* State = curious */ - write(fd, &bcsp_conf_pkt, 10); + alarm(0); + sa.sa_handler = bcsp_tconf_sig_alarm; + sigaction(SIGALRM, &sa, NULL); + alarm(1); + while (1) { do { - read(fd, &byte, 1); - } while(byte != 0xC0); + if (read_check(fd, &byte, 1) == -1){ + perror("Failed to read"); + return -1; + } + } while (byte != 0xC0); do { - read(fd, &bcsph[0], 1); - } while(bcsph[0] == 0xC0); + if (read_check(fd, &bcsph[0], 1) == -1){ + perror("Failed to read"); + return -1; + } + } while (bcsph[0] == 0xC0); - read(fd, &bcsph[1], 3); + if (read_check(fd, &bcsph[1], 3) == -1){ + perror("Failed to read"); + return -1; + } + if (((bcsph[0] + bcsph[1] + bcsph[2]) & 0xFF) != (unsigned char)~bcsph[3]) continue; if (bcsph[1] != 0x41 || bcsph[2] != 0x00) continue; - read(fd, &bcspp, 4); + if (read_check(fd, &bcspp, 4) == -1){ + perror("Failed to read"); + return -1; + } + if (!memcmp(bcspp, bcspsync, 4)) write(fd, &bcsp_sync_resp_pkt, 10); else if (!memcmp(bcspp, bcspconf, 4)) -- cgit From ee48a96c55129102d78383e461f785ca5fd005ef Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 7 Oct 2002 05:54:34 +0000 Subject: cleanup. --- tools/rctest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/rctest.c b/tools/rctest.c index 388195a7..0584a6a9 100644 --- a/tools/rctest.c +++ b/tools/rctest.c @@ -202,9 +202,9 @@ void recv_mode(int s) gettimeofday(&tv_beg,NULL); total = 0; while (total < data_size) { - uint32_t sq; - uint16_t l; - int i,r; + //uint32_t sq; + //uint16_t l; + int r; if ((r = recv(s, buf, data_size, 0)) <= 0) { if (r < 0) -- cgit From 8c6e7af8ac997ce101009569e3bdaee231e8fb12 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 7 Oct 2002 05:55:21 +0000 Subject: Add for get/set link supervision timeout. --- tools/hcitool.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 730605db..ec6f007a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -886,6 +886,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) struct hci_conn_info_req *cr; struct hci_request rq; set_conn_ptype_cp cp; + evt_conn_ptype_changed rp; bdaddr_t bdaddr; int opt, dd, ptype; @@ -936,10 +937,13 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; rq.clen = SET_CONN_PTYPE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CONN_PTYPE_CHANGED_SIZE; + rq.event = EVT_CONN_PTYPE_CHANGED; if (hci_send_req(dd, &rq, 100) < 0) { perror("Packet type change failed"); @@ -950,6 +954,113 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } +/* Get/Set Link Supervision Timeout */ + +static struct option link_supervision_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *link_supervision_help = + "Usage:\n" + "\tlst [new value in slots]\n"; + +static void cmd_link_sup_to(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_link_supervision_timeout_rp rp; + write_link_supervision_timeout_cp cp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, link_supervision_options, NULL) { + switch(opt) { + default: + printf(link_supervision_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(link_supervision_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (argc == 1) { + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cr->conn_info->handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read_link_supervision_timeout request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_link_supervision_timeout failed (0x%2.2X)\n", + rp.status); + exit(1); + } + if (rp.link_sup_to) + printf("Link supervision timeout: %u slots (%.2f msec)\n", + rp.link_sup_to, (float)rp.link_sup_to * 0.625); + else + printf("Link supervision timeout never expires\n"); + } + else { + cp.handle = cr->conn_info->handle; + cp.link_sup_to = strtol(argv[1], NULL, 10); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cp; + rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI write_link_supervision_timeout request failed"); + exit(1); + } + } + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -967,6 +1078,7 @@ struct { { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_link_quality, "Display link quality" }, + { "lst", cmd_link_sup_to, "Set/display link supervision timeout" }, { NULL, NULL, 0} }; -- cgit From 6728b0dbbfba17d6d41c46aa4cadb52945070771 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 7 Oct 2002 05:58:18 +0000 Subject: Add RFCOMM TTY configuration tool. --- AUTHORS | 6 + Makefile.am | 2 +- configure.in | 4 +- rfcomm/Makefile.am | 13 ++ rfcomm/kword.c | 60 ++++++++ rfcomm/kword.h | 48 ++++++ rfcomm/lexer.l | 107 +++++++++++++ rfcomm/main.c | 433 +++++++++++++++++++++++++++++++++++++++++++++++++++++ rfcomm/parser.y | 164 ++++++++++++++++++++ rfcomm/rfcomm.8 | 36 +++++ rfcomm/rfcomm.conf | 19 +++ 11 files changed, 889 insertions(+), 3 deletions(-) create mode 100644 rfcomm/Makefile.am create mode 100644 rfcomm/kword.c create mode 100644 rfcomm/kword.h create mode 100644 rfcomm/lexer.l create mode 100644 rfcomm/main.c create mode 100644 rfcomm/parser.y create mode 100644 rfcomm/rfcomm.8 create mode 100644 rfcomm/rfcomm.conf diff --git a/AUTHORS b/AUTHORS index d0e84f45..9cd176d2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -26,3 +26,9 @@ Martin Leopold Stephen Crane Support for human readable class of device display. + +Wolfgang Heidrich + Support for displaying link quality (hcitool). + +Fabrizio Gennari + Support for link supervision timeout (hcitool). diff --git a/Makefile.am b/Makefile.am index 6c007cbd..a9fe27a4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,4 +2,4 @@ # $Id$ # -SUBDIRS := hcid tools scripts pcmcia +SUBDIRS := hcid tools rfcomm scripts pcmcia diff --git a/configure.in b/configure.in index fef17598..af2f6ee1 100644 --- a/configure.in +++ b/configure.in @@ -9,7 +9,7 @@ dnl Guess host type. AC_CANONICAL_SYSTEM AC_CANONICAL_HOST -AM_INIT_AUTOMAKE(bluez-utils, 2.0) +AM_INIT_AUTOMAKE(bluez-utils, 2.1) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) @@ -84,4 +84,4 @@ AC_ARG_ENABLE(pcmcia, AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=) fi ]) -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile scripts/Makefile pcmcia/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am new file mode 100644 index 00000000..6b7a9eee --- /dev/null +++ b/rfcomm/Makefile.am @@ -0,0 +1,13 @@ +# +# $Id$ +# + +sbin_PROGRAMS = rfcomm + +rfcomm_SOURCES = main.c parser.h parser.y lexer.l kword.h kword.c + +man_MANS = rfcomm.8 + +YFLAGS = -d + +CLEANFILES = lexer.c parser.c parser.h diff --git a/rfcomm/kword.c b/rfcomm/kword.c new file mode 100644 index 00000000..c83dcc4b --- /dev/null +++ b/rfcomm/kword.c @@ -0,0 +1,60 @@ +/* + * + * RFCOMM configuration file + * + * Copyright (C) 2001-2002 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include +#include + +#include "kword.h" +#include "parser.h" + +int lineno; + +struct keyword_t rfcomm_keyword[] = { + { "bind", K_BIND }, + { "device", K_DEVICE }, + { "channel", K_CHANNEL }, + { "comment", K_COMMENT }, + + { "yes", K_YES }, + { "no", K_NO }, + { "enable", K_YES }, + { "disable", K_NO }, + + { NULL , 0 } +}; + +int rfcomm_find_keyword(struct keyword_t *keyword, char *string) +{ + while (keyword->string) { + if (!strcmp(string, keyword->string)) + return keyword->type; + keyword++; + } + + return -1; +} + +struct rfcomm_opts rfcomm_opts[RFCOMM_MAX_DEV]; diff --git a/rfcomm/kword.h b/rfcomm/kword.h new file mode 100644 index 00000000..cdee0c8c --- /dev/null +++ b/rfcomm/kword.h @@ -0,0 +1,48 @@ +/* + * + * RFCOMM configuration file + * + * Copyright (C) 2001-2002 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +extern int lineno; + + +struct keyword_t { + char *string; + int type; +}; + +extern struct keyword_t rfcomm_keyword[]; + +int rfcomm_find_keyword(struct keyword_t *keyword, char *string); + + +#define MAXCOMMENTLEN 100 + +struct rfcomm_opts { + int bind; + bdaddr_t bdaddr; + int channel; + char comment[MAXCOMMENTLEN + 1]; +}; + +extern struct rfcomm_opts rfcomm_opts[RFCOMM_MAX_DEV]; + +int rfcomm_read_config(char *filename); diff --git a/rfcomm/lexer.l b/rfcomm/lexer.l new file mode 100644 index 00000000..c044391f --- /dev/null +++ b/rfcomm/lexer.l @@ -0,0 +1,107 @@ +%{ +/* + * + * RFCOMM configuration file + * + * Copyright (C) 2001-2002 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include +#include + +#include "kword.h" +#include "parser.h" + + +#define ECHO {;} +#define YY_DECL int yylex(void) + +int yyerror(char *str); + +%} + +space [ \t] +linebreak \n +comment \#.*\n +keyword [A-Za-z0-9\_\-]+ + +number [0-9]+ +string \".*\" +bdaddr [A-Za-z0-9]{2}:[A-Za-z0-9]{2}:[A-Za-z0-9]{2}:[A-Za-z0-9]{2}:[A-Za-z0-9]{2}:[A-Za-z0-9]{2} + +%% + +{space} { + /* Skip spaces and tabs */ + ; + } + +{comment} { + /* Skip comments */ + lineno++; + } + +{number} { + yylval.number = atoi(yytext); + return NUMBER; + } + +{string} { + yylval.string = yytext; + return STRING; + } + +{bdaddr} { + bdaddr_t *ba = malloc(sizeof(bdaddr_t)); + str2ba(yytext, ba); + yylval.bdaddr = ba; + return BDADDR; + } + +{keyword} { + int keyword = rfcomm_find_keyword(rfcomm_keyword, yytext); + if (keyword != -1) + return keyword; + + if (strncmp(yytext, "rfcomm", 6) == 0) { + yylval.number = atoi(yytext + 6); + return RFCOMM; + } + + yylval.string = yytext; + return WORD; + } + +{linebreak} { + lineno++; + } + +. { + return *yytext; + } + +%% + +int yywrap(void) +{ + return 1; +} diff --git a/rfcomm/main.c b/rfcomm/main.c new file mode 100644 index 00000000..2f793faa --- /dev/null +++ b/rfcomm/main.c @@ -0,0 +1,433 @@ +/* + * + * RFCOMM configuration utility + * + * Copyright (C) 2002 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "kword.h" + +static char *rfcomm_config_file = NULL; + +extern int optind, opterr, optopt; +extern char *optarg; + +static char *rfcomm_state[] = { + "unknown", + "connected", + "open", + "bound", + "listening", + "connecting", + "connecting", + "config", + "disconnecting", + "closed" +}; + +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ + return; +} + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + +static char *rfcomm_flagstostr(uint32_t flags) +{ + static char str[100]; + str[0] = 0; + + strcat(str, "["); + + if (flags & (1 << RFCOMM_REUSE_DLC)) + strcat(str, "reuse-dlc "); + + if (flags & (1 << RFCOMM_RELEASE_ONHUP)) + strcat(str, "release-on-hup "); + + if (flags & (1 << RFCOMM_TTY_ATTACHED)) + strcat(str, "tty-attached"); + + strcat(str, "]"); + return str; +} + +static void print_dev_info(struct rfcomm_dev_info *di) +{ + char src[18], dst[18], addr[100]; + + ba2str(&di->src, src); ba2str(&di->dst, dst); + + if (bacmp(&di->src, BDADDR_ANY) == 0) + sprintf(addr, "%s", dst); + else + sprintf(addr, "%s -> %s", src, dst); + + printf("rfcomm%d: %s channel %d %s %s\n", + di->id, addr, di->channel, + rfcomm_state[di->state], + di->flags ? rfcomm_flagstostr(di->flags) : ""); +} + +static void print_dev_list(int ctl, int flags) +{ + struct rfcomm_dev_list_req *dl; + struct rfcomm_dev_info *di; + int i; + + dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); + if (!dl) { + perror("Can't allocate memory"); + exit(1); + } + + dl->dev_num = RFCOMM_MAX_DEV; + di = dl->dev_info; + + if (ioctl(ctl, RFCOMMGETDEVLIST, (void *) dl) < 0) { + perror("Can't get device list"); + exit(1); + } + + for (i = 0; i < dl->dev_num; i++) + print_dev_info(di + i); +} + +static int create_dev(int ctl, int dev, int flags, bdaddr_t *bdaddr, int argc, char **argv) +{ + struct rfcomm_dev_req req; + int err; + + memset(&req, 0, sizeof(req)); + req.dev_id = dev; + req.flags = flags; + bacpy(&req.src, bdaddr); + + if (argc < 2) { + if ((err = rfcomm_read_config(rfcomm_config_file)) < 0) { + perror("Can't open RFCOMM config file"); + return err; + } + + bacpy(&req.dst, &rfcomm_opts[dev].bdaddr); + req.channel = rfcomm_opts[dev].channel; + + if (bacmp(&req.dst, BDADDR_ANY) == 0) { + fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev); + return -EFAULT; + } + + } else { + str2ba(argv[1], &req.dst); + + if (argc > 2) + req.channel = atoi(argv[2]); + else + req.channel = 1; + } + + if ((err = ioctl(ctl, RFCOMMCREATEDEV, &req)) < 0 ) + perror("Can't create device"); + + return err; +} + +static int create_all(int ctl) +{ + struct rfcomm_dev_req req; + int i, err; + + if ((err = rfcomm_read_config(rfcomm_config_file)) < 0) { + perror("Can't open RFCOMM config file"); + return err; + } + + for (i = 0; i < RFCOMM_MAX_DEV; i++) { + memset(&req, 0, sizeof(req)); + req.dev_id = i; + req.flags = 0; + bacpy(&req.src, BDADDR_ANY); + bacpy(&req.dst, &rfcomm_opts[i].bdaddr); + req.channel = rfcomm_opts[i].channel; + + if (bacmp(&req.dst, BDADDR_ANY) != 0) + ioctl(ctl, RFCOMMCREATEDEV, &req); + } + + return 0; +} + +static int release_dev(int ctl, int dev, int flags) +{ + struct rfcomm_dev_req req; + int err; + + memset(&req, 0, sizeof(req)); + req.dev_id = dev; + + if ((err = ioctl(ctl, RFCOMMRELEASEDEV, &req)) < 0 ) + perror("Can't release device"); + + return err; +} + +static int release_all(int ctl) +{ + struct rfcomm_dev_list_req *dl; + struct rfcomm_dev_info *di; + int i; + + dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); + if (!dl) { + perror("Can't allocate memory"); + exit(1); + } + + dl->dev_num = RFCOMM_MAX_DEV; + di = dl->dev_info; + + if (ioctl(ctl, RFCOMMGETDEVLIST, (void *) dl) < 0) { + perror("Can't get device list"); + exit(1); + } + + for (i = 0; i < dl->dev_num; i++) + release_dev(ctl, (di + i)->id, 0); + + return 0; +} + +static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ + struct sigaction sa; + struct pollfd p; + char devname[MAXPATHLEN]; + int fd; + + if (create_dev(ctl, dev, 0, bdaddr, argc, argv) < 0) + return; + + snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); + if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + perror("Can't open RFCOMM device"); + goto release; + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + p.fd = fd; + p.events = POLLHUP; + + while (!__io_canceled) { + p.revents = 0; + poll(&p, 1, 100); + } + + close(fd); + +release: + release_dev(ctl, dev, 0); +} + +static void cmd_create(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ + if (strcmp(argv[0], "all") == 0) + create_all(ctl); + else + create_dev(ctl, dev, 0, bdaddr, argc, argv); +} + +static void cmd_release(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ + if (strcmp(argv[0], "all") == 0) + release_all(ctl); + else + release_dev(ctl, dev, 0); +} + +static void cmd_show(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ + if (strcmp(argv[0], "all") == 0) + print_dev_list(ctl, 0); + else { + struct rfcomm_dev_info di = { id: atoi(argv[0]) }; + if (ioctl(ctl, RFCOMMGETDEVINFO, &di) < 0) { + perror("Get info failed"); + exit(1); + } + + print_dev_info(&di); + } +} + +struct { + char *cmd; + char *alt; + void (*func)(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv); + char *opt; + char *doc; +} command[] = { + { "bind", "create", cmd_create, " [channel]", "Bind device" }, + { "release", "unbind", cmd_release, "", "Release device" }, + { "connect", "conn", cmd_connect, " [channel]", "Connect device" }, + { "show", "info", cmd_show, 0, "Show device" }, + { NULL, NULL, NULL, 0, 0 } +}; + +static void usage(void) +{ + int i; + + printf("RFCOMM configuration utility ver %s\n", VERSION); + + printf("Usage:\n" + "\trfcomm [options] \n" + "\n"); + + printf("Options:\n" + "\t-i [hciX|bdaddr] Local HCI device or BD Address\n" + "\t-h, --help Display help\n" + "\t-a Show all devices (default)\n" + "\n"); + + printf("Commands:\n"); + for (i = 0; command[i].cmd; i++) + printf("\t%-8s %-24s\t%s\n", + command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); + printf("\n"); +} + + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { "config", 1, 0, 'f' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + + bdaddr_t bdaddr; + int i, opt, ctl, dev_id, show_all = 0; + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt = getopt_long(argc, argv, "+i:f:ah", main_options, NULL)) != -1) { + switch(opt) { + case 'i': + if (strncmp(optarg, "hci", 3) == 0) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); + break; + + case 'f': + rfcomm_config_file = strdup(optarg); + break; + + case 'a': + show_all = 1; + break; + + case 'h': + usage(); + exit(0); + + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 2) + show_all = 1; + + if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM)) < 0 ) { + perror("Can't open RFCOMM control socket"); + exit(1); + } + + if (show_all) { + print_dev_list(ctl, 0); + close(ctl); + exit(0); + } + + if (strncmp(argv[1], "rfcomm", 6) == 0) + dev_id = atoi(argv[1] + 6); + else + dev_id = atoi(argv[1]); + + for (i = 0; command[i].cmd; i++) { + if (strncmp(command[i].cmd, argv[0], 4) && strncmp(command[i].alt, argv[0], 4)) + continue; + argc--; + argv++; + command[i].func(ctl, dev_id, &bdaddr, argc, argv); + close(ctl); + exit(0); + } + + usage(); + + close(ctl); + + return 0; +} diff --git a/rfcomm/parser.y b/rfcomm/parser.y new file mode 100644 index 00000000..9f05f044 --- /dev/null +++ b/rfcomm/parser.y @@ -0,0 +1,164 @@ +%{ +/* + * + * RFCOMM configuration file + * + * Copyright (C) 2001-2002 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "kword.h" + +int yyparse(void); +int yylex(void); +int yyerror(char *s); + +struct rfcomm_opts *opts; + +%} + +%union { + int number; + char *string; + bdaddr_t *bdaddr; +} + +%token K_BIND K_DEVICE K_CHANNEL K_COMMENT +%token K_YES K_NO + +%token NUMBER RFCOMM +%token STRING WORD +%token BDADDR + +%type bool + +%% + +config : statement | config statement + ; + +statement : section '{' rfcomm_options '}' + | rfcomm '{' rfcomm_options '}' + | WORD + { + } + | error + { + yyclearin; + yyerrok; + } + ; + +section : WORD + { + opts = NULL; + } + +rfcomm : RFCOMM + { + if (($1 >= 0) && ($1 < RFCOMM_MAX_DEV)) + opts = &rfcomm_opts[$1]; + else + opts = NULL; + } + ; + +rfcomm_options : rfcomm_option ';' + | error ';' + | rfcomm_options rfcomm_option ';' + ; + +rfcomm_option : K_BIND bool + { + if (opts) + opts->bind = $2; + } + | K_DEVICE BDADDR + { + if (opts) + bacpy(&opts->bdaddr, $2); + } + | K_CHANNEL NUMBER + { + if (opts) + opts->channel = $2; + } + | K_COMMENT STRING + { + if (opts) + snprintf(opts->comment, MAXCOMMENTLEN, "%s", $2); + } + | WORD + { + // Unknown option + } + ; + +bool : K_YES { $$ = 1; } + | K_NO { $$ = 0; } + ; + +%% + +int yyerror(char *s) +{ + fprintf(stderr, "%s line %d\n", s, lineno); + return 0; +} + +int rfcomm_read_config(char *filename) +{ + extern FILE *yyin; + char file[MAXPATHLEN + 1]; + int i; + + for (i = 0; i < RFCOMM_MAX_DEV; i++) { + rfcomm_opts[i].bind = 0; + bacpy(&rfcomm_opts[i].bdaddr, BDADDR_ANY); + rfcomm_opts[i].channel = 1; + } + + if (filename) { + snprintf(file, MAXPATHLEN, "%s", filename); + } else { + snprintf(file, MAXPATHLEN, "%s/.bluetooth/rfcomm.conf", getenv("HOME")); + + if ((getuid() == 0) || (access(file, R_OK) < 0)) + snprintf(file, MAXPATHLEN, "/etc/bluetooth/rfcomm.conf"); + } + + if (!(yyin = fopen(file, "r"))) + return -1; + + lineno = 1; + yyparse(); + + fclose(yyin); + + return 0; +} diff --git a/rfcomm/rfcomm.8 b/rfcomm/rfcomm.8 new file mode 100644 index 00000000..d60af804 --- /dev/null +++ b/rfcomm/rfcomm.8 @@ -0,0 +1,36 @@ +.\" +.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH RFCOMM 8 "APRIL 28, 2002" "" "" + +.SH NAME +rfcomm \- RFCOMM configuration utility +.SH SYNOPSIS +.BR "rfcomm +[-i +.I hciX | bdaddr +] < +.I command +> < +.I dev +> +.SH DESCRIPTION +.B rfcomm +is used to set up, maintain, and inspect the RFCOMM configuration +of the Bluetooth subsystem in the Linux kernel. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/rfcomm/rfcomm.conf b/rfcomm/rfcomm.conf new file mode 100644 index 00000000..c1b10cd5 --- /dev/null +++ b/rfcomm/rfcomm.conf @@ -0,0 +1,19 @@ +# +# RFCOMM configuration file. +# +# $Id$ +# + +rfcomm0 { + # Automatically bind the device at startup + bind no; + + # Bluetooth address of the device + device 11:22:33:44:55:66; + + # RFCOMM channel for the connection + channel 1; + + # Description of the connection + comment "Example Bluetooth device"; +} -- cgit From c450127ad7b9705add1c299ec5340e59ff71fbe3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Oct 2002 07:30:04 +0000 Subject: Correct year in the copyright line --- rfcomm/kword.c | 2 +- rfcomm/kword.h | 2 +- rfcomm/lexer.l | 2 +- rfcomm/parser.y | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rfcomm/kword.c b/rfcomm/kword.c index c83dcc4b..26943c09 100644 --- a/rfcomm/kword.c +++ b/rfcomm/kword.c @@ -2,7 +2,7 @@ * * RFCOMM configuration file * - * Copyright (C) 2001-2002 Marcel Holtmann + * Copyright (C) 2002 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/kword.h b/rfcomm/kword.h index cdee0c8c..9016a5b4 100644 --- a/rfcomm/kword.h +++ b/rfcomm/kword.h @@ -2,7 +2,7 @@ * * RFCOMM configuration file * - * Copyright (C) 2001-2002 Marcel Holtmann + * Copyright (C) 2002 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/lexer.l b/rfcomm/lexer.l index c044391f..4585f5c9 100644 --- a/rfcomm/lexer.l +++ b/rfcomm/lexer.l @@ -3,7 +3,7 @@ * * RFCOMM configuration file * - * Copyright (C) 2001-2002 Marcel Holtmann + * Copyright (C) 2002 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/parser.y b/rfcomm/parser.y index 9f05f044..d8747c93 100644 --- a/rfcomm/parser.y +++ b/rfcomm/parser.y @@ -3,7 +3,7 @@ * * RFCOMM configuration file * - * Copyright (C) 2001-2002 Marcel Holtmann + * Copyright (C) 2002 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 78c812d9f44075238c2f3f8d46a51d574f383cd1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Oct 2002 07:44:31 +0000 Subject: Install the default rfcomm.conf file --- rfcomm/Makefile.am | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index 6b7a9eee..83b1f3f2 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -2,12 +2,23 @@ # $Id$ # -sbin_PROGRAMS = rfcomm +mandir = $(prefix)/share/man +confdir = /etc/bluetooth + +bin_PROGRAMS = rfcomm rfcomm_SOURCES = main.c parser.h parser.y lexer.l kword.h kword.c +rfcomm_CONFIG = rfcomm.conf -man_MANS = rfcomm.8 +man_MANS = rfcomm.8 YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h + +EXTRA_DIST = $(man_MANS) $(rfcomm_CONFIG) + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(confdir) + [ -f $(DESTDIR)$(confdir)/$(rfcomm_CONFIG) ] || \ + $(INSTALL_DATA) $(srcdir)/$(rfcomm_CONFIG) $(DESTDIR)$(confdir)/$(rfcomm_CONFIG) -- cgit From cd0f1ea91c4ffa3ecb6a9b3c6c179fa389d85ac6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Oct 2002 08:14:34 +0000 Subject: Cleanup --- AUTHORS | 1 + rfcomm/kword.c | 2 +- rfcomm/kword.h | 2 +- rfcomm/lexer.l | 2 +- rfcomm/parser.y | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 9cd176d2..b3eee626 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,6 +17,7 @@ Thomas Moser Marcel Holtmann Various patches, fixes and other contributions. + RFCOMM configuration utility. Nils Faerber Man pages. diff --git a/rfcomm/kword.c b/rfcomm/kword.c index 26943c09..3cb9f2c6 100644 --- a/rfcomm/kword.c +++ b/rfcomm/kword.c @@ -1,6 +1,6 @@ /* * - * RFCOMM configuration file + * RFCOMM configuration utility * * Copyright (C) 2002 Marcel Holtmann * diff --git a/rfcomm/kword.h b/rfcomm/kword.h index 9016a5b4..dddd2a83 100644 --- a/rfcomm/kword.h +++ b/rfcomm/kword.h @@ -1,6 +1,6 @@ /* * - * RFCOMM configuration file + * RFCOMM configuration utility * * Copyright (C) 2002 Marcel Holtmann * diff --git a/rfcomm/lexer.l b/rfcomm/lexer.l index 4585f5c9..0f64cb43 100644 --- a/rfcomm/lexer.l +++ b/rfcomm/lexer.l @@ -1,7 +1,7 @@ %{ /* * - * RFCOMM configuration file + * RFCOMM configuration utility * * Copyright (C) 2002 Marcel Holtmann * diff --git a/rfcomm/parser.y b/rfcomm/parser.y index d8747c93..f45f367c 100644 --- a/rfcomm/parser.y +++ b/rfcomm/parser.y @@ -1,7 +1,7 @@ %{ /* * - * RFCOMM configuration file + * RFCOMM configuration utility * * Copyright (C) 2002 Marcel Holtmann * -- cgit From 1debc2bcd696df9b7cd3c830db1f56a1ff1ac097 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 7 Oct 2002 16:23:09 +0000 Subject: update --- ChangeLog | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4c40f80e..55b1dfbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,15 @@ +ver 2.1: + Improved BCSP initialization (hciattach). + Support for displaying link quality (hcitool). + Support for changing link supervision timeout (hcitool). + New RFCOMM TTY configuration tool (rfcomm). + Minor fixes and updates. + ver 2.0: BCSP initialization (hciattach). Minor hciconfig fixes. -ver 2.0-pre13: +ver 2.0-pr13: Support for multiple pairing modes. Link key database handling fixes. -- cgit From 3f1417ff2d1e3fc91ae02c63cfb10eb1f50167cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Oct 2002 21:58:09 +0000 Subject: Move the man page of rfcomm to section 1 --- rfcomm/Makefile.am | 2 +- rfcomm/rfcomm.1 | 36 ++++++++++++++++++++++++++++++++++++ rfcomm/rfcomm.8 | 36 ------------------------------------ 3 files changed, 37 insertions(+), 37 deletions(-) create mode 100644 rfcomm/rfcomm.1 delete mode 100644 rfcomm/rfcomm.8 diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index 83b1f3f2..8ba03314 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -10,7 +10,7 @@ bin_PROGRAMS = rfcomm rfcomm_SOURCES = main.c parser.h parser.y lexer.l kword.h kword.c rfcomm_CONFIG = rfcomm.conf -man_MANS = rfcomm.8 +man_MANS = rfcomm.1 YFLAGS = -d diff --git a/rfcomm/rfcomm.1 b/rfcomm/rfcomm.1 new file mode 100644 index 00000000..51a258dc --- /dev/null +++ b/rfcomm/rfcomm.1 @@ -0,0 +1,36 @@ +.\" +.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH RFCOMM 1 "APRIL 28, 2002" "" "" + +.SH NAME +rfcomm \- RFCOMM configuration utility +.SH SYNOPSIS +.BR "rfcomm +[-i +.I hciX | bdaddr +] < +.I command +> < +.I dev +> +.SH DESCRIPTION +.B rfcomm +is used to set up, maintain, and inspect the RFCOMM configuration +of the Bluetooth subsystem in the Linux kernel. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/rfcomm/rfcomm.8 b/rfcomm/rfcomm.8 deleted file mode 100644 index d60af804..00000000 --- a/rfcomm/rfcomm.8 +++ /dev/null @@ -1,36 +0,0 @@ -.\" -.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. -.\" -.\" -.TH RFCOMM 8 "APRIL 28, 2002" "" "" - -.SH NAME -rfcomm \- RFCOMM configuration utility -.SH SYNOPSIS -.BR "rfcomm -[-i -.I hciX | bdaddr -] < -.I command -> < -.I dev -> -.SH DESCRIPTION -.B rfcomm -is used to set up, maintain, and inspect the RFCOMM configuration -of the Bluetooth subsystem in the Linux kernel. -.SH AUTHOR -Written by Marcel Holtmann . -.br -- cgit From a92838eca1015b435ad9f10acd2868793055d063 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 10 Oct 2002 18:29:12 +0000 Subject: Use original path when libtoolized library not found. --- acinclude.m4 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index cca660ee..a2fa7784 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -76,6 +76,8 @@ AC_DEFUN([AC_SEARCH_LIB], # Check for libtool library if test -f $p/lib$1.la; then path=$p/.libs + else + path=$p fi LDFLAGS="-L$path -l$1" -- cgit From 342bdf14bfe6340a8fcf6b6a412685a94ad843b5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Oct 2002 18:56:06 +0000 Subject: Add ppporc program --- tools/Makefile.am | 2 +- tools/ppporc.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 tools/ppporc.c diff --git a/tools/Makefile.am b/tools/Makefile.am index 281be99e..b4049c32 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -9,6 +9,6 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -noinst_PROGRAMS = l2test scotest rctest +noinst_PROGRAMS = ppporc l2test scotest rctest EXTRA_DIST = $(man_MANS) diff --git a/tools/ppporc.c b/tools/ppporc.c new file mode 100644 index 00000000..514ceb65 --- /dev/null +++ b/tools/ppporc.c @@ -0,0 +1,282 @@ +/* + * + * PPP over Bluetooth RFCOMM + * + * Copyright (C) 2002 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +extern int optind, opterr, optopt; +extern char *optarg; + + +/* IO cancelation */ +static volatile sig_atomic_t __io_canceled; + +static inline void io_init(void) +{ + __io_canceled = 0; +} + +static inline void io_cancel(void) +{ + __io_canceled = 1; +} + + +/* Signal functions */ +static void sig_hup(int sig) +{ + return; +} + +static void sig_term(int sig) +{ + syslog(LOG_INFO, "Closing RFCOMM channel"); + io_cancel(); +} + + +/* Read exactly len bytes (Signal safe)*/ +static inline int read_n(int fd, char *buf, int len) +{ + register int t = 0, w; + + while (!__io_canceled && len > 0) { + if ((w = read(fd, buf, len)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!w) + return 0; + len -= w; + buf += w; + t += w; + } + + return t; +} + + +/* Write exactly len bytes (Signal safe)*/ +static inline int write_n(int fd, char *buf, int len) +{ + register int t = 0, w; + + while (!__io_canceled && len > 0) { + if ((w = write(fd, buf, len)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!w) + return 0; + len -= w; + buf += w; + t += w; + } + + return t; +} + + +/* Create the RFCOMM connection */ +static int create_connection(bdaddr_t *bdaddr, uint8_t channel) +{ + struct sockaddr_rc remote_addr, local_addr; + int fd, err; + + if ((fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) + return fd; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.rc_family = AF_BLUETOOTH; + bacpy(&local_addr.rc_bdaddr, BDADDR_ANY); + if ((err = bind(fd, (struct sockaddr *)&local_addr, sizeof(local_addr))) < 0) { + close(fd); + return err; + } + + memset(&remote_addr, 0, sizeof(remote_addr)); + remote_addr.rc_family = AF_BLUETOOTH; + bacpy(&remote_addr.rc_bdaddr, bdaddr); + remote_addr.rc_channel = channel; + if ((err = connect(fd, (struct sockaddr *)&remote_addr, sizeof(remote_addr))) < 0) { + close(fd); + return err; + } + + syslog(LOG_INFO, "RFCOMM channel %d connected", channel); + + return fd; +} + + +/* Process the data from socket and pseudo tty */ +static int process_data(int fd) +{ + struct pollfd p[2]; + char buf[1024]; + int err, r; + + p[0].fd = 0; + p[0].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; + + p[1].fd = fd; + p[1].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; + + err = 0; + + while (!__io_canceled) { + p[0].revents = 0; + p[1].revents = 0; + + err = poll(p, 2, -1); + if (err < 0) + break; + + err = 0; + + if (p[0].revents) { + if (p[0].revents & (POLLERR | POLLHUP | POLLNVAL)) + break; + r = read(0, buf, sizeof(buf)); + if (r < 0) { + if (errno != EINTR && errno != EAGAIN) { + err = r; + break; + } + } + + err = write_n(fd, buf, r); + if (err < 0) + break; + } + + if (p[1].revents) { + if (p[1].revents & (POLLERR | POLLHUP | POLLNVAL)) + break; + r = read(fd, buf, sizeof(buf)); + if (r < 0) { + if (errno != EINTR && errno != EAGAIN) { + err = r; + break; + } + } + + err = write_n(1, buf, r); + if (err < 0) + break; + } + } + + return err; +} + + +static void usage(void) +{ + printf("Usage:\tppporc [channel]\n"); +} + + +int main(int argc, char** argv) +{ + struct sigaction sa; + int fd, err, opt; + + bdaddr_t bdaddr; + uint8_t channel; + + + /* Parse command line options */ + while ((opt = getopt(argc, argv, "h")) != EOF) { + switch(opt) { + case 'h': + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + + switch (argc) { + case 1: + str2ba(argv[0], &bdaddr); + channel = 1; + break; + case 2: + str2ba(argv[0], &bdaddr); + channel = atoi(argv[1]); + break; + default: + usage(); + exit(0); + } + + + /* Initialize syslog */ + openlog("ppporc", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); + syslog(LOG_INFO, "PPP over RFCOMM"); + + + /* Initialize signals */ + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + + syslog(LOG_INFO, "Connecting to %s", argv[0]); + + if ((fd = create_connection(&bdaddr, channel)) < 0) { + syslog(LOG_ERR, "Can't connect to remote device (%s)", strerror(errno)); + return fd; + } + + err = process_data(fd); + + close(fd); + + return err; +} -- cgit From b5edb3c0a92674b27a95f7968e18bb51150c52f6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Oct 2002 20:46:47 +0000 Subject: Move testing programs from tools directory into the test directory --- Makefile.am | 2 +- configure.in | 2 +- test/Makefile.am | 5 + test/attest.c | 178 ++++++++++++++++++ test/l2test.c | 530 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/rctest.c | 469 +++++++++++++++++++++++++++++++++++++++++++++++ test/scotest.c | 358 ++++++++++++++++++++++++++++++++++++ tools/Makefile.am | 2 +- tools/l2test.c | 530 ------------------------------------------------------ tools/rctest.c | 469 ----------------------------------------------- tools/scotest.c | 358 ------------------------------------ 11 files changed, 1543 insertions(+), 1360 deletions(-) create mode 100644 test/Makefile.am create mode 100644 test/attest.c create mode 100644 test/l2test.c create mode 100644 test/rctest.c create mode 100644 test/scotest.c delete mode 100644 tools/l2test.c delete mode 100644 tools/rctest.c delete mode 100644 tools/scotest.c diff --git a/Makefile.am b/Makefile.am index a9fe27a4..d0351af9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,4 +2,4 @@ # $Id$ # -SUBDIRS := hcid tools rfcomm scripts pcmcia +SUBDIRS := hcid tools rfcomm test scripts pcmcia diff --git a/configure.in b/configure.in index af2f6ee1..529f231b 100644 --- a/configure.in +++ b/configure.in @@ -84,4 +84,4 @@ AC_ARG_ENABLE(pcmcia, AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=) fi ]) -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile scripts/Makefile pcmcia/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 00000000..dc84f46f --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,5 @@ +# +# $Id$ +# + +noinst_PROGRAMS = l2test scotest rctest attest diff --git a/test/attest.c b/test/attest.c new file mode 100644 index 00000000..078bb886 --- /dev/null +++ b/test/attest.c @@ -0,0 +1,178 @@ +/* + * + * Programm for testing AT commands over Bluetooth RFCOMM + * + * Copyright (C) 2001-2002 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + + +static int at_command(int fd, char *cmd, int to) +{ + fd_set rfds; + struct timeval timeout; + unsigned char buf[1024]; + int sel, len, i, n; + + write(fd, cmd, strlen(cmd)); + + for (i = 0; i < 100; i++) { + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + timeout.tv_sec = 0; + timeout.tv_usec = to; + + if ((sel = select(fd + 1, &rfds, NULL, NULL, &timeout)) > 0) { + + if (FD_ISSET(fd, &rfds)) { + memset(buf, 0, sizeof(buf)); + len = read(fd, buf, sizeof(buf)); + for (n = 0; n < len; n++) + printf("%c", buf[n]); + if (strstr(buf, "\r\nOK") != NULL) + break; + if (strstr(buf, "\r\nERROR") != NULL) + break; + if (strstr(buf, "\r\nCONNECT") != NULL) + break; + } + + } + + } + + return 0; +} + + +static int open_device(char *device) +{ + int fd; + struct termios ti; + + if ((fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { + printf("Can't open serial port. %s (%d)\n", strerror(errno), errno); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + /* Switch tty to RAW mode */ + cfmakeraw(&ti); + tcsetattr(fd, TCSANOW, &ti); + + return fd; +} + + +static int open_socket(bdaddr_t *bdaddr, uint8_t channel) +{ + struct sockaddr_rc remote_addr, local_addr; + int s; + + if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { + printf("Can't create socket. %s (%d)\n", strerror(errno), errno); + return -1; + } + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.rc_family = AF_BLUETOOTH; + bacpy(&local_addr.rc_bdaddr, BDADDR_ANY); + if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { + printf("Can't bind socket. %s (%d)\n", strerror(errno), errno); + close(s); + return -1; + } + + memset(&remote_addr, 0, sizeof(remote_addr)); + remote_addr.rc_family = AF_BLUETOOTH; + bacpy(&remote_addr.rc_bdaddr, bdaddr); + remote_addr.rc_channel = channel; + if (connect(s, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) < 0) { + printf("Can't connect. %s (%d)\n", strerror(errno), errno); + close(s); + return -1; + } + + return s; +} + + +static void usage(void) +{ + printf("Usage:\n\tattest | [channel]\n"); +} + + +int main(int argc, char *argv[]) +{ + int fd; + + bdaddr_t bdaddr; + uint8_t channel; + + switch (argc) { + case 2: + str2ba(argv[1], &bdaddr); + channel = 1; + break; + case 3: + str2ba(argv[1], &bdaddr); + channel = atoi(argv[2]); + break; + default: + usage(); + exit(-1); + } + + if (bacmp(BDADDR_ANY, &bdaddr)) { + printf("Connecting to %s on channel %d\n", argv[1], channel); + fd = open_socket(&bdaddr, channel); + } else { + printf("Opening device %s\n", argv[1]); + fd = open_device(argv[1]); + } + + if (fd < 0) + exit(-2); + + at_command(fd, "ATZ\r\n", 10000); + at_command(fd, "AT+CPBS=\"ME\"\r\n", 10000); + at_command(fd, "AT+CPBR=1,100\r\n", 100000); + + close(fd); + + return 0; +} diff --git a/test/l2test.c b/test/l2test.c new file mode 100644 index 00000000..b08b2d34 --- /dev/null +++ b/test/l2test.c @@ -0,0 +1,530 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP, + CONNECT, + CRECV, + LSEND +}; + +unsigned char *buf; + +/* Default mtu */ +int imtu = 672; +int omtu = 0; + +/* Default data size */ +long data_size = 672; + +/* Default addr and psm */ +bdaddr_t bdaddr; +unsigned short psm = 10; + +int master = 0; +int auth = 0; +int encrypt = 0; +int socktype = SOCK_SEQPACKET; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_l2 rem_addr, loc_addr; + struct l2cap_options opts; + int s, opt; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.l2_family = AF_BLUETOOTH; + loc_addr.l2_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Get default options */ + opt = sizeof(opts); + if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + /* Set new options */ + opts.omtu = omtu; + opts.imtu = imtu; + if( setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0 ) { + syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.l2_family = AF_BLUETOOTH; + baswap(&rem_addr.l2_bdaddr, strtoba(svr)); + rem_addr.l2_psm = htobs(psm); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + opt = sizeof(opts); + if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ + syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d]\n", + opts.imtu, opts.omtu, opts.flush_to); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_l2 loc_addr, rem_addr; + struct l2cap_options opts; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.l2_family = AF_BLUETOOTH; + loc_addr.l2_bdaddr = bdaddr; + loc_addr.l2_psm = htobs(psm); + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Set link mode */ + opt = 0; + if (master) + opt |= L2CAP_LM_MASTER; + + if (auth) + opt |= L2CAP_LM_AUTH; + + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + + if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Get default options */ + opt = sizeof(opts); + if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { + syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + /* Set new options */ + opts.imtu = imtu; + if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { + syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + if (socktype == SOCK_DGRAM) { + handler(s); + return; + } + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection on psm %d ...", psm); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + opt = sizeof(opts); + if( getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + exit(1); + } + + baswap(&ba, &rem_addr.l2_bdaddr); + syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", + batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO, "Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO,"Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + uint32_t sq; + uint16_t l; + int i,r; + + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + + /* Check sequence */ + sq = btohl(*(uint32_t *)buf); + if (seq != sq) { + syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); + seq = sq; + } + seq++; + + /* Check length */ + l = btohs(*(uint16_t *)(buf+4)); + if (r != l) { + syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); + continue; + } + + /* Verify data */ + for (i=6; i < r; i++) { + if (buf[i] != 0x7f) + syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); + } + + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + } +} + +void send_mode(int s) +{ + uint32_t seq; + int i; + + syslog(LOG_INFO,"Sending ..."); + + for(i=6; i < data_size; i++) + buf[i]=0x7f; + + seq = 0; + while (1) { + *(uint32_t *) buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, data_size, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + exit(1); + } + } +} + +void reconnect_mode(char *svr) +{ + while(1) { + int s = do_connect(svr); + close(s); + } +} + +void connect_mode(char *svr) +{ + int s; + if ((s = do_connect(svr)) < 0) + exit(1); + sleep(99999999); +} + +void multi_connect_mode(char *svr) +{ + while (1) { + int i, s; + for (i=0; i<10; i++) { + if (fork()) continue; + + /* Child */ + s = do_connect(svr); + usleep(500); + close(s); + exit(0); + } + sleep(2); + } +} + +void usage(void) +{ + printf("l2test - L2CAP testing\n" + "Usage:\n"); + printf("\tl2test [options] [bdaddr]\n"); + printf("Modes:\n" + "\t-r listen and receive\n" + "\t-w listen and send\n" + "\t-d listen and dump incomming data\n" + "\t-s connect and send\n" + "\t-u connect and receive\n" + "\t-n connect and be silent\n" + "\t-c connect, disconnect, connect, ...\n" + "\t-m multiple connects\n"); + + printf("Options:\n" + "\t[-b bytes] [-S bdaddr] [-P psm]\n" + "\t[-I imtu] [-O omtu]\n" + "\t[-D] use connectionless channel (datagram)\n" + "\t[-E] request encryption\n" + "\t[-E] request encryption\n" + "\t[-M] become master\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + int opt, mode, s, need_addr; + struct sigaction sa; + + mode = RECV; need_addr = 0; + + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAED")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + need_addr = 1; + break; + + case 'w': + mode = LSEND; + break; + + case 'u': + mode = CRECV; + need_addr = 1; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + need_addr = 1; + break; + + case 'n': + mode = CONNECT; + need_addr = 1; + break; + + case 'm': + mode = MULTY; + need_addr = 1; + break; + + case 'b': + data_size = atoi(optarg); + break; + + case 'S': + baswap(&bdaddr, strtoba(optarg)); + break; + + case 'P': + psm = atoi(optarg); + break; + + case 'I': + imtu = atoi(optarg); + break; + + case 'O': + omtu = atoi(optarg); + break; + + case 'M': + master = 1; + break; + + case 'A': + auth = 1; + break; + + case 'E': + encrypt = 1; + break; + + case 'D': + socktype = SOCK_DGRAM; + break; + + default: + usage(); + exit(1); + } + } + + if (need_addr && !(argc - optind)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case CRECV: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + recv_mode(s); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + send_mode(s); + break; + + case LSEND: + do_listen(send_mode); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multi_connect_mode(argv[optind]); + break; + + case CONNECT: + connect_mode(argv[optind]); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} diff --git a/test/rctest.c b/test/rctest.c new file mode 100644 index 00000000..0584a6a9 --- /dev/null +++ b/test/rctest.c @@ -0,0 +1,469 @@ +/* + RFCOMM test tool + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP, + CONNECT, + CRECV, + LSEND +}; + +unsigned char *buf; + +/* Default mtu */ +int imtu = 672; +int omtu = 0; + +/* Default data size */ +long data_size = 127; + +/* Default addr and channel */ +bdaddr_t bdaddr; +uint8_t channel = 10; + +int master = 0; +int auth = 0; +int encrypt = 0; +int socktype = SOCK_STREAM; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_rc rem_addr, loc_addr; + int s; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.rc_family = AF_BLUETOOTH; + loc_addr.rc_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.rc_family = AF_BLUETOOTH; + baswap(&rem_addr.rc_bdaddr, strtoba(svr)); + rem_addr.rc_channel = channel; + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + syslog(LOG_INFO, "Connected"); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_rc loc_addr, rem_addr; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.rc_family = AF_BLUETOOTH; + loc_addr.rc_bdaddr = bdaddr; + loc_addr.rc_channel = channel; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + +#if 0 + /* Set link mode */ + opt = 0; + if (master) + opt |= L2CAP_LM_MASTER; + + if (auth) + opt |= L2CAP_LM_AUTH; + + if (encrypt) + opt |= L2CAP_LM_ENCRYPT; + + if (setsockopt(s, SOL_RFCOMM, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } +#endif + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection on channel %d ...", channel); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + baswap(&ba, &rem_addr.rc_bdaddr); + syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO, "Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO,"Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + //uint32_t sq; + //uint16_t l; + int r; + + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } +#if 0 + /* Check sequence */ + sq = btohl(*(uint32_t *)buf); + if (seq != sq) { + syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); + seq = sq; + } + seq++; + + /* Check length */ + l = btohs(*(uint16_t *)(buf+4)); + if (r != l) { + syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); + continue; + } + + /* Verify data */ + for (i=6; i < r; i++) { + if (buf[i] != 0x7f) + syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); + } +#endif + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + } +} + +void send_mode(int s) +{ + uint32_t seq; + int i; + + syslog(LOG_INFO,"Sending ..."); + + for(i=6; i < data_size; i++) + buf[i]=0x7f; + + seq = 0; + while (1) { + *(uint32_t *) buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, data_size, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + exit(1); + } + } +} + +void reconnect_mode(char *svr) +{ + while(1) { + int s = do_connect(svr); + close(s); + } +} + +void multi_connect_mode(char *svr) +{ + while (1) { + int i, s; + for (i=0; i<10; i++) { + if (fork()) continue; + + /* Child */ + s = do_connect(svr); + usleep(500); + close(s); + exit(0); + } + sleep(2); + } +} + +void usage(void) +{ + printf("rctest - RFCOMM testing\n" + "Usage:\n"); + printf("\trctest [options] [bdaddr]\n"); + printf("Modes:\n" + "\t-r listen and receive\n" + "\t-w listen and send\n" + "\t-d listen and dump incomming data\n" + "\t-s connect and send\n" + "\t-u connect and receive\n" + "\t-n connect and be silent\n" + "\t-c connect, disconnect, connect, ...\n" + "\t-m multiple connects\n"); + + printf("Options:\n" + "\t[-b bytes] [-S bdaddr] [-P channel]\n" + "\t[-I imtu] [-O omtu]\n" + "\t[-E] request encryption\n" + "\t[-E] request encryption\n" + "\t[-M] become master\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + int opt, mode, s, need_addr; + struct sigaction sa; + + mode = RECV; need_addr = 0; + + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + need_addr = 1; + break; + + case 'w': + mode = LSEND; + break; + + case 'u': + mode = CRECV; + need_addr = 1; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + need_addr = 1; + break; + + case 'n': + mode = CONNECT; + need_addr = 1; + break; + + case 'm': + mode = MULTY; + need_addr = 1; + break; + + case 'b': + data_size = atoi(optarg); + break; + + case 'S': + baswap(&bdaddr, strtoba(optarg)); + break; + + case 'P': + channel = atoi(optarg); + break; + + case 'I': + imtu = atoi(optarg); + break; + + case 'O': + omtu = atoi(optarg); + break; + + case 'M': + master = 1; + break; + + case 'A': + auth = 1; + break; + + case 'E': + encrypt = 1; + break; + + default: + usage(); + exit(1); + } + } + + if (need_addr && !(argc - optind)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case CRECV: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + recv_mode(s); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + send_mode(s); + break; + + case LSEND: + do_listen(send_mode); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multi_connect_mode(argv[optind]); + break; + + case CONNECT: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + dump_mode(s); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} diff --git a/test/scotest.c b/test/scotest.c new file mode 100644 index 00000000..dcb1acdf --- /dev/null +++ b/test/scotest.c @@ -0,0 +1,358 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +/* Test modes */ +enum { + SEND, + RECV, + RECONNECT, + MULTY, + DUMP +}; + +unsigned char *buf; + +/* Default data size */ +long data_size = 672; + +bdaddr_t bdaddr; + +float tv2fl(struct timeval tv) +{ + return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); +} + +int do_connect(char *svr) +{ + struct sockaddr_sco rem_addr, loc_addr; + int s; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&loc_addr, 0, sizeof(loc_addr)); + loc_addr.sco_family = AF_BLUETOOTH; + loc_addr.sco_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.sco_family = AF_BLUETOOTH; + baswap(&rem_addr.sco_bdaddr, strtoba(svr)); + if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + return -1; + } + + syslog(LOG_INFO, "Connected\n"); + + return s; +} + +void do_listen( void (*handler)(int sk) ) +{ + struct sockaddr_sco loc_addr, rem_addr; + int s, s1, opt; + bdaddr_t ba; + + if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + loc_addr.sco_family = AF_BLUETOOTH; + loc_addr.sco_bdaddr = bdaddr; + if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + if( listen(s, 10) ) { + syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + exit(1); + } + + syslog(LOG_INFO,"Waiting for connection ..."); + + while(1) { + opt = sizeof(rem_addr); + if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + exit(1); + } + if( fork() ) { + /* Parent */ + close(s1); + continue; + } + /* Child */ + + close(s); + + baswap(&ba, &rem_addr.sco_bdaddr); + syslog(LOG_INFO, "Connect from %s\n", batostr(&ba)); + + handler(s1); + + syslog(LOG_INFO, "Disconnect\n"); + exit(0); + } +} + +void dump_mode(int s) +{ + int len; + + syslog(LOG_INFO,"Receiving ..."); + while ((len = read(s, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes\n", len); +} + +void recv_mode(int s) +{ + struct timeval tv_beg,tv_end,tv_diff; + long total; + uint32_t seq; + + syslog(LOG_INFO, "Receiving ..."); + + seq = 0; + while (1) { + gettimeofday(&tv_beg,NULL); + total = 0; + while (total < data_size) { + int r; + if ((r = recv(s, buf, data_size, 0)) <= 0) { + if (r < 0) + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + return; + } + total += r; + } + gettimeofday(&tv_end,NULL); + + timersub(&tv_end,&tv_beg,&tv_diff); + + syslog(LOG_INFO,"%ld bytes in %.2fm speed %.2f kb",total, + tv2fl(tv_diff) / 60.0, + (float)( total / tv2fl(tv_diff) ) / 1024.0 ); + } +} + +void send_mode(char *svr) +{ + struct sco_options so; + uint32_t seq; + int s, i, opt; + + if ((s = do_connect(svr)) < 0) { + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", + strerror(errno), errno); + exit(1); + } + + opt = sizeof(so); + if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { + syslog(LOG_ERR, "Can't get SCO options. %s(%d)", + strerror(errno), errno); + exit(1); + } + + + syslog(LOG_INFO,"Sending ..."); + + for (i=6; i < so.mtu; i++) + buf[i]=0x7f; + + seq = 0; + while (1) { + *(uint32_t *)buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, so.mtu, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", + strerror(errno), errno); + exit(1); + } + usleep(1); + } +} + +void reconnect_mode(char *svr) +{ + while(1){ + int s; + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + exit(1); + } + close(s); + + sleep(5); + } +} + +void multy_connect_mode(char *svr) +{ + while(1){ + int i, s; + for(i=0; i<10; i++){ + if( fork() ) continue; + + /* Child */ + if( (s = do_connect(svr)) < 0 ){ + syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + } + close(s); + exit(0); + } + sleep(19); + } +} + +void usage(void) +{ + printf("scotest - SCO testing\n" + "Usage:\n"); + printf("\tscotest [-b bytes] [bd_addr]\n"); + printf("Modes:\n" + "\t-d dump (server)\n" + "\t-c reconnect (client)\n" + "\t-m multiple connects (client)\n" + "\t-r receive (server)\n" + "\t-s send (client)\n"); +} + +extern int optind,opterr,optopt; +extern char *optarg; + +int main(int argc ,char *argv[]) +{ + struct sigaction sa; + int opt, mode = RECV; + + while ((opt=getopt(argc,argv,"rdscmb:")) != EOF) { + switch(opt) { + case 'r': + mode = RECV; + break; + + case 's': + mode = SEND; + break; + + case 'd': + mode = DUMP; + break; + + case 'c': + mode = RECONNECT; + break; + + case 'm': + mode = MULTY; + break; + + case 'b': + data_size = atoi(optarg); + break; + + default: + usage(); + exit(1); + } + } + + if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + usage(); + exit(1); + } + + if (!(buf = malloc(data_size))) { + perror("Can't allocate data buffer"); + exit(1); + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_NOCLDSTOP; + sigaction(SIGCHLD, &sa, NULL); + + openlog("scotest", LOG_PERROR | LOG_PID, LOG_LOCAL0); + + switch( mode ){ + case RECV: + do_listen(recv_mode); + break; + + case DUMP: + do_listen(dump_mode); + break; + + case SEND: + send_mode(argv[optind]); + break; + + case RECONNECT: + reconnect_mode(argv[optind]); + break; + + case MULTY: + multy_connect_mode(argv[optind]); + break; + } + syslog(LOG_INFO, "Exit"); + + closelog(); + + return 0; +} diff --git a/tools/Makefile.am b/tools/Makefile.am index b4049c32..9ff29c14 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -9,6 +9,6 @@ bin_PROGRAMS = hcitool l2ping man_MANS = hciattach.8 l2ping.8 -noinst_PROGRAMS = ppporc l2test scotest rctest +noinst_PROGRAMS = ppporc EXTRA_DIST = $(man_MANS) diff --git a/tools/l2test.c b/tools/l2test.c deleted file mode 100644 index b08b2d34..00000000 --- a/tools/l2test.c +++ /dev/null @@ -1,530 +0,0 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -/* Test modes */ -enum { - SEND, - RECV, - RECONNECT, - MULTY, - DUMP, - CONNECT, - CRECV, - LSEND -}; - -unsigned char *buf; - -/* Default mtu */ -int imtu = 672; -int omtu = 0; - -/* Default data size */ -long data_size = 672; - -/* Default addr and psm */ -bdaddr_t bdaddr; -unsigned short psm = 10; - -int master = 0; -int auth = 0; -int encrypt = 0; -int socktype = SOCK_SEQPACKET; - -float tv2fl(struct timeval tv) -{ - return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); -} - -int do_connect(char *svr) -{ - struct sockaddr_l2 rem_addr, loc_addr; - struct l2cap_options opts; - int s, opt; - - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - return -1; - } - - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.l2_family = AF_BLUETOOTH; - loc_addr.l2_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - /* Get default options */ - opt = sizeof(opts); - if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { - syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); - return -1; - } - - /* Set new options */ - opts.omtu = omtu; - opts.imtu = imtu; - if( setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0 ) { - syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); - return -1; - } - - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.l2_family = AF_BLUETOOTH; - baswap(&rem_addr.l2_bdaddr, strtoba(svr)); - rem_addr.l2_psm = htobs(psm); - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); - close(s); - return -1; - } - - opt = sizeof(opts); - if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ - syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); - close(s); - return -1; - } - - syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d]\n", - opts.imtu, opts.omtu, opts.flush_to); - - return s; -} - -void do_listen( void (*handler)(int sk) ) -{ - struct sockaddr_l2 loc_addr, rem_addr; - struct l2cap_options opts; - int s, s1, opt; - bdaddr_t ba; - - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - loc_addr.l2_family = AF_BLUETOOTH; - loc_addr.l2_bdaddr = bdaddr; - loc_addr.l2_psm = htobs(psm); - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - /* Set link mode */ - opt = 0; - if (master) - opt |= L2CAP_LM_MASTER; - - if (auth) - opt |= L2CAP_LM_AUTH; - - if (encrypt) - opt |= L2CAP_LM_ENCRYPT; - - if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); - exit(1); - } - - /* Get default options */ - opt = sizeof(opts); - if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); - exit(1); - } - - /* Set new options */ - opts.imtu = imtu; - if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); - exit(1); - } - - if (socktype == SOCK_DGRAM) { - handler(s); - return; - } - - if( listen(s, 10) ) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - syslog(LOG_INFO,"Waiting for connection on psm %d ...", psm); - - while(1) { - opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); - exit(1); - } - if( fork() ) { - /* Parent */ - close(s1); - continue; - } - /* Child */ - - close(s); - - opt = sizeof(opts); - if( getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { - syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); - exit(1); - } - - baswap(&ba, &rem_addr.l2_bdaddr); - syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", - batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); - - handler(s1); - - syslog(LOG_INFO, "Disconnect\n"); - exit(0); - } -} - -void dump_mode(int s) -{ - int len; - - syslog(LOG_INFO, "Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) - syslog(LOG_INFO, "Recevied %d bytes\n", len); -} - -void recv_mode(int s) -{ - struct timeval tv_beg,tv_end,tv_diff; - long total; - uint32_t seq; - - syslog(LOG_INFO,"Receiving ..."); - - seq = 0; - while (1) { - gettimeofday(&tv_beg,NULL); - total = 0; - while (total < data_size) { - uint32_t sq; - uint16_t l; - int i,r; - - if ((r = recv(s, buf, data_size, 0)) <= 0) { - if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); - return; - } - - /* Check sequence */ - sq = btohl(*(uint32_t *)buf); - if (seq != sq) { - syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); - seq = sq; - } - seq++; - - /* Check length */ - l = btohs(*(uint16_t *)(buf+4)); - if (r != l) { - syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); - continue; - } - - /* Verify data */ - for (i=6; i < r; i++) { - if (buf[i] != 0x7f) - syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); - } - - total += r; - } - gettimeofday(&tv_end,NULL); - - timersub(&tv_end,&tv_beg,&tv_diff); - - syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, - tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); - } -} - -void send_mode(int s) -{ - uint32_t seq; - int i; - - syslog(LOG_INFO,"Sending ..."); - - for(i=6; i < data_size; i++) - buf[i]=0x7f; - - seq = 0; - while (1) { - *(uint32_t *) buf = htobl(seq++); - *(uint16_t *)(buf+4) = htobs(data_size); - - if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); - exit(1); - } - } -} - -void reconnect_mode(char *svr) -{ - while(1) { - int s = do_connect(svr); - close(s); - } -} - -void connect_mode(char *svr) -{ - int s; - if ((s = do_connect(svr)) < 0) - exit(1); - sleep(99999999); -} - -void multi_connect_mode(char *svr) -{ - while (1) { - int i, s; - for (i=0; i<10; i++) { - if (fork()) continue; - - /* Child */ - s = do_connect(svr); - usleep(500); - close(s); - exit(0); - } - sleep(2); - } -} - -void usage(void) -{ - printf("l2test - L2CAP testing\n" - "Usage:\n"); - printf("\tl2test [options] [bdaddr]\n"); - printf("Modes:\n" - "\t-r listen and receive\n" - "\t-w listen and send\n" - "\t-d listen and dump incomming data\n" - "\t-s connect and send\n" - "\t-u connect and receive\n" - "\t-n connect and be silent\n" - "\t-c connect, disconnect, connect, ...\n" - "\t-m multiple connects\n"); - - printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P psm]\n" - "\t[-I imtu] [-O omtu]\n" - "\t[-D] use connectionless channel (datagram)\n" - "\t[-E] request encryption\n" - "\t[-E] request encryption\n" - "\t[-M] become master\n"); -} - -extern int optind,opterr,optopt; -extern char *optarg; - -int main(int argc ,char *argv[]) -{ - int opt, mode, s, need_addr; - struct sigaction sa; - - mode = RECV; need_addr = 0; - - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAED")) != EOF) { - switch(opt) { - case 'r': - mode = RECV; - break; - - case 's': - mode = SEND; - need_addr = 1; - break; - - case 'w': - mode = LSEND; - break; - - case 'u': - mode = CRECV; - need_addr = 1; - break; - - case 'd': - mode = DUMP; - break; - - case 'c': - mode = RECONNECT; - need_addr = 1; - break; - - case 'n': - mode = CONNECT; - need_addr = 1; - break; - - case 'm': - mode = MULTY; - need_addr = 1; - break; - - case 'b': - data_size = atoi(optarg); - break; - - case 'S': - baswap(&bdaddr, strtoba(optarg)); - break; - - case 'P': - psm = atoi(optarg); - break; - - case 'I': - imtu = atoi(optarg); - break; - - case 'O': - omtu = atoi(optarg); - break; - - case 'M': - master = 1; - break; - - case 'A': - auth = 1; - break; - - case 'E': - encrypt = 1; - break; - - case 'D': - socktype = SOCK_DGRAM; - break; - - default: - usage(); - exit(1); - } - } - - if (need_addr && !(argc - optind)) { - usage(); - exit(1); - } - - if (!(buf = malloc(data_size))) { - perror("Can't allocate data buffer"); - exit(1); - } - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - sa.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &sa, NULL); - - openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); - - switch( mode ){ - case RECV: - do_listen(recv_mode); - break; - - case CRECV: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - recv_mode(s); - break; - - case DUMP: - do_listen(dump_mode); - break; - - case SEND: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - send_mode(s); - break; - - case LSEND: - do_listen(send_mode); - break; - - case RECONNECT: - reconnect_mode(argv[optind]); - break; - - case MULTY: - multi_connect_mode(argv[optind]); - break; - - case CONNECT: - connect_mode(argv[optind]); - break; - } - syslog(LOG_INFO, "Exit"); - - closelog(); - - return 0; -} diff --git a/tools/rctest.c b/tools/rctest.c deleted file mode 100644 index 0584a6a9..00000000 --- a/tools/rctest.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - RFCOMM test tool - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -/* Test modes */ -enum { - SEND, - RECV, - RECONNECT, - MULTY, - DUMP, - CONNECT, - CRECV, - LSEND -}; - -unsigned char *buf; - -/* Default mtu */ -int imtu = 672; -int omtu = 0; - -/* Default data size */ -long data_size = 127; - -/* Default addr and channel */ -bdaddr_t bdaddr; -uint8_t channel = 10; - -int master = 0; -int auth = 0; -int encrypt = 0; -int socktype = SOCK_STREAM; - -float tv2fl(struct timeval tv) -{ - return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); -} - -int do_connect(char *svr) -{ - struct sockaddr_rc rem_addr, loc_addr; - int s; - - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - return -1; - } - - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.rc_family = AF_BLUETOOTH; - loc_addr.rc_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.rc_family = AF_BLUETOOTH; - baswap(&rem_addr.rc_bdaddr, strtoba(svr)); - rem_addr.rc_channel = channel; - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); - close(s); - return -1; - } - - syslog(LOG_INFO, "Connected"); - - return s; -} - -void do_listen( void (*handler)(int sk) ) -{ - struct sockaddr_rc loc_addr, rem_addr; - int s, s1, opt; - bdaddr_t ba; - - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - loc_addr.rc_family = AF_BLUETOOTH; - loc_addr.rc_bdaddr = bdaddr; - loc_addr.rc_channel = channel; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - -#if 0 - /* Set link mode */ - opt = 0; - if (master) - opt |= L2CAP_LM_MASTER; - - if (auth) - opt |= L2CAP_LM_AUTH; - - if (encrypt) - opt |= L2CAP_LM_ENCRYPT; - - if (setsockopt(s, SOL_RFCOMM, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); - exit(1); - } -#endif - - if( listen(s, 10) ) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - syslog(LOG_INFO,"Waiting for connection on channel %d ...", channel); - - while(1) { - opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); - exit(1); - } - if( fork() ) { - /* Parent */ - close(s1); - continue; - } - /* Child */ - - close(s); - - baswap(&ba, &rem_addr.rc_bdaddr); - syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); - - handler(s1); - - syslog(LOG_INFO, "Disconnect\n"); - exit(0); - } -} - -void dump_mode(int s) -{ - int len; - - syslog(LOG_INFO, "Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) - syslog(LOG_INFO, "Recevied %d bytes\n", len); -} - -void recv_mode(int s) -{ - struct timeval tv_beg,tv_end,tv_diff; - long total; - uint32_t seq; - - syslog(LOG_INFO,"Receiving ..."); - - seq = 0; - while (1) { - gettimeofday(&tv_beg,NULL); - total = 0; - while (total < data_size) { - //uint32_t sq; - //uint16_t l; - int r; - - if ((r = recv(s, buf, data_size, 0)) <= 0) { - if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); - return; - } -#if 0 - /* Check sequence */ - sq = btohl(*(uint32_t *)buf); - if (seq != sq) { - syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); - seq = sq; - } - seq++; - - /* Check length */ - l = btohs(*(uint16_t *)(buf+4)); - if (r != l) { - syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); - continue; - } - - /* Verify data */ - for (i=6; i < r; i++) { - if (buf[i] != 0x7f) - syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); - } -#endif - total += r; - } - gettimeofday(&tv_end,NULL); - - timersub(&tv_end,&tv_beg,&tv_diff); - - syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, - tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); - } -} - -void send_mode(int s) -{ - uint32_t seq; - int i; - - syslog(LOG_INFO,"Sending ..."); - - for(i=6; i < data_size; i++) - buf[i]=0x7f; - - seq = 0; - while (1) { - *(uint32_t *) buf = htobl(seq++); - *(uint16_t *)(buf+4) = htobs(data_size); - - if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); - exit(1); - } - } -} - -void reconnect_mode(char *svr) -{ - while(1) { - int s = do_connect(svr); - close(s); - } -} - -void multi_connect_mode(char *svr) -{ - while (1) { - int i, s; - for (i=0; i<10; i++) { - if (fork()) continue; - - /* Child */ - s = do_connect(svr); - usleep(500); - close(s); - exit(0); - } - sleep(2); - } -} - -void usage(void) -{ - printf("rctest - RFCOMM testing\n" - "Usage:\n"); - printf("\trctest [options] [bdaddr]\n"); - printf("Modes:\n" - "\t-r listen and receive\n" - "\t-w listen and send\n" - "\t-d listen and dump incomming data\n" - "\t-s connect and send\n" - "\t-u connect and receive\n" - "\t-n connect and be silent\n" - "\t-c connect, disconnect, connect, ...\n" - "\t-m multiple connects\n"); - - printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P channel]\n" - "\t[-I imtu] [-O omtu]\n" - "\t[-E] request encryption\n" - "\t[-E] request encryption\n" - "\t[-M] become master\n"); -} - -extern int optind,opterr,optopt; -extern char *optarg; - -int main(int argc ,char *argv[]) -{ - int opt, mode, s, need_addr; - struct sigaction sa; - - mode = RECV; need_addr = 0; - - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { - switch(opt) { - case 'r': - mode = RECV; - break; - - case 's': - mode = SEND; - need_addr = 1; - break; - - case 'w': - mode = LSEND; - break; - - case 'u': - mode = CRECV; - need_addr = 1; - break; - - case 'd': - mode = DUMP; - break; - - case 'c': - mode = RECONNECT; - need_addr = 1; - break; - - case 'n': - mode = CONNECT; - need_addr = 1; - break; - - case 'm': - mode = MULTY; - need_addr = 1; - break; - - case 'b': - data_size = atoi(optarg); - break; - - case 'S': - baswap(&bdaddr, strtoba(optarg)); - break; - - case 'P': - channel = atoi(optarg); - break; - - case 'I': - imtu = atoi(optarg); - break; - - case 'O': - omtu = atoi(optarg); - break; - - case 'M': - master = 1; - break; - - case 'A': - auth = 1; - break; - - case 'E': - encrypt = 1; - break; - - default: - usage(); - exit(1); - } - } - - if (need_addr && !(argc - optind)) { - usage(); - exit(1); - } - - if (!(buf = malloc(data_size))) { - perror("Can't allocate data buffer"); - exit(1); - } - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - sa.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &sa, NULL); - - openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0); - - switch( mode ){ - case RECV: - do_listen(recv_mode); - break; - - case CRECV: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - recv_mode(s); - break; - - case DUMP: - do_listen(dump_mode); - break; - - case SEND: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - send_mode(s); - break; - - case LSEND: - do_listen(send_mode); - break; - - case RECONNECT: - reconnect_mode(argv[optind]); - break; - - case MULTY: - multi_connect_mode(argv[optind]); - break; - - case CONNECT: - s = do_connect(argv[optind]); - if (s < 0) - exit(1); - dump_mode(s); - break; - } - syslog(LOG_INFO, "Exit"); - - closelog(); - - return 0; -} diff --git a/tools/scotest.c b/tools/scotest.c deleted file mode 100644 index dcb1acdf..00000000 --- a/tools/scotest.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -/* Test modes */ -enum { - SEND, - RECV, - RECONNECT, - MULTY, - DUMP -}; - -unsigned char *buf; - -/* Default data size */ -long data_size = 672; - -bdaddr_t bdaddr; - -float tv2fl(struct timeval tv) -{ - return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); -} - -int do_connect(char *svr) -{ - struct sockaddr_sco rem_addr, loc_addr; - int s; - - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - return -1; - } - - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.sco_family = AF_BLUETOOTH; - loc_addr.sco_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.sco_family = AF_BLUETOOTH; - baswap(&rem_addr.sco_bdaddr, strtoba(svr)); - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); - return -1; - } - - syslog(LOG_INFO, "Connected\n"); - - return s; -} - -void do_listen( void (*handler)(int sk) ) -{ - struct sockaddr_sco loc_addr, rem_addr; - int s, s1, opt; - bdaddr_t ba; - - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - loc_addr.sco_family = AF_BLUETOOTH; - loc_addr.sco_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - if( listen(s, 10) ) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); - exit(1); - } - - syslog(LOG_INFO,"Waiting for connection ..."); - - while(1) { - opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); - exit(1); - } - if( fork() ) { - /* Parent */ - close(s1); - continue; - } - /* Child */ - - close(s); - - baswap(&ba, &rem_addr.sco_bdaddr); - syslog(LOG_INFO, "Connect from %s\n", batostr(&ba)); - - handler(s1); - - syslog(LOG_INFO, "Disconnect\n"); - exit(0); - } -} - -void dump_mode(int s) -{ - int len; - - syslog(LOG_INFO,"Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) - syslog(LOG_INFO, "Recevied %d bytes\n", len); -} - -void recv_mode(int s) -{ - struct timeval tv_beg,tv_end,tv_diff; - long total; - uint32_t seq; - - syslog(LOG_INFO, "Receiving ..."); - - seq = 0; - while (1) { - gettimeofday(&tv_beg,NULL); - total = 0; - while (total < data_size) { - int r; - if ((r = recv(s, buf, data_size, 0)) <= 0) { - if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); - return; - } - total += r; - } - gettimeofday(&tv_end,NULL); - - timersub(&tv_end,&tv_beg,&tv_diff); - - syslog(LOG_INFO,"%ld bytes in %.2fm speed %.2f kb",total, - tv2fl(tv_diff) / 60.0, - (float)( total / tv2fl(tv_diff) ) / 1024.0 ); - } -} - -void send_mode(char *svr) -{ - struct sco_options so; - uint32_t seq; - int s, i, opt; - - if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", - strerror(errno), errno); - exit(1); - } - - opt = sizeof(so); - if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { - syslog(LOG_ERR, "Can't get SCO options. %s(%d)", - strerror(errno), errno); - exit(1); - } - - - syslog(LOG_INFO,"Sending ..."); - - for (i=6; i < so.mtu; i++) - buf[i]=0x7f; - - seq = 0; - while (1) { - *(uint32_t *)buf = htobl(seq++); - *(uint16_t *)(buf+4) = htobs(data_size); - - if (send(s, buf, so.mtu, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", - strerror(errno), errno); - exit(1); - } - usleep(1); - } -} - -void reconnect_mode(char *svr) -{ - while(1){ - int s; - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); - exit(1); - } - close(s); - - sleep(5); - } -} - -void multy_connect_mode(char *svr) -{ - while(1){ - int i, s; - for(i=0; i<10; i++){ - if( fork() ) continue; - - /* Child */ - if( (s = do_connect(svr)) < 0 ){ - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); - } - close(s); - exit(0); - } - sleep(19); - } -} - -void usage(void) -{ - printf("scotest - SCO testing\n" - "Usage:\n"); - printf("\tscotest [-b bytes] [bd_addr]\n"); - printf("Modes:\n" - "\t-d dump (server)\n" - "\t-c reconnect (client)\n" - "\t-m multiple connects (client)\n" - "\t-r receive (server)\n" - "\t-s send (client)\n"); -} - -extern int optind,opterr,optopt; -extern char *optarg; - -int main(int argc ,char *argv[]) -{ - struct sigaction sa; - int opt, mode = RECV; - - while ((opt=getopt(argc,argv,"rdscmb:")) != EOF) { - switch(opt) { - case 'r': - mode = RECV; - break; - - case 's': - mode = SEND; - break; - - case 'd': - mode = DUMP; - break; - - case 'c': - mode = RECONNECT; - break; - - case 'm': - mode = MULTY; - break; - - case 'b': - data_size = atoi(optarg); - break; - - default: - usage(); - exit(1); - } - } - - if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { - usage(); - exit(1); - } - - if (!(buf = malloc(data_size))) { - perror("Can't allocate data buffer"); - exit(1); - } - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_IGN; - sa.sa_flags = SA_NOCLDSTOP; - sigaction(SIGCHLD, &sa, NULL); - - openlog("scotest", LOG_PERROR | LOG_PID, LOG_LOCAL0); - - switch( mode ){ - case RECV: - do_listen(recv_mode); - break; - - case DUMP: - do_listen(dump_mode); - break; - - case SEND: - send_mode(argv[optind]); - break; - - case RECONNECT: - reconnect_mode(argv[optind]); - break; - - case MULTY: - multy_connect_mode(argv[optind]); - break; - } - syslog(LOG_INFO, "Exit"); - - closelog(); - - return 0; -} -- cgit From d774efc2f8cc21d599cacc933ea26e0d63e91365 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 15 Oct 2002 17:44:49 +0000 Subject: Use select in dump mode. --- test/l2test.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/l2test.c b/test/l2test.c index b08b2d34..53e9e768 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -236,8 +237,24 @@ void dump_mode(int s) int len; syslog(LOG_INFO, "Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) + while (1) { + fd_set rset; + + FD_ZERO(&rset); + FD_SET(s, &rset); + + if (select(s + 1, &rset, NULL, NULL, NULL) < 0) + return; + + if (!FD_ISSET(s, &rset)) + continue; + + len = read(s, buf, data_size); + if (len <= 0) + return; + syslog(LOG_INFO, "Recevied %d bytes\n", len); + } } void recv_mode(int s) -- cgit From ca71f93f6b66c424e8e76237b98bc293b2f5674c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 17 Oct 2002 22:15:48 +0000 Subject: Correct the man path for rfcomm.1 --- rfcomm/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index 8ba03314..72635ff2 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -mandir = $(prefix)/share/man +mandir = $(prefix)/usr/share/man confdir = /etc/bluetooth bin_PROGRAMS = rfcomm -- cgit From 79438cb92e480c022d46e251982776c76037c108 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 18 Oct 2002 05:23:18 +0000 Subject: Add the bluetooth class to all drivers --- pcmcia/bluetooth.conf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index e451a6a2..8670cb57 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -1,11 +1,12 @@ device "dtl1_cs" - module "dtl1_cs" + class "bluetooth" module "dtl1_cs" device "bluecard_cs" - module "bluecard_cs" + class "bluetooth" module "bluecard_cs" device "bt3c_cs" - module "bt3c_cs" + class "bluetooth" module "bt3c_cs" + card "Xircom CreditCard Bluetooth Adapter" version "Xircom", "*", "CBT" -- cgit From c81148946afc66e3855466dc099cfaaa521d34a2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 18 Oct 2002 21:06:16 +0000 Subject: Added UART PCMCIA driver --- pcmcia/bluetooth.conf | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 8670cb57..48595415 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -1,11 +1,14 @@ device "dtl1_cs" class "bluetooth" module "dtl1_cs" +device "bt3c_cs" + class "bluetooth" module "bt3c_cs" + device "bluecard_cs" class "bluetooth" module "bluecard_cs" -device "bt3c_cs" - class "bluetooth" module "bt3c_cs" +device "btuart_cs" + class "bluetooth" module "btuart_cs" card "Xircom CreditCard Bluetooth Adapter" @@ -50,6 +53,11 @@ card "Socket Bluetooth Card" bind "dtl1_cs" +card "3Com Bluetooth PC Card" + version "3COM", "*", "Bluetooth PC Card" + bind "bt3c_cs" + + card "LSE041 Bluetooth PC Card" version "BlueCard", "LSE041" bind "bluecard_cs" @@ -59,6 +67,6 @@ card "LSE039 Bluetooth Compact Flash Card" bind "bluecard_cs" -card "3Com Bluetooth PC Card" - version "3COM", "*", "Bluetooth PC Card" - bind "bt3c_cs" +card "CyberBlue CompactFlash Card" + manfid 0x0279, 0x950b + bind "btuart_cs" -- cgit From 9295987f15f7b96ac07a19da7d1e0a6f6f51ee6c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 18 Oct 2002 21:59:04 +0000 Subject: Let "rfcomm connect ..." also work with DevFS --- rfcomm/main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rfcomm/main.c b/rfcomm/main.c index 2f793faa..f0275f74 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -249,8 +249,11 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { - perror("Can't open RFCOMM device"); - goto release; + snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); + if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + perror("Can't open RFCOMM device"); + goto release; + } } memset(&sa, 0, sizeof(sa)); -- cgit From d23ea21e9494a690bcf1f85b00697542516c0993 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 19 Oct 2002 11:18:36 +0000 Subject: Cleanup --- pcmcia/bluetooth.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 48595415..bf15d385 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -67,6 +67,6 @@ card "LSE039 Bluetooth Compact Flash Card" bind "bluecard_cs" -card "CyberBlue CompactFlash Card" +card "Cyber-blue Compact Flash Card" manfid 0x0279, 0x950b bind "btuart_cs" -- cgit From 203d9766269684c2b302a3f3601e299b6e700226 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 25 Oct 2002 11:22:43 +0000 Subject: Better use the version string --- pcmcia/bluetooth.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index bf15d385..c3e4b85c 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -68,5 +68,5 @@ card "LSE039 Bluetooth Compact Flash Card" card "Cyber-blue Compact Flash Card" - manfid 0x0279, 0x950b + version "BT", "", "", "" bind "btuart_cs" -- cgit From b172c800ea6c3375be9ded04480038a4ee3044b9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Oct 2002 16:08:42 +0000 Subject: New RFCOMM connect command which can be called by normal users --- rfcomm/main.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 12 deletions(-) diff --git a/rfcomm/main.c b/rfcomm/main.c index f0275f74..a98c584e 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -94,7 +94,7 @@ static char *rfcomm_flagstostr(uint32_t flags) static void print_dev_info(struct rfcomm_dev_info *di) { - char src[18], dst[18], addr[100]; + char src[18], dst[18], addr[40]; ba2str(&di->src, src); ba2str(&di->dst, dst); @@ -133,7 +133,7 @@ static void print_dev_list(int ctl, int flags) print_dev_info(di + i); } -static int create_dev(int ctl, int dev, int flags, bdaddr_t *bdaddr, int argc, char **argv) +static int create_dev(int ctl, int dev, uint32_t flags, bdaddr_t *bdaddr, int argc, char **argv) { struct rfcomm_dev_req req; int err; @@ -197,7 +197,7 @@ static int create_all(int ctl) return 0; } -static int release_dev(int ctl, int dev, int flags) +static int release_dev(int ctl, int dev, uint32_t flags) { struct rfcomm_dev_req req; int err; @@ -239,23 +239,93 @@ static int release_all(int ctl) static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) { + struct sockaddr_rc laddr, raddr; + struct rfcomm_dev_req req; struct sigaction sa; struct pollfd p; - char devname[MAXPATHLEN]; - int fd; + char dst[18], devname[MAXPATHLEN]; + int sk, fd, alen; + + laddr.rc_family = AF_BLUETOOTH; + bacpy(&laddr.rc_bdaddr, bdaddr); + laddr.rc_channel = 0; + + if (argc < 2) { + if (rfcomm_read_config(rfcomm_config_file) < 0) { + perror("Can't open RFCOMM config file"); + return; + } + + raddr.rc_family = AF_BLUETOOTH; + bacpy(&raddr.rc_bdaddr, &rfcomm_opts[dev].bdaddr); + raddr.rc_channel = rfcomm_opts[dev].channel; - if (create_dev(ctl, dev, 0, bdaddr, argc, argv) < 0) + if (bacmp(&req.dst, BDADDR_ANY) == 0) { + fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev); + return; + } + + } else { + raddr.rc_family = AF_BLUETOOTH; + str2ba(argv[1], &raddr.rc_bdaddr); + + if (argc > 2) + raddr.rc_channel = atoi(argv[2]); + else + raddr.rc_channel = 1; + } + + if ((sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { + perror("Can't create RFCOMM socket"); return; + } + + if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { + perror("Can't bind RFCOMM socket"); + close(sk); + return; + } + + if (connect(sk, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) { + perror("Can't connect RFCOMM socket"); + close(sk); + return; + } + + alen = sizeof(laddr); + if (getsockname(sk, (struct sockaddr *)&laddr, &alen) < 0) { + perror("Can't get RFCOMM socket name"); + close(sk); + return; + } + + memset(&req, 0, sizeof(req)); + req.dev_id = dev; + req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); + + bacpy(&req.src, &laddr.rc_bdaddr); + bacpy(&req.dst, &raddr.rc_bdaddr); + req.channel = raddr.rc_channel; + + if ((dev = ioctl(sk, RFCOMMCREATEDEV, &req)) < 0) { + perror("Can't create RFCOMM TTY"); + close(sk); + return; + } snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { perror("Can't open RFCOMM device"); - goto release; + return; } } + ba2str(&req.dst, dst); + printf("Connected %s to %s on channel %d\n", devname, dst, req.channel); + printf("Press CTRL-C for hangup\n"); + memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = SIG_IGN; @@ -270,17 +340,17 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg sigaction(SIGHUP, &sa, NULL); p.fd = fd; - p.events = POLLHUP; + p.events = POLLERR | POLLHUP; while (!__io_canceled) { p.revents = 0; - poll(&p, 1, 100); + if (poll(&p, 1, 100)) + break; } - close(fd); + printf("Disconnected\n"); -release: - release_dev(ctl, dev, 0); + close(fd); } static void cmd_create(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) -- cgit From c9f0375c2a2c9f2488354b83972af955c44daef8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 31 Oct 2002 10:09:48 +0000 Subject: Syntax fix --- rfcomm/parser.y | 1 + 1 file changed, 1 insertion(+) diff --git a/rfcomm/parser.y b/rfcomm/parser.y index f45f367c..5a42b2f1 100644 --- a/rfcomm/parser.y +++ b/rfcomm/parser.y @@ -78,6 +78,7 @@ section : WORD { opts = NULL; } + ; rfcomm : RFCOMM { -- cgit From 0137a3922771558d22189839ce78449397651ca8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 1 Nov 2002 19:29:26 +0000 Subject: Display "clean" instead of "open" --- rfcomm/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcomm/main.c b/rfcomm/main.c index a98c584e..0dae70e6 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -50,7 +50,7 @@ extern char *optarg; static char *rfcomm_state[] = { "unknown", "connected", - "open", + "clean", "bound", "listening", "connecting", -- cgit From 878f8c349c5df588e512fbc0e76dfa7baf4b26db Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Nov 2002 18:58:24 +0000 Subject: Add check for (!opt) in cmd_aclmtu() and cmd_scomtu() --- tools/hciconfig.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index bbc61d0e..65512a09 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -259,7 +259,10 @@ void cmd_aclmtu(int ctl, int hdev, char *opt) { struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; - + + if (!opt) + return; + if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; @@ -277,7 +280,10 @@ void cmd_scomtu(int ctl, int hdev, char *opt) { struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; - + + if (!opt) + return; + if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; -- cgit From 951e7b0747a9bd29be7cf1fb886dd7a207cce1dd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Nov 2002 01:44:53 +0000 Subject: Add new manpages and update the old ones --- tools/Makefile.am | 2 +- tools/hciattach.8 | 3 + tools/hciconfig.8 | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/hcitool.1 | 145 +++++++++++++++++++++++++++++++++++++ tools/l2ping.1 | 49 +++++++++++++ tools/l2ping.8 | 49 ------------- 6 files changed, 410 insertions(+), 50 deletions(-) create mode 100644 tools/hciconfig.8 create mode 100644 tools/hcitool.1 create mode 100644 tools/l2ping.1 delete mode 100644 tools/l2ping.8 diff --git a/tools/Makefile.am b/tools/Makefile.am index 9ff29c14..0513c83b 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -7,7 +7,7 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping -man_MANS = hciattach.8 l2ping.8 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 noinst_PROGRAMS = ppporc diff --git a/tools/hciattach.8 b/tools/hciattach.8 index b327336b..812c40dc 100644 --- a/tools/hciattach.8 +++ b/tools/hciattach.8 @@ -59,6 +59,9 @@ BrainBoxes PCMCIA card (BL620) .TP swave Silicon Wave kits +.TP +bcsp +Serial adapters using CSR chips with BCSP serial protocol .RE Supported IDs are (manufacturer id, product id) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 new file mode 100644 index 00000000..bf13c2bd --- /dev/null +++ b/tools/hciconfig.8 @@ -0,0 +1,212 @@ +.TH HCICONFIG 1 "Nov 11 2002" BlueZ "Linux System Administration" +.SH NAME +hciconfig \- configure Bluetooth devices +.SH SYNOPSIS +.B hciconfig -h +.br +.B hciconfig [-a] +.br +.B hciconfig [-a] [command [command parameters]] + +.SH DESCRIPTION +.LP +.B +hciconfig +is used to configure Bluetooth devices. is the name of a Bluetooth +device installed in the system. If is not given, +.B +hciconfig +prints name and basic information about all the Bluetooth devices installed in +the system. If is given but no command is given, +it prints basic information on device only. Basic information is +interface type, BD address, ACL MTU, SCO MTU, flags (up, init, running, raw, +page scan enabled, inquiry scan enabled, inquiry, authentication enabled, +encryption enabled). +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands +.TP +.BI -a +Other than the basic info, print features, packet type, link policy, link mode, +name, class, version. +.SH COMMANDS +.TP +.BI up +Open and initialize HCI device +.TP +.BI down +Close HCI device +.TP +.BI reset +Reset HCI device +.TP +.BI rstat +Reset statistic counters +.TP +.BI auth +Enable authentication +.TP +.BI noauth +Disable authentication +.TP +.BI encrypt +Enable encryption +.TP +.BI noencrypt +Disable encryption +.TP +.BI piscan +Enable page and inquiry scan +.TP +.BI noscan +Disable page and inquiry scan +.TP +.BI iscan +Enable inquiry scan, disable page scan +.TP +.BI pscan +Enable page scan, disable inquiry scan +.TP +.BI ptype " [type]" +With no +.I +type +, displays the current packet types. Otherwise, all the packet types specified +by +.I +type +are set. +.I +type +is a comma-separated list of packet types, where the possible packet types are +.BR DM1 , +.BR DM3 , +.BR DM5 , +.BR DH1 , +.BR DH3 , +.BR DH5 , +.BR HV1 , +.BR HV2 , +.BR HV3 . +.TP +.BI name " [name]" +With no +.IR name , +prints local name. Otherwise, sets local name to +.IR name . +.TP +.BI class " [class]" +With no +.IR class , +prints class of device. Otherwise, sets class of device to +.IR class . +.I +class +is a 24-bit hex number describing the class of device, as specified in section +1.2 of the Bluetooth Assigned Numers document. +.TP +.BI inqparms " [win:int]" +With no +.IR win:int , +prints inquiry scan window and interval. Otherwise, sets inquiry scan window +to +.I win +slots and inquiry scan interval to +.I int +slots. +.TP +.BI pageparms " [win:int]" +With no +.IR win:int , +prints page scan window and interval. Otherwise, sets page scan window to +.I +win +slots and page scan interval to +.I +int +slots. +.TP +.BI pageto " [to]" +With no +.IR to , +prints page timeout. Otherwise, sets page timeout +to +.I +to +slots. +.TP +.BI aclmtu " " +Sets ACL MTU to +to +.I +mtu +bytes and ACL buffer size to +.I +pkt +packets. +.TP +.BI scomtu " " +Sets SCO MTU to +to +.I mtu +bytes and SCO buffer size to +.I pkt +packets. +.TP +.BI features +Display device features +.TP +.BI version +Display version information +.TP +.BI revision +Display revision information +.TP +.BI lm " [mode]" +With no +.I +mode +, prints link mode. +.B +MASTER +or +.B +SLAVE +mean, respectively, to ask to become master or to remain slave when a +connection request comes in. The additional keyword +.B +ACCEPT +means that baseband connections will be accepted even if there are no +listening +.I AF_BLUETOOTH +sockets. +.I mode +is +.B +NONE +or a comma-separated list of keywords, where possible keywords are +.B +MASTER +and +.B "ACCEPT" . +.B +NONE +sets link policy to the default behaviour of remaining slave and not accepting +baseband connections when there are no listening +.I AF_BLUETOOTH +sockets. If +.B +MASTER +is present, the device will ask to become master if a connection request comes +in. If +.B +ACCEPT +is present, the device will accept baseband connections even when there are no +listening +.I AF_BLUETOOTH +sockets +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Fabrizio Gennari diff --git a/tools/hcitool.1 b/tools/hcitool.1 new file mode 100644 index 00000000..49b5e715 --- /dev/null +++ b/tools/hcitool.1 @@ -0,0 +1,145 @@ +.TH HCITOOL 1 "Nov 12 2002" BlueZ "Linux System Administration" +.SH NAME +hcitool \- configure Bluetooth connections +.SH SYNOPSIS +.B hcitool [-h] +.br +.B hcitool [-i ] [command [command parameters]] + +.SH DESCRIPTION +.LP +.B +hcitool +is used to configure Bluetooth connections and send some special command to +Bluetooth devices. If no +.B +command +is given, or if the option +.B +-h +is used, +.B +hcitool +prints some usage information and exits. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands +.TP +.BI -i " " +The command is applied to device +.I +hciX +, which must be the name of an installed Bluetooth device. If not specified, +the command will be sent to the first available Bluetooth device. +.SH COMMANDS +.TP +.BI dev +Display local devices +.TP +.BI inq +Inquire remote devices. For each discovered device, Bluetooth device address, +clock offset and class are printed. +.TP +.BI scan +Inquire remote devices. For each discovered device, device name is printed. +.TP +.BI name " " +Print device name of remote device with Bluetooth address +.IR bdaddr . +.TP +.BI info " " +Print device name, version and supported features of remote device with +Bluetooth address +.IR bdaddr . +.TP +.BI cmd " [parameters]" +Submit an arbitrary HCI command to local device. +.IR ogf , +.IR ocf +and +.IR parameters +are hexadecimal bytes +.TP +.BI con +Display active baseband connections +.TP +.BI cc " [--role=m|s] [--pkt-type=] " +Create baseband connection to remote device with Bluetooth address +.IR bdaddr . +Option +.I +--pkt-type +specifies a list of allowed packet types. +.I + +is a comma-separated list of packet types, where the possible packet types are +.BR DM1 , +.BR DM3 , +.BR DM5 , +.BR DH1 , +.BR DH3 , +.BR DH5 , +.BR HV1 , +.BR HV2 , +.BR HV3 . +Default is to allow all packet types. Option +.I +--role +can have value +.I +m +(do not allow role switch, stay master) or +.I +s +(allow role switch, become slave if the peer asks to become master). Default is +.IR m . +.TP +.BI dc " " +Delete baseband connection from remote device with Bluetooth address +.IR bdaddr . +.TP +.BI cpt " " +Change packet types for baseband connection to device with Bluetooth address +.IR bdaddr . +.I +packet types +is a comma-separated list of packet types, where the possible packet types are +.BR DM1 , +.BR DM3 , +.BR DM5 , +.BR DH1 , +.BR DH3 , +.BR DH5 , +.BR HV1 , +.BR HV2 , +.BR HV3 . +.TP +.BI rssi " " +Display received signal strength information for the connection to the device +with Bluetooth address +.IR bdaddr . +.TP +.BI lq " " +Display link quality for the connection to the device with Bluetooth address +.IR bdaddr . +.TP +.BI lst " [value]" +With no +.IR value , +displays link supervision timeout for the connection to the device with Bluetooth address +.IR bdaddr . +If +.I +value +is given, sets the link supervision timeout for that connection to +.I +value +slots, or to infinite if +.I +value +is 0. +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Fabrizio Gennari diff --git a/tools/l2ping.1 b/tools/l2ping.1 new file mode 100644 index 00000000..186e5056 --- /dev/null +++ b/tools/l2ping.1 @@ -0,0 +1,49 @@ +.TH L2PING 1 "Jan 22 2002" BlueZ "Linux System Administration" +.SH NAME +l2ping \- Send L2CAP echo request and receive answer +.SH SYNOPSIS +.B l2ping +[ +.I -S source addr +] [ +.I -s size +] [ +.I -c count +] [ +.I -f +] < +.I bd_addr +> +.SH DESCRIPTION +.LP +L2ping sends a L2CAP echo request to the Bluetooth MAC address +.B bd_addr +given in dotted hex notation. +.SH OPTIONS +.TP +.I -S source addr +Select address to be used as source address for the request. +.TP +.I -s size +The +.B size +of the data packets to be sent. +.TP +.I -c count +Send +.B count +number of packets then exit. +.TP +.I -f +Kind of flood ping. Use with care! It reduces the delay time between packets +to 0. +.TP +.I bd_addr +The Bluetooth MAC address to be pinged in dotted hex notation like +.B 01:02:03:ab:cd:ef +or +.B 01:EF:cd:aB:02:03 +.SH AUTHORS +Written by Maxim Krasnyansky +.PP +man page by Nils Faerber diff --git a/tools/l2ping.8 b/tools/l2ping.8 deleted file mode 100644 index 41becdba..00000000 --- a/tools/l2ping.8 +++ /dev/null @@ -1,49 +0,0 @@ -.TH L2PING 8 "Jan 22 2002" BlueZ "Linux System Administration" -.SH NAME -l2ping \- Send L2CAP echo request and receive answer -.SH SYNOPSIS -.B l2ping -[ -.I -S source addr -] [ -.I -s size -] [ -.I -c count -] [ -.I -f -] < -.I bd_addr -> -.SH DESCRIPTION -.LP -L2ping sends a L2CAP echo request to the Bluetooth MAC address -.B bd_addr -given in dotted hex notation. -.SH OPTIONS -.TP -.I -S source addr -Select address to be used as source address for the request. -.TP -.I -s size -The -.B size -of the data packets to be sent. -.TP -.I -c count -Send -.B count -number of packets then exit. -.TP -.I -f -Kind of flood ping. Use with care! It reduces the delay time between packets -to 0. -.TP -.I bd_addr -The Bluetooth MAC address to be pinged in dotted hex notation like -.B 01:02:03:ab:cd:ef -or -.B 01:EF:cd:aB:02:03 -.SH AUTHORS -Written by Maxim Krasnyansky -.PP -man page by Nils Faerber -- cgit From 1c57015e3e0a917d3b3df7fa61017aed6abf7d0d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Nov 2002 02:33:57 +0000 Subject: Update of the manpage for rfcomm --- rfcomm/rfcomm.1 | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/rfcomm/rfcomm.1 b/rfcomm/rfcomm.1 index 51a258dc..2164febe 100644 --- a/rfcomm/rfcomm.1 +++ b/rfcomm/rfcomm.1 @@ -20,8 +20,8 @@ rfcomm \- RFCOMM configuration utility .SH SYNOPSIS .BR "rfcomm -[-i -.I hciX | bdaddr +[ +.I options ] < .I command > < @@ -30,7 +30,48 @@ rfcomm \- RFCOMM configuration utility .SH DESCRIPTION .B rfcomm is used to set up, maintain, and inspect the RFCOMM configuration -of the Bluetooth subsystem in the Linux kernel. +of the Bluetooth subsystem in the Linux kernel. If no +.B command +is given, or if the option +.B -a +is used, +.B rfcomm +prints information about the configured RFCOMM devices. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands. +.TP +.BI -a +Prints information about all configured RFCOMM devices. +.TP +.BI -i " | " +The command is applied to device +.I +hciX +, which must be the name or the address of an installed Bluetooth +device. If not specified, the command will be use the first +available Bluetooth device. +.SH COMMANDS +.TP +.BI show " " +Display the information about the specified device. +.TP +.BI conn " [bdaddr] [channel]" +Connect the RFCOMM device to the remote Bluetooth device on the +specified channel. If no channel is specified, it will use the +channel number 1. If also the Bluetooth address is left out, it +tries to read the data from the config file. This command can +be terminated with the key sequence CTRL-C. +.TP +.BI bind " [bdaddr] [channel]" +This binds the RFCOMM device to a remote Bluetooth device. The +command did not establish a connection to the remote device, it +only creates the binding. The connection will be establish right +after an application tries to open the RFCOMM device. +.TP +.BI release " " +This command releases a defined RFCOMM binding. .SH AUTHOR Written by Marcel Holtmann . .br -- cgit From aa46d739fe5cc6aebc912306f84af5c91b2f1f2b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Nov 2002 00:48:06 +0000 Subject: Add entries for the AmbiCom and Pretec Bluetooth cards --- pcmcia/bluetooth.conf | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index c3e4b85c..f717d4c2 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -7,6 +7,9 @@ device "bt3c_cs" device "bluecard_cs" class "bluetooth" module "bluecard_cs" +device "bt950_cs" + class "bluetooth" module "bt950_cs" + device "btuart_cs" class "bluetooth" module "btuart_cs" @@ -27,10 +30,6 @@ card "COM One Platinium Bluetooth PC Card" version "COM1 SA", "MC310 CARD" bind "serial_cs" class "bluetooth" -card "AmbiCom BT2000E Bluetooth PC/CF Card" - version "AmbiCom,Inc", "BT2000E" - bind "serial_cs" class "bluetooth" - card "Sphinx PICO Card" version "SPHINX", "BT-CARD" bind "serial_cs" class "bluetooth" @@ -67,6 +66,15 @@ card "LSE039 Bluetooth Compact Flash Card" bind "bluecard_cs" +card "AmbiCom BT2000E Bluetooth Card" + version "AmbiCom,Inc", "BT2000E" + bind "bt950_cs" + +card "Pretec BT2000E Bluetooth Card" + version "Pretec", "BT2000E" + bind "bt950_cs" + + card "Cyber-blue Compact Flash Card" version "BT", "", "", "" bind "btuart_cs" -- cgit From 82763bafbedb3393a7d433e8dee7c5e7d01cb769 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 23 Nov 2002 18:07:07 +0000 Subject: Add entry for Billionton Bluetooth card --- pcmcia/bluetooth.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index f717d4c2..84f8e985 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -74,6 +74,10 @@ card "Pretec BT2000E Bluetooth Card" version "Pretec", "BT2000E" bind "bt950_cs" +card "Billionton Bluetooth Card" + version "Compact Flash", "Bluetooth Card" + bind "bt950_cs" + card "Cyber-blue Compact Flash Card" version "BT", "", "", "" -- cgit From 30a4cfe6010a27030f8b89115e5362f01888ec93 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Dec 2002 14:18:03 +0000 Subject: Support for voice setting --- tools/hciconfig.8 | 9 +++++++++ tools/hciconfig.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index bf13c2bd..96b503ae 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -106,6 +106,15 @@ class is a 24-bit hex number describing the class of device, as specified in section 1.2 of the Bluetooth Assigned Numers document. .TP +.BI voice " [voice]" +With no +.IR voice , +prints voice setting. Otherwise, sets voice setting to +.IR voice . +.I +voice +is a 16-bit hex number describing the voice setting. +.TP .BI inqparms " [win:int]" With no .IR win:int , diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 65512a09..45d9a23d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -522,6 +522,47 @@ void cmd_class(int ctl, int hdev, char *opt) } } +void cmd_voice(int ctl, int hdev, char *opt) +{ + static char *icf[] = { "Linear", "u-Law", "A-Law", "Reserved" }; + static char *idf[] = { "1's complement", "2's complement", "Sign-Magnitude", "Reserved" }; + static char *iss[] = { "8 bit", "16 bit" }; + static char *acf[] = { "CVSD", "u-Law", "A-Law", "Reserved" }; + int s = hci_open_dev(hdev); + + if (s < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + if (opt) { + uint16_t vs = htobl(strtoul(opt, NULL, 16)); + if (0 > hci_write_voice_setting(s, vs, 1000)) { + printf("Can't write voice setting on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint16_t vs; + uint8_t ic; + if (0 > hci_read_voice_setting(s, &vs, 1000)) { + printf("Can't read voice setting on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + ic = (vs & 0x0300) >> 8; + print_dev_hdr(&di); + printf("\tVoice setting: 0x%04x%s\n", vs, + ((vs & 0x03fc) == 0x0060) ? " (Default Condition)" : ""); + printf("\tInput Coding: %s\n", icf[ic]); + printf("\tInput Data Format: %s\n", idf[(vs & 0xc0) >> 6]); + if (!ic) { + printf("\tInput Sample Size: %s\n", iss[(vs & 0x20) >> 5]); + printf("\t# of bits padding at MSB: %d\n", (vs & 0x1c) >> 2); + } + printf("\tAir Coding Format: %s\n", acf[vs & 0x03]); + } +} + void cmd_version(int ctl, int hdev, char *opt) { struct hci_version ver; @@ -859,6 +900,7 @@ struct { { "lp", cmd_lp, "[policy]", "Get/Set default link policy" }, { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, + { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, -- cgit From 85f1b67672730596df37adc362f490c17ff6d4f3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Dec 2002 05:31:24 +0000 Subject: Support for voice setting --- tools/hcisecfilter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index bee16df1..8cd47420 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -62,6 +62,7 @@ int main(void) hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); + hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); printf("OGF_HOST_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); -- cgit From 3d997d70a4dbbf09ad93738e82cd1137e253adec Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 17 Dec 2002 06:46:30 +0000 Subject: Support for --with-bluez-includes option --- configure.in | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/configure.in b/configure.in index 529f231b..bf66615a 100644 --- a/configure.in +++ b/configure.in @@ -34,14 +34,15 @@ AM_PROG_LEX AM_PROG_LIBTOOL AC_ARG_WITH(bluez-libs, - --with-bluez-libs=DIR BlueZ libraries and header files, - [ - BLUEZ_INCDIR="$withval"/include - BLUEZ_LIBDIR="$withval"/src - ],[ - BLUEZ_INCDIR='../libs/include /usr/include' - BLUEZ_LIBDIR='../libs/src /usr/lib' - ] + --with-bluez-libs=DIR BlueZ libraries, + BLUEZ_LIBDIR="$withval", + BLUEZ_LIBDIR='../libs/src /usr/lib' +) + +AC_ARG_WITH(bluez-includes, + --with-bluez-includes=DIR BlueZ header files, + BLUEZ_INCDIR="$withval", + BLUEZ_INCDIR='../libs/include /usr/include/bluetooth' ) AC_SEARCH_HEADERS(bluetooth/bluetooth.h, $BLUEZ_INCDIR,, @@ -55,7 +56,7 @@ AC_SEARCH_LIB(bluetooth, hci_open_dev, $BLUEZ_LIBDIR,, ) AC_ARG_WITH(glib-config, - --with-glib-config=program glib-config location, + --with-glib-config=prog glib-config location, GLIB_CONFIG="$withval", [ AC_PATH_PROGS(GLIB_CONFIG, glib-config, no) @@ -78,7 +79,7 @@ fi dnl Check for PCMCIA AC_ARG_ENABLE(pcmcia, - --enable-pcmcia Always install PCMCIA support files, + --enable-pcmcia Always install PCMCIA support files, [PCMCIA=pcmcia], [ if test "$cross_compiling" != yes; then AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=) -- cgit From d77d3f848c60d692cc9029ccf9a15b06f0704e90 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 20 Dec 2002 11:06:35 +0000 Subject: Make the info command reusing an existing connection handle --- tools/hcitool.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index ec6f007a..dd289b04 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -386,7 +386,8 @@ static void cmd_info(int dev_id, int argc, char **argv) char name[248]; unsigned char features[8]; struct hci_version version; - int opt, dd; + struct hci_conn_info_req *cr; + int opt, dd, cc = 0; for_each_opt(opt, info_options, NULL) { switch(opt) { @@ -403,14 +404,19 @@ static void cmd_info(int dev_id, int argc, char **argv) return; } - baswap(&bdaddr, strtoba(argv[0])); + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { dev_id = hci_get_route(&bdaddr); - if (dev_id < 0) { - fprintf(stderr, "Device is not available.\n"); - exit(1); - } + cc = 1; + } + + if (dev_id < 0) { + fprintf(stderr, "Device is not available or not connected.\n"); + exit(1); } printf("Requesting information ...\n"); @@ -421,13 +427,29 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } - printf("\tBD Address: %s\n", argv[0]); + if (cc) { + if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { + perror("Can't create connection"); + close(dd); + exit(1); + } + } else { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; - if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { - close(dd); - exit(1); + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + handle = cr->conn_info->handle; } + printf("\tBD Address: %s\n", argv[0]); + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); @@ -444,7 +466,8 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 3)); } - hci_disconnect(dd, handle, 0x13, 10000); + if (cc) + hci_disconnect(dd, handle, 0x13, 10000); close(dd); } -- cgit From 976e691e5dcb92629f6f7d75a37d9ebc8e7d4da3 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 21 Dec 2002 06:47:32 +0000 Subject: Add RPM spec file. Configure fixes. --- Makefile.am | 4 +++ configure.in | 2 +- utils.spec | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 utils.spec diff --git a/Makefile.am b/Makefile.am index d0351af9..308ede8d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,3 +3,7 @@ # SUBDIRS := hcid tools rfcomm test scripts pcmcia + +DISTCLEANFILES = conftest.c conftest + +EXTRA_DIST = ChangeLog utils.spec diff --git a/configure.in b/configure.in index bf66615a..f7154f1a 100644 --- a/configure.in +++ b/configure.in @@ -42,7 +42,7 @@ AC_ARG_WITH(bluez-libs, AC_ARG_WITH(bluez-includes, --with-bluez-includes=DIR BlueZ header files, BLUEZ_INCDIR="$withval", - BLUEZ_INCDIR='../libs/include /usr/include/bluetooth' + BLUEZ_INCDIR='../libs/include /usr/include' ) AC_SEARCH_HEADERS(bluetooth/bluetooth.h, $BLUEZ_INCDIR,, diff --git a/utils.spec b/utils.spec new file mode 100644 index 00000000..e12ba74b --- /dev/null +++ b/utils.spec @@ -0,0 +1,80 @@ +# Note that this is NOT a relocatable package +%define ver 2.1 +%define RELEASE 1 +%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} +%define prefix / + +Summary: Bluetooth utilities +Name: bluez-utils +Version: %ver +Release: %rel +Copyright: GPL +Group: Applications/System +Vendor: Official Linux Bluetooth protocol stack +Packager: Sebastian Frankfurt +Source: http://bluez.sourceforge.net/%{name}-%{ver}.tar.gz +Patch0: %{name}-%{ver}.patch +BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root +URL: http://bluez.sourceforge.net +Docdir: %{prefix}/usr/share/doc +Requires: glibc >= 2.2.4 +Requires: glib >= 1.2 +Requires: bluez-libs >= 2.0 +BuildRequires: glibc >= 2.2.4 +BuildRequires: glib-devel >= 1.2 +BuildRequires: bluez-libs >= 2.0 + +%description +Bluetooth utilities (bluez-utils): + - hcitool + - hciattach + - hciconfig + - hcid + - l2ping + - start scripts (RedHat) + - pcmcia configuration files + +The BLUETOOTH trademarks are owned by Bluetooth SIG, Inc., U.S.A. + +%changelog +* Tue Aug 13 2002 Sebastian Frankfurt +- Initial RPM + +%prep +rm -rf $RPM_BUILD_ROOT + +%setup -q +#%patch0 -p1 + +%build +CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --mandir=%{_mandir} --sysconfdir=%{_sysconfdir} +make + +%install +rm -rf $RPM_BUILD_ROOT +make DESTDIR=$RPM_BUILD_ROOT prefix=%{prefix} mandir=%{_mandir} install + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-, root, root) + +/etc/rc.d/init.d/bluetooth +/bin/hcitool +/bin/l2ping +/bin/bluepin +/bin/rfcomm +/sbin/hciattach +/sbin/hciconfig +/sbin/hcid +%{_mandir}/man8/hciattach.8.gz +%{_mandir}/man8/hciconfig.8.gz +%{_mandir}/man1/hcitool.1.gz +%{_mandir}/man1/l2ping.1.gz +%{_sysconfdir}/bluetooth/* +%{_sysconfdir}/pcmcia/bluetooth.conf +%{_sysconfdir}/pcmcia/bluetooth + +%doc AUTHORS COPYING INSTALL ChangeLog NEWS README + -- cgit From 34e63ae877d59207762da9f96e414a704c825393 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 21 Dec 2002 07:07:05 +0000 Subject: Minor fix --- utils.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/utils.spec b/utils.spec index e12ba74b..1e91faf3 100644 --- a/utils.spec +++ b/utils.spec @@ -44,7 +44,6 @@ The BLUETOOTH trademarks are owned by Bluetooth SIG, Inc., U.S.A. rm -rf $RPM_BUILD_ROOT %setup -q -#%patch0 -p1 %build CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --mandir=%{_mandir} --sysconfdir=%{_sysconfdir} -- cgit From 7490b6c61bfa0b581ff7a15f6482787973cf7e3f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 21 Dec 2002 15:40:33 +0000 Subject: Add Headset Test utility --- test/Makefile.am | 4 +- test/hsmicro | 20 ++++ test/hsplay | 22 ++++ test/hstest.c | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 378 insertions(+), 1 deletion(-) create mode 100755 test/hsmicro create mode 100755 test/hsplay create mode 100644 test/hstest.c diff --git a/test/Makefile.am b/test/Makefile.am index dc84f46f..ec6b7779 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,4 +2,6 @@ # $Id$ # -noinst_PROGRAMS = l2test scotest rctest attest +noinst_PROGRAMS = l2test scotest rctest attest hstest + +EXTRA_DIST = hsplay hsmicro diff --git a/test/hsmicro b/test/hsmicro new file mode 100755 index 00000000..8aec68f2 --- /dev/null +++ b/test/hsmicro @@ -0,0 +1,20 @@ +#!/bin/sh + +SOX=`which sox` +HSTEST=`which hstest` + +if [ -z "$HSTEST" ] +then + HSTEST="./hstest" +fi + +if [ -z "$1" ] +then + echo -e "Usage:\n\thsmicro [channel]" + exit +fi + +BDADDR=$1 +CHANNEL=$2 + +$HSTEST record - $BDADDR $CHANNEL | $SOX -t raw -r 8000 -c 1 -s -b - -t ossdsp -r 44100 -c 2 -s -w /dev/dsp polyphase vol 5.0 2> /dev/null diff --git a/test/hsplay b/test/hsplay new file mode 100755 index 00000000..8a676459 --- /dev/null +++ b/test/hsplay @@ -0,0 +1,22 @@ +#!/bin/sh + +MPG123=`which mpg123` +SOX=`which sox` +HSTEST=`which hstest` + +if [ -z "$HSTEST" ] +then + HSTEST="./hstest" +fi + +if [ -z "$1" -o -z "$2" ] +then + echo -e "Usage:\n\thsplay [channel]" + exit +fi + +FILE=$1 +BDADDR=$2 +CHANNEL=$3 + +$MPG123 -q -s "$FILE" | $SOX -t raw -r 44100 -c 2 -s -w - -t raw -r 8000 -c 1 -s -b - | $HSTEST play - $BDADDR $CHANNEL diff --git a/test/hstest.c b/test/hstest.c new file mode 100644 index 00000000..867eb20b --- /dev/null +++ b/test/hstest.c @@ -0,0 +1,333 @@ +/* + * + * Bluetooth Headset Test utility + * + * Copyright (C) 2002 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#ifndef OCF_READ_VOICE_SETTING +#define OCF_READ_VOICE_SETTING 0x0025 +typedef struct { + uint8_t status; + uint16_t voice_setting; +} __attribute__ ((packed)) read_voice_setting_rp; +#define READ_VOICE_SETTING_RP_SIZE 3 + +static int hci_read_voice_setting(int dd, uint16_t *vs, int to) +{ + read_voice_setting_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_VOICE_SETTING; + rq.rparam = &rp; + rq.rlen = READ_VOICE_SETTING_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *vs = rp.voice_setting; + return 0; +} +#endif + + +static volatile int terminate = 0; + + +static void sig_term(int sig) { + terminate = 1; +} + + +static int rfcomm_connect(bdaddr_t *src, bdaddr_t *dst, uint8_t channel) +{ + struct sockaddr_rc addr; + int s; + + if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, src); + addr.rc_channel = 0; + if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(s); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, dst); + addr.rc_channel = channel; + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){ + close(s); + return -1; + } + + return s; +} + + +static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t *mtu) +{ + struct sockaddr_sco addr; + struct sco_conninfo conn; + struct sco_options opts; + int s, size; + + if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_bdaddr, src); + if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(s); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_bdaddr, dst); + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){ + close(s); + return -1; + } + + size = sizeof(conn); + if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &size) < 0) { + close(s); + return -1; + } + + size = sizeof(opts); + if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &opts, &size) < 0) { + close(s); + return -1; + } + + if (handle) + *handle = conn.hci_handle; + + if (mtu) + *mtu = opts.mtu; + + return s; +} + + +static void usage(void) +{ + printf("Usage:\n" + "\thstest play [channel]\n" + "\thstest record [channel]\n"); +} + + +#define PLAY 1 +#define RECORD 2 + +int main(int argc, char *argv[]) +{ + struct sigaction sa; + + fd_set rfds; + struct timeval timeout; + unsigned char buf[2048]; + int maxfd, sel, rlen, wlen; + + bdaddr_t local; + bdaddr_t bdaddr; + uint8_t channel; + + char *filename; + mode_t filemode; + int mode = 0; + int dd, rd, sd, fd; + uint16_t sco_handle, sco_mtu, vs; + + + switch (argc) { + case 4: + str2ba(argv[3], &bdaddr); + channel = 6; + break; + case 5: + str2ba(argv[3], &bdaddr); + channel = atoi(argv[4]); + break; + default: + usage(); + exit(-1); + } + + if (strncmp(argv[1], "play", 4) == 0) { + mode = PLAY; + filemode = O_RDONLY; + } else if (strncmp(argv[1], "rec", 3) == 0) { + mode = RECORD; + filemode = O_WRONLY | O_CREAT | O_TRUNC; + } else { + usage(); + exit(-1); + } + + filename = argv[2]; + + + hci_devba(0, &local); + dd = hci_open_dev(0); + hci_read_voice_setting(dd, &vs, 1000); + fprintf(stderr, "Voice setting: 0x%04x\n", vs); + close(dd); + if (vs != 0x0040) { + fprintf(stderr, "The voice setting must be 0x0040\n"); + return -1; + } + + + if (strcmp(filename, "-") == 0) { + switch (mode) { + case PLAY: + fd = 0; + break; + case RECORD: + fd = 1; + break; + default: + return -1; + } + } else { + if ((fd = open(filename, filemode)) < 0) { + perror("Can't open input/output file"); + return -1; + } + } + + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + + if ((rd = rfcomm_connect(&local, &bdaddr, channel)) < 0) { + perror("Can't connect RFCOMM channel"); + return -1; + } + + fprintf(stderr, "RFCOMM channel connected\n"); + + + if ((sd = sco_connect(&local, &bdaddr, &sco_handle, &sco_mtu)) < 0) { + perror("Can't connect SCO audio channel"); + close(rd); + return -1; + } + + fprintf(stderr, "SCO audio channel connected (handle %d, mtu %d)\n", sco_handle, sco_mtu); + + + if (mode == RECORD) + write(rd, "RING\r\n", 6); + + maxfd = (rd > sd) ? rd : sd; + + while (!terminate) { + + FD_ZERO(&rfds); + FD_SET(rd, &rfds); + FD_SET(sd, &rfds); + + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + + if ((sel = select(maxfd + 1, &rfds, NULL, NULL, &timeout)) > 0) { + + if (FD_ISSET(rd, &rfds)) { + memset(buf, 0, sizeof(buf)); + rlen = read(rd, buf, sizeof(buf)); + if (rlen > 0) { + fprintf(stderr, "%s\n", buf); + wlen = write(rd, "OK\r\n", 4); + } + } + + if (FD_ISSET(sd, &rfds)) { + memset(buf, 0, sizeof(buf)); + rlen = read(sd, buf, sizeof(buf)); + if (rlen > 0) + switch (mode) { + case PLAY: + rlen = read(fd, buf, rlen); + wlen = write(sd, buf, rlen); + break; + case RECORD: + wlen = write(fd, buf, rlen); + break; + default: + break; + } + } + + } + + } + + close(sd); + sleep(5); + close(rd); + + close(fd); + + return 0; +} -- cgit From 52f6de4179a0509775939f4df90d9ae4bc93723b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 25 Dec 2002 01:18:03 +0000 Subject: New version. --- ChangeLog | 7 +++++++ configure.in | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 55b1dfbb..97ce4d1c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +ver 2.2: + Support for voice settings (hciconfig). + Minor hcitool fixes. + Added Headset testing tool. + Updated man pages. + RPM package. + ver 2.1: Improved BCSP initialization (hciattach). Support for displaying link quality (hcitool). diff --git a/configure.in b/configure.in index f7154f1a..77586a6a 100644 --- a/configure.in +++ b/configure.in @@ -9,7 +9,7 @@ dnl Guess host type. AC_CANONICAL_SYSTEM AC_CANONICAL_HOST -AM_INIT_AUTOMAKE(bluez-utils, 2.1) +AM_INIT_AUTOMAKE(bluez-utils, 2.2) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) -- cgit From bf5b1c256d52e29b08374386820bbe47d2b9157a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 25 Dec 2002 01:19:36 +0000 Subject: update --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 97ce4d1c..0ae56a12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ ver 2.2: Support for voice settings (hciconfig). Minor hcitool fixes. + Improved configure script. Added Headset testing tool. Updated man pages. RPM package. -- cgit From 0e0d2c799eadcd614ae8f5c07c9c98469cce4c55 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 25 Dec 2002 01:21:10 +0000 Subject: Add MAINTAINER_MODE --- configure.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.in b/configure.in index 77586a6a..80a1b092 100644 --- a/configure.in +++ b/configure.in @@ -9,6 +9,8 @@ dnl Guess host type. AC_CANONICAL_SYSTEM AC_CANONICAL_HOST +AM_MAINTAINER_MODE + AM_INIT_AUTOMAKE(bluez-utils, 2.2) AC_SUBST(DISTRO) -- cgit From 287334c3349f0c5a4ffe014416aaa73540936224 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 25 Dec 2002 01:21:35 +0000 Subject: new version --- utils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.spec b/utils.spec index 1e91faf3..95b26c8d 100644 --- a/utils.spec +++ b/utils.spec @@ -1,5 +1,5 @@ # Note that this is NOT a relocatable package -%define ver 2.1 +%define ver 2.2 %define RELEASE 1 %define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} %define prefix / -- cgit From eb6639784b6a47684078f28935f5150f26e561ea Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 25 Dec 2002 01:26:13 +0000 Subject: Always install pcmcia scripts. --- utils.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.spec b/utils.spec index 95b26c8d..e207e004 100644 --- a/utils.spec +++ b/utils.spec @@ -46,7 +46,7 @@ rm -rf $RPM_BUILD_ROOT %setup -q %build -CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --mandir=%{_mandir} --sysconfdir=%{_sysconfdir} +CFLAGS="$RPM_OPT_FLAGS" ./configure --enable-pcmcia --prefix=%{prefix} --mandir=%{_mandir} --sysconfdir=%{_sysconfdir} make %install -- cgit From c9271603f6ae622ee61f4514d97adf8e38f3eef1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 2 Jan 2003 01:50:47 +0000 Subject: Basic support for listen command --- rfcomm/main.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 134 insertions(+), 15 deletions(-) diff --git a/rfcomm/main.c b/rfcomm/main.c index 0dae70e6..c03f6127 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -2,7 +2,7 @@ * * RFCOMM configuration utility * - * Copyright (C) 2002 Marcel Holtmann + * Copyright (C) 2002-2003 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -50,14 +51,14 @@ extern char *optarg; static char *rfcomm_state[] = { "unknown", "connected", - "clean", - "bound", - "listening", - "connecting", - "connecting", - "config", - "disconnecting", - "closed" + "clean", + "bound", + "listening", + "connecting", + "connecting", + "config", + "disconnecting", + "closed" }; static volatile sig_atomic_t __io_canceled = 0; @@ -241,6 +242,7 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg { struct sockaddr_rc laddr, raddr; struct rfcomm_dev_req req; + struct termios ti; struct sigaction sa; struct pollfd p; char dst[18], devname[MAXPATHLEN]; @@ -264,7 +266,7 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev); return; } - + } else { raddr.rc_family = AF_BLUETOOTH; str2ba(argv[1], &raddr.rc_bdaddr); @@ -296,7 +298,7 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg if (getsockname(sk, (struct sockaddr *)&laddr, &alen) < 0) { perror("Can't get RFCOMM socket name"); close(sk); - return; + return; } memset(&req, 0, sizeof(req)); @@ -305,7 +307,7 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg bacpy(&req.src, &laddr.rc_bdaddr); bacpy(&req.dst, &raddr.rc_bdaddr); - req.channel = raddr.rc_channel; + req.channel = raddr.rc_channel; if ((dev = ioctl(sk, RFCOMMCREATEDEV, &req)) < 0) { perror("Can't create RFCOMM TTY"); @@ -318,10 +320,18 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { perror("Can't open RFCOMM device"); + close(sk); return; } } + tcflush(fd, TCIOFLUSH); + + cfmakeraw(&ti); + tcsetattr(fd, TCSANOW, &ti); + + close(sk); + ba2str(&req.dst, dst); printf("Connected %s to %s on channel %d\n", devname, dst, req.channel); printf("Press CTRL-C for hangup\n"); @@ -353,6 +363,112 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg close(fd); } +static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) +{ + struct sockaddr_rc laddr, raddr; + struct rfcomm_dev_req req; + struct termios ti; + char dst[18], devname[MAXPATHLEN]; + int sk, nsk, fd, alen; + int i; + + if (argc < 3) { + fprintf(stderr, "No command specified\n"); + return; + } + + laddr.rc_family = AF_BLUETOOTH; + bacpy(&laddr.rc_bdaddr, bdaddr); + + if (strncmp(argv[1], "exec", 4) == 0) { + laddr.rc_channel = 1; + argc -= 2; + argv += 2; + } else if (strncmp(argv[2], "exec", 4) == 0) { + laddr.rc_channel = atoi(argv[1]); + argc -= 3; + argv += 3; + } else { + fprintf(stderr, "Unknown syntax\n"); + return; + } + + argv[argc] = NULL; + + if ((sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { + perror("Can't create RFCOMM socket"); + return; + } + + if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) { + perror("Can't bind RFCOMM socket"); + close(sk); + return; + } + + printf("Waiting for connection on channel %d\n", laddr.rc_channel); + + listen(sk, 10); + + alen = sizeof(raddr); + nsk = accept(sk, (struct sockaddr *) &raddr, &alen); + + alen = sizeof(laddr); + if (getsockname(nsk, (struct sockaddr *)&laddr, &alen) < 0) { + perror("Can't get RFCOMM socket name"); + close(nsk); + return; + } + + memset(&req, 0, sizeof(req)); + req.dev_id = dev; + req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP); + + bacpy(&req.src, &laddr.rc_bdaddr); + bacpy(&req.dst, &raddr.rc_bdaddr); + req.channel = raddr.rc_channel; + + if ((dev = ioctl(nsk, RFCOMMCREATEDEV, &req)) < 0) { + perror("Can't create RFCOMM TTY"); + close(sk); + return; + } + + snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); + if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); + if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + perror("Can't open RFCOMM device"); + close(sk); + return; + } + } + + tcflush(fd, TCIOFLUSH); + + cfmakeraw(&ti); + tcsetattr(fd, TCSANOW, &ti); + + close(sk); + close(nsk); + + ba2str(&req.dst, dst); + printf("Connection from %s to %s\n", dst, devname); + + for (i = 1; i < argc; i++) + if (strcmp(argv[i], "%d") == 0) + argv[i] = devname; + + printf("Executing "); + for (i = 0; i < argc; i++) + printf("%s%s", (i == 0) ? "\"" : " ", argv[i]); + printf("\"\n"); + + execvp(argv[0], argv); + + close(fd); +} + static void cmd_create(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv) { if (strcmp(argv[0], "all") == 0) @@ -393,8 +509,9 @@ struct { } command[] = { { "bind", "create", cmd_create, " [channel]", "Bind device" }, { "release", "unbind", cmd_release, "", "Release device" }, + { "show", "info", cmd_show, "", "Show device" }, { "connect", "conn", cmd_connect, " [channel]", "Connect device" }, - { "show", "info", cmd_show, 0, "Show device" }, + { "listen", "server", cmd_listen, " [channel]", "Listen" }, { NULL, NULL, NULL, 0, 0 } }; @@ -447,7 +564,7 @@ int main(int argc, char *argv[]) else str2ba(optarg, &bdaddr); break; - + case 'f': rfcomm_config_file = strdup(optarg); break; @@ -483,7 +600,9 @@ int main(int argc, char *argv[]) exit(0); } - if (strncmp(argv[1], "rfcomm", 6) == 0) + if (strncmp(argv[1], "/dev/rfcomm", 11) == 0) + dev_id = atoi(argv[1] + 11); + else if (strncmp(argv[1], "rfcomm", 6) == 0) dev_id = atoi(argv[1] + 6); else dev_id = atoi(argv[1]); -- cgit From 3e8471f6fc3e46a168ebb1bdfacdfb182c746f59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Jan 2003 17:52:56 +0000 Subject: Support for switch role command --- tools/hcitool.1 | 6 ++ tools/hcitool.c | 215 +++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 155 insertions(+), 66 deletions(-) diff --git a/tools/hcitool.1 b/tools/hcitool.1 index 49b5e715..fa51efce 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -99,6 +99,12 @@ s Delete baseband connection from remote device with Bluetooth address .IR bdaddr . .TP +.BI sr " " +Switch role for the baseband connection from the remote device to +.BR master +or +.BR slave . +.TP .BI cpt " " Change packet types for baseband connection to device with Bluetooth address .IR bdaddr . diff --git a/tools/hcitool.c b/tools/hcitool.c index dd289b04..00c84b05 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -59,7 +59,7 @@ static int dev_info(int s, int dev_id, long arg) bdaddr_t bdaddr; if (ioctl(s, HCIGETDEVINFO, (void*) &di)) return 0; - + baswap(&bdaddr, &di.bdaddr); printf("\t%s\t%s\n", di.name, batostr(&bdaddr)); return 0; @@ -171,18 +171,18 @@ static void cmd_dev(int dev_id, int argc, char **argv) /* Inquiry */ static struct option inq_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, {0, 0, 0, 0} }; static char *inq_help = "Usage:\n" "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" - "\t [--numrsp=N] specify maximum number of inquiry responses\n" - "\t [--flush] flush the inquiry cache\n"; + "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--flush] flush the inquiry cache\n"; static void cmd_inq(int dev_id, int argc, char **argv) { @@ -200,7 +200,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) case 'l': length = atoi(optarg); break; - + case 'n': num_rsp = atoi(optarg); break; @@ -236,10 +236,10 @@ static void cmd_inq(int dev_id, int argc, char **argv) /* Device scanning */ static struct option scan_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, + {"help", 0,0, 'h'}, + {"length", 1,0, 'l'}, + {"numrsp", 1,0, 'n'}, + {"flush", 0,0, 'f'}, {0, 0, 0, 0} }; @@ -356,7 +356,7 @@ static void cmd_name(int dev_id, int argc, char **argv) } dd = hci_open_dev(dev_id); - if (dd < 0) { + if (dd < 0) { perror("HCI device open failed"); exit(1); } @@ -371,7 +371,7 @@ static void cmd_name(int dev_id, int argc, char **argv) /* Info about remote device */ static struct option info_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -475,7 +475,7 @@ static void cmd_info(int dev_id, int argc, char **argv) /* Send arbitrary HCI commands */ static struct option cmd_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -492,7 +492,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) hci_event_hdr *hdr; int i, opt, len, dd; uint16_t ocf; - uint8_t ogf; + uint8_t ogf; for_each_opt(opt, cmd_options, NULL) { switch(opt) { @@ -566,7 +566,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) /* Display active connections */ static struct option con_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -593,9 +593,9 @@ static void cmd_con(int dev_id, int argc, char **argv) /* Create connection */ static struct option cc_options[] = { - {"help", 0,0, 'h'}, - {"role", 1,0, 'r'}, - {"ptype", 1,0, 'p'}, + {"help", 0,0, 'h'}, + {"role", 1,0, 'r'}, + {"ptype", 1,0, 'p'}, {0, 0, 0, 0} }; @@ -621,7 +621,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) case 'p': hci_strtoptype(optarg, &ptype); break; - + case 'r': role = optarg[0] == 'm' ? 0 : 1; break; @@ -662,7 +662,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) /* Close connection */ static struct option dc_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -707,16 +707,16 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; - bacpy(&cr->bdaddr, &bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { perror("Get connection info failed"); - exit(1); - } + exit(1); + } hci_disconnect(dd, cr->conn_info->handle, 0x13, 100); @@ -724,10 +724,92 @@ static void cmd_dc(int dev_id, int argc, char **argv) free(cr); } +/* Role switch */ + +static struct option sr_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *sr_help = + "Usage:\n" + "\tsr \n"; + +static void cmd_sr(int dev_id, int argc, char **argv) +{ + struct hci_request rq; + switch_role_cp cp; + evt_role_change rp; + int opt, dd; + + for_each_opt(opt, sr_options, NULL) { + switch(opt) { + default: + printf(sr_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 2) { + printf(sr_help); + return; + } + + str2ba(argv[0], &cp.bdaddr); + switch (argv[1][0]) { + case 'm': + cp.role = 0; + break; + case 's': + cp.role = 1; + break; + default: + cp.role = atoi(argv[1]); + break; + } + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &cp.bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_SWITCH_ROLE; + rq.cparam = &cp; + rq.clen = SWITCH_ROLE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_ROLE_CHANGE_SIZE; + rq.event = EVT_ROLE_CHANGE; + + if (hci_send_req(dd, &rq, 300) < 0) { + perror("Switch role request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "Switch role cmd failed (0x%2.2X)\n", rp.status); + exit(1); + } + + close(dd); +} + /* Read RSSI */ static struct option rssi_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -738,7 +820,7 @@ static char *rssi_help = static void cmd_rssi(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; + struct hci_request rq; read_rssi_rp rp; bdaddr_t bdaddr; int opt, dd; @@ -776,7 +858,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -786,13 +868,13 @@ static void cmd_rssi(int dev_id, int argc, char **argv) } memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_RSSI; rq.cparam = &cr->conn_info->handle; - rq.clen = 2; + rq.clen = 2; rq.rparam = &rp; - rq.rlen = READ_RSSI_RP_SIZE; - + rq.rlen = READ_RSSI_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { perror("Read RSSI failed"); exit(1); @@ -803,7 +885,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } printf("\tRSSI return value: %d\n", rp.rssi); - + close(dd); free(cr); } @@ -811,7 +893,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) /* Get Link Quality */ static struct option link_quality_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -822,7 +904,7 @@ static char *link_quality_help = static void cmd_link_quality(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; + struct hci_request rq; get_link_quality_rp rp; bdaddr_t bdaddr; int opt, dd; @@ -860,7 +942,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -868,7 +950,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_GET_LINK_QUALITY; @@ -888,7 +970,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) exit(1); } printf("Link quality: %d\n", rp.link_quality); - + close(dd); free(cr); } @@ -896,7 +978,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) /* Set connection packet type */ static struct option cpt_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -908,7 +990,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; struct hci_request rq; - set_conn_ptype_cp cp; + set_conn_ptype_cp cp; evt_conn_ptype_changed rp; bdaddr_t bdaddr; int opt, dd, ptype; @@ -947,7 +1029,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -955,19 +1037,19 @@ static void cmd_cpt(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + cp.handle = cr->conn_info->handle; cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_PTYPE; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; rq.clen = SET_CONN_PTYPE_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_CONN_PTYPE_CHANGED_SIZE; rq.event = EVT_CONN_PTYPE_CHANGED; - + if (hci_send_req(dd, &rq, 100) < 0) { perror("Packet type change failed"); exit(1); @@ -980,7 +1062,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) /* Get/Set Link Supervision Timeout */ static struct option link_supervision_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -991,7 +1073,7 @@ static char *link_supervision_help = static void cmd_link_sup_to(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; + struct hci_request rq; read_link_supervision_timeout_rp rp; write_link_supervision_timeout_cp cp; bdaddr_t bdaddr; @@ -1030,7 +1112,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); if (!cr) - return; + return; bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1038,16 +1120,16 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + if (argc == 1) { memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cr->conn_info->handle; - rq.clen = 2; + rq.clen = 2; rq.rparam = &rp; - rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; - + rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI read_link_supervision_timeout request failed"); exit(1); @@ -1069,11 +1151,11 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) cp.link_sup_to = strtol(argv[1], NULL, 10); memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cp; - rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; - + rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI write_link_supervision_timeout request failed"); exit(1); @@ -1098,6 +1180,7 @@ struct { { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, { "dc", cmd_dc, "Disconnect from remote device" }, + { "sr", cmd_sr, "Switch master/slave role" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_link_quality, "Display link quality" }, @@ -1125,8 +1208,8 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"device", 1,0, 'i'}, + {"help", 0,0, 'h'}, + {"device", 1,0, 'i'}, {0, 0, 0, 0} }; -- cgit From 13c90373161dea879719e09696d6dc6141465264 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 15 Jan 2003 13:08:16 +0000 Subject: Add the create_dev script --- scripts/Makefile.am | 2 +- scripts/create_dev | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100755 scripts/create_dev diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 4d86094a..812f160a 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -4,7 +4,7 @@ bin_SCRIPTS = bluepin -EXTRA_DIST = bluepin bluetooth.rc.rh bluetooth.rc.deb +EXTRA_DIST = bluepin bluetooth.rc.rh bluetooth.rc.deb create_dev install-data-local: @DISTRO@ diff --git a/scripts/create_dev b/scripts/create_dev new file mode 100755 index 00000000..4ea0c263 --- /dev/null +++ b/scripts/create_dev @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Create Bluetooth devices in /dev +# +# $Id$ +# + +VHCI_MAJOR=10 +VHCI_MINOR=250 + +RFCOMM_MAJOR=216 + +# +# Create device for VHCI +# +if [ ! -c /dev/vhci ]; then + mknod /dev/vhci c ${VHCI_MAJOR} ${VHCI_MINOR} + chmod 664 /dev/vhci +fi + +# +# Create devices for RFCOMM +# +for i in `seq 0 255` +do + if [ ! -c /dev/rfcomm$i ]; then + mknod -m 666 /dev/rfcomm$i c ${RFCOMM_MAJOR} $i + fi +done -- cgit From 9d2bce555fcd594df420b39d67f0d4bec313e46f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 18 Jan 2003 15:52:33 +0000 Subject: Update of the copyright statement --- rfcomm/kword.c | 2 +- rfcomm/kword.h | 2 +- rfcomm/lexer.l | 2 +- rfcomm/parser.y | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rfcomm/kword.c b/rfcomm/kword.c index 3cb9f2c6..f0aaed4f 100644 --- a/rfcomm/kword.c +++ b/rfcomm/kword.c @@ -2,7 +2,7 @@ * * RFCOMM configuration utility * - * Copyright (C) 2002 Marcel Holtmann + * Copyright (C) 2002-2003 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/kword.h b/rfcomm/kword.h index dddd2a83..f8e4210e 100644 --- a/rfcomm/kword.h +++ b/rfcomm/kword.h @@ -2,7 +2,7 @@ * * RFCOMM configuration utility * - * Copyright (C) 2002 Marcel Holtmann + * Copyright (C) 2002-2003 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/lexer.l b/rfcomm/lexer.l index 0f64cb43..46b76d13 100644 --- a/rfcomm/lexer.l +++ b/rfcomm/lexer.l @@ -3,7 +3,7 @@ * * RFCOMM configuration utility * - * Copyright (C) 2002 Marcel Holtmann + * Copyright (C) 2002-2003 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/parser.y b/rfcomm/parser.y index 5a42b2f1..3775de95 100644 --- a/rfcomm/parser.y +++ b/rfcomm/parser.y @@ -3,7 +3,7 @@ * * RFCOMM configuration utility * - * Copyright (C) 2002 Marcel Holtmann + * Copyright (C) 2002-2003 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 0c19759d355a83b63158c66d5f601be816f90424 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 18 Jan 2003 20:15:45 +0000 Subject: Update of the listen command --- rfcomm/main.c | 77 ++++++++++++++++++++++++++++++--------------------------- rfcomm/rfcomm.1 | 7 +++++- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/rfcomm/main.c b/rfcomm/main.c index c03f6127..b0df9c72 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -44,6 +44,7 @@ #include "kword.h" static char *rfcomm_config_file = NULL; +static int rfcomm_raw_tty = 0; extern int optind, opterr, optopt; extern char *optarg; @@ -325,10 +326,12 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg } } - tcflush(fd, TCIOFLUSH); + if (rfcomm_raw_tty) { + tcflush(fd, TCIOFLUSH); - cfmakeraw(&ti); - tcsetattr(fd, TCSANOW, &ti); + cfmakeraw(&ti); + tcsetattr(fd, TCSANOW, &ti); + } close(sk); @@ -368,32 +371,14 @@ static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv struct sockaddr_rc laddr, raddr; struct rfcomm_dev_req req; struct termios ti; + struct sigaction sa; + struct pollfd p; char dst[18], devname[MAXPATHLEN]; int sk, nsk, fd, alen; - int i; - - if (argc < 3) { - fprintf(stderr, "No command specified\n"); - return; - } laddr.rc_family = AF_BLUETOOTH; bacpy(&laddr.rc_bdaddr, bdaddr); - - if (strncmp(argv[1], "exec", 4) == 0) { - laddr.rc_channel = 1; - argc -= 2; - argv += 2; - } else if (strncmp(argv[2], "exec", 4) == 0) { - laddr.rc_channel = atoi(argv[1]); - argc -= 3; - argv += 3; - } else { - fprintf(stderr, "Unknown syntax\n"); - return; - } - - argv[argc] = NULL; + laddr.rc_channel = (argc < 2) ? 1 : atoi(argv[1]); if ((sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { perror("Can't create RFCOMM socket"); @@ -444,27 +429,43 @@ static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv } } - tcflush(fd, TCIOFLUSH); + if (rfcomm_raw_tty) { + tcflush(fd, TCIOFLUSH); - cfmakeraw(&ti); - tcsetattr(fd, TCSANOW, &ti); + cfmakeraw(&ti); + tcsetattr(fd, TCSANOW, &ti); + } close(sk); close(nsk); ba2str(&req.dst, dst); printf("Connection from %s to %s\n", dst, devname); + printf("Press CTRL-C for hangup\n"); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); - for (i = 1; i < argc; i++) - if (strcmp(argv[i], "%d") == 0) - argv[i] = devname; + p.fd = fd; + p.events = POLLERR | POLLHUP; - printf("Executing "); - for (i = 0; i < argc; i++) - printf("%s%s", (i == 0) ? "\"" : " ", argv[i]); - printf("\"\n"); + while (!__io_canceled) { + p.revents = 0; + if (poll(&p, 1, 100)) + break; + } - execvp(argv[0], argv); + printf("Disconnected\n"); close(fd); } @@ -545,6 +546,7 @@ static struct option main_options[] = { { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, { "config", 1, 0, 'f' }, + { "raw", 0, 0, 'r' }, { 0, 0, 0, 0 } }; @@ -556,7 +558,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:f:ah", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+i:f:rah", main_options, NULL)) != -1) { switch(opt) { case 'i': if (strncmp(optarg, "hci", 3) == 0) @@ -568,6 +570,9 @@ int main(int argc, char *argv[]) case 'f': rfcomm_config_file = strdup(optarg); break; + case 'r': + rfcomm_raw_tty = 1; + break; case 'a': show_all = 1; diff --git a/rfcomm/rfcomm.1 b/rfcomm/rfcomm.1 index 2164febe..0a0f48a0 100644 --- a/rfcomm/rfcomm.1 +++ b/rfcomm/rfcomm.1 @@ -57,12 +57,17 @@ available Bluetooth device. .BI show " " Display the information about the specified device. .TP -.BI conn " [bdaddr] [channel]" +.BI connect " [bdaddr] [channel]" Connect the RFCOMM device to the remote Bluetooth device on the specified channel. If no channel is specified, it will use the channel number 1. If also the Bluetooth address is left out, it tries to read the data from the config file. This command can be terminated with the key sequence CTRL-C. +.TP +.BI listen " [channel]" +Listen on a specified RFCOMM channel for incoming connections. +If no channel is specified, it will use the channel number 1. +This command can be terminated with the key sequence CTRL-C. .TP .BI bind " [bdaddr] [channel]" This binds the RFCOMM device to a remote Bluetooth device. The -- cgit From f03489827214efb7e5314e61b57278eec173b786 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 28 Jan 2003 01:55:08 +0000 Subject: Added OGF_PARAM_STATUS --- tools/hcisecfilter.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 8cd47420..13dee183 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -77,4 +77,14 @@ int main(void) printf("OGF_INFO_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + // OGF_INFO_PARAM + memset((void *) ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); + hci_set_bit(OCF_RESET_FAILED_CONTACT_COUNTER, ocf_mask); + hci_set_bit(OCF_GET_LINK_QUALITY, ocf_mask); + hci_set_bit(OCF_READ_RSSI, ocf_mask); + + printf("OGF_STATUS_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); } -- cgit From 96209b933e9b3b9c93701e15e4a9590f859cc8c6 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 4 Feb 2003 15:32:21 +0000 Subject: fix typo --- test/l2test.c | 2 +- test/rctest.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index 53e9e768..69960c35 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -376,7 +376,7 @@ void usage(void) printf("Modes:\n" "\t-r listen and receive\n" "\t-w listen and send\n" - "\t-d listen and dump incomming data\n" + "\t-d listen and dump incoming data\n" "\t-s connect and send\n" "\t-u connect and receive\n" "\t-n connect and be silent\n" diff --git a/test/rctest.c b/test/rctest.c index 0584a6a9..2afafaa2 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -300,7 +300,7 @@ void usage(void) printf("Modes:\n" "\t-r listen and receive\n" "\t-w listen and send\n" - "\t-d listen and dump incomming data\n" + "\t-d listen and dump incoming data\n" "\t-s connect and send\n" "\t-u connect and receive\n" "\t-n connect and be silent\n" -- cgit From 227df09e733b7ad5421903d4e48d36860d14327f Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 4 Feb 2003 15:49:49 +0000 Subject: fix typo --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 45d9a23d..0c8437f3 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -824,7 +824,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) break; default: - printf("\tUnsuported manufacturer\n"); + printf("\tUnsupported manufacturer\n"); break; } return; -- cgit From aaa780de16b91375ba63bdf4929bc5b7a2a0c8f6 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Sat, 8 Feb 2003 12:08:55 +0000 Subject: typos --- tools/hciattach.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 78deb53b..f30ae033 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -796,10 +796,10 @@ int init_uart(char *dev, struct uart_t *u) return -1; } - /* Set TTY to N_HCI line discpline */ + /* Set TTY to N_HCI line discipline */ i = N_HCI; if (ioctl(fd, TIOCSETD, &i) < 0) { - perror("Can't set line disc"); + perror("Can't set line discipline"); return -1; } @@ -890,7 +890,7 @@ int main(int argc, char *argv[]) } if (!u) { - fprintf(stderr, "Unknow device type or id\n"); + fprintf(stderr, "Unknown device type or id\n"); exit(1); } @@ -910,7 +910,7 @@ int main(int argc, char *argv[]) } if (!u) { - fprintf(stderr, "Unknow device type or id\n"); + fprintf(stderr, "Unknown device type or id\n"); exit(1); } @@ -919,12 +919,12 @@ int main(int argc, char *argv[]) sa.sa_handler = sig_alarm; sigaction(SIGALRM, &sa, NULL); - /* 5 seconds should be enough for intialization */ + /* 5 seconds should be enough for initialization */ alarm(to); n = init_uart(dev, u); if (n < 0) { - perror("Can't init device"); + perror("Can't initialize device"); exit(1); } -- cgit From 495f345e287c55e16ac5c868485806d2edb2356f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Feb 2003 11:34:06 +0000 Subject: New boot script for Debian --- scripts/bluetooth.rc.deb | 76 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 25 deletions(-) diff --git a/scripts/bluetooth.rc.deb b/scripts/bluetooth.rc.deb index 36892187..2480d385 100755 --- a/scripts/bluetooth.rc.deb +++ b/scripts/bluetooth.rc.deb @@ -1,57 +1,83 @@ #! /bin/sh # -# bluetooth Bluetooth subsystem starting and stopping +# bluetooth Bluetooth subsystem starting and stopping # -# Edd Dumbill +NAME=bluetooth +DESC="Bluetooth subsystem" PATH=/sbin:/bin:/usr/sbin:/usr/bin -DAEMON=/sbin/hcid +HCID=/sbin/hcid +HCID_CONF=/etc/bluetooth/hcid.conf HCIATTACH=/sbin/hciattach UART_CONF=/etc/bluetooth/uart -NAME=hcid -DESC=bluez-utils - -test -f $DAEMON || exit 0 -test -f $HCIATTACH || exit 0 +SDPD=/usr/sbin/sdpd +RFCOMM=/bin/rfcomm +RFCOMM_CONF=/etc/bluetooth/rfcomm.conf set -e start_uarts() { - [ -f $HCIATTACH -a -f $UART_CONF ] || return - grep -v '^#' $UART_CONF | while read i; do - $HCIATTACH $i - done + [ -x $HCIATTACH -a -f $UART_CONF ] || return + grep -v '^#' $UART_CONF | while read i; do + $HCIATTACH $i + done } stop_uarts() { - killall hciattach > /dev/null 2>&1 || true + killall $HCIATTACH > /dev/null 2>&1 || true } case "$1" in start) - echo -n "Starting $DESC: " - $DAEMON - echo "$NAME." + echo -n "Starting $DESC:" + if [ -x $HCID -a -f $HCID_CONF ] ; then + $HCID -f $HCID_CONF + echo -n " hcid" + fi + if [ -x $SDPD ] ; then + $SDPD + echo -n " sdpd" + fi + if [ -x $RFCOMM -a -f $RFCOMM_CONF ] ; then + $RFCOMM -f $RFCOMM_CONF bind all + echo -n " rfcomm" + fi + echo "." start_uarts || true ;; stop) - echo -n "Stopping $DESC: " - killall $NAME || true - echo "$NAME." + echo -n "Stopping $DESC:" + if [ -x $RFCOMM ] ; then + echo -n " rfcomm" + $RFCOMM unbind all + fi + echo -n " sdpd" + killall $SDPD > /dev/null 2>&1 || true + echo -n " hcid" + killall $HCID > /dev/null 2>&1 || true + echo "." stop_uarts ;; restart|force-reload) - echo -n "Restarting $DESC: " - killall $NAME || true + echo -n "Restarting $DESC:" + echo -n " hcid" + killall $HCID > /dev/null 2>&1 || true + sleep 1 + if [ -x $HCID -a -f $HCID_CONF ] ; then + $HCID -f $HCID_CONF + fi + echo -n " sdpd" + killall $SDPD > /dev/null 2>&1 || true sleep 1 - $DAEMON - echo "$NAME." + if [ -x $SDPD ] ; then + $SDPD + fi + echo "." ;; *) - N=/etc/init.d/bluez-utils - # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 + N=/etc/init.d/bluetooth echo "Usage: $N {start|stop|restart|force-reload}" >&2 exit 1 ;; -- cgit From e4be7ba24dd532b782e60ff7d3bcdfd87989cc37 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 10 Feb 2003 15:34:55 +0000 Subject: fix typo --- scripts/bluepin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bluepin b/scripts/bluepin index aa1a0f3c..b17f4a03 100755 --- a/scripts/bluepin +++ b/scripts/bluepin @@ -141,7 +141,7 @@ def main(*args): if dir == "out": mesg = "Outgoing connection to " else: - mesg = "Incomming connection from " + mesg = "Incoming connection from " mesg = mesg + name + "[" + bdaddr + "]" -- cgit From 427f4bbc07f40706dd5e3c5500f14c63a160c979 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 12 Feb 2003 12:34:16 +0000 Subject: describe optional arguments --- tools/hciattach.8 | 13 +++++++++++-- tools/hciattach.c | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/hciattach.8 b/tools/hciattach.8 index 812c40dc..0dadec99 100644 --- a/tools/hciattach.8 +++ b/tools/hciattach.8 @@ -3,7 +3,7 @@ hciattach \- attach serial devices via UART HCI to BlueZ stack .SH SYNOPSIS .B hciattach -< +[ -n ] [ -p ] [ -t timeout ] < .I tty > < .I type @@ -20,6 +20,15 @@ Hciattach is used to attach a serial UART to the Bluetooth stack as HCI transport interface. .SH OPTIONS .TP +.BI -n +Don't detach from controlling terminal. +.TP +.BI -p +Print the PID when detaching. +.TP +.BI -t timeout +Specify an initialization timeout. (Default is 5 seconds.) +.TP .I This specifies the serial device to attach. A leading .B /dev @@ -102,4 +111,4 @@ instead. .SH AUTHORS Written by Maxim Krasnyansky .PP -man page by Nils Faerber +Manual page by Nils Faerber diff --git a/tools/hciattach.c b/tools/hciattach.c index f30ae033..b6aa7376 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -815,7 +815,7 @@ static void usage(void) { printf("hciattach - HCI UART driver initialization utility\n"); printf("Usage:\n"); - printf("\thciattach [speed] [flow]\n"); + printf("\thciattach [-n] [-p] [-t timeout] [speed] [flow]\n"); printf("\thciattach -l\n"); } -- cgit From d436459deed7ec8a472f6d27c4f0e3539aa482ef Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 12 Feb 2003 13:34:55 +0000 Subject: bugfix --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 0c8437f3..ed8fdcd2 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -486,7 +486,7 @@ void cmd_class(int ctl, int hdev, char *opt) exit(1); } if (opt) { - uint32_t cod = htobl(strtoul(opt, NULL, 16)); + uint32_t cod = strtoul(opt, NULL, 16); if (0 > hci_write_class_of_dev(s, cod, 1000)) { printf("Can't write local class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); -- cgit From 047f07b46aa8afabe5ebd67fa02365c92a4ff224 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 12 Feb 2003 13:46:00 +0000 Subject: add support for texas module --- tools/hciattach.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index b6aa7376..0131dcb6 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -230,14 +230,74 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) return 0; } +static int texas(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[10]; + unsigned char resp[100]; /* Response */ + int n; + + memset(resp,'\0', 100); + + /* Switch to default Texas baudrate*/ + if (set_speed(fd, ti, 115200) < 0) { + perror("Can't set default baud rate"); + return -1; + } + + /* It is possible to get software version with manufacturer specific + HCI command HCI_VS_TI_Version_Number. But the only thing you get more + is if this is point-to-point or point-to-multipoint module */ + + /* Get Manufacturer and LMP version */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x01; + cmd[2] = 0x10; + cmd[3] = 0x00; + + do { + n = write(fd, cmd, 4); + if (n < 0) { + perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)"); + return -1; + } + if (n < 4) { + fprintf(stderr, "Wanted to write 4 bytes, could only write %d. Stop\n", n); + return -1; + } + + /* Read reply. */ + if (read_hci_event(fd, resp, 100) < 0) { + perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)"); + return -1; + } + + /* Wait for command complete event for our Opcode */ + } while (resp[4] != cmd[1] && resp[5] != cmd[2]); + + /* Verify manufacturer */ + if ((resp[11] & 0xFF) != 0x0d) + fprintf(stderr,"WARNING : module's manufacturer is not Texas Instrument\n"); + + /* Print LMP version */ + fprintf(stderr, "Texas module LMP version : 0x%02x\n", resp[10] & 0xFF); + + /* Print LMP subversion */ + fprintf(stderr, "Texas module LMP sub-version : 0x%02x%02x\n", resp[14] & 0xFF, resp[13] & 0xFF); + + nanosleep(&tm, NULL); + return 0; +} + static int read_check(int fd, void *buf, int count) { int res; - do{ + do { res = read(fd, buf, count); if (res != -1) { - buf += res; count -= res; + buf += res; + count -= res; } } while (count && (errno == 0 || errno == EINTR)); @@ -704,6 +764,7 @@ struct uart_t uart[] = { { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, + { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, texas}, { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 0, bcsp }, -- cgit From ae072dcf83d8124e45a0bf5ca69c3699e2a4b8fe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 Feb 2003 15:53:40 +0000 Subject: Fix the voice command for big endian machines --- tools/hciconfig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index ed8fdcd2..9f80f4c4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -535,7 +535,7 @@ void cmd_voice(int ctl, int hdev, char *opt) exit(1); } if (opt) { - uint16_t vs = htobl(strtoul(opt, NULL, 16)); + uint16_t vs = htobs(strtoul(opt, NULL, 16)); if (0 > hci_write_voice_setting(s, vs, 1000)) { printf("Can't write voice setting on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -549,6 +549,7 @@ void cmd_voice(int ctl, int hdev, char *opt) hdev, strerror(errno), errno); exit(1); } + vs = htobs(vs); ic = (vs & 0x0300) >> 8; print_dev_hdr(&di); printf("\tVoice setting: 0x%04x%s\n", vs, -- cgit From a9ea91fd12bfac8dfb529911c56e062cd2abc34b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Feb 2003 06:04:55 +0000 Subject: Allow rfcomm.conf without entries --- rfcomm/parser.y | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rfcomm/parser.y b/rfcomm/parser.y index 3775de95..f7ee3d70 100644 --- a/rfcomm/parser.y +++ b/rfcomm/parser.y @@ -59,7 +59,9 @@ struct rfcomm_opts *opts; %% -config : statement | config statement +config : + | statement + | config statement ; statement : section '{' rfcomm_options '}' -- cgit From eeb3109cedd192d95abe9b103d78d10685ba4004 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 Mar 2003 22:55:41 +0000 Subject: Display CSR firmware with revision command --- tools/hciconfig.c | 79 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 9f80f4c4..bae20770 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -785,11 +785,66 @@ void cmd_page_to(int ctl, int hdev, char *opt) } } -static void cmd_revision(int ctl, int hdev, char *opt) +static void print_rev_ericsson(int dd) { - struct hci_version ver; struct hci_request rq; unsigned char buf[102]; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = 0x3f; + rq.ocf = 0x000f; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("\n Can't read revision info. %s(%d)\n", strerror(errno), errno); + return; + } + + printf("\t%s\n", buf + 1); +} + +static struct { + char *str; + uint16_t rev; +} csr_map[] = { + { "HCI 11.2 (bc01b)", 114 }, + { "HCI 11.3 (bc01b)", 115 }, + { "HCI 12.1 (bc01b)", 119 }, + { "HCI 12.3 (bc01b)", 134 }, + { "HCI 12.7 (bc01b)", 188 }, + { "HCI 12.8 (bc01b)", 218 }, + { "HCI 12.9 (bc01b)", 283 }, + { "HCI 13.10 (bc01b)", 309 }, + { "HCI 13.11 (bc01b)", 351 }, + { "HCI 16.4 (bc01b)", 523 }, + { "HCI 14.3 (bc02x)", 272 }, + { "HCI 14.6 (bc02x)", 336 }, + { "HCI 14.7 (bc02x)", 373 }, + { "HCI 14.8 (bc02x)", 487 }, + { "HCI 15.3 (bc02x)", 443 }, + { "HCI 16.4 (bc02x)", 525 }, + { NULL } +}; + +static void print_rev_csr(uint16_t rev) +{ + int i; + + for (i = 0; csr_map[i].str; i++) + if (csr_map[i].rev == rev) { + printf("\t%s\n", csr_map[i].str); + return; + } + + printf("\tUnknown firmware\n"); +} + +static void cmd_revision(int ctl, int hdev, char *opt) +{ + struct hci_version ver; int dd; dd = hci_open_dev(hdev); @@ -807,23 +862,11 @@ static void cmd_revision(int ctl, int hdev, char *opt) print_dev_hdr(&di); switch (ver.manufacturer) { case 0: - memset(&rq, 0, sizeof(rq)); - rq.ogf = 0x3f; - rq.ocf = 0x000f; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &buf; - rq.rlen = sizeof(buf); - - if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\n Can't read revision info. %s(%d)\n", - strerror(errno), errno); - return; - } - - printf("\t%s\n", buf + 1); + print_rev_ericsson(dd); + break; + case 10: + print_rev_csr(ver.hci_rev); break; - default: printf("\tUnsupported manufacturer\n"); break; -- cgit From c7c04aac86fec5084e3e1caf3eaaa3abd545f58d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 Mar 2003 23:10:29 +0000 Subject: Removes all dependencies on glib --- configure.in | 16 ----- hcid/Makefile.am | 4 +- hcid/glib-ectomy.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++ hcid/glib-ectomy.h | 101 ++++++++++++++++++++++++++++++++ hcid/hcid.h | 2 +- hcid/main.c | 2 +- hcid/security.c | 21 ++++--- utils.spec | 3 +- 8 files changed, 287 insertions(+), 30 deletions(-) create mode 100644 hcid/glib-ectomy.c create mode 100644 hcid/glib-ectomy.h diff --git a/configure.in b/configure.in index 80a1b092..3ee5b5f0 100644 --- a/configure.in +++ b/configure.in @@ -16,9 +16,6 @@ AM_INIT_AUTOMAKE(bluez-utils, 2.2) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) -AC_SUBST(GLIB_CFLAGS) -AC_SUBST(GLIB_LDFLAGS) - CFLAGS="-Wall -g -O2" AC_PREFIX_DEFAULT() @@ -57,19 +54,6 @@ AC_SEARCH_LIB(bluetooth, hci_open_dev, $BLUEZ_LIBDIR,, Please compile and install bluez-libs package.) ) -AC_ARG_WITH(glib-config, - --with-glib-config=prog glib-config location, - GLIB_CONFIG="$withval", - [ - AC_PATH_PROGS(GLIB_CONFIG, glib-config, no) - if test "$GLIB_CONFIG" = "no"; then - AC_MSG_ERROR(GLib not found) - fi - ] -) -GLIB_CFLAGS="`$GLIB_CONFIG --cflags`" -GLIB_LDFLAGS="`$GLIB_CONFIG --libs`" - dnl Check for distro type. DISTRO=unknown diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 49386a93..bb666044 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -4,11 +4,9 @@ sbin_PROGRAMS = hcid -hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c +hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c hcid_CONFIG = hcid.conf -hcid_LDADD = @GLIB_LDFLAGS@ -INCLUDES = @GLIB_CFLAGS@ YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h diff --git a/hcid/glib-ectomy.c b/hcid/glib-ectomy.c new file mode 100644 index 00000000..0f168d80 --- /dev/null +++ b/hcid/glib-ectomy.c @@ -0,0 +1,168 @@ +#include "glib-ectomy.h" + +#include +#include +#include +#include +#include +#include + +// static void remove_watch(int fd); + +GIOError g_io_channel_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read) +{ + int fd = channel->fd; + gssize result; + + if (count > SSIZE_MAX) /* At least according to the Debian manpage for read */ + count = SSIZE_MAX; + + retry: + result = read (fd, buf, count); + + if (result < 0) + { + *bytes_read = 0; + + switch (errno) + { +#ifdef EINTR + case EINTR: + goto retry; +#endif +#ifdef EAGAIN + case EAGAIN: + return G_IO_STATUS_AGAIN; +#endif + default: + return G_IO_STATUS_ERROR; + } + } + + *bytes_read = result; + + return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; +} + +void g_io_channel_close (GIOChannel *channel) +{ + int fd = channel->fd; + + close(fd); + + memset(channel, 0, sizeof(channel)); + free(channel); +} + +GIOChannel* g_io_channel_unix_new (int fd) +{ + GIOChannel *channel = malloc(sizeof(GIOChannel)); + channel->fd = fd; + return channel; +} + +gint g_io_channel_unix_get_fd (GIOChannel *channel) +{ + return channel->fd; +} + + + +struct watch { + guint id; + GIOChannel *channel; + GIOCondition condition; + GIOFunc func; + gpointer user_data; + + struct watch *next; +}; + +static struct watch watch_head = { .id = 0, .next = 0 }; + +guint g_io_add_watch (GIOChannel *channel, + GIOCondition condition, + GIOFunc func, + gpointer user_data) +{ + struct watch *watch = malloc(sizeof(struct watch)); + + watch->id = ++watch_head.id; + watch->channel = channel; + watch->condition = condition; + watch->func = func; + watch->user_data = user_data; + + watch->next = watch_head.next; + watch_head.next = watch; + + return watch->id; +} + +GMainLoop *g_main_loop_new (GMainContext *context, + gboolean is_running) +{ + GMainLoop *ml = malloc(sizeof(GMainLoop)); + + ml->bail = 0; + + return ml; +} + +void g_main_loop_run (GMainLoop *loop) +{ + int open_max = sysconf(_SC_OPEN_MAX); + struct pollfd *ufds = malloc(open_max * sizeof(struct pollfd)); + + while (!loop->bail) { + int nfds, rc, i; + struct watch *p, *w; + + nfds = 0; + for (w = watch_head.next; w != NULL; w = w->next) { + ufds[nfds].fd = w->channel->fd; + ufds[nfds].events = w->condition; + ufds[nfds].revents = 0; + nfds++; + } + + rc = poll(ufds, nfds, -1); + + if (rc < 0 && (errno == EINTR)) + continue; + + if (rc < 0) { + perror("poll"); + continue; + } + + p = &watch_head; + w = watch_head.next; + i = 0; + while (w) { + if (ufds[i].revents) { + gboolean keep = w->func(w->channel, ufds[i].revents, w->user_data); + if (!keep) { + p->next = w->next; + memset(w, 0, sizeof(*w)); + w = p->next; + i++; + continue; + } + } + + p = w; + w = w->next; + i++; + } + + } +} + +void g_main_loop_quit (GMainLoop *loop) +{ + loop->bail = 1; +} diff --git a/hcid/glib-ectomy.h b/hcid/glib-ectomy.h new file mode 100644 index 00000000..78cd9d8a --- /dev/null +++ b/hcid/glib-ectomy.h @@ -0,0 +1,101 @@ +#ifndef _GLIB_ECTOMY_H_ +#define _GLIB_ECTOMY_H_ + +#include +#include + +typedef char gchar; +typedef short gshort; +typedef long glong; +typedef int gint; +typedef gint gboolean; + +typedef unsigned char guchar; +typedef unsigned short gushort; +typedef unsigned long gulong; +typedef unsigned int guint; + +typedef float gfloat; +typedef double gdouble; + +typedef void* gpointer; +typedef const void *gconstpointer; + +typedef size_t gsize; +typedef ssize_t gssize; + +typedef struct _GIOChannel { + int fd; +} GIOChannel; + +typedef struct _GMainContext { + int dummy; +} GMainContext; + +typedef struct _GMainLoop { + int bail; +} GMainLoop; + +typedef enum +{ + G_IO_ERROR_NONE, + G_IO_ERROR_AGAIN, + G_IO_ERROR_INVAL, + G_IO_ERROR_UNKNOWN +} GIOError; + +typedef enum +{ + G_IO_STATUS_ERROR = -1, + G_IO_STATUS_NORMAL = 0, + G_IO_STATUS_EOF = 1, + G_IO_STATUS_AGAIN = 2 +} GIOStatus; + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + + +typedef enum +{ + G_IO_IN = POLLIN, + G_IO_OUT = POLLOUT, + G_IO_PRI = POLLPRI, + G_IO_ERR = POLLERR, + G_IO_HUP = POLLHUP, + G_IO_NVAL = POLLNVAL +} GIOCondition; + +typedef gboolean (*GIOFunc) (GIOChannel *source, + GIOCondition condition, + gpointer data); + +GIOError g_io_channel_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read); +void g_io_channel_close (GIOChannel *channel); + +GIOChannel* g_io_channel_unix_new (int fd); +gint g_io_channel_unix_get_fd (GIOChannel *channel); +guint g_io_add_watch (GIOChannel *channel, + GIOCondition condition, + GIOFunc func, + gpointer user_data); + + +GMainLoop *g_main_loop_new (GMainContext *context, + gboolean is_running); +void g_main_loop_run (GMainLoop *loop); +void g_main_loop_quit (GMainLoop *loop); + +#define g_main_new(is_running) g_main_loop_new (NULL, is_running); +#define g_main_run(loop) g_main_loop_run(loop) +#define g_main_quit(loop) g_main_loop_quit(loop) + +#endif diff --git a/hcid/hcid.h b/hcid/hcid.h index 3e7838b4..55ef0ab0 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -26,7 +26,7 @@ #include -#include +#include "glib-ectomy.h" #include diff --git a/hcid/main.c b/hcid/main.c index 8a5371e5..85534fdf 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -44,7 +44,7 @@ #include #include -#include +#include "glib-ectomy.h" #include "hcid.h" #include "lib.h" diff --git a/hcid/security.c b/hcid/security.c index b7839c4c..0380d31f 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -46,7 +46,7 @@ #include #include -#include +#include "glib-ectomy.h" #include "hcid.h" #include "lib.h" @@ -108,6 +108,9 @@ static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) { struct link_key *key = get_link_key(sba, dba); + syslog(LOG_INFO, "link_key_request (sba=%s, dba=%s)\n", + batostr(sba), batostr(dba)); + if (key) { /* Link key found */ link_key_reply_cp lr; @@ -170,6 +173,8 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) bdaddr_t *dba = &evt->bdaddr; struct link_key key; + syslog(LOG_INFO, "link_key_notify (sba=%s)\n", batostr(sba)); + memcpy(key.key, evt->link_key, 16); bacpy(&key.sba, sba); bacpy(&key.dba, dba); @@ -289,6 +294,9 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) struct hci_conn_info_req *cr; struct hci_conn_info *ci; + syslog(LOG_INFO, "pin_code_request (sba=%s, dba=%s)\n", + batostr(sba), batostr(dba)); + cr = malloc(sizeof(*cr) + sizeof(*ci)); if (!cr) return; @@ -350,12 +358,7 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) hci_event_hdr *eh; GIOError err; - if (cond & G_IO_NVAL) { - free(data); - return FALSE; - } - - if (cond & (G_IO_HUP | G_IO_ERR)) { + if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { g_io_channel_close(chan); free(data); return FALSE; @@ -365,6 +368,7 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) if (err == G_IO_ERROR_AGAIN) return TRUE; g_io_channel_close(chan); + free(data); return FALSE; } @@ -458,6 +462,9 @@ void stop_security_manager(int hdev) syslog(LOG_INFO, "Stoping security manager %d", hdev); + /* this is a bit sneaky. closing the fd will cause the event + loop to call us right back with G_IO_NVAL set, at which + point we will see it and clean things up */ close(g_io_channel_unix_get_fd(chan)); io_chan[hdev] = NULL; } diff --git a/utils.spec b/utils.spec index e207e004..85b857c1 100644 --- a/utils.spec +++ b/utils.spec @@ -18,10 +18,8 @@ BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root URL: http://bluez.sourceforge.net Docdir: %{prefix}/usr/share/doc Requires: glibc >= 2.2.4 -Requires: glib >= 1.2 Requires: bluez-libs >= 2.0 BuildRequires: glibc >= 2.2.4 -BuildRequires: glib-devel >= 1.2 BuildRequires: bluez-libs >= 2.0 %description @@ -71,6 +69,7 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man8/hciconfig.8.gz %{_mandir}/man1/hcitool.1.gz %{_mandir}/man1/l2ping.1.gz +%{_mandir}/man1/rfcomm.1.gz %{_sysconfdir}/bluetooth/* %{_sysconfdir}/pcmcia/bluetooth.conf %{_sysconfdir}/pcmcia/bluetooth -- cgit From a8b6c0b9d190457f40f30147fe70ef0f8467a60b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 17 Mar 2003 09:06:19 +0000 Subject: Flush the serial buffer before quit in BCSP initialization --- tools/hciattach.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/hciattach.c b/tools/hciattach.c index 0131dcb6..6959a006 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -323,6 +323,7 @@ static void bcsp_tshy_sig_alarm(int sig) alarm(1); return; } + tcflush(serial_fd, TCIOFLUSH); fprintf(stderr, "BCSP initialization timed out\n"); exit(1); } @@ -337,6 +338,7 @@ static void bcsp_tconf_sig_alarm(int sig) alarm(1); return; } + tcflush(serial_fd, TCIOFLUSH); fprintf(stderr, "BCSP initialization timed out\n"); exit(1); } -- cgit From 55682f4240f0854ea60d53314fc0c471d1e146b2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 19 Mar 2003 21:17:46 +0000 Subject: Add 921600 bps for Ericsson modules --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/hciattach.c b/tools/hciattach.c index 6959a006..15a9d367 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -173,6 +173,9 @@ static int ericsson(int fd, struct uart_t *u, struct termios *ti) case 460800: cmd[4] = 0x00; break; + case 921600: + cmd[4] = 0x20; + break; default: cmd[4] = 0x03; u->speed = 57600; -- cgit From c983d302e10d3e6849634b7114e624ef5e3710f0 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Mar 2003 20:15:07 +0000 Subject: memset() is in string.h --- hcid/glib-ectomy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hcid/glib-ectomy.c b/hcid/glib-ectomy.c index 0f168d80..b97cdea7 100644 --- a/hcid/glib-ectomy.c +++ b/hcid/glib-ectomy.c @@ -1,6 +1,7 @@ #include "glib-ectomy.h" #include +#include #include #include #include -- cgit From bbc64980becd62088bf04427f8652d0935962167 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Mar 2003 20:26:31 +0000 Subject: New version. --- ChangeLog | 13 +++++++++++++ configure.in | 2 +- utils.spec | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ae56a12..3017c206 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +var 2.3: + hciconfig changes: + CSR firmware version is now displayed by 'revision' command. + Voice command is working properly on big endian machines. + hciattach changes: + Added support for Texas Bluetooth modules. + Added support for high UART baud rates on Ericsson modules. + BCSP initialization fixes. + Support for role switch command (hcitool). + RFCOMM config file parser fixes. + Update man pages. + Removed GLib dependency. + ver 2.2: Support for voice settings (hciconfig). Minor hcitool fixes. diff --git a/configure.in b/configure.in index 3ee5b5f0..460ffc06 100644 --- a/configure.in +++ b/configure.in @@ -11,7 +11,7 @@ AC_CANONICAL_HOST AM_MAINTAINER_MODE -AM_INIT_AUTOMAKE(bluez-utils, 2.2) +AM_INIT_AUTOMAKE(bluez-utils, 2.3) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) diff --git a/utils.spec b/utils.spec index 85b857c1..a608e498 100644 --- a/utils.spec +++ b/utils.spec @@ -1,5 +1,5 @@ # Note that this is NOT a relocatable package -%define ver 2.2 +%define ver 2.3 %define RELEASE 1 %define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} %define prefix / -- cgit From 17990fc4315e60ba6a3ffd59ea8781f2c1647cfc Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 26 Mar 2003 14:39:19 +0000 Subject: typo --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/l2test.c b/test/l2test.c index 69960c35..f7d487d7 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -387,7 +387,7 @@ void usage(void) "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" "\t[-D] use connectionless channel (datagram)\n" - "\t[-E] request encryption\n" + "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); } -- cgit From 499f43343f20d5a562ee041d950086df01fb4868 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Mar 2003 09:54:01 +0000 Subject: Remove the voice setting command and fix a big endian problem --- test/hstest.c | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/test/hstest.c b/test/hstest.c index 867eb20b..8b47a10a 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -39,42 +39,8 @@ #include -#ifndef OCF_READ_VOICE_SETTING -#define OCF_READ_VOICE_SETTING 0x0025 -typedef struct { - uint8_t status; - uint16_t voice_setting; -} __attribute__ ((packed)) read_voice_setting_rp; -#define READ_VOICE_SETTING_RP_SIZE 3 - -static int hci_read_voice_setting(int dd, uint16_t *vs, int to) -{ - read_voice_setting_rp rp; - struct hci_request rq; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_VOICE_SETTING; - rq.rparam = &rp; - rq.rlen = READ_VOICE_SETTING_RP_SIZE; - - if (hci_send_req(dd, &rq, to) < 0) - return -1; - - if (rp.status) { - errno = EIO; - return -1; - } - - *vs = rp.voice_setting; - return 0; -} -#endif - - static volatile int terminate = 0; - static void sig_term(int sig) { terminate = 1; } @@ -110,7 +76,6 @@ static int rfcomm_connect(bdaddr_t *src, bdaddr_t *dst, uint8_t channel) return s; } - static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t *mtu) { struct sockaddr_sco addr; @@ -167,7 +132,6 @@ static void usage(void) "\thstest record [channel]\n"); } - #define PLAY 1 #define RECORD 2 @@ -222,6 +186,7 @@ int main(int argc, char *argv[]) hci_devba(0, &local); dd = hci_open_dev(0); hci_read_voice_setting(dd, &vs, 1000); + vs = htobs(vs); fprintf(stderr, "Voice setting: 0x%04x\n", vs); close(dd); if (vs != 0x0040) { -- cgit From 40fbc58cb2874081e624d2658282f90f29525624 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 5 Apr 2003 14:13:04 +0000 Subject: Support for initial baud rate and sending of a break --- tools/hciattach.c | 128 +++++++++++++++++++++++++----------------------------- 1 file changed, 58 insertions(+), 70 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 15a9d367..7b8c20a0 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -51,6 +51,7 @@ struct uart_t { int m_id; int p_id; int proto; + int start_speed; int speed; int flags; int (*init) (int fd, struct uart_t *u, struct termios *ti); @@ -79,6 +80,8 @@ static int uart_speed(int s) return B921600; case 1000000: return B1000000; + case 1152000: + return B1152000; default: return B57600; } @@ -149,12 +152,6 @@ static int ericsson(int fd, struct uart_t *u, struct termios *ti) struct timespec tm = {0, 50000}; char cmd[10]; - /* Switch to default Ericsson baudrate*/ - if (set_speed(fd, ti, 57600) < 0) { - perror("Can't set default baud rate"); - return -1; - } - cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x09; cmd[2] = 0xfc; @@ -199,12 +196,6 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) struct timespec tm = {0, 50000}; char cmd[10]; - /* Switch to default Digi baudrate*/ - if (set_speed(fd, ti, 9600) < 0) { - perror("Can't set default baud rate"); - return -1; - } - /* DigiAnswer set baud rate command */ cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x07; @@ -242,12 +233,6 @@ static int texas(int fd, struct uart_t *u, struct termios *ti) memset(resp,'\0', 100); - /* Switch to default Texas baudrate*/ - if (set_speed(fd, ti, 115200) < 0) { - perror("Can't set default baud rate"); - return -1; - } - /* It is possible to get software version with manufacturer specific HCI command HCI_VS_TI_Version_Number. But the only thing you get more is if this is point-to-point or point-to-multipoint module */ @@ -484,12 +469,6 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) static int csr_seq = 0; /* Sequence number of command */ int divisor; - /* Switch to default CSR baudrate */ - if (set_speed(fd, ti, 115200) < 0) { - perror("Can't set default baud rate"); - return -1; - } - /* It seems that if we set the CSR UART speed straight away, it * won't work, the CSR UART gets into a state where we can't talk * to it anymore. @@ -596,6 +575,19 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) } #endif + if (u->speed > 1500000) { + fprintf(stderr, "Speed %d too high. Remaining at %d baud\n", + u->speed, u->start_speed); + u->speed = u->start_speed; + } else if (u->speed != 57600 && uart_speed(u->speed) == B57600) { + /* Unknown speed. Why oh why can't we just pass an int to the kernel? */ + fprintf(stderr, "Speed %d unrecognised. Remaining at %d baud\n", + u->speed, u->start_speed); + u->speed = u->start_speed; + } + if (u->speed == u->start_speed) + return 0; + /* Now, create the command that will set the UART speed */ /* CSR BCC header */ cmd[5] = 0x02; /* type = SET-REQ */ @@ -604,30 +596,8 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) cmd[10] = (csr_seq >> 8) & 0xFF;/* - msB */ csr_seq++; - switch (u->speed) { - case 9600: - divisor = 0x0027; - break; - /* Various speeds ommited */ - case 57600: - divisor = 0x00EC; - break; - case 115200: - divisor = 0x01D8; - break; - /* For Brainbox Pcmcia cards */ - case 460800: - divisor = 0x075F; - break; - case 921600: - divisor = 0x0EBF; - break; - default: - /* Safe default */ - divisor = 0x01D8; - u->speed = 115200; - break; - } + divisor = (u->speed*64+7812)/15625; + /* No parity, one stop bit -> divisor |= 0x0000; */ cmd[15] = (divisor) & 0xFF; /* divider */ cmd[16] = (divisor >> 8) & 0xFF; /* - msB */ @@ -665,12 +635,6 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) char cmd[10], rsp[100]; int r; - /* Switch to default Silicon Wave baudrate*/ - if (set_speed(fd, ti, 115200) < 0) { - perror("Can't set default baud rate"); - return -1; - } - // Silicon Wave set baud rate command // see HCI Vendor Specific Interface from Silicon Wave // first send a "param access set" command to set the @@ -766,33 +730,33 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) } struct uart_t uart[] = { - { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, - { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, ericsson }, - { "digi", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, digi }, - { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, texas}, + { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, + { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, digi }, + { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, texas}, - { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 0, bcsp }, + { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */ - { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ - { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, csr }, + { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, /* BrainBoxes PCMCIA card (BL620) */ - { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 460800, FLOW_CTL, csr }, + { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 115200, 460800, FLOW_CTL, csr }, /* Silicon Wave kits */ - { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, swave }, + { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, swave }, /* Sphinx Electronics PICO Card */ - { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* Inventel BlueBird Module */ - { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, FLOW_CTL, NULL }, + { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* COM One Platinium Bluetooth PC Card */ - { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 0, bcsp }, + { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, { NULL, 0 } }; @@ -818,7 +782,7 @@ struct uart_t * get_by_type(char *type) } /* Initialize UART driver */ -int init_uart(char *dev, struct uart_t *u) +int init_uart(char *dev, struct uart_t *u, int send_break) { struct termios ti; int fd, i; @@ -849,8 +813,17 @@ int init_uart(char *dev, struct uart_t *u) return -1; } + /* Set initial baudrate */ + if (set_speed(fd, &ti, u->start_speed) < 0) { + perror("Can't set initial baud rate"); + return -1; + } + tcflush(fd, TCIOFLUSH); + if (send_break) + tcsendbreak(fd, 0); + if (u->init && u->init(fd, u, &ti) < 0) return -1; @@ -881,7 +854,7 @@ static void usage(void) { printf("hciattach - HCI UART driver initialization utility\n"); printf("Usage:\n"); - printf("\thciattach [-n] [-p] [-t timeout] [speed] [flow]\n"); + printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [speed] [flow]\n"); printf("\thciattach -l\n"); } @@ -893,6 +866,8 @@ int main(int argc, char *argv[]) struct uart_t *u = NULL; int detach, printpid, opt, i, n; int to = 5; + int start_speed = 0; + int send_break = 0; pid_t pid; struct sigaction sa; char dev[20]; @@ -900,8 +875,12 @@ int main(int argc, char *argv[]) detach = 1; printpid = 0; - while ((opt=getopt(argc, argv, "npt:l")) != EOF) { + while ((opt=getopt(argc, argv, "bnpt:s:l")) != EOF) { switch(opt) { + case 'b': + send_break = 1; + break; + case 'n': detach = 0; break; @@ -914,6 +893,10 @@ int main(int argc, char *argv[]) to = atoi(optarg); break; + case 's': + start_speed = atoi(optarg); + break; + case 'l': for (i = 0; uart[i].type; i++) { printf("%-10s0x%04x,0x%04x\n", uart[i].type, @@ -980,6 +963,11 @@ int main(int argc, char *argv[]) exit(1); } + /* If user specified a starting speed, use that instead of + the hardware's default */ + if (start_speed) + u->start_speed = start_speed; + memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = sig_alarm; @@ -988,7 +976,7 @@ int main(int argc, char *argv[]) /* 5 seconds should be enough for initialization */ alarm(to); - n = init_uart(dev, u); + n = init_uart(dev, u, send_break); if (n < 0) { perror("Can't initialize device"); exit(1); -- cgit From 1c341784341174627ca3d8a76a4a2ca3bde2713b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 8 Apr 2003 00:12:02 +0000 Subject: start_speed -> init_speed --- tools/hciattach.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 7b8c20a0..54980ded 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -51,7 +51,7 @@ struct uart_t { int m_id; int p_id; int proto; - int start_speed; + int init_speed; int speed; int flags; int (*init) (int fd, struct uart_t *u, struct termios *ti); @@ -577,15 +577,15 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) if (u->speed > 1500000) { fprintf(stderr, "Speed %d too high. Remaining at %d baud\n", - u->speed, u->start_speed); - u->speed = u->start_speed; + u->speed, u->init_speed); + u->speed = u->init_speed; } else if (u->speed != 57600 && uart_speed(u->speed) == B57600) { /* Unknown speed. Why oh why can't we just pass an int to the kernel? */ fprintf(stderr, "Speed %d unrecognised. Remaining at %d baud\n", - u->speed, u->start_speed); - u->speed = u->start_speed; + u->speed, u->init_speed); + u->speed = u->init_speed; } - if (u->speed == u->start_speed) + if (u->speed == u->init_speed) return 0; /* Now, create the command that will set the UART speed */ @@ -814,7 +814,7 @@ int init_uart(char *dev, struct uart_t *u, int send_break) } /* Set initial baudrate */ - if (set_speed(fd, &ti, u->start_speed) < 0) { + if (set_speed(fd, &ti, u->init_speed) < 0) { perror("Can't set initial baud rate"); return -1; } @@ -866,7 +866,7 @@ int main(int argc, char *argv[]) struct uart_t *u = NULL; int detach, printpid, opt, i, n; int to = 5; - int start_speed = 0; + int init_speed = 0; int send_break = 0; pid_t pid; struct sigaction sa; @@ -894,7 +894,7 @@ int main(int argc, char *argv[]) break; case 's': - start_speed = atoi(optarg); + init_speed = atoi(optarg); break; case 'l': @@ -963,10 +963,10 @@ int main(int argc, char *argv[]) exit(1); } - /* If user specified a starting speed, use that instead of + /* If user specified a initial speed, use that instead of the hardware's default */ - if (start_speed) - u->start_speed = start_speed; + if (init_speed) + u->init_speed = init_speed; memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; -- cgit From 723681ffa3035a55fe3a293add7e26da0e7296bd Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 8 Apr 2003 13:34:39 +0000 Subject: use constants; report errors --- tools/hcitool.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 00c84b05..f2ffb891 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -428,7 +428,7 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (cc) { - if (hci_create_connection(dd, &bdaddr, 0x0008 | 0x0010, 0, 0, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, HCI_DM1 | HCI_DH1, 0, 0, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -467,7 +467,7 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (cc) - hci_disconnect(dd, handle, 0x13, 10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); close(dd); } @@ -655,7 +655,8 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000); + if (0 > hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000)) + perror("Can't create connection"); hci_close_dev(dd); } @@ -718,7 +719,8 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - hci_disconnect(dd, cr->conn_info->handle, 0x13, 100); + if (0 > hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100)) + perror("Disconnect failed"); close(dd); free(cr); -- cgit From 424f2b1bb5f34a89adc279c216bdf1f032dffa8d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 8 Apr 2003 14:51:17 +0000 Subject: Cleanup --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index f2ffb891..04d756eb 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -655,7 +655,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (0 > hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000)) + if (hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000) < 0) perror("Can't create connection"); hci_close_dev(dd); } @@ -719,7 +719,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (0 > hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100)) + if (hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100) < 0) perror("Disconnect failed"); close(dd); -- cgit From e9c06d166a352ee2e9b037397f4fb4ba1c8c43f2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 15 Apr 2003 19:20:58 +0000 Subject: Use the bind option in the config file --- rfcomm/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rfcomm/main.c b/rfcomm/main.c index b0df9c72..17cb14b6 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -185,6 +185,9 @@ static int create_all(int ctl) } for (i = 0; i < RFCOMM_MAX_DEV; i++) { + if (!rfcomm_opts[i].bind) + continue; + memset(&req, 0, sizeof(req)); req.dev_id = i; req.flags = 0; -- cgit From 9d6d2bae4f2598f97863568b327e4b57ae8db0bd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 15 Apr 2003 19:30:47 +0000 Subject: Update of the man page --- rfcomm/rfcomm.1 | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/rfcomm/rfcomm.1 b/rfcomm/rfcomm.1 index 0a0f48a0..4085e5ec 100644 --- a/rfcomm/rfcomm.1 +++ b/rfcomm/rfcomm.1 @@ -72,11 +72,25 @@ This command can be terminated with the key sequence CTRL-C. .BI bind " [bdaddr] [channel]" This binds the RFCOMM device to a remote Bluetooth device. The command did not establish a connection to the remote device, it -only creates the binding. The connection will be establish right -after an application tries to open the RFCOMM device. +only creates the binding. The connection will be established right +after an application tries to open the RFCOMM device. If no channel +number is specified, it uses the channel number 1. If the Bluetooth +address is also left out, it tries to read the data from the config +file. + +If +.B all +is specified for the RFCOMM device, then all devices that have +.B "bind yes" +set in the config will be bound. .TP .BI release " " This command releases a defined RFCOMM binding. + +If +.B all +is specified for the RFCOMM device, then all bindings will be removed. +This command didn't care about the settings in the config file. .SH AUTHOR Written by Marcel Holtmann . .br -- cgit From a5a51aaf5fd8de7903e3f14d65452c30eb2f837f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 15 Apr 2003 19:37:48 +0000 Subject: Update of the init scripts --- scripts/bluetooth.rc.deb | 2 +- scripts/bluetooth.rc.rh | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/bluetooth.rc.deb b/scripts/bluetooth.rc.deb index 2480d385..01ae1b56 100755 --- a/scripts/bluetooth.rc.deb +++ b/scripts/bluetooth.rc.deb @@ -51,7 +51,7 @@ case "$1" in echo -n "Stopping $DESC:" if [ -x $RFCOMM ] ; then echo -n " rfcomm" - $RFCOMM unbind all + $RFCOMM release all fi echo -n " sdpd" killall $SDPD > /dev/null 2>&1 || true diff --git a/scripts/bluetooth.rc.rh b/scripts/bluetooth.rc.rh index 95ae4222..c8560946 100755 --- a/scripts/bluetooth.rc.rh +++ b/scripts/bluetooth.rc.rh @@ -38,6 +38,10 @@ start() daemon /usr/sbin/sdpd fi + if [ -x /bin/rfcomm -a -f /etc/bluetooth/rfcomm.conf ]; then + /bin/rfcomm -f /etc/bluetooth/rfcomm.conf bind all + fi + start_uarts touch /var/lock/subsys/bluetooth echo @@ -52,6 +56,10 @@ stop() killproc sdpd fi + if [ -x /bin/rfcomm ]; then + /bin/rfcomm release all + fi + stop_uarts rm -f /var/lock/subsys/bluetooth echo -- cgit From 32966b50fcda0b716027380b0ef67e5ae5eca770 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Apr 2003 15:46:45 +0000 Subject: Define SSIZE_MAX if not defined --- hcid/glib-ectomy.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hcid/glib-ectomy.h b/hcid/glib-ectomy.h index 78cd9d8a..b1ac263b 100644 --- a/hcid/glib-ectomy.h +++ b/hcid/glib-ectomy.h @@ -24,6 +24,11 @@ typedef const void *gconstpointer; typedef size_t gsize; typedef ssize_t gssize; +#ifndef SSIZE_MAX +#define SSIZE_MAX INT_MAX +#endif + + typedef struct _GIOChannel { int fd; } GIOChannel; -- cgit From cf68ecb96dba46e75fd03df9407fc9d8d9b07efb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Apr 2003 21:03:18 +0000 Subject: Allow PIN length from 1 to 16 --- scripts/bluepin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bluepin b/scripts/bluepin index b17f4a03..66eec987 100755 --- a/scripts/bluepin +++ b/scripts/bluepin @@ -148,7 +148,7 @@ def main(*args): if dialog(title, mesg, pin) == DLG_OK: pin["PIN"] = string.strip(pin["PIN"]) - if len(pin["PIN"]) >= 4 and len(pin["PIN"]) <=16: + if len(pin["PIN"]) >= 1 and len(pin["PIN"]) <= 16: print "PIN:" + pin["PIN"] else: print "ERR" -- cgit From 33a6d8d6bc6bf30a37a92ef40353e6426beeb59b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 16 May 2003 07:11:27 +0000 Subject: Add support for sending a number of blocks --- test/l2test.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index f7d487d7..c345d06a 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -71,6 +71,9 @@ long data_size = 672; bdaddr_t bdaddr; unsigned short psm = 10; +/* Default number of blocks to send */ +int num_blocks = -1; // Infinite + int master = 0; int auth = 0; int encrypt = 0; @@ -324,7 +327,7 @@ void send_mode(int s) buf[i]=0x7f; seq = 0; - while (1) { + while ((num_blocks == -1) || (num_blocks-- > 0)) { *(uint32_t *) buf = htobl(seq++); *(uint16_t *)(buf+4) = htobs(data_size); @@ -386,6 +389,7 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" + "\t[-N num] send num blocks (default = infinite)\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" @@ -402,7 +406,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAED")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:MAED")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -477,6 +481,10 @@ int main(int argc ,char *argv[]) socktype = SOCK_DGRAM; break; + case 'N': + num_blocks = atoi(optarg); + break; + default: usage(); exit(1); -- cgit From 79cc4e4e2d74be3f1445203b1fdb844caa1cb009 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Sat, 17 May 2003 00:45:58 +0000 Subject: Add SO_LINGER support. --- test/l2test.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/test/l2test.c b/test/l2test.c index c345d06a..fa8cdf5e 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -78,6 +78,7 @@ int master = 0; int auth = 0; int encrypt = 0; int socktype = SOCK_SEQPACKET; +int linger = 0; float tv2fl(struct timeval tv) { @@ -118,6 +119,16 @@ int do_connect(char *svr) return -1; } + /* Enable SO_LINGER */ + if (linger) { + struct linger l = { .l_onoff = 1, .l_linger = linger }; + if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + strerror(errno), errno); + return -1; + } + } + memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.l2_family = AF_BLUETOOTH; baswap(&rem_addr.l2_bdaddr, strtoba(svr)); @@ -228,6 +239,16 @@ void do_listen( void (*handler)(int sk) ) syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); + /* Enable SO_LINGER */ + if (linger) { + struct linger l = { .l_onoff = 1, .l_linger = linger }; + if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + strerror(errno), errno); + exit(1); + } + } + handler(s1); syslog(LOG_INFO, "Disconnect\n"); @@ -390,6 +411,7 @@ void usage(void) "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" "\t[-N num] send num blocks (default = infinite)\n" + "\t[-L seconds] enable SO_LINGER\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" @@ -406,7 +428,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:MAED")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:MAEDL:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -465,6 +487,10 @@ int main(int argc ,char *argv[]) omtu = atoi(optarg); break; + case 'L': + linger = atoi(optarg); + break; + case 'M': master = 1; break; -- cgit From d68d01e1d2aecd2326cbc7dc0a8ec77ce30a1b02 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 May 2003 14:20:23 +0000 Subject: Display AVM firmware version with 'revision' command --- tools/hciconfig.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index bae20770..87de4b3f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -842,6 +842,11 @@ static void print_rev_csr(uint16_t rev) printf("\tUnknown firmware\n"); } +static void print_rev_avm(uint16_t rev) +{ + printf("\tFirmware 3.%d.%d\n", rev >> 8, rev & 0xff); +} + static void cmd_revision(int ctl, int hdev, char *opt) { struct hci_version ver; @@ -867,6 +872,9 @@ static void cmd_revision(int ctl, int hdev, char *opt) case 10: print_rev_csr(ver.hci_rev); break; + case 31: + print_rev_avm(ver.hci_rev); + break; default: printf("\tUnsupported manufacturer\n"); break; -- cgit From 893ddcab14bb2b5309ba0f181a5a9941a2d28661 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 19 May 2003 21:04:25 +0000 Subject: Call shutdown() before closing the socket and check return value. This is used along with SO_LINGER option to check for errors during cahnel close. Minor cleanups. --- test/l2test.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index fa8cdf5e..a502d7dc 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -71,8 +71,8 @@ long data_size = 672; bdaddr_t bdaddr; unsigned short psm = 10; -/* Default number of blocks to send */ -int num_blocks = -1; // Infinite +/* Default number of frames to send */ +int num_frames = -1; // Infinite int master = 0; int auth = 0; @@ -251,7 +251,7 @@ void do_listen( void (*handler)(int sk) ) handler(s1); - syslog(LOG_INFO, "Disconnect\n"); + syslog(LOG_INFO, "Disconnect. %m\n"); exit(0); } } @@ -342,13 +342,13 @@ void send_mode(int s) uint32_t seq; int i; - syslog(LOG_INFO,"Sending ..."); + syslog(LOG_INFO, "Sending ..."); for(i=6; i < data_size; i++) buf[i]=0x7f; seq = 0; - while ((num_blocks == -1) || (num_blocks-- > 0)) { + while ((num_frames == -1) || (num_frames-- > 0)) { *(uint32_t *) buf = htobl(seq++); *(uint16_t *)(buf+4) = htobs(data_size); @@ -357,6 +357,12 @@ void send_mode(int s) exit(1); } } + + syslog(LOG_INFO, "Closing channel ..."); + if (shutdown(s, SHUT_RDWR) < 0) + syslog(LOG_INFO, "Close failed. %m."); + else + syslog(LOG_INFO, "Done"); } void reconnect_mode(char *svr) @@ -410,7 +416,7 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" - "\t[-N num] send num blocks (default = infinite)\n" + "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" @@ -508,7 +514,7 @@ int main(int argc ,char *argv[]) break; case 'N': - num_blocks = atoi(optarg); + num_frames = atoi(optarg); break; default: -- cgit From 982ff3a573a6c043c48cf64059d92e550ec2d1b6 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 19 May 2003 21:05:27 +0000 Subject: Add support for SO_LINGER option. Call shutdown() before closing socket and check return value. This is used with SO_LINGER to check for errors during DCL disconnection. --- test/rctest.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/test/rctest.c b/test/rctest.c index 2afafaa2..47039555 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -63,6 +63,7 @@ int omtu = 0; /* Default data size */ long data_size = 127; +long num_frames = -1; /* Default addr and channel */ bdaddr_t bdaddr; @@ -72,6 +73,7 @@ int master = 0; int auth = 0; int encrypt = 0; int socktype = SOCK_STREAM; +int linger = 0; float tv2fl(struct timeval tv) { @@ -88,6 +90,16 @@ int do_connect(char *svr) return -1; } + /* Enable SO_LINGER */ + if (linger) { + struct linger l = { .l_onoff = 1, .l_linger = linger }; + if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + strerror(errno), errno); + return -1; + } + } + memset(&loc_addr, 0, sizeof(loc_addr)); loc_addr.rc_family = AF_BLUETOOTH; loc_addr.rc_bdaddr = bdaddr; @@ -173,6 +185,16 @@ void do_listen( void (*handler)(int sk) ) baswap(&ba, &rem_addr.rc_bdaddr); syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); + /* Enable SO_LINGER */ + if (linger) { + struct linger l = { .l_onoff = 1, .l_linger = linger }; + if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + strerror(errno), errno); + exit(1); + } + } + handler(s1); syslog(LOG_INFO, "Disconnect\n"); @@ -256,7 +278,7 @@ void send_mode(int s) buf[i]=0x7f; seq = 0; - while (1) { + while ((num_frames == -1) || (num_frames-- > 0)) { *(uint32_t *) buf = htobl(seq++); *(uint16_t *)(buf+4) = htobs(data_size); @@ -265,6 +287,12 @@ void send_mode(int s) exit(1); } } + + syslog(LOG_INFO, "Closing channel ..."); + if (shutdown(s, SHUT_RDWR) < 0) + syslog(LOG_INFO, "Close failed. %m."); + else + syslog(LOG_INFO, "Done"); } void reconnect_mode(char *svr) @@ -310,6 +338,8 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-S bdaddr] [-P channel]\n" "\t[-I imtu] [-O omtu]\n" + "\t[-L seconds] enabled SO_LINGER option\n" + "\t[-N num] number of frames to send\n" "\t[-E] request encryption\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); @@ -325,7 +355,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAE")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAEL:N:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -396,6 +426,14 @@ int main(int argc ,char *argv[]) encrypt = 1; break; + case 'L': + linger = atoi(optarg); + break; + + case 'N': + num_frames = atoi(optarg); + break; + default: usage(); exit(1); -- cgit From f6557046863c041920180d232c8f0a63bb2faf3c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 May 2003 12:05:10 +0000 Subject: Add LM_RELIABLE option --- test/l2test.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 18 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index a502d7dc..608c84ff 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -79,6 +79,7 @@ int auth = 0; int encrypt = 0; int socktype = SOCK_SEQPACKET; int linger = 0; +int reliable = 0; float tv2fl(struct timeval tv) { @@ -91,7 +92,7 @@ int do_connect(char *svr) struct l2cap_options opts; int s, opt; - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); return -1; } @@ -99,14 +100,14 @@ int do_connect(char *svr) memset(&loc_addr, 0, sizeof(loc_addr)); loc_addr.l2_family = AF_BLUETOOTH; loc_addr.l2_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); } /* Get default options */ opt = sizeof(opts); - if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); return -1; } @@ -114,7 +115,7 @@ int do_connect(char *svr) /* Set new options */ opts.omtu = omtu; opts.imtu = imtu; - if( setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0 ) { + if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); return -1; } @@ -129,18 +130,28 @@ int do_connect(char *svr) } } + /* Set link mode */ + opt = 0; + if (reliable) + opt |= L2CAP_LM_RELIABLE; + + if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + exit(1); + } + memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.l2_family = AF_BLUETOOTH; baswap(&rem_addr.l2_bdaddr, strtoba(svr)); rem_addr.l2_psm = htobs(psm); - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + if (connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ) { syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); close(s); return -1; } opt = sizeof(opts); - if( getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ){ + if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); close(s); return -1; @@ -159,7 +170,7 @@ void do_listen( void (*handler)(int sk) ) int s, s1, opt; bdaddr_t ba; - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -167,13 +178,16 @@ void do_listen( void (*handler)(int sk) ) loc_addr.l2_family = AF_BLUETOOTH; loc_addr.l2_bdaddr = bdaddr; loc_addr.l2_psm = htobs(psm); - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); } /* Set link mode */ opt = 0; + if (reliable) + opt |= L2CAP_LM_RELIABLE; + if (master) opt |= L2CAP_LM_MASTER; @@ -207,7 +221,7 @@ void do_listen( void (*handler)(int sk) ) return; } - if( listen(s, 10) ) { + if (listen(s, 10)) { syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -216,7 +230,7 @@ void do_listen( void (*handler)(int sk) ) while(1) { opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + if ((s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0) { syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); exit(1); } @@ -230,7 +244,7 @@ void do_listen( void (*handler)(int sk) ) close(s); opt = sizeof(opts); - if( getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0 ) { + if (getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); exit(1); } @@ -259,6 +273,7 @@ void do_listen( void (*handler)(int sk) ) void dump_mode(int s) { int len; + int opt, optl; syslog(LOG_INFO, "Receiving ..."); while (1) { @@ -274,8 +289,23 @@ void dump_mode(int s) continue; len = read(s, buf, data_size); - if (len <= 0) + if (len <= 0) { + if (len < 0) { + if (reliable && (errno == ECOMM)) { + syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); + optl = sizeof(opt); + if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", + strerror(errno), errno); + return; + } + continue; + } else { + syslog(LOG_ERR, "Read error: %s(%d)\n", strerror(errno), errno); + } + } return; + } syslog(LOG_INFO, "Recevied %d bytes\n", len); } @@ -286,6 +316,7 @@ void recv_mode(int s) struct timeval tv_beg,tv_end,tv_diff; long total; uint32_t seq; + int opt, optl; syslog(LOG_INFO,"Receiving ..."); @@ -299,10 +330,22 @@ void recv_mode(int s) int i,r; if ((r = recv(s, buf, data_size, 0)) <= 0) { - if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); - return; + if (r < 0) { + if (reliable && (errno == ECOMM)) { + syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); + optl = sizeof(opt); + if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", + strerror(errno), errno); + return; + } + continue; + } else { + syslog(LOG_ERR, "Read failed. %s(%d)", + strerror(errno), errno); + } + } + return; } /* Check sequence */ @@ -385,7 +428,7 @@ void multi_connect_mode(char *svr) { while (1) { int i, s; - for (i=0; i<10; i++) { + for (i = 0; i < 10; i++) { if (fork()) continue; /* Child */ @@ -418,6 +461,7 @@ void usage(void) "\t[-I imtu] [-O omtu]\n" "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" + "\t[-R] reliable mode\n" "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" @@ -434,7 +478,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:MAEDL:")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:RMAEDL:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -497,6 +541,10 @@ int main(int argc ,char *argv[]) linger = atoi(optarg); break; + case 'R': + reliable = 1; + break; + case 'M': master = 1; break; -- cgit From 0ce9154a53a990998d0030a78e544ef8e8285352 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 May 2003 16:41:48 +0000 Subject: Support for TDK, IBM and Socket cards --- tools/hciattach.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 54980ded..05230d3c 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -758,7 +758,13 @@ struct uart_t uart[] = { /* COM One Platinium Bluetooth PC Card */ { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, - { NULL, 0 } + /* TDK Bluetooth PC Card and IBM Bluetooth PC Card II */ + { "tdk", 0x0105, 0x4254, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + + /* Socket Bluetooth CF Card (Rev G) */ + { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, bcsp }, + + { NULL, 0 } }; struct uart_t * get_by_id(int m_id, int p_id) -- cgit From 1f882b1b0f5c381c63c34c8558e13068868198b6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 May 2003 21:27:00 +0000 Subject: Add new modes that can dump the incoming data --- test/l2test.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 131 insertions(+), 7 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index 608c84ff..d02eb3c0 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -29,12 +29,12 @@ #include #include #include -#include -#include #include #include #include +#include #include +#include #include #include @@ -46,6 +46,8 @@ #include #include +#define NIBBLE_TO_ASCII(c) ((c) < 0x0a ? (c) + 0x30 : (c) + 0x57) + /* Test modes */ enum { SEND, @@ -55,7 +57,9 @@ enum { DUMP, CONNECT, CRECV, - LSEND + LSEND, + SENDDUMP, + LSENDDUMP }; unsigned char *buf; @@ -86,6 +90,78 @@ float tv2fl(struct timeval tv) return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); } +char *ltoh(unsigned long c, char* s) +{ + int c1; + + c1 = (c >> 28) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 24) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 20) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 16) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 12) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 8) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = (c >> 4) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = c & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + *s = 0; + return (s); +} + +char *ctoh(char c, char* s) +{ + char c1; + + c1 = (c >> 4) & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + c1 = c & 0x0f; + *(s++) = NIBBLE_TO_ASCII (c1); + *s = 0; + return (s); +} + +void hexdump(char *s, unsigned long l) +{ + char bfr[80]; + char *pb; + unsigned long i, n = 0; + + if (l == 0) + return; + + while (n < l) { + pb = bfr; + pb = ltoh (n, pb); + *(pb++) = ':'; + *(pb++) = ' '; + for (i = 0; i < 16; i++) { + if (n + i >= l) { + *(pb++) = ' '; + *(pb++) = ' '; + } else + pb = ctoh (*(s + i), pb); + *(pb++) = ' '; + } + *(pb++) = ' '; + for (i = 0; i < 16; i++) { + if (n + i >= l) + break; + else + *(pb++) = (isprint (*(s + i)) ? *(s + i) : '.'); + } + *pb = 0; + n += 16; + s += 16; + puts(bfr); + } +} + int do_connect(char *svr) { struct sockaddr_l2 rem_addr, loc_addr; @@ -163,7 +239,7 @@ int do_connect(char *svr) return s; } -void do_listen( void (*handler)(int sk) ) +void do_listen(void (*handler)(int sk)) { struct sockaddr_l2 loc_addr, rem_addr; struct l2cap_options opts; @@ -308,6 +384,7 @@ void dump_mode(int s) } syslog(LOG_INFO, "Recevied %d bytes\n", len); + hexdump(buf,len); } } @@ -387,8 +464,8 @@ void send_mode(int s) syslog(LOG_INFO, "Sending ..."); - for(i=6; i < data_size; i++) - buf[i]=0x7f; + for(i = 6; i < data_size; i++) + buf[i] = 0x7f; seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { @@ -408,6 +485,31 @@ void send_mode(int s) syslog(LOG_INFO, "Done"); } +void senddump_mode(int s) +{ + uint32_t seq; + int i; + + syslog(LOG_INFO, "Sending ..."); + + for(i = 6; i < data_size; i++) + buf[i] = 0x7f; + + seq = 0; + while ((num_frames == -1) || (num_frames-- > 0)) { + *(uint32_t *) buf = htobl(seq++); + *(uint16_t *)(buf+4) = htobs(data_size); + + if (send(s, buf, data_size, 0) <= 0) { + syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + exit(1); + } + } + + dump_mode(s); + +} + void reconnect_mode(char *svr) { while(1) { @@ -450,9 +552,11 @@ void usage(void) "\t-r listen and receive\n" "\t-w listen and send\n" "\t-d listen and dump incoming data\n" + "\t-x listen, then send, then dump incoming data\n" "\t-s connect and send\n" "\t-u connect and receive\n" "\t-n connect and be silent\n" + "\t-y connect, then send, then dump incoming data\n" "\t-c connect, disconnect, connect, ...\n" "\t-m multiple connects\n"); @@ -478,7 +582,7 @@ int main(int argc ,char *argv[]) mode = RECV; need_addr = 0; - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:N:RMAEDL:")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyb:P:I:O:S:N:RMAEDL:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -521,6 +625,14 @@ int main(int argc ,char *argv[]) data_size = atoi(optarg); break; + case 'x': + mode = LSENDDUMP; + break; + + case 'y': + mode = SENDDUMP; + break; + case 'S': baswap(&bdaddr, strtoba(optarg)); break; @@ -626,6 +738,18 @@ int main(int argc ,char *argv[]) case CONNECT: connect_mode(argv[optind]); break; + + case SENDDUMP: + s = do_connect(argv[optind]); + if (s < 0) + exit(1); + senddump_mode(s); + break; + + case LSENDDUMP: + do_listen(senddump_mode); + break; + } syslog(LOG_INFO, "Exit"); -- cgit From 1181a51f587089189aeb8df20567ed45f350d88e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Jun 2003 16:42:44 +0000 Subject: Typo --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 87de4b3f..538e03bc 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -844,7 +844,7 @@ static void print_rev_csr(uint16_t rev) static void print_rev_avm(uint16_t rev) { - printf("\tFirmware 3.%d.%d\n", rev >> 8, rev & 0xff); + printf("\tFirmware 03.%d.%d\n", rev >> 8, rev & 0xff); } static void cmd_revision(int ctl, int hdev, char *opt) -- cgit From e7490562668965f3433aa4270b88ce55bfa9e1e3 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 18 Jun 2003 09:52:01 +0000 Subject: ... --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 04d756eb..a8f79f6d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -282,7 +282,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (dev_id < 0) { dev_id = hci_get_route(&bdaddr); if (dev_id < 0) { - perror("Device is not available."); + perror("Device is not available"); exit(1); } } @@ -290,7 +290,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("Scanning ...\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { - perror("Inquiry failed."); + perror("Inquiry failed"); exit(1); } -- cgit From 26d5498a00afec5ed676ef84ce1e7b94557ff46c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jun 2003 11:56:55 +0000 Subject: Add command for reading transmit power level --- tools/hcitool.1 | 9 +++ tools/hcitool.c | 170 +++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 139 insertions(+), 40 deletions(-) diff --git a/tools/hcitool.1 b/tools/hcitool.1 index fa51efce..dd92e351 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -130,6 +130,15 @@ with Bluetooth address Display link quality for the connection to the device with Bluetooth address .IR bdaddr . .TP +.BI tpl " [type]" +Display transmit power level for the connection to the device with Bluetooth address +.IR bdaddr . +The type can be +.BR 0 +for the current transmit power level (which is default) or +.BR 1 +for the maximum transmit power level. +.TP .BI lst " [value]" With no .IR value , diff --git a/tools/hcitool.c b/tools/hcitool.c index a8f79f6d..88c53266 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -37,9 +37,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -786,7 +786,7 @@ static void cmd_sr(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_POLICY; rq.ocf = OCF_SWITCH_ROLE; rq.cparam = &cp; @@ -869,7 +869,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; rq.cparam = &cr->conn_info->handle; @@ -886,24 +886,24 @@ static void cmd_rssi(int dev_id, int argc, char **argv) printf("Read RSSI returned (error) status 0x%2.2X\n", rp.status); exit(1); } - printf("\tRSSI return value: %d\n", rp.rssi); + printf("RSSI return value: %d\n", rp.rssi); close(dd); free(cr); } -/* Get Link Quality */ +/* Get link quality */ -static struct option link_quality_options[] = { +static struct option lq_options[] = { {"help", 0,0, 'h'}, {0, 0, 0, 0} }; -static char *link_quality_help = +static char *lq_help = "Usage:\n" "\tlq \n"; -static void cmd_link_quality(int dev_id, int argc, char **argv) +static void cmd_lq(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; struct hci_request rq; @@ -911,10 +911,10 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) bdaddr_t bdaddr; int opt, dd; - for_each_opt(opt, link_quality_options, NULL) { + for_each_opt(opt, lq_options, NULL) { switch(opt) { default: - printf(link_quality_help); + printf(lq_help); return; } } @@ -922,7 +922,7 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) argv += optind; if (argc < 1) { - printf(link_quality_help); + printf(lq_help); return; } @@ -953,13 +953,13 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_GET_LINK_QUALITY; + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_GET_LINK_QUALITY; rq.cparam = &cr->conn_info->handle; - rq.clen = 2; + rq.clen = 2; rq.rparam = &rp; - rq.rlen = GET_LINK_QUALITY_RP_SIZE; + rq.rlen = GET_LINK_QUALITY_RP_SIZE; if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI get_link_quality request failed"); @@ -977,6 +977,95 @@ static void cmd_link_quality(int dev_id, int argc, char **argv) free(cr); } +/* Get transmit power level */ + +static struct option tpl_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *tpl_help = + "Usage:\n" + "\ttpl [type]\n"; + +static void cmd_tpl(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_transmit_power_level_cp cp; + read_transmit_power_level_rp rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, tpl_options, NULL) { + switch(opt) { + default: + printf(tpl_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(tpl_help); + return; + } + + str2ba(argv[0], &bdaddr); + cp.type = (argc > 1) ? atoi(argv[1]) : 0; + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + cp.handle = cr->conn_info->handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; + rq.rparam = &rp; + rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read transmit power level request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_transmit_power_level cmd failed (0x%2.2X)\n", + rp.status); + exit(1); + } + printf("%s transmit power level: %d\n", + (cp.type == 0) ? "Current" : "Maximum", rp.level); + + close(dd); + free(cr); +} + /* Set connection packet type */ static struct option cpt_options[] = { @@ -1043,7 +1132,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) cp.handle = cr->conn_info->handle; cp.pkt_type = ptype; - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_SET_CONN_PTYPE; rq.cparam = &cp; @@ -1061,18 +1150,18 @@ static void cmd_cpt(int dev_id, int argc, char **argv) free(cr); } -/* Get/Set Link Supervision Timeout */ +/* Get/Set link supervision timeout */ -static struct option link_supervision_options[] = { +static struct option lst_options[] = { {"help", 0,0, 'h'}, {0, 0, 0, 0} }; -static char *link_supervision_help = +static char *lst_help = "Usage:\n" "\tlst [new value in slots]\n"; -static void cmd_link_sup_to(int dev_id, int argc, char **argv) +static void cmd_lst(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; struct hci_request rq; @@ -1081,10 +1170,10 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) bdaddr_t bdaddr; int opt, dd; - for_each_opt(opt, link_supervision_options, NULL) { + for_each_opt(opt, lst_options, NULL) { switch(opt) { default: - printf(link_supervision_help); + printf(lst_help); return; } } @@ -1092,7 +1181,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) argv += optind; if (argc < 1) { - printf(link_supervision_help); + printf(lst_help); return; } @@ -1124,7 +1213,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) } if (argc == 1) { - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cr->conn_info->handle; @@ -1152,7 +1241,7 @@ static void cmd_link_sup_to(int dev_id, int argc, char **argv) cp.handle = cr->conn_info->handle; cp.link_sup_to = strtol(argv[1], NULL, 10); - memset(&rq, 0, sizeof(rq)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cp; @@ -1173,20 +1262,21 @@ struct { void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { - { "dev", cmd_dev, "Display local devices" }, - { "inq", cmd_inq, "Inquire remote devices" }, - { "scan", cmd_scan, "Scan for remote devices" }, - { "name", cmd_name, "Get name from remote device" }, - { "info", cmd_info, "Get information from remote device" }, - { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, - { "con", cmd_con, "Display active connections" }, - { "cc", cmd_cc, "Create connection to remote device" }, - { "dc", cmd_dc, "Disconnect from remote device" }, - { "sr", cmd_sr, "Switch master/slave role" }, - { "cpt", cmd_cpt, "Change connection packet type" }, - { "rssi", cmd_rssi, "Display connection RSSI" }, - { "lq", cmd_link_quality, "Display link quality" }, - { "lst", cmd_link_sup_to, "Set/display link supervision timeout" }, + { "dev", cmd_dev, "Display local devices" }, + { "inq", cmd_inq, "Inquire remote devices" }, + { "scan", cmd_scan, "Scan for remote devices" }, + { "name", cmd_name, "Get name from remote device" }, + { "info", cmd_info, "Get information from remote device" }, + { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, + { "con", cmd_con, "Display active connections" }, + { "cc", cmd_cc, "Create connection to remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, + { "sr", cmd_sr, "Switch master/slave role" }, + { "cpt", cmd_cpt, "Change connection packet type" }, + { "rssi", cmd_rssi, "Display connection RSSI" }, + { "lq", cmd_lq, "Display link quality" }, + { "tpl", cmd_tpl, "Display transmit power level" }, + { "lst", cmd_lst, "Set/display link supervision timeout" }, { NULL, NULL, 0} }; -- cgit From 529a4a6e9be63df61d41a82787adae204822a6e7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 27 Jun 2003 10:49:13 +0000 Subject: Support for reading transmit power level --- tools/hcisecfilter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 13dee183..2ff5c48a 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -63,6 +63,7 @@ int main(void) hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); + hci_set_bit(OCF_READ_TRANSMIT_POWER_LEVEL, ocf_mask); printf("OGF_HOST_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); -- cgit From 49ceef7a27ee6112148f5ef5fe37f1ee6f1f44ea Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 2 Jul 2003 22:27:41 +0000 Subject: New code for CSR specific revision information --- tools/Makefile.am | 2 + tools/csr.c | 347 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 35 ++++++ tools/hciconfig.c | 126 +++++++++----------- 4 files changed, 442 insertions(+), 68 deletions(-) create mode 100644 tools/csr.c create mode 100644 tools/csr.h diff --git a/tools/Makefile.am b/tools/Makefile.am index 0513c83b..180c0cc1 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -7,6 +7,8 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping +hciconfig_SOURCES = hciconfig.c csr.h csr.c + man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 noinst_PROGRAMS = ppporc diff --git a/tools/csr.c b/tools/csr.c new file mode 100644 index 00000000..e2069cd7 --- /dev/null +++ b/tools/csr.c @@ -0,0 +1,347 @@ +/* + * + * CSR BlueCore specific functions + * + * Copyright (C) 2003 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "csr.h" + + +static struct { + uint16_t id; + char *str; +} csr_map[] = { + { 111, "HCI 11.0" }, + { 112, "HCI 11.1" }, + { 114, "HCI 11.2" }, + { 115, "HCI 11.3" }, + { 117, "HCI 12.0" }, + { 119, "HCI 12.1" }, + { 133, "HCI 12.2" }, + { 134, "HCI 12.3" }, + { 162, "HCI 12.4" }, + { 165, "HCI 12.5" }, + { 169, "HCI 12.6" }, + { 188, "HCI 12.7" }, + { 218, "HCI 12.8" }, + { 283, "HCI 12.9" }, + { 203, "HCI 13.2" }, + { 204, "HCI 13.2" }, + { 210, "HCI 13.3" }, + { 211, "HCI 13.3" }, + { 213, "HCI 13.4" }, + { 214, "HCI 13.4" }, + { 225, "HCI 13.5" }, + { 226, "HCI 13.5" }, + { 237, "HCI 13.6" }, + { 238, "HCI 13.6" }, + { 242, "HCI 14.0" }, + { 243, "HCI 14.0" }, + { 244, "HCI 14.0" }, + { 245, "HCI 14.0" }, + { 254, "HCI 13.7" }, + { 255, "HCI 13.7" }, + { 264, "HCI 14.1" }, + { 265, "HCI 14.1" }, + { 267, "HCI 14.2" }, + { 268, "HCI 14.2" }, + { 272, "HCI 14.3" }, + { 273, "HCI 14.3" }, + { 274, "HCI 13.8" }, + { 275, "HCI 13.8" }, + { 286, "HCI 13.9" }, + { 287, "HCI 13.9" }, + { 309, "HCI 13.10" }, + { 310, "HCI 13.10" }, + { 313, "HCI 14.4" }, + { 314, "HCI 14.4" }, + { 323, "HCI 14.5" }, + { 324, "HCI 14.5" }, + { 336, "HCI 14.6" }, + { 337, "HCI 14.6" }, + { 351, "HCI 13.11" }, + { 352, "HCI 13.11" }, + { 362, "HCI 15.0" }, + { 363, "HCI 15.0" }, + { 364, "HCI 15.0" }, + { 365, "HCI 15.0" }, + { 373, "HCI 14.7" }, + { 374, "HCI 14.7" }, + { 379, "HCI 15.1" }, + { 380, "HCI 15.1" }, + { 381, "HCI 15.1" }, + { 382, "HCI 15.1" }, + { 392, "HCI 15.2" }, + { 393, "HCI 15.2" }, + { 394, "HCI 15.2" }, + { 395, "HCI 15.2" }, + { 436, "HCI 16.0" }, + { 437, "HCI 16.0" }, + { 438, "HCI 16.0" }, + { 439, "HCI 16.0" }, + { 443, "HCI 15.3" }, + { 444, "HCI 15.3" }, + { 465, "HCI 16.1" }, + { 466, "HCI 16.1" }, + { 467, "HCI 16.1" }, + { 468, "HCI 16.1" }, + { 487, "HCI 14.8" }, + { 488, "HCI 14.8" }, + { 492, "HCI 16.2" }, + { 493, "HCI 16.2" }, + { 495, "HCI 16.2" }, + { 496, "HCI 16.2" }, + { 502, "HCI 16.1.1" }, + { 503, "HCI 16.1.1" }, + { 504, "HCI 16.1.1" }, + { 505, "HCI 16.1.1" }, + { 506, "HCI 16.1.2" }, + { 507, "HCI 16.1.2" }, + { 508, "HCI 16.1.2" }, + { 509, "HCI 16.1.2" }, + { 516, "HCI 16.3" }, + { 517, "HCI 16.3" }, + { 518, "HCI 16.3" }, + { 519, "HCI 16.3" }, + { 523, "HCI 16.4" }, + { 524, "HCI 16.4" }, + { 525, "HCI 16.4" }, + { 526, "HCI 16.4" }, + { 553, "HCI 15.3" }, + { 554, "HCI 15.3" }, + { 562, "HCI 16.5" }, + { 563, "HCI 16.5" }, + { 564, "HCI 16.5" }, + { 565, "HCI 16.5" }, + { 593, "HCI 17.0" }, + { 594, "HCI 17.0" }, + { 595, "HCI 17.0" }, + { 599, "HCI 17.0" }, + { 600, "HCI 17.0" }, + { 608, "HCI 13.10.1" }, + { 609, "HCI 13.10.1" }, + { 613, "HCI 17.1" }, + { 614, "HCI 17.1" }, + { 615, "HCI 17.1" }, + { 616, "HCI 17.1" }, + { 618, "HCI 17.1" }, + { 624, "HCI 17.2" }, + { 625, "HCI 17.2" }, + { 626, "HCI 17.2" }, + { 627, "HCI 17.2" }, + { 637, "HCI 16.6" }, + { 638, "HCI 16.6" }, + { 639, "HCI 16.6" }, + { 640, "HCI 16.6" }, + { 642, "HCI 13.10.2" }, + { 643, "HCI 13.10.2" }, + { 644, "HCI 13.10.3" }, + { 645, "HCI 13.10.3" }, + { 668, "HCI 13.10.4" }, + { 669, "HCI 13.10.4" }, + { 681, "HCI 16.7" }, + { 682, "HCI 16.7" }, + { 683, "HCI 16.7" }, + { 684, "HCI 16.7" }, + { 704, "HCI 16.8" }, + { 718, "HCI 16.4.1" }, + { 719, "HCI 16.4.1" }, + { 720, "HCI 16.4.1" }, + { 721, "HCI 16.4.1" }, + { 722, "HCI 16.7.1" }, + { 723, "HCI 16.7.1" }, + { 724, "HCI 16.7.1" }, + { 725, "HCI 16.7.1" }, + { 731, "HCI 16.7.2" }, + { 732, "HCI 16.7.2" }, + { 733, "HCI 16.7.2" }, + { 734, "HCI 16.7.2" }, + { 735, "HCI 16.4.2" }, + { 736, "HCI 16.4.2" }, + { 737, "HCI 16.4.2" }, + { 738, "HCI 16.4.2" }, + { 750, "HCI 16.7.3" }, + { 751, "HCI 16.7.3" }, + { 752, "HCI 16.7.3" }, + { 753, "HCI 16.7.3" }, + { 760, "HCI 16.7.4" }, + { 761, "HCI 16.7.4" }, + { 762, "HCI 16.7.4" }, + { 763, "HCI 16.7.4" }, + { 770, "HCI 16.9" }, + { 771, "HCI 16.9" }, + { 772, "HCI 16.9" }, + { 773, "HCI 16.9" }, + { 774, "HCI 17.3" }, + { 775, "HCI 17.3" }, + { 776, "HCI 17.3" }, + { 777, "HCI 17.3" }, + { 781, "HCI 16.7.5" }, + { 786, "HCI 16.10" }, + { 787, "HCI 16.10" }, + { 788, "HCI 16.10" }, + { 789, "HCI 16.10" }, + { 791, "HCI 16.4.3" }, + { 792, "HCI 16.4.3" }, + { 793, "HCI 16.4.3" }, + { 794, "HCI 16.4.3" }, + { 798, "HCI 16.11" }, + { 799, "HCI 16.11" }, + { 800, "HCI 16.11" }, + { 801, "HCI 16.11" }, + { 806, "HCI 16.7.5" }, + { 807, "HCI 16.12" }, + { 808, "HCI 16.12" }, + { 809, "HCI 16.12" }, + { 810, "HCI 16.12" }, + { 817, "HCI 16.13" }, + { 818, "HCI 16.13" }, + { 819, "HCI 16.13" }, + { 820, "HCI 16.13" }, + { 823, "HCI 13.10.5" }, + { 824, "HCI 13.10.5" }, + { 826, "HCI 16.14" }, + { 827, "HCI 16.14" }, + { 828, "HCI 16.14" }, + { 829, "HCI 16.14" }, + { 843, "HCI 17.3.1" }, + { 856, "HCI 17.3.2" }, + { 857, "HCI 17.3.2" }, + { 858, "HCI 17.3.2" }, + { 0, } +}; + +char *csr_buildidtostr(uint16_t id) +{ + static char str[12]; + int i; + + for (i = 0; csr_map[i].id; i++) + if (csr_map[i].id == id) + return csr_map[i].str; + + snprintf(str, 11, "Build %d", id); + return str; +} + +char *csr_chipvertostr(uint16_t ver, uint16_t rev) +{ + switch (ver) { + case 0x00: + return "BlueCore01a"; + case 0x01: + if (rev == 0x64) + return "BlueCore01b (ES)"; + else + return "BlueCore01b"; + case 0x02: + if (rev == 0x89) + return "BlueCore02 (ES2)"; + else + return "BlueCore02"; + default: + return "Unknown"; + } +} + +int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value) +{ + unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) + return -1; + + *value = rp[11] + (rp[12] << 8); + + return 0; +} + +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value) +{ + unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, + pskey & 0xff, pskey >> 8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) + return -1; + + *value = rp[17] + (rp[18] << 8); + + return 0; +} diff --git a/tools/csr.h b/tools/csr.h new file mode 100644 index 00000000..254f108e --- /dev/null +++ b/tools/csr.h @@ -0,0 +1,35 @@ +/* + * + * CSR BlueCore specific functions + * + * Copyright (C) 2003 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define CSR_VARID_BUILDID 0x2819 +#define CSR_VARID_CHIPVER 0x281a +#define CSR_VARID_CHIPREV 0x281b +#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c + +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab + +char *csr_buildidtostr(uint16_t id); +char *csr_chipvertostr(uint16_t ver, uint16_t rev); + +int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 538e03bc..aa3d9ab4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -43,6 +43,8 @@ #include #include +#include "csr.h" + extern int optind,opterr,optopt; extern char *optarg; @@ -268,7 +270,7 @@ void cmd_aclmtu(int ctl, int hdev, char *opt) *((uint16_t *)&dr.dev_opt + 1) = mtu; *((uint16_t *)&dr.dev_opt + 0) = mpkt; - + if (ioctl(ctl, HCISETACLMTU, (unsigned long)&dr) < 0) { printf("Can't set ACL mtu on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -608,21 +610,21 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) printf("Invalid argument format\n"); exit(1); } - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_INQ_ACTIVITY; rq.cparam = &cp; rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE; - + cp.window = htobs((uint16_t)window); cp.interval = htobs((uint16_t)interval); - + if (window < 0x12 || window > 0x1000) printf("Warning: inquiry window out of range!\n"); - + if (interval < 0x12 || interval > 0x1000) printf("Warning: inquiry interval out of range!\n"); - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't set inquiry parameters name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -631,12 +633,12 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) } else { uint16_t window, interval; read_inq_activity_rp rp; - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_INQ_ACTIVITY; rq.rparam = &rp; rq.rlen = READ_INQ_ACTIVITY_RP_SIZE; - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't read inquiry parameters on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -648,7 +650,7 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) exit(1); } print_dev_hdr(&di); - + window = btohs(rp.window); interval = btohs(rp.interval); printf("\tInquiry interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", @@ -675,21 +677,21 @@ void cmd_page_parms(int ctl, int hdev, char *opt) printf("Invalid argument format\n"); exit(1); } - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_PAGE_ACTIVITY; rq.cparam = &cp; rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE; - + cp.window = htobs((uint16_t)window); cp.interval = htobs((uint16_t)interval); - + if (window < 0x12 || window > 0x1000) printf("Warning: page window out of range!\n"); - + if (interval < 0x12 || interval > 0x1000) printf("Warning: page interval out of range!\n"); - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't set page parameters name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -698,12 +700,12 @@ void cmd_page_parms(int ctl, int hdev, char *opt) } else { uint16_t window, interval; read_page_activity_rp rp; - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_PAGE_ACTIVITY; rq.rparam = &rp; rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE; - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't read page parameters on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -715,12 +717,12 @@ void cmd_page_parms(int ctl, int hdev, char *opt) exit(1); } print_dev_hdr(&di); - + window = btohs(rp.window); interval = btohs(rp.interval); printf("\tPage interval: %u slots (%.2f ms), window: %u slots (%.2f ms)\n", interval, (float)interval * 0.625, window, (float)window * 0.625); - } + } } void cmd_page_to(int ctl, int hdev, char *opt) @@ -742,17 +744,17 @@ void cmd_page_to(int ctl, int hdev, char *opt) printf("Invalid argument format\n"); exit(1); } - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_PAGE_TIMEOUT; rq.cparam = &cp; rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE; - + cp.timeout = htobs((uint16_t)timeout); - + if (timeout < 0x01 || timeout > 0xFFFF) printf("Warning: page timeout out of range!\n"); - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't set page timeout on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -761,12 +763,12 @@ void cmd_page_to(int ctl, int hdev, char *opt) } else { uint16_t timeout; read_page_timeout_rp rp; - + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_PAGE_TIMEOUT; rq.rparam = &rp; rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE; - + if (hci_send_req(s, &rq, 1000) < 0) { printf("Can't read page timeout on hci%d. %s(%d)\n", hdev, strerror(errno), errno); @@ -782,7 +784,7 @@ void cmd_page_to(int ctl, int hdev, char *opt) timeout = btohs(rp.timeout); printf("\tPage timeout: %u slots (%.2f ms)\n", timeout, (float)timeout * 0.625); - } + } } static void print_rev_ericsson(int dd) @@ -791,12 +793,12 @@ static void print_rev_ericsson(int dd) unsigned char buf[102]; memset(&rq, 0, sizeof(rq)); - rq.ogf = 0x3f; - rq.ocf = 0x000f; + rq.ogf = 0x3f; + rq.ocf = 0x000f; rq.cparam = NULL; - rq.clen = 0; + rq.clen = 0; rq.rparam = &buf; - rq.rlen = sizeof(buf); + rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 1000) < 0) { printf("\n Can't read revision info. %s(%d)\n", strerror(errno), errno); @@ -806,40 +808,28 @@ static void print_rev_ericsson(int dd) printf("\t%s\n", buf + 1); } -static struct { - char *str; - uint16_t rev; -} csr_map[] = { - { "HCI 11.2 (bc01b)", 114 }, - { "HCI 11.3 (bc01b)", 115 }, - { "HCI 12.1 (bc01b)", 119 }, - { "HCI 12.3 (bc01b)", 134 }, - { "HCI 12.7 (bc01b)", 188 }, - { "HCI 12.8 (bc01b)", 218 }, - { "HCI 12.9 (bc01b)", 283 }, - { "HCI 13.10 (bc01b)", 309 }, - { "HCI 13.11 (bc01b)", 351 }, - { "HCI 16.4 (bc01b)", 523 }, - { "HCI 14.3 (bc02x)", 272 }, - { "HCI 14.6 (bc02x)", 336 }, - { "HCI 14.7 (bc02x)", 373 }, - { "HCI 14.8 (bc02x)", 487 }, - { "HCI 15.3 (bc02x)", 443 }, - { "HCI 16.4 (bc02x)", 525 }, - { NULL } -}; - -static void print_rev_csr(uint16_t rev) +static void print_rev_csr(int dd, uint16_t rev) { - int i; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco; - for (i = 0; csr_map[i].str; i++) - if (csr_map[i].rev == rev) { - printf("\t%s\n", csr_map[i].str); - return; - } + if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { + printf("\t%s\n", csr_buildidtostr(rev)); + return; + } + + printf("\t%s\n", csr_buildidtostr(buildid)); + + if (!csr_read_varid_uint16(dd, 1, CSR_VARID_CHIPVER, &chipver)) { + if (csr_read_varid_uint16(dd, 2, CSR_VARID_CHIPREV, &chiprev) < 0) + chiprev = 0; + printf("\tChip version: %s\n", csr_chipvertostr(chipver, chiprev)); + } + + if (!csr_read_varid_uint16(dd, 3, CSR_VARID_MAX_CRYPT_KEY_LENGTH, &maxkeylen)) + printf("\tMax key size: %d bit\n", maxkeylen * 8); - printf("\tUnknown firmware\n"); + if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) + printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); } static void print_rev_avm(uint16_t rev) @@ -870,7 +860,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) print_rev_ericsson(dd); break; case 10: - print_rev_csr(ver.hci_rev); + print_rev_csr(dd, ver.hci_rev); break; case 31: print_rev_avm(ver.hci_rev); @@ -890,13 +880,13 @@ void print_dev_hdr(struct hci_dev_info *di) if (hdr == di->dev_id) return; hdr = di->dev_id; - + baswap(&bdaddr, &di->bdaddr); printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", - batostr(&bdaddr), di->acl_mtu, di->acl_pkts, - di->sco_mtu, di->sco_pkts); + batostr(&bdaddr), di->acl_mtu, di->acl_pkts, + di->sco_mtu, di->sco_pkts); } void print_dev_info(int ctl, struct hci_dev_info *di) @@ -908,10 +898,10 @@ void print_dev_info(int ctl, struct hci_dev_info *di) printf("\t%s\n", hci_dflagstostr(di->flags) ); printf("\tRX bytes:%d acl:%d sco:%d events:%d errors:%d\n", - st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx); + st->byte_rx, st->acl_rx, st->sco_rx, st->evt_rx, st->err_rx); printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n", - st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); + st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); if (all) { print_dev_features(di, 0); @@ -925,7 +915,7 @@ void print_dev_info(int ctl, struct hci_dev_info *di) cmd_version(ctl, di->dev_id, NULL); } } - + printf("\n"); } @@ -1033,7 +1023,7 @@ int main(int argc, char **argv, char **env) if (command[i].opt) { argc--; argv++; } - + command[i].func(ctl, di.dev_id, *argv); cmd = 1; break; -- cgit From 7c4dcfec6261dea71c93c27a8f09e34e2837dc2c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 3 Jul 2003 15:45:21 +0000 Subject: Display addresses in correct order --- hcid/security.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/hcid/security.c b/hcid/security.c index 0380d31f..36fb6a71 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -107,9 +107,10 @@ static struct link_key *get_link_key(bdaddr_t *sba, bdaddr_t *dba) static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) { struct link_key *key = get_link_key(sba, dba); + char sa[18], da[18]; - syslog(LOG_INFO, "link_key_request (sba=%s, dba=%s)\n", - batostr(sba), batostr(dba)); + ba2str(sba, sa); ba2str(dba, da); + syslog(LOG_INFO, "link_key_request (sba=%s, dba=%s)\n", sa, da); if (key) { /* Link key found */ @@ -127,8 +128,8 @@ static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) static void save_link_key(struct link_key *key) { - char sa[40], da[40]; struct link_key *exist; + char sa[18], da[18]; int f, err; f = open(hcid.key_file, O_RDWR | O_CREAT, 0); @@ -172,8 +173,10 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) evt_link_key_notify *evt = ptr; bdaddr_t *dba = &evt->bdaddr; struct link_key key; - - syslog(LOG_INFO, "link_key_notify (sba=%s)\n", batostr(sba)); + char sa[18]; + + ba2str(sba, sa); + syslog(LOG_INFO, "link_key_notify (sba=%s)\n", sa); memcpy(key.key, evt->link_key, 16); bacpy(&key.sba, sba); @@ -293,9 +296,10 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) { struct hci_conn_info_req *cr; struct hci_conn_info *ci; - - syslog(LOG_INFO, "pin_code_request (sba=%s, dba=%s)\n", - batostr(sba), batostr(dba)); + char sa[18], da[18]; + + ba2str(sba, sa); ba2str(dba, da); + syslog(LOG_INFO, "pin_code_request (sba=%s, dba=%s)\n", sa, da); cr = malloc(sizeof(*cr) + sizeof(*ci)); if (!cr) @@ -313,9 +317,8 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) if (pairing == HCID_PAIRING_ONCE) { struct link_key *key = get_link_key(sba, dba); if (key) { - char ba[40]; - ba2str(dba, ba); - syslog(LOG_WARNING, "PIN code request for already paired device %s", ba); + ba2str(dba, da); + syslog(LOG_WARNING, "PIN code request for already paired device %s", da); goto reject; } } else if (pairing == HCID_PAIRING_NONE) -- cgit From 1854d87540f35ec18ed8adc5464c6e55aa906978 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 18 Jul 2003 09:25:50 +0000 Subject: Honor the setting of --sysconfdir --- hcid/Makefile.am | 2 +- rfcomm/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index bb666044..378d3a35 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -16,7 +16,7 @@ EXTRA_DIST = $(hcid_CONFIG) # # Install configuration files # -confdir = $(prefix)/etc/bluetooth +confdir = $(sysconfdir)/bluetooth conf_FILE = $(confdir)/$(hcid_CONFIG) pin_FILE = $(confdir)/pin diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index 72635ff2..aa0c5462 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -3,7 +3,7 @@ # mandir = $(prefix)/usr/share/man -confdir = /etc/bluetooth +confdir = $(sysconfdir)/bluetooth bin_PROGRAMS = rfcomm -- cgit From 8891e1ab4d0832e12815bb94689fd0f87c06a11f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Jul 2003 17:15:15 +0000 Subject: Add a missing free() --- hcid/glib-ectomy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hcid/glib-ectomy.c b/hcid/glib-ectomy.c index b97cdea7..5b56855e 100644 --- a/hcid/glib-ectomy.c +++ b/hcid/glib-ectomy.c @@ -161,6 +161,8 @@ void g_main_loop_run (GMainLoop *loop) } } + + free(ufds); } void g_main_loop_quit (GMainLoop *loop) -- cgit From 6b410af5c3e83f36ed8b5a620f1ab3029a271058 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Jul 2003 17:34:34 +0000 Subject: Kill usage of strtoba() and batostr() --- hcid/security.c | 7 +++---- tools/hciconfig.c | 6 +++--- tools/hcitool.c | 29 +++++++++++++++-------------- tools/l2ping.c | 9 +++++---- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/hcid/security.c b/hcid/security.c index 36fb6a71..7aa9a7a4 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -227,8 +227,7 @@ int read_pin_code(void) static void call_pin_helper(int dev, struct hci_conn_info *ci) { pin_code_reply_cp pr; - char str[255], *pin, name[20]; - bdaddr_t ba; + char addr[12], str[255], *pin, name[20]; FILE *pipe; int len; @@ -252,10 +251,10 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) name[0] = 0; //hci_remote_name(dev, &ci->bdaddr, sizeof(name), name, 0); - baswap(&ba, &ci->bdaddr); + ba2str(&ci->bdaddr, addr); sprintf(str, "%s %s %s \'%s\'", hcid.pin_helper, ci->out ? "out" : "in", - batostr(&ba), name); + addr, name); setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1); diff --git a/tools/hciconfig.c b/tools/hciconfig.c index aa3d9ab4..c1df2815 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -875,17 +875,17 @@ static void cmd_revision(int ctl, int hdev, char *opt) void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; - bdaddr_t bdaddr; + char addr[18]; if (hdr == di->dev_id) return; hdr = di->dev_id; - baswap(&bdaddr, &di->bdaddr); + ba2str(&di->bdaddr, addr); printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", - batostr(&bdaddr), di->acl_mtu, di->acl_pkts, + addr, di->acl_mtu, di->acl_pkts, di->sco_mtu, di->sco_pkts); } diff --git a/tools/hcitool.c b/tools/hcitool.c index 88c53266..59235270 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -56,12 +56,13 @@ static void usage(void); static int dev_info(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; - bdaddr_t bdaddr; + char addr[18]; + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) return 0; - baswap(&bdaddr, &di.bdaddr); - printf("\t%s\t%s\n", di.name, batostr(&bdaddr)); + ba2str(&di.bdaddr, addr); + printf("\t%s\t%s\n", di.name, addr); return 0; } @@ -89,12 +90,12 @@ static int conn_list(int s, int dev_id, long arg) } for (i=0; i < cl->conn_num; i++, ci++) { - bdaddr_t bdaddr; - baswap(&bdaddr, &ci->bdaddr); + char addr[18]; + ba2str(&ci->bdaddr, addr); printf("\t%s %s %s handle %d state %d lm %s\n", ci->out ? "<" : ">", ci->type == ACL_LINK ? "ACL" : "SCO", - batostr(&bdaddr), ci->handle, ci->state, + addr, ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } return 0; @@ -188,7 +189,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) { int num_rsp, length, flags; inquiry_info *info = NULL; - bdaddr_t bdaddr; + char addr[18]; int i, opt; length = 8; /* ~10 seconds */ @@ -223,9 +224,9 @@ static void cmd_inq(int dev_id, int argc, char **argv) } for (i = 0; i < num_rsp; i++) { - baswap(&bdaddr, &(info+i)->bdaddr); + ba2str(&(info+i)->bdaddr, addr); printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", - batostr(&bdaddr), (info+i)->clock_offset, + addr, (info+i)->clock_offset, (info+i)->dev_class[2], (info+i)->dev_class[1], (info+i)->dev_class[0]); @@ -251,7 +252,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; int num_rsp, length, flags; - bdaddr_t bdaddr; + char addr[18]; char name[248]; int i, opt, dd; @@ -280,7 +281,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) } if (dev_id < 0) { - dev_id = hci_get_route(&bdaddr); + dev_id = hci_get_route(NULL); if (dev_id < 0) { perror("Device is not available"); exit(1); @@ -305,8 +306,8 @@ static void cmd_scan(int dev_id, int argc, char **argv) memset(name, 0, sizeof(name)); if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - baswap(&bdaddr, &(info+i)->bdaddr); - printf("\t%s\t%s\n", batostr(&bdaddr), name); + ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\t%s\n", addr, name); } close(dd); @@ -345,7 +346,7 @@ static void cmd_name(int dev_id, int argc, char **argv) return; } - baswap(&bdaddr, strtoba(argv[0])); + str2ba(argv[0], &bdaddr); if (dev_id < 0) { dev_id = hci_get_route(&bdaddr); diff --git a/tools/l2ping.c b/tools/l2ping.c index 310ba86b..d5d7748b 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -77,6 +77,7 @@ static void ping(char *svr) struct sockaddr_l2 addr; struct sigaction sa; char buf[2048]; + char str[18]; int s, i, opt, lost; uint8_t id; @@ -97,7 +98,7 @@ static void ping(char *svr) exit(1); } - baswap(&addr.l2_bdaddr, strtoba(svr)); + str2ba(svr, &addr.l2_bdaddr); if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Can't connect."); exit(1); @@ -109,9 +110,9 @@ static void ping(char *svr) perror("Can't get local address."); exit(1); } - baswap(&bdaddr, &addr.l2_bdaddr); + ba2str(&addr.l2_bdaddr, str); - printf("Ping: %s from %s (data size %d) ...\n", svr, batostr(&bdaddr), size); + printf("Ping: %s from %s (data size %d) ...\n", svr, str, size); /* Initialize buffer */ for(i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) @@ -231,7 +232,7 @@ int main(int argc, char *argv[]) break; case 'S': - baswap(&bdaddr, strtoba(optarg)); + str2ba(optarg, &bdaddr); break; default: -- cgit From 4e2dd78121a7c16836a1e28b6f545e4dd9c2d596 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 27 Aug 2003 09:55:43 +0000 Subject: Support for 3Com card version 3.0 --- tools/hciattach.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/hciattach.c b/tools/hciattach.c index 05230d3c..5e33c97e 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -764,6 +764,9 @@ struct uart_t uart[] = { /* Socket Bluetooth CF Card (Rev G) */ { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, bcsp }, + /* 3Com Bluetooth Card (Version 3.0) */ + { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + { NULL, 0 } }; -- cgit From 68e6756b899d040b14062baaa1ae9ae0e14f3b02 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Sep 2003 21:40:13 +0000 Subject: Correct decoding class of device --- tools/hciconfig.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index c1df2815..c241b7d5 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -516,11 +516,11 @@ void cmd_class(int ctl, int hdev, char *opt) } else printf("Unspecified"); printf("\n\tDevice Class: "); - if (cls[1] > sizeof(major_devices)) + if ((cls[1] & 0x1f) > sizeof(major_devices)) printf("Invalid Device Class!\n"); else - printf("%s, %s\n", major_devices[cls[1]], - get_minor_device_name(cls[1], cls[0] / 4)); + printf("%s, %s\n", major_devices[cls[1] & 0x1f], + get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); } } -- cgit From 693d345b0cc02c961748aad2074a2ca64934c9f5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Oct 2003 15:18:55 +0000 Subject: Let the headset test tools use 16 bit PCM for input and output --- test/hsmicro | 2 +- test/hsplay | 2 +- test/hstest.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/hsmicro b/test/hsmicro index 8aec68f2..c254226b 100755 --- a/test/hsmicro +++ b/test/hsmicro @@ -17,4 +17,4 @@ fi BDADDR=$1 CHANNEL=$2 -$HSTEST record - $BDADDR $CHANNEL | $SOX -t raw -r 8000 -c 1 -s -b - -t ossdsp -r 44100 -c 2 -s -w /dev/dsp polyphase vol 5.0 2> /dev/null +$HSTEST record - $BDADDR $CHANNEL | $SOX -t raw -r 8000 -c 1 -s -w - -t ossdsp -r 44100 -c 2 -s -w /dev/dsp polyphase vol 5.0 2> /dev/null diff --git a/test/hsplay b/test/hsplay index 8a676459..5f53562b 100755 --- a/test/hsplay +++ b/test/hsplay @@ -19,4 +19,4 @@ FILE=$1 BDADDR=$2 CHANNEL=$3 -$MPG123 -q -s "$FILE" | $SOX -t raw -r 44100 -c 2 -s -w - -t raw -r 8000 -c 1 -s -b - | $HSTEST play - $BDADDR $CHANNEL +$MPG123 -q -s "$FILE" | $SOX -t raw -r 44100 -c 2 -s -w - -t raw -r 8000 -c 1 -s -w - | $HSTEST play - $BDADDR $CHANNEL diff --git a/test/hstest.c b/test/hstest.c index 8b47a10a..23bbf089 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -189,8 +189,8 @@ int main(int argc, char *argv[]) vs = htobs(vs); fprintf(stderr, "Voice setting: 0x%04x\n", vs); close(dd); - if (vs != 0x0040) { - fprintf(stderr, "The voice setting must be 0x0040\n"); + if (vs != 0x0060) { + fprintf(stderr, "The voice setting must be 0x0060\n"); return -1; } -- cgit From cebcc0af94a87b9e416bad4fe9567dcd1315b4cc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 6 Nov 2003 11:20:24 +0000 Subject: Fix minor class decoding of the peripheral major class --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index c241b7d5..9787fe79 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -443,7 +443,7 @@ static char *get_minor_device_name(int major, int minor) return "Keyboard"; case 32: return "Pointing device"; - case 64: + case 48: return "Combo keyboard/pointing device"; } break; -- cgit From 61011fc68193ff2f1b75a69a83323a41ca6fe5fd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 16 Nov 2003 12:51:32 +0000 Subject: Use Ericsson revision command for ST Microelectronics devices --- tools/hciconfig.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 9787fe79..e2acba83 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -857,6 +857,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) print_dev_hdr(&di); switch (ver.manufacturer) { case 0: + case 48: print_rev_ericsson(dd); break; case 10: -- cgit From bfe1cc41a50bda9420bf0ca43b0caabe12955eef Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 17 Nov 2003 15:30:14 +0000 Subject: add iac command --- tools/hciconfig.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index e2acba83..932ec4e7 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -137,6 +137,50 @@ void cmd_scan(int ctl, int hdev, char *opt) } } +void cmd_iac(int ctl, int hdev, char *opt) +{ + int s = hci_open_dev(hdev); + + if (s < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + if (opt) { + int l = strtoul(opt, 0, 16); + uint8_t lap[3]; + if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + if (hci_write_current_iac_lap(s, 1, lap, 1000) < 0) { + printf("Failed to set IAC on hci%d: %s\n", hdev, strerror(errno)); + exit(1); + } + } else { + uint8_t lap[3 * MAX_IAC_LAP]; + int i, j; + uint8_t n; + if (hci_read_current_iac_lap(s, &n, lap, 1000) < 0) { + printf("Failed to read IAC from hci%d: %s\n", hdev, strerror(errno)); + exit(1); + } + print_dev_hdr(&di); + printf("\tIAC: "); + for (i = 0; i < n; i++) { + printf("0x"); + for (j = 3; j--; ) + printf("%02x", lap[j + 3*i]); + if (i < n-1) + printf(", "); + } + printf("\n"); + } + close(s); +} + void cmd_auth(int ctl, int hdev, char *opt) { struct hci_dev_req dr; @@ -913,6 +957,7 @@ void print_dev_info(int ctl, struct hci_dev_info *di) if (hci_test_bit(HCI_UP, &di->flags)) { cmd_name(ctl, di->dev_id, NULL); cmd_class(ctl, di->dev_id, NULL); + cmd_iac(ctl, di->dev_id, NULL); cmd_version(ctl, di->dev_id, NULL); } } @@ -952,6 +997,7 @@ struct { { "features", cmd_features, 0, "Display device features" }, { "version", cmd_version, 0, "Display version information" }, { "revision", cmd_revision, 0, "Display revision information" }, + { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { NULL, NULL, 0 } }; -- cgit From d877c418537d529a9c693f23b59ca8b61e089e43 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 08:16:21 +0000 Subject: Add ST Microelectronics specific initialization --- tools/hciattach.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 5e33c97e..799e338d 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -150,7 +150,7 @@ static int read_hci_event(int fd, unsigned char* buf, int size) static int ericsson(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 50000}; - char cmd[10]; + char cmd[5]; cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x09; @@ -194,7 +194,7 @@ static int ericsson(int fd, struct uart_t *u, struct termios *ti) static int digi(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 50000}; - char cmd[10]; + char cmd[5]; /* DigiAnswer set baud rate command */ cmd[0] = HCI_COMMAND_PKT; @@ -227,7 +227,7 @@ static int digi(int fd, struct uart_t *u, struct termios *ti) static int texas(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 50000}; - char cmd[10]; + char cmd[4]; unsigned char resp[100]; /* Response */ int n; @@ -241,7 +241,7 @@ static int texas(int fd, struct uart_t *u, struct termios *ti) cmd[0] = HCI_COMMAND_PKT; cmd[1] = 0x01; cmd[2] = 0x10; - cmd[3] = 0x00; + cmd[3] = 0x00; do { n = write(fd, cmd, 4); @@ -632,7 +632,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) static int swave(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 500000}; - char cmd[10], rsp[100]; + char cmd[9], rsp[100]; int r; // Silicon Wave set baud rate command @@ -671,7 +671,7 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) } /* Send initialization command */ - if (write(fd, cmd, 10) != 5) { + if (write(fd, cmd, 9) != 9) { perror("Failed to write init command"); return -1; } @@ -729,6 +729,61 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) return 0; } +/* + * ST Microelectronics specific initialization + * Marcel Holtmann + */ +static int st(int fd, struct uart_t *u, struct termios *ti) +{ + struct timespec tm = {0, 50000}; + char cmd[5]; + + /* ST Microelectronics set baud rate command */ + cmd[0] = HCI_COMMAND_PKT; + cmd[1] = 0x46; // OCF = Hci_Cmd_ST_Set_Uart_Baud_Rate + cmd[2] = 0xfc; // OGF = Vendor specific + cmd[3] = 0x01; + + switch (u->speed) { + case 9600: + cmd[4] = 0x09; + break; + case 19200: + cmd[4] = 0x0b; + break; + case 38400: + cmd[4] = 0x0d; + break; + case 57600: + cmd[4] = 0x0e; + break; + case 115200: + cmd[4] = 0x10; + break; + case 230400: + cmd[4] = 0x12; + break; + case 460800: + cmd[4] = 0x13; + break; + case 921600: + cmd[4] = 0x14; + break; + default: + cmd[4] = 0x10; + u->speed = 57600; + break; + } + + /* Send initialization command */ + if (write(fd, cmd, 5) != 5) { + perror("Failed to write init command"); + return -1; + } + nanosleep(&tm, NULL); + return 0; +} + struct uart_t uart[] = { { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, @@ -749,6 +804,9 @@ struct uart_t uart[] = { /* Silicon Wave kits */ { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, swave }, + /* ST Microelectronics minikits based on STLC2410/STLC2415 */ + { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, st }, + /* Sphinx Electronics PICO Card */ { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, -- cgit From 7fbea8e4421d04d23747ad4dbcc31aa2d10e0c74 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 11:38:31 +0000 Subject: Display all 8 bytes of the features --- tools/hciconfig.c | 10 +++++++--- tools/hcitool.c | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 932ec4e7..ee7afb75 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -97,13 +97,17 @@ void print_link_mode(struct hci_dev_info *di) void print_dev_features(struct hci_dev_info *di, int format) { if (!format) { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", di->features[0], di->features[1], - di->features[2], di->features[3] ); + di->features[2], di->features[3], + di->features[4], di->features[5], + di->features[6], di->features[7] ); } else { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", di->features[0], di->features[1], di->features[2], di->features[3], + di->features[4], di->features[5], + di->features[6], di->features[7], lmp_featurestostr(di->features, "\t\t", 3)); } } diff --git a/tools/hcitool.c b/tools/hcitool.c index 59235270..cd546735 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -462,8 +462,9 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7], lmp_featurestostr(features, "\t\t", 3)); } -- cgit From 8246c9b6086d525ca83a05da5c8ed370662a69e1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 14:31:29 +0000 Subject: Update iac command and add entry to the manpage --- tools/hciconfig.8 | 6 ++++++ tools/hciconfig.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 96b503ae..aac5e98a 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -115,6 +115,12 @@ prints voice setting. Otherwise, sets voice setting to voice is a 16-bit hex number describing the voice setting. .TP +.BI iac " [iac]" +With no +.IR iac , +prints the current IAC setting. Otherwise, sets the IAC to +.IR iac . +.TP .BI inqparms " [win:int]" With no .IR win:int , diff --git a/tools/hciconfig.c b/tools/hciconfig.c index ee7afb75..b51fcc7e 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -356,6 +356,7 @@ void cmd_features(int ctl, int hdev, char *opt) void cmd_name(int ctl, int hdev, char *opt) { int s = hci_open_dev(hdev); + if (s < 0) { printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); @@ -993,6 +994,7 @@ struct { { "name", cmd_name, "[name]", "Get/Set local name" }, { "class", cmd_class, "[class]", "Get/Set class of device" }, { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, + { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, @@ -1001,7 +1003,6 @@ struct { { "features", cmd_features, 0, "Display device features" }, { "version", cmd_version, 0, "Display version information" }, { "revision", cmd_revision, 0, "Display revision information" }, - { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { NULL, NULL, 0 } }; -- cgit From d0008d9f3d92b9b38cc3a53687fa391f7adbe9c6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 14:36:31 +0000 Subject: Don't read the IAC with a default call --- tools/hciconfig.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index b51fcc7e..92292a20 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -962,7 +962,6 @@ void print_dev_info(int ctl, struct hci_dev_info *di) if (hci_test_bit(HCI_UP, &di->flags)) { cmd_name(ctl, di->dev_id, NULL); cmd_class(ctl, di->dev_id, NULL); - cmd_iac(ctl, di->dev_id, NULL); cmd_version(ctl, di->dev_id, NULL); } } -- cgit From 8793e6002250dde7f85ab89410ad96aebf2dbb76 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 16 Dec 2003 18:45:07 +0000 Subject: Increase number of inquiry responses --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index cd546735..f8125f43 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -193,7 +193,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) int i, opt; length = 8; /* ~10 seconds */ - num_rsp = 10; + num_rsp = 100; flags = 0; for_each_opt(opt, inq_options, NULL) { @@ -257,7 +257,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) int i, opt, dd; length = 8; /* ~10 seconds */ - num_rsp = 10; + num_rsp = 100; flags = 0; for_each_opt(opt, scan_options, NULL) { -- cgit From 350e84f553eece612ba722c55f7b39c71b449994 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 17 Dec 2003 14:26:35 +0000 Subject: Update changelog and bump version number --- ChangeLog | 22 +++++++++++++++++++++- configure.in | 2 +- utils.spec | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3017c206..dcf08308 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,24 @@ -var 2.3: +ver 2.4: + hcitool changes: + Increase number of inquiry responses. + Support for transmit power level. + Minor updates. + hciconfig changes: + Display all 8 bytes of the features. + Add support for reading and writing of IAC. + Correct decoding class of device. + Use Ericsson revision command for ST Microelectronics devices. + Display AVM firmware version with 'revision' command. + New code for CSR specific revision information. + hciattach changes: + Support for ST Microelectronics specific initialization. + Support for 3Com card version 3.0. + Support for TDK, IBM and Socket cards. + Support for initial baud rate. + Update man pages. + Fixes for some memory leaks. + +ver 2.3: hciconfig changes: CSR firmware version is now displayed by 'revision' command. Voice command is working properly on big endian machines. diff --git a/configure.in b/configure.in index 460ffc06..bc49b56b 100644 --- a/configure.in +++ b/configure.in @@ -11,7 +11,7 @@ AC_CANONICAL_HOST AM_MAINTAINER_MODE -AM_INIT_AUTOMAKE(bluez-utils, 2.3) +AM_INIT_AUTOMAKE(bluez-utils, 2.4) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) diff --git a/utils.spec b/utils.spec index a608e498..9df55a4b 100644 --- a/utils.spec +++ b/utils.spec @@ -1,5 +1,5 @@ # Note that this is NOT a relocatable package -%define ver 2.3 +%define ver 2.4 %define RELEASE 1 %define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} %define prefix / -- cgit From 16e217b4b13b828a9bb6c372d544deafa0e01f24 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Dec 2003 16:08:25 +0000 Subject: Fix automatic connection creation for the info command --- tools/hcitool.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index f8125f43..0194b650 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -410,10 +410,8 @@ static void cmd_info(int dev_id, int argc, char **argv) if (dev_id < 0) dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); - if (dev_id < 0) { + if (dev_id < 0) dev_id = hci_get_route(&bdaddr); - cc = 1; - } if (dev_id < 0) { fprintf(stderr, "Device is not available or not connected.\n"); @@ -428,26 +426,24 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } - if (cc) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't get connection info"); + close(dd); + exit(1); + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { if (hci_create_connection(dd, &bdaddr, HCI_DM1 | HCI_DH1, 0, 0, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); } - } else { - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; - - bacpy(&cr->bdaddr, &bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - perror("Get connection info failed"); - exit(1); - } - + cc = 1; + } else handle = cr->conn_info->handle; - } printf("\tBD Address: %s\n", argv[0]); -- cgit From 5ff58cb0e277fb4cb4613aa3d2a83e7237c59894 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Feb 2004 10:08:18 +0000 Subject: Add device specific configuration --- hcid/hcid.h | 27 ++++++--- hcid/lexer.l | 21 +++++-- hcid/main.c | 178 ++++++++++++++++++++++++++++++++++++++++++++-------------- hcid/parser.y | 95 ++++++++++++++++++++----------- 4 files changed, 233 insertions(+), 88 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index 55ef0ab0..3bd0ad46 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -20,23 +20,24 @@ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ + /* * $Id$ */ #include -#include "glib-ectomy.h" - #include +#include "glib-ectomy.h" + #define HCID_CONFIG_FILE "/etc/bluetooth/hcid.conf" #define HCID_PIN_FILE "/etc/bluetooth/pin" #define HCID_KEY_FILE "/etc/bluetooth/link_key" #define HCID_PIN_HELPER "/bin/bluepin" struct device_opts { - char *name; + char *name; uint32_t class; uint16_t pkt_type; uint16_t scan; @@ -44,15 +45,23 @@ struct device_opts { uint16_t link_policy; uint16_t auth; uint16_t encrypt; -}; -extern struct device_opts devi; +}; + +extern struct device_opts default_device; +extern struct device_opts *parser_device; + +struct device_list { + char *ref; /* HCI device or Bluetooth address */ + struct device_list *next; + struct device_opts opts; +}; struct link_key { bdaddr_t sba; bdaddr_t dba; - uint8_t key[16]; - uint8_t type; - time_t time; + uint8_t key[16]; + uint8_t type; + time_t time; }; struct hcid_opts { @@ -84,6 +93,8 @@ extern struct hcid_opts hcid; int read_config(char *file); +struct device_opts *alloc_device_opts(char *addr); + gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data); gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data); diff --git a/hcid/lexer.l b/hcid/lexer.l index 85cd5780..1947bcd4 100644 --- a/hcid/lexer.l +++ b/hcid/lexer.l @@ -24,7 +24,7 @@ /* * $Id$ - */ + */ #include @@ -44,16 +44,19 @@ int yyerror(char *str); hex 0x[0-9a-zA-Z]+ num [0-9]+ -kword [A-Za-z0-9\_\-]+ +kword [A-Za-z0-9\_\-]+ word [A-Za-z0-9\-\_+=\!\$\#\%\&\*\^\@@\\\~\.]+ wordnm {word}:{num} list ({word}\,*)+ comment \#.*\n -fname [A-Za-z0-9\_\.\-]+ +fname [A-Za-z0-9\_\.\-]+ path (\/{fname})+ string \".*\" +hci hci[0-9]+ +hextuple [0-9a-zA-Z][0-9a-zA-Z] +bdaddr {hextuple}:{hextuple}:{hextuple}:{hextuple}:{hextuple}:{hextuple} -%x OPTION PARAM +%x OPTION PARAM %% [ \t] { @@ -70,6 +73,16 @@ string \".*\" lineno++; } +{hci} { + yylval.str = yytext; + return HCI; +} + +{bdaddr} { + yylval.str = yytext; + return BDADDR; +} + {hex} { yylval.num = strtol(yytext, NULL, 16); return NUM; diff --git a/hcid/main.c b/hcid/main.c index 85534fdf..d5c52c9d 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -20,6 +20,7 @@ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ + /* * $Id$ */ @@ -50,7 +51,9 @@ #include "lib.h" struct hcid_opts hcid; -struct device_opts devi; +struct device_opts default_device; +struct device_opts *parser_device; +static struct device_list *device_list = NULL; static GMainLoop *event_loop; @@ -64,8 +67,93 @@ static void usage(void) printf("\thcid [-n not_daemon] [-f config file]\n"); } +static inline void init_device_defaults(struct device_opts *device_opts) +{ + memset(device_opts, 0, sizeof(*device_opts)); + device_opts->scan = SCAN_PAGE | SCAN_INQUIRY; +} + +struct device_opts *alloc_device_opts(char *ref) +{ + struct device_list *device; + + device = malloc(sizeof(struct device_list)); + if (!device) { + syslog(LOG_INFO, "Can't allocate devlist opts buffer. %s(%d)", + strerror(errno), errno); + exit(1); + } + + device->ref = ref; + device->next = device_list; + device_list = device; + + init_device_defaults(&device->opts); + + return &device->opts; +} + +static void free_device_opts(void) +{ + struct device_list *device, *next; + + if (default_device.name) { + free(default_device.name); + default_device.name = NULL; + } + + for (device = device_list; device; device = next) { + free(device->ref); + if (device->opts.name) + free(device->opts.name); + next = device->next; + free(device); + } + + device_list = NULL; +} + +static inline struct device_opts *find_device_opts(char *ref) +{ + struct device_list *device; + + for (device = device_list; device; device = device->next) + if (!strcmp(ref, device->ref)) + return &device->opts; + + return NULL; +} + +static struct device_opts *get_device_opts(int sock, int hdev) +{ + struct device_opts *device_opts = NULL; + struct hci_dev_info di; + + /* First try to get BD_ADDR based settings ... */ + di.dev_id = hdev; + if (!ioctl(sock, HCIGETDEVINFO, (void *) &di)) { + char addr[18]; + ba2str(&di.bdaddr, addr); + device_opts = find_device_opts(addr); + } + + /* ... then try HCI based settings ... */ + if (!device_opts) { + char ref[8]; + snprintf(ref, sizeof(ref) - 1, "hci%d", hdev); + device_opts = find_device_opts(ref); + } + + /* ... and last use the default settings. */ + if (!device_opts) + device_opts = &default_device; + + return device_opts; +} + static void configure_device(int hdev) { + struct device_opts *device_opts; struct hci_dev_req dr; int s; @@ -87,51 +175,52 @@ static void configure_device(int hdev) exit(1); } - dr.dev_id = hdev; + dr.dev_id = hdev; + device_opts = get_device_opts(s, hdev); /* Set scan mode */ - dr.dev_opt = devi.scan; - if (ioctl(s, HCISETSCAN, (unsigned long)&dr) < 0) { + dr.dev_opt = device_opts->scan; + if (ioctl(s, HCISETSCAN, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set scan mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } /* Set authentication */ - if (devi.auth) + if (device_opts->auth) dr.dev_opt = AUTH_ENABLED; else dr.dev_opt = AUTH_DISABLED; - if (ioctl(s, HCISETAUTH, (unsigned long)&dr) < 0) { + if (ioctl(s, HCISETAUTH, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set auth on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } /* Set encryption */ - if (devi.encrypt) + if (device_opts->encrypt) dr.dev_opt = ENCRYPT_P2P; else dr.dev_opt = ENCRYPT_DISABLED; - if (ioctl(s, HCISETENCRYPT, (unsigned long)&dr) < 0) { + if (ioctl(s, HCISETENCRYPT, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set encrypt on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } - /* Set device class */ - if (devi.class) { - uint32_t class = htobl(devi.class); + /* Set device class */ + if (device_opts->class) { + uint32_t class = htobl(device_opts->class); write_class_of_dev_cp cp; - + memcpy(cp.dev_class, &class, 3); hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, WRITE_CLASS_OF_DEV_CP_SIZE, (void *) &cp); } /* Set device name */ - if (devi.name) { + if (device_opts->name) { change_local_name_cp cp; - expand_name(cp.name, devi.name, hdev); + expand_name(cp.name, device_opts->name, hdev); hci_send_cmd(s, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, CHANGE_LOCAL_NAME_CP_SIZE, (void *) &cp); @@ -142,6 +231,7 @@ static void configure_device(int hdev) static void init_device(int hdev) { + struct device_opts *device_opts; struct hci_dev_req dr; int s; @@ -170,30 +260,31 @@ static void init_device(int hdev) exit(1); } - dr.dev_id = hdev; + dr.dev_id = hdev; + device_opts = get_device_opts(s, hdev); /* Set packet type */ - if (devi.pkt_type) { - dr.dev_opt = devi.pkt_type; - if (ioctl(s, HCISETPTYPE, (unsigned long)&dr) < 0) { + if (device_opts->pkt_type) { + dr.dev_opt = device_opts->pkt_type; + if (ioctl(s, HCISETPTYPE, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set packet type on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } } /* Set link mode */ - if (devi.link_mode) { - dr.dev_opt = devi.link_mode; - if (ioctl(s, HCISETLINKMODE, (unsigned long)&dr) < 0) { + if (device_opts->link_mode) { + dr.dev_opt = device_opts->link_mode; + if (ioctl(s, HCISETLINKMODE, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set link mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } } /* Set link policy */ - if (devi.link_policy) { - dr.dev_opt = devi.link_policy; - if (ioctl(s, HCISETLINKPOL, (unsigned long)&dr) < 0) { + if (device_opts->link_policy) { + dr.dev_opt = device_opts->link_policy; + if (ioctl(s, HCISETLINKPOL, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set link policy on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } @@ -216,13 +307,13 @@ static void init_all_devices(int ctl) dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(ctl, HCIGETDEVLIST, (void*)dl)) { + if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) { syslog(LOG_INFO, "Can't get device list. %s(%d)", strerror(errno), errno); exit(1); } - for (i=0; i < dl->dev_num; i++, dr++) { + for (i = 0; i < dl->dev_num; i++, dr++) { if (hcid.auto_init) init_device(dr->dev_id); @@ -232,7 +323,7 @@ static void init_all_devices(int ctl) if (hcid.security && hci_test_bit(HCI_UP, &dr->dev_opt)) start_security_manager(dr->dev_id); } - + free(dl); } @@ -241,10 +332,7 @@ static void init_defaults(void) hcid.auto_init = 0; hcid.security = 0; - devi.pkt_type = 0; - devi.scan = SCAN_PAGE | SCAN_INQUIRY; - devi.auth = 0; - devi.encrypt = 0; + init_device_defaults(&default_device); } static void sig_usr1(int sig) @@ -265,7 +353,9 @@ static void sig_term(int sig) static void sig_hup(int sig) { syslog(LOG_INFO, "Reloading config file"); + init_defaults(); + if (read_config(hcid.config_file) < 0) syslog(LOG_ERR, "Config reload failed"); @@ -346,7 +436,7 @@ gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data) return TRUE; } -extern int optind,opterr,optopt; +extern int optind, opterr, optopt; extern char *optarg; int main(int argc, char *argv[], char *env[]) @@ -361,18 +451,18 @@ int main(int argc, char *argv[], char *env[]) /* Default HCId settings */ hcid.config_file = HCID_CONFIG_FILE; - hcid.host_name = get_host_name(); - hcid.security = HCID_SEC_AUTO; - hcid.pairing = HCID_PAIRING_MULTI; + hcid.host_name = get_host_name(); + hcid.security = HCID_SEC_AUTO; + hcid.pairing = HCID_PAIRING_MULTI; - hcid.pin_file = strdup(HCID_PIN_FILE); - hcid.pin_helper = strdup(HCID_PIN_HELPER); - hcid.key_file = strdup(HCID_KEY_FILE); + hcid.pin_file = strdup(HCID_PIN_FILE); + hcid.pin_helper = strdup(HCID_PIN_HELPER); + hcid.key_file = strdup(HCID_KEY_FILE); init_defaults(); - while ((opt=getopt(argc,argv,"f:n")) != EOF) { - switch(opt) { + while ((opt = getopt(argc, argv, "f:n")) != EOF) { + switch (opt) { case 'n': daemon = 0; break; @@ -402,8 +492,8 @@ int main(int argc, char *argv[], char *env[]) } umask(0077); - - init_title(argc, argv, env, "hcid: "); + + init_title(argc, argv, env, "hcid: "); set_title("initializing"); /* Start logging to syslog and stderr */ @@ -443,7 +533,7 @@ int main(int argc, char *argv[], char *env[]) addr.hci_family = AF_BLUETOOTH; addr.hci_dev = HCI_DEV_NONE; - if (bind(hcid.sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + if (bind(hcid.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { syslog(LOG_ERR, "Can't bind HCI socket. %s(%d)\n", strerror(errno), errno); exit(1); } @@ -467,6 +557,8 @@ int main(int argc, char *argv[], char *env[]) /* Start event processor */ g_main_run(event_loop); + free_device_opts(); + syslog(LOG_INFO, "Exit."); return 0; } diff --git a/hcid/parser.y b/hcid/parser.y index f0aafbd3..e14ca200 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -24,7 +24,7 @@ /* * $Id$ - */ + */ #include #include @@ -45,7 +45,7 @@ int cfg_error(const char *fmt, ...); int yyparse(void); -int yylex(void); +int yylex(void); int yyerror(char *s); %} @@ -61,27 +61,42 @@ int yyerror(char *s); %token K_PINHELP %token K_YES K_NO -%token WORD PATH STRING LIST +%token WORD PATH STRING LIST HCI BDADDR %token NUM %type bool pkt_type link_mode link_policy sec_mode pair_mode -%type dev_name +%type dev_name hci bdaddr %% config: statement | config statement; statement: K_OPTIONS hcid_options - - | K_DEVICE device_options + + | device device_options | WORD { cfg_error("Invalid statement '%s'", $1); } + | error { yyclearin; yyerrok; } ; +device: + K_DEVICE { + parser_device = &default_device; + } + + | K_DEVICE hci { + parser_device = alloc_device_opts($2); + } + + | K_DEVICE bdaddr { + parser_device = alloc_device_opts($2); + } + ; + hcid_options: '{' hcid_opts '}'; hcid_opts: | hcid_opt ';' | error ';' | hcid_opts hcid_opt ';'; hcid_opt: @@ -109,7 +124,7 @@ hcid_opt: ; sec_mode: - WORD { + WORD { int opt = find_keyword(sec_param, $1); if (opt < 0) { cfg_error("Unknown security mode '%s'", $1); @@ -118,11 +133,13 @@ sec_mode: $$ = opt; } - | K_NO { $$ = HCID_SEC_NONE; } + | K_NO { + $$ = HCID_SEC_NONE; + } ; pair_mode: - WORD { + WORD { int opt = find_keyword(pair_param, $1); if (opt < 0) { cfg_error("Unknown pairing mode '%s'", $1); @@ -137,47 +154,47 @@ device_options: '{' device_opts '}'; device_opts: | device_opt ';' | error ';' | device_opts device_opt ';'; device_opt: K_PTYPE pkt_type { - devi.pkt_type = $2; + parser_device->pkt_type = $2; } | K_LM link_mode { - devi.link_mode = $2; + parser_device->link_mode = $2; } | K_LP link_policy { - devi.link_policy = $2; + parser_device->link_policy = $2; } - | K_NAME dev_name { - if (devi.name) - free(devi.name); - devi.name = $2; + | K_NAME dev_name { + if (parser_device->name) + free(parser_device->name); + parser_device->name = $2; } | K_CLASS NUM { - devi.class = $2; + parser_device->class = $2; } | K_AUTH bool { - devi.auth = $2; + parser_device->auth = $2; } | K_ENCRYPT bool { - devi.encrypt = $2; + parser_device->encrypt = $2; } | K_ISCAN bool { if ($2) - devi.scan |= SCAN_INQUIRY; + parser_device->scan |= SCAN_INQUIRY; else - devi.scan &= ~SCAN_INQUIRY; + parser_device->scan &= ~SCAN_INQUIRY; } | K_PSCAN bool { if ($2) - devi.scan |= SCAN_PAGE; + parser_device->scan |= SCAN_PAGE; else - devi.scan &= ~SCAN_PAGE; + parser_device->scan &= ~SCAN_PAGE; } | WORD { @@ -187,7 +204,7 @@ device_opt: ; dev_name: - WORD { + WORD { $$ = strdup($1); } @@ -196,8 +213,20 @@ dev_name: } ; +hci: + HCI { + $$ = strdup($1); + } + ; + +bdaddr: + BDADDR { + $$ = strdup($1); + } + ; + pkt_type: - WORD { + WORD { int opt; if (!hci_strtoptype($1, &opt)) cfg_error("Unknown packet type '%s'", $1); @@ -209,11 +238,11 @@ pkt_type: if (!hci_strtoptype($1, &opt)) cfg_error("Unknown packet type '%s'", $1); $$ = opt; - } + } ; link_mode: - WORD { + WORD { int opt; if (!hci_strtolm($1, &opt)) cfg_error("Unknown link mode '%s'", $1); @@ -225,11 +254,11 @@ link_mode: if (!hci_strtolm($1, &opt)) cfg_error("Unknown link mode '%s'", $1); $$ = opt; - } + } ; link_policy: - WORD { + WORD { int opt; if (!hci_strtolp($1, &opt)) cfg_error("Unknown link policy '%s'", $1); @@ -241,7 +270,7 @@ link_policy: if (!hci_strtolp($1, &opt)) cfg_error("Unknown link policy '%s'", $1); $$ = opt; - } + } ; bool: K_YES { $$ = 1; } | K_NO { $$ = 0; }; @@ -276,13 +305,13 @@ int read_config(char *file) if( !(yyin = fopen(file,"r")) ){ syslog(LOG_ERR,"Can not open %s", file); - return -1; + return -1; } lineno = 1; yyparse(); fclose(yyin); - - return 0; + + return 0; } -- cgit From 2cabb56f7528c9756617dbae8a73d9878bfa9b59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Feb 2004 23:25:53 +0000 Subject: Fix endian problem with hci_create_connection() --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 0194b650..675d829e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -436,7 +436,7 @@ static void cmd_info(int dev_id, int argc, char **argv) bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &bdaddr, HCI_DM1 | HCI_DH1, 0, 0, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, htobs(HCI_DM1 | HCI_DH1), 0, 0, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -653,7 +653,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (hci_create_connection(dd, &bdaddr, ptype, 0, role, &handle, 1000) < 0) + if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 1000) < 0) perror("Can't create connection"); hci_close_dev(dd); } -- cgit From 5903cfe8fdfa5df4a0ce737219385d16da85e279 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Feb 2004 13:06:19 +0000 Subject: Add D-Bus support for PIN request --- configure.in | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/configure.in b/configure.in index bc49b56b..4d57acdd 100644 --- a/configure.in +++ b/configure.in @@ -44,6 +44,12 @@ AC_ARG_WITH(bluez-includes, BLUEZ_INCDIR='../libs/include /usr/include' ) +AC_ARG_ENABLE(dbus, + --enable-dbus use D-BUS, + BLUEZ_DBUS="$enableval", + BLUEZ_DBUS="no" +) + AC_SEARCH_HEADERS(bluetooth/bluetooth.h, $BLUEZ_INCDIR,, AC_MSG_ERROR(Bluetooth headers not found. Please compile and install bluez-libs package.) @@ -71,4 +77,13 @@ AC_ARG_ENABLE(pcmcia, AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=) fi ]) +if test x"$BLUEZ_DBUS" == "xyes"; then + PKG_CHECK_MODULES(DBUS, dbus-1, have_dbus=yes, have_dbus=no) + + CFLAGS="$CFLAGS $DBUS_CFLAGS -DENABLE_DBUS" + LIBS="$LIBS $DBUS_LIBS" +fi + +AM_CONDITIONAL(ENABLE_DBUS, test x$BLUEZ_DBUS = xyes) + AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) -- cgit From f17bb94f47090f3397b60b5e264aa9f18dbf203d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Feb 2004 18:04:03 +0000 Subject: Add D-Bus support for PIN request --- hcid/Makefile.am | 8 ++- hcid/dbus.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++ hcid/glib-ectomy.c | 19 ++++- hcid/glib-ectomy.h | 2 + hcid/hcid.h | 6 ++ hcid/kword.c | 76 +++++++++++--------- hcid/kword.h | 44 ++++++------ hcid/lexer.l | 5 ++ hcid/lib.c | 4 ++ hcid/main.c | 12 ++++ hcid/parser.y | 12 +++- hcid/security.c | 21 ++++-- 12 files changed, 347 insertions(+), 68 deletions(-) create mode 100644 hcid/dbus.c diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 378d3a35..14428722 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -4,7 +4,13 @@ sbin_PROGRAMS = hcid -hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c +if ENABLE_DBUS +dbus_hcid_sources = dbus.c +else +dbus_hcid_sources = +endif + +hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) hcid_CONFIG = hcid.conf YFLAGS = -d diff --git a/hcid/dbus.c b/hcid/dbus.c new file mode 100644 index 00000000..4c2bb18d --- /dev/null +++ b/hcid/dbus.c @@ -0,0 +1,206 @@ +#include +#include +#include + +#include +#include +#include + +#define DBUS_API_SUBJECT_TO_CHANGE +#include + +#include "hcid.h" +#include "glib-ectomy.h" + +static DBusConnection *connection; + +#define TIMEOUT (30 * 1000) // 30 seconds + +#define SERVICE_NAME "org.handhelds.gpe.bluez" +#define INTERFACE_NAME SERVICE_NAME ".PinAgent" +#define REQUEST_NAME "PinRequest" +#define PATH_NAME "/org/handhelds/gpe/bluez/PinAgent" + +#define WRONG_ARGS_ERROR "org.handhelds.gpe.bluez.Error.WrongArgs" + +struct pin_request +{ + int dev; + bdaddr_t bda; +}; + +static void reply_handler_function(DBusPendingCall *call, void *user_data) +{ + struct pin_request *req = (struct pin_request *) user_data; + pin_code_reply_cp pr; + DBusMessage *message; + DBusMessageIter iter; + int type; + size_t len; + char *pin; + + message = dbus_pending_call_get_reply(call); + + if (dbus_message_is_error(message, WRONG_ARGS_ERROR)) + goto error; + + dbus_message_iter_init(message, &iter); + + type = dbus_message_iter_get_arg_type(&iter); + if (type != DBUS_TYPE_STRING) + goto error; + + pin = dbus_message_iter_get_string(&iter); + len = strlen(pin); + + memset(&pr, 0, sizeof(pr)); + bacpy(&pr.bdaddr, &req->bda); + memcpy(pr.pin_code, pin, len); + pr.pin_len = len; + hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, + PIN_CODE_REPLY_CP_SIZE, &pr); + + return; + +error: + hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, + 6, &req->bda); +} + + +static void free_pin_req(void *req) +{ + free(req); +} + +void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) +{ + DBusMessage *message; + DBusMessageIter iter; + DBusPendingCall *pending = NULL; + struct pin_request *req; + + message = dbus_message_new_method_call(SERVICE_NAME, PATH_NAME, + INTERFACE_NAME, REQUEST_NAME); + if (message == NULL) { + syslog(LOG_ERR, "Couldn't allocate D-BUS message"); + goto failed; + } + + req = malloc(sizeof(*req)); + req->dev = dev; + bacpy(&req->bda, &ci->bdaddr); + + dbus_message_append_iter_init(message, &iter); + + dbus_message_iter_append_boolean(&iter, ci->out); + dbus_message_iter_append_byte_array(&iter, + (unsigned char *) &ci->bdaddr, sizeof(ci->bdaddr)); + + if (dbus_connection_send_with_reply(connection, message, + &pending, TIMEOUT) == FALSE) { + syslog(LOG_ERR, "D-BUS send failed"); + goto failed; + } + + dbus_pending_call_set_notify(pending, reply_handler_function, + req, free_pin_req); + + dbus_connection_flush (connection); + + dbus_message_unref (message); + + return; + +failed: + dbus_message_unref (message); + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, + 6, &ci->bdaddr); +} + +gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + DBusWatch *watch = (DBusWatch *) data; + int flags = 0; + + if (cond & G_IO_IN) flags |= DBUS_WATCH_READABLE; + if (cond & G_IO_OUT) flags |= DBUS_WATCH_WRITABLE; + if (cond & G_IO_HUP) flags |= DBUS_WATCH_HANGUP; + if (cond & G_IO_ERR) flags |= DBUS_WATCH_ERROR; + + dbus_watch_handle(watch, flags); + + dbus_connection_ref(connection); + + /* Dispatch messages */ + while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS); + + dbus_connection_unref(connection); + + return TRUE; +} + +dbus_bool_t add_watch(DBusWatch *watch, void *data) +{ + GIOCondition cond = G_IO_HUP | G_IO_ERR; + GIOChannel *io; + guint id; + int fd, flags; + + if (!dbus_watch_get_enabled(watch)) + return TRUE; + + fd = dbus_watch_get_fd(watch); + io = g_io_channel_unix_new(fd); + flags = dbus_watch_get_flags(watch); + + if (flags & DBUS_WATCH_READABLE) cond |= G_IO_IN; + if (flags & DBUS_WATCH_WRITABLE) cond |= G_IO_OUT; + + id = g_io_add_watch(io, cond, watch_func, watch); + + dbus_watch_set_data(watch, (void *) id, NULL); + + return TRUE; +} + +static void remove_watch(DBusWatch *watch, void *data) +{ + guint id = (guint) dbus_watch_get_data(watch); + + dbus_watch_set_data(watch, NULL, NULL); + + if (id) + g_io_remove_watch(id); +} + +static void watch_toggled(DBusWatch *watch, void *data) +{ + /* Because we just exit on OOM, enable/disable is + * no different from add/remove + */ + if (dbus_watch_get_enabled(watch)) + add_watch(watch, data); + else + remove_watch(watch, data); +} + +gboolean hcid_dbus_init(void) +{ + DBusError error; + + dbus_error_init(&error); + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + fprintf(stderr, "Failed to open connection to system message bus: %s\n", + error.message); + dbus_error_free(&error); + return FALSE; + } + + dbus_connection_set_watch_functions(connection, + add_watch, remove_watch, watch_toggled, NULL, NULL); + + return TRUE; +} diff --git a/hcid/glib-ectomy.c b/hcid/glib-ectomy.c index 5b56855e..8489cd73 100644 --- a/hcid/glib-ectomy.c +++ b/hcid/glib-ectomy.c @@ -1,5 +1,3 @@ -#include "glib-ectomy.h" - #include #include #include @@ -8,7 +6,7 @@ #include #include -// static void remove_watch(int fd); +#include "glib-ectomy.h" GIOError g_io_channel_read (GIOChannel *channel, gchar *buf, @@ -84,6 +82,21 @@ struct watch { static struct watch watch_head = { .id = 0, .next = 0 }; +void g_io_remove_watch (guint id) +{ + struct watch *w, *p; + + for (p = &watch_head, w = watch_head.next; w; w = w->next) + { + if (w->id == id) + { + p->next = w->next; + free (w); + return; + } + } +} + guint g_io_add_watch (GIOChannel *channel, GIOCondition condition, GIOFunc func, diff --git a/hcid/glib-ectomy.h b/hcid/glib-ectomy.h index b1ac263b..703ae54b 100644 --- a/hcid/glib-ectomy.h +++ b/hcid/glib-ectomy.h @@ -92,6 +92,8 @@ guint g_io_add_watch (GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data); +void g_io_remove_watch (guint id); + GMainLoop *g_main_loop_new (GMainContext *context, diff --git a/hcid/hcid.h b/hcid/hcid.h index 3bd0ad46..f8233d70 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -76,6 +76,7 @@ struct hcid_opts { int pin_len; char *pin_helper; char *pin_file; + int dbus_pin_helper; char *key_file; @@ -102,3 +103,8 @@ void init_security_data(void); void start_security_manager(int hdev); void stop_security_manager(int hdev); void toggle_pairing(int enable); + +#ifdef ENABLE_DBUS +void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); +gboolean hcid_dbus_init(void); +#endif diff --git a/hcid/kword.c b/hcid/kword.c index 0486f21b..09ad0573 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -26,58 +26,64 @@ #include #include +#include + +#include +#include +#include #include "hcid.h" #include "kword.h" #include "parser.h" struct kword cfg_keyword[] = { - { "options", K_OPTIONS }, - { "default", K_DEVICE }, - { "device", K_DEVICE }, - { "autoinit", K_AUTOINIT }, - { "security", K_SECURITY }, - { "pairing", K_PAIRING }, - { "pkt_type", K_PTYPE }, - { "lm", K_LM }, - { "lp", K_LP }, - { "iscan", K_ISCAN }, - { "pscan", K_PSCAN }, - { "name", K_NAME }, - { "class", K_CLASS }, - { "auth", K_AUTH }, - { "encrypt", K_ENCRYPT }, - { "pin_helper", K_PINHELP }, + { "options", K_OPTIONS }, + { "default", K_DEVICE }, + { "device", K_DEVICE }, + { "autoinit", K_AUTOINIT }, + { "security", K_SECURITY }, + { "pairing", K_PAIRING }, + { "pkt_type", K_PTYPE }, + { "lm", K_LM }, + { "lp", K_LP }, + { "iscan", K_ISCAN }, + { "pscan", K_PSCAN }, + { "name", K_NAME }, + { "class", K_CLASS }, + { "auth", K_AUTH }, + { "encrypt", K_ENCRYPT }, + { "pin_helper", K_PINHELP }, + { "dbus_pin_helper", K_DBUSPINHELP }, - { "yes", K_YES }, - { "no", K_NO }, - { "enable", K_YES }, - { "disable", K_NO }, - { NULL , 0 } + { "yes", K_YES }, + { "no", K_NO }, + { "enable", K_YES }, + { "disable", K_NO }, + { NULL , 0 } }; struct kword sec_param[] = { - { "none", HCID_SEC_NONE }, - { "auto", HCID_SEC_AUTO }, - { "user", HCID_SEC_USER }, - { NULL , 0 } + { "none", HCID_SEC_NONE }, + { "auto", HCID_SEC_AUTO }, + { "user", HCID_SEC_USER }, + { NULL , 0 } }; struct kword pair_param[] = { - { "none", HCID_PAIRING_NONE }, - { "multi", HCID_PAIRING_MULTI }, - { "once", HCID_PAIRING_ONCE }, - { NULL , 0 } + { "none", HCID_PAIRING_NONE }, + { "multi", HCID_PAIRING_MULTI }, + { "once", HCID_PAIRING_ONCE }, + { NULL , 0 } }; int lineno; int find_keyword(struct kword *kw, char *str) { - while( kw->str ){ - if( !strcmp(str,kw->str) ) - return kw->type; - kw++; - } - return -1; + while (kw->str) { + if (!strcmp(str,kw->str)) + return kw->type; + kw++; + } + return -1; } diff --git a/hcid/kword.h b/hcid/kword.h index 10c54493..67baaf13 100644 --- a/hcid/kword.h +++ b/hcid/kword.h @@ -1,32 +1,32 @@ /* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ /* * $Id$ */ struct kword { - char *str; - int type; + char *str; + int type; }; extern int lineno; diff --git a/hcid/lexer.l b/hcid/lexer.l index 1947bcd4..3c9ed308 100644 --- a/hcid/lexer.l +++ b/hcid/lexer.l @@ -27,6 +27,11 @@ */ #include +#include + +#include +#include +#include #include "hcid.h" #include "kword.h" diff --git a/hcid/lib.c b/hcid/lib.c index 2e310012..bb85feb4 100644 --- a/hcid/lib.c +++ b/hcid/lib.c @@ -32,6 +32,10 @@ #include #include +#include +#include +#include + #include "hcid.h" #include "lib.h" diff --git a/hcid/main.c b/hcid/main.c index d5c52c9d..c3f4131d 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -541,6 +541,18 @@ int main(int argc, char *argv[], char *env[]) if (read_config(hcid.config_file) < 0) syslog(LOG_ERR, "Config load failed"); +#ifdef ENABLE_DBUS + if (hcid_dbus_init() == FALSE && hcid.dbus_pin_helper) { + syslog(LOG_ERR, "Unable to get on D-BUS"); + exit(1); + } +#else + if (hcid.dbus_pin_helper) { + syslog(LOG_ERR, "D-BUS not configured in this build of hcid"); + exit(1); + } +#endif + init_security_data(); /* Create event loop */ diff --git a/hcid/parser.y b/hcid/parser.y index e14ca200..1848bd04 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -58,7 +58,7 @@ int yyerror(char *s); %token K_OPTIONS K_DEVICE %token K_AUTOINIT K_SECURITY K_PAIRING %token K_PTYPE K_NAME K_CLASS K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN -%token K_PINHELP +%token K_PINHELP K_DBUSPINHELP %token K_YES K_NO %token WORD PATH STRING LIST HCI BDADDR @@ -112,10 +112,18 @@ hcid_opt: hcid.pairing = $2; } - | K_PINHELP PATH { + | K_PINHELP PATH { if (hcid.pin_helper) free(hcid.pin_helper); hcid.pin_helper = strdup($2); + hcid.dbus_pin_helper = 0; + } + + | K_DBUSPINHELP { + if (hcid.pin_helper) + free(hcid.pin_helper); + hcid.pin_helper = NULL; + hcid.dbus_pin_helper = 1; } | WORD { diff --git a/hcid/security.c b/hcid/security.c index 7aa9a7a4..189bc7d8 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -173,7 +173,7 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) evt_link_key_notify *evt = ptr; bdaddr_t *dba = &evt->bdaddr; struct link_key key; - char sa[18]; + char sa[18]; ba2str(sba, sa); syslog(LOG_INFO, "link_key_notify (sba=%s)\n", sa); @@ -291,6 +291,17 @@ reject: exit(0); } +static void request_pin(int dev, struct hci_conn_info *ci) +{ +#ifdef ENABLE_DBUS + if (hcid.dbus_pin_helper) { + hcid_dbus_request_pin(dev, ci); + return; + } +#endif + call_pin_helper(dev, ci); +} + static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) { struct hci_conn_info_req *cr; @@ -337,11 +348,11 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) /* Outgoing connection */ /* Let PIN helper handle that */ - call_pin_helper(dev, ci); + request_pin(dev, ci); } } else { /* Let PIN helper handle that */ - call_pin_helper(dev, ci); + request_pin(dev, ci); } free(cr); return; @@ -397,7 +408,7 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) link_key_notify(dev, &di->bdaddr, ptr); break; } - + return TRUE; } @@ -410,7 +421,7 @@ void start_security_manager(int hdev) if (chan) return; - + syslog(LOG_INFO, "Starting security manager %d", hdev); if ((dev = hci_open_dev(hdev)) < 0) { -- cgit From 1118351ad3803d4508a146762775a9ee1e05c09c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Feb 2004 18:05:38 +0000 Subject: Replace unprintable characters for device name --- tools/hciconfig.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 92292a20..651e1438 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -369,11 +370,15 @@ void cmd_name(int ctl, int hdev, char *opt) } } else { char name[248]; + int i; if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { printf("Can't read local name on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } + for (i = 0; i < 248 && name[i]; i++) + if (!isprint(name[i])) + name[i] = '.'; print_dev_hdr(&di); printf("\tName: '%s'\n", name); } -- cgit From b2d7fd8c8e1c7948169726639675d462bd83e50e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Feb 2004 18:29:02 +0000 Subject: Fix sequence increment --- test/l2test.c | 6 ++++-- test/rctest.c | 3 ++- test/scotest.c | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index d02eb3c0..4d782532 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -469,8 +469,9 @@ void send_mode(int s) seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { - *(uint32_t *) buf = htobl(seq++); + *(uint32_t *) buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); + seq++; if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); @@ -497,8 +498,9 @@ void senddump_mode(int s) seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { - *(uint32_t *) buf = htobl(seq++); + *(uint32_t *) buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); + seq++; if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); diff --git a/test/rctest.c b/test/rctest.c index 47039555..3d50ba95 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -279,8 +279,9 @@ void send_mode(int s) seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { - *(uint32_t *) buf = htobl(seq++); + *(uint32_t *) buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); + seq++; if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); diff --git a/test/scotest.c b/test/scotest.c index dcb1acdf..0c8d8da3 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -215,8 +215,9 @@ void send_mode(char *svr) seq = 0; while (1) { - *(uint32_t *)buf = htobl(seq++); + *(uint32_t *)buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); + seq++; if (send(s, buf, so.mtu, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", -- cgit From f3be9c15792728861db02c8b0a3692903a30552b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Feb 2004 23:20:50 +0000 Subject: Add command for authentication request --- tools/hcitool.1 | 4 +++ tools/hcitool.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.1 b/tools/hcitool.1 index dd92e351..bb52e1ba 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -154,6 +154,10 @@ slots, or to infinite if .I value is 0. +.TP +.BI auth " " +Request authentication for the device with Bluetooth address +.IR bdaddr . .SH AUTHORS Written by Maxim Krasnyansky .PP diff --git a/tools/hcitool.c b/tools/hcitool.c index 675d829e..3a4a59ef 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1255,6 +1255,88 @@ static void cmd_lst(int dev_id, int argc, char **argv) free(cr); } +/* Request authentication */ + +static struct option auth_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *auth_help = + "Usage:\n" + "\tauth \n"; + +static void cmd_auth(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + auth_requested_cp cp; + evt_auth_complete rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, auth_options, NULL) { + switch(opt) { + default: + printf(auth_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(auth_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = cr->conn_info->handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_AUTH_REQUESTED; + rq.cparam = &cp; + rq.clen = AUTH_REQUESTED_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_AUTH_COMPLETE_SIZE; + rq.event = EVT_AUTH_COMPLETE; + + if (hci_send_req(dd, &rq, 25000) < 0) { + perror("HCI authentication request failed"); + exit(1); + } + + close(dd); + free(cr); +} + struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -1268,14 +1350,15 @@ struct { { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, - { "dc", cmd_dc, "Disconnect from remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, { "sr", cmd_sr, "Switch master/slave role" }, { "cpt", cmd_cpt, "Change connection packet type" }, { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_lq, "Display link quality" }, { "tpl", cmd_tpl, "Display transmit power level" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, - { NULL, NULL, 0} + { "auth", cmd_auth, "Request authentication" }, + { NULL, NULL, 0 } }; static void usage(void) -- cgit From 8100e0c660e200a9d789dcd054f25a20778379cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 22 Feb 2004 13:22:36 +0000 Subject: Fix 64-bit size_t problem with HCI events --- hcid/main.c | 5 +++-- hcid/security.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hcid/main.c b/hcid/main.c index c3f4131d..2d1d5686 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -397,10 +397,11 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si) gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data) { - char buf[HCI_MAX_FRAME_SIZE], *ptr; + unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; evt_stack_internal *si; hci_event_hdr *eh; - int len, type; + int type; + size_t len; GIOError err; ptr = buf; diff --git a/hcid/security.c b/hcid/security.c index 189bc7d8..4f0d942e 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -365,9 +365,10 @@ reject: gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) { - char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; + unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_dev_info *di = (void *) data; - int len, type, dev; + int type, dev; + size_t len; hci_event_hdr *eh; GIOError err; -- cgit From 36448c2702b4f496e16cd0e7c0ea64f859eb6040 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 3 Mar 2004 03:31:18 +0000 Subject: Cleanup --- configure.in | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/configure.in b/configure.in index 4d57acdd..14496cda 100644 --- a/configure.in +++ b/configure.in @@ -5,10 +5,6 @@ dnl Process this file with autoconf to produce a configure script. dnl AC_INIT() -dnl Guess host type. -AC_CANONICAL_SYSTEM -AC_CANONICAL_HOST - AM_MAINTAINER_MODE AM_INIT_AUTOMAKE(bluez-utils, 2.4) @@ -20,18 +16,11 @@ CFLAGS="-Wall -g -O2" AC_PREFIX_DEFAULT() -dnl Check for programs. AC_PROG_CC -AC_PROG_AWK -AC_PROG_INSTALL -AC_CHECK_TOOL(LD, ld, ld) -AC_CHECK_TOOL(AR, ar, ar) AC_PROG_INSTALL AC_PROG_YACC AM_PROG_LEX -AM_PROG_LIBTOOL - AC_ARG_WITH(bluez-libs, --with-bluez-libs=DIR BlueZ libraries, BLUEZ_LIBDIR="$withval", @@ -56,20 +45,18 @@ AC_SEARCH_HEADERS(bluetooth/bluetooth.h, $BLUEZ_INCDIR,, ) AC_SEARCH_LIB(bluetooth, hci_open_dev, $BLUEZ_LIBDIR,, - AC_MSG_ERROR(Bluetooth library not found. + AC_MSG_ERROR(Bluetooth library not found. Please compile and install bluez-libs package.) ) -dnl Check for distro type. DISTRO=unknown if test "$cross_compiling" != yes; then - AC_TEST_FILE(/etc/redhat-release, DISTRO=redhat) - AC_TEST_FILE(/etc/mandrake-release, DISTRO=redhat) - AC_TEST_FILE(/etc/debian_version, DISTRO=debian) + AC_TEST_FILE(/etc/redhat-release, DISTRO=redhat) + AC_TEST_FILE(/etc/mandrake-release, DISTRO=redhat) + AC_TEST_FILE(/etc/debian_version, DISTRO=debian) fi -dnl Check for PCMCIA AC_ARG_ENABLE(pcmcia, --enable-pcmcia Always install PCMCIA support files, [PCMCIA=pcmcia], @@ -78,10 +65,10 @@ AC_ARG_ENABLE(pcmcia, fi ]) if test x"$BLUEZ_DBUS" == "xyes"; then - PKG_CHECK_MODULES(DBUS, dbus-1, have_dbus=yes, have_dbus=no) + PKG_CHECK_MODULES(DBUS, dbus-1, have_dbus=yes, have_dbus=no) - CFLAGS="$CFLAGS $DBUS_CFLAGS -DENABLE_DBUS" - LIBS="$LIBS $DBUS_LIBS" + CFLAGS="$CFLAGS $DBUS_CFLAGS -DENABLE_DBUS" + LIBS="$LIBS $DBUS_LIBS" fi AM_CONDITIONAL(ENABLE_DBUS, test x$BLUEZ_DBUS = xyes) -- cgit From 136fe53de38de79eda487f3c5c690cab45b1767a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Mar 2004 17:38:39 +0000 Subject: Display revision information for Broadcom devices --- tools/hciconfig.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 651e1438..39804e45 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -886,6 +886,11 @@ static void print_rev_csr(int dd, uint16_t rev) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); } +static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) +{ + printf("\tFirmware %d.%d.%03d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); +} + static void print_rev_avm(uint16_t rev) { printf("\tFirmware 03.%d.%d\n", rev >> 8, rev & 0xff); @@ -917,6 +922,9 @@ static void cmd_revision(int ctl, int hdev, char *opt) case 10: print_rev_csr(dd, ver.hci_rev); break; + case 15: + print_rev_broadcom(ver.hci_rev, ver.lmp_subver); + break; case 31: print_rev_avm(ver.hci_rev); break; -- cgit From 49d9fac05db902dcd7e3909fcc1380f907c9b55b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Mar 2004 23:11:21 +0000 Subject: Report an error on PIN helper failure --- hcid/security.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/hcid/security.c b/hcid/security.c index 4f0d942e..98f075f6 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -227,10 +227,11 @@ int read_pin_code(void) static void call_pin_helper(int dev, struct hci_conn_info *ci) { pin_code_reply_cp pr; + struct sigaction sa; char addr[12], str[255], *pin, name[20]; FILE *pipe; - int len; - + int ret, len; + /* Run PIN helper in the separate process */ switch (fork()) { case 0: @@ -258,6 +259,11 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1); + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &sa, NULL); + pipe = popen(str, "r"); if (!pipe) { syslog(LOG_ERR, "Can't exec PIN helper. %s(%d)", strerror(errno), errno); @@ -265,15 +271,15 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) } pin = fgets(str, sizeof(str), pipe); - pclose(pipe); + ret = pclose(pipe); if (!pin || strlen(pin) < 5) - goto reject; + goto nopin; strtok(pin, "\n\r"); if (strncmp("PIN:", pin, 4)) - goto reject; + goto nopin; pin += 4; len = strlen(pin); @@ -286,6 +292,10 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) PIN_CODE_REPLY_CP_SIZE, &pr); exit(0); +nopin: + if (!pin || strncmp("ERR", pin, 3)) + syslog(LOG_ERR, "PIN helper exited abnormally with code %d", ret); + reject: hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); exit(0); -- cgit From e1d0ebd7b44b29e9ef54ec98f07c42c01e2fd173 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Mar 2004 23:14:00 +0000 Subject: Update bluepin script for GTK2 --- scripts/bluepin | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/scripts/bluepin b/scripts/bluepin index 66eec987..607facba 100755 --- a/scripts/bluepin +++ b/scripts/bluepin @@ -3,11 +3,13 @@ # Bluetooth PIN helper # Written by Maxim Krasnyansky # -import sys, os, string, popen2 +import sys, os, string, popen2, pygtk + +pygtk.require('2.0') # X Display initialization. -# Find running X Server and parse it's arguments. -# Set enviroment variables DISPLAY and XAUTHORITY +# Find running X Server and parse its arguments. +# Set environment variables DISPLAY and XAUTHORITY # using info extracted from X Server args. # def set_display(): @@ -31,55 +33,58 @@ def set_display(): # Set X display before initializing GTK set_display() -from gtk import * +# Some versions of fontconfig will segfault if HOME isn't set. +os.environ['HOME'] = "" + +import gtk # Dialog Class DLG_OK = 1 DLG_CANCEL = 2 -class Dialog(GtkDialog): +class Dialog(gtk.Dialog): result = DLG_CANCEL args = {} - def __init__(self, modal=FALSE, mesg=None, args = {}): - GtkDialog.__init__(self) + def __init__(self, modal=gtk.FALSE, mesg=None, args = {}): + gtk.Dialog.__init__(self) self.args = args self.set_modal(modal) - self.set_usize(400, 0) - self.set_uposition(300,300) +# self.set_usize(400, 0) +# self.set_uposition(300,300) self.connect("destroy", self.quit) self.connect("delete_event", self.quit) self.action_area.set_border_width(2) - ok = GtkButton("Accept") + ok = gtk.Button("Accept") ok.connect("clicked", self.ok) self.action_area.pack_start(ok, padding = 20) ok.show() - cl = GtkButton("Reject") + cl = gtk.Button("Reject") cl.connect("clicked", self.cancel) self.action_area.pack_start(cl, padding = 20) cl.show() if mesg: - msg = GtkLabel() + msg = gtk.Label("") msg.set_text(mesg) self.vbox.pack_start(msg, padding = 10) msg.show() self.ents = [] for k in self.args.keys(): - hbox = GtkHBox() + hbox = gtk.HBox() hbox.set_border_width(5) self.vbox.pack_start(hbox) hbox.show() - l = GtkLabel() - e = GtkEntry() + l = gtk.Label("") + e = gtk.Entry() l.set_text( k ) e.set_text( self.args[k] ) e.connect("key_press_event", self.key_press) - hbox.pack_start(l, padding = 10, expand = FALSE) + hbox.pack_start(l, padding = 10, expand = gtk.FALSE) hbox.pack_start(e) l.show() e.show() @@ -89,10 +94,10 @@ class Dialog(GtkDialog): self.ents[0][1].grab_focus() def key_press(self, entry, event): - if event.keyval == GDK.Return: + if event.keyval == gtk.keysyms.Return: entry.emit_stop_by_name("key_press_event") self.ok() - elif event.keyval == GDK.Escape: + elif event.keyval == gtk.keysyms.Escape: entry.emit_stop_by_name("key_press_event") self.cancel() @@ -110,13 +115,13 @@ class Dialog(GtkDialog): def quit(self, *args): self.hide() self.destroy() - mainquit() + gtk.mainquit() -def dialog(title, mesg, args, modal = FALSE): +def dialog(title, mesg, args, modal = gtk.FALSE): dlg = Dialog(args = args, mesg = mesg, modal = modal) dlg.set_title(title) dlg.show() - mainloop() + gtk.mainloop() return dlg.result def main(*args): -- cgit From ec0e9aeb30c4733f063e7591a728d1a98649a64c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 8 Mar 2004 23:09:51 +0000 Subject: Change D-Bus service names --- hcid/dbus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 4c2bb18d..3be67d26 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -16,12 +16,12 @@ static DBusConnection *connection; #define TIMEOUT (30 * 1000) // 30 seconds -#define SERVICE_NAME "org.handhelds.gpe.bluez" -#define INTERFACE_NAME SERVICE_NAME ".PinAgent" +#define SERVICE_NAME "org.bluez.PinAgent" +#define INTERFACE_NAME SERVICE_NAME #define REQUEST_NAME "PinRequest" -#define PATH_NAME "/org/handhelds/gpe/bluez/PinAgent" +#define PATH_NAME "/org/bluez/PinAgent" -#define WRONG_ARGS_ERROR "org.handhelds.gpe.bluez.Error.WrongArgs" +#define WRONG_ARGS_ERROR "org.bluez.Error.WrongArgs" struct pin_request { -- cgit From a3607755c836532a6a6e3cb8acc911b8cf2b61da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Mar 2004 12:31:29 +0000 Subject: Give udev some time to create the RFCOMM device nodes --- rfcomm/main.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/rfcomm/main.c b/rfcomm/main.c index 17cb14b6..68396b5e 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -250,7 +250,7 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg struct sigaction sa; struct pollfd p; char dst[18], devname[MAXPATHLEN]; - int sk, fd, alen; + int sk, fd, alen, try = 3; laddr.rc_family = AF_BLUETOOTH; bacpy(&laddr.rc_bdaddr, bdaddr); @@ -270,7 +270,6 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev); return; } - } else { raddr.rc_family = AF_BLUETOOTH; str2ba(argv[1], &raddr.rc_bdaddr); @@ -322,7 +321,11 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); - if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + if (try--) { + sleep(1); + continue; + } perror("Can't open RFCOMM device"); close(sk); return; @@ -377,7 +380,7 @@ static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv struct sigaction sa; struct pollfd p; char dst[18], devname[MAXPATHLEN]; - int sk, nsk, fd, alen; + int sk, nsk, fd, alen, try = 3; laddr.rc_family = AF_BLUETOOTH; bacpy(&laddr.rc_bdaddr, bdaddr); @@ -425,7 +428,11 @@ static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); - if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + if (try--) { + sleep(1); + continue; + } perror("Can't open RFCOMM device"); close(sk); return; -- cgit From 4352b6d63fb5eb038e5f678ae143f97662b7db3b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Mar 2004 21:25:22 +0000 Subject: Add support for setting connection encryption --- tools/hcitool.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 98 insertions(+), 15 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 3a4a59ef..8fd7b83d 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -146,7 +146,7 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) /* Display local devices */ static struct option dev_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -265,7 +265,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) case 'l': length = atoi(optarg); break; - + case 'n': num_rsp = atoi(optarg); break; @@ -317,7 +317,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) /* Remote name */ static struct option name_options[] = { - {"help", 0,0, 'h'}, + {"help", 0,0, 'h'}, {0, 0, 0, 0} }; @@ -699,7 +699,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -849,7 +849,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -866,7 +866,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; @@ -933,7 +933,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -958,7 +958,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) rq.clen = 2; rq.rparam = &rp; rq.rlen = GET_LINK_QUALITY_RP_SIZE; - + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI get_link_quality request failed"); exit(1); @@ -1020,7 +1020,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -1046,7 +1046,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; rq.rparam = &rp; rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; - + if (hci_send_req(dd, &rq, 100) < 0) { perror("HCI read transmit power level request failed"); exit(1); @@ -1109,7 +1109,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -1192,7 +1192,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) exit(1); } } - + dd = hci_open_dev(dev_id); if (dd < 0) { perror("HCI device open failed"); @@ -1234,8 +1234,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) rp.link_sup_to, (float)rp.link_sup_to * 0.625); else printf("Link supervision timeout never expires\n"); - } - else { + } else { cp.handle = cr->conn_info->handle; cp.link_sup_to = strtol(argv[1], NULL, 10); @@ -1337,7 +1336,90 @@ static void cmd_auth(int dev_id, int argc, char **argv) free(cr); } -struct { +/* Activate encryption */ + +static struct option enc_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *enc_help = + "Usage:\n" + "\tenc [encrypt enable]\n"; + +static void cmd_enc(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + set_conn_encrypt_cp cp; + evt_encrypt_change rp; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, enc_options, NULL) { + switch(opt) { + default: + printf(enc_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(enc_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + cp.handle = cr->conn_info->handle; + cp.encrypt = (argc > 1) ? atoi(argv[1]) : 1; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.cparam = &cp; + rq.clen = SET_CONN_ENCRYPT_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; + rq.event = EVT_ENCRYPT_CHANGE; + + if (hci_send_req(dd, &rq, 25000) < 0) { + perror("HCI set encryption request failed"); + exit(1); + } + + close(dd); + free(cr); +} + +static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); char *doc; @@ -1358,6 +1440,7 @@ struct { { "tpl", cmd_tpl, "Display transmit power level" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, + { "enc", cmd_enc, "Set connection encryption" }, { NULL, NULL, 0 } }; -- cgit From 22dfbf516115cee3a2cc7e3c1defe92e41e74fc7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Mar 2004 22:55:49 +0000 Subject: Update changelog and bump version number --- AUTHORS | 11 +++++++---- ChangeLog | 14 ++++++++++++++ configure.in | 2 +- utils.spec | 2 +- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/AUTHORS b/AUTHORS index b3eee626..209ae29a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,10 @@ Maxim Krasnyansky Original author. + +Marcel Holtmann Primary maintainer. + Various patches, fixes and other contributions. + RFCOMM configuration utility. Ilguiz Latypov Patches. Suggestions. @@ -15,10 +19,6 @@ Jean Tourrilhes Thomas Moser Silicon Wave UART initialization. -Marcel Holtmann - Various patches, fixes and other contributions. - RFCOMM configuration utility. - Nils Faerber Man pages. @@ -33,3 +33,6 @@ Wolfgang Heidrich Fabrizio Gennari Support for link supervision timeout (hcitool). + +Philip Blundell + D-Bus PIN helper support. diff --git a/ChangeLog b/ChangeLog index dcf08308..b0ca09ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +ver 2.5: + hcitool changes: + Support for requesting authentication. + Support for setting connection encryption. + Fix some endian problems. + hciconfig changes: + Show revision information for Broadcom devices. + Replace unprintable characters in device name. + hcid changes: + Add D-Bus support for PIN request. + Report an error on PIN helper failure. + Fix some 64-bit problems. + Update bluepin script for GTK2. + ver 2.4: hcitool changes: Increase number of inquiry responses. diff --git a/configure.in b/configure.in index 14496cda..19be6b53 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT() AM_MAINTAINER_MODE -AM_INIT_AUTOMAKE(bluez-utils, 2.4) +AM_INIT_AUTOMAKE(bluez-utils, 2.5) AC_SUBST(DISTRO) AC_SUBST(PCMCIA) diff --git a/utils.spec b/utils.spec index 9df55a4b..1ea074f9 100644 --- a/utils.spec +++ b/utils.spec @@ -1,5 +1,5 @@ # Note that this is NOT a relocatable package -%define ver 2.4 +%define ver 2.5 %define RELEASE 1 %define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} %define prefix / -- cgit From 4500e3be8f2cd50536f29f04f94ba67a264c28dc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 24 Mar 2004 16:54:41 +0000 Subject: Add manpages for hcid and hcid.conf --- hcid/Makefile.am | 6 +- hcid/hcid.8 | 39 ++++++++++ hcid/hcid.conf.5 | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 hcid/hcid.8 create mode 100644 hcid/hcid.conf.5 diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 14428722..ba00df7e 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -2,6 +2,8 @@ # $Id$ # +mandir = $(prefix)/usr/share/man + sbin_PROGRAMS = hcid if ENABLE_DBUS @@ -13,11 +15,13 @@ endif hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) hcid_CONFIG = hcid.conf +man_MANS = hcid.8 hcid.conf.5 + YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -EXTRA_DIST = $(hcid_CONFIG) +EXTRA_DIST = $(hcid_CONFIG) $(man_MANS) dbus.c # # Install configuration files diff --git a/hcid/hcid.8 b/hcid/hcid.8 new file mode 100644 index 00000000..2ef8ed31 --- /dev/null +++ b/hcid/hcid.8 @@ -0,0 +1,39 @@ +.\" +.TH "HCID" "8" "March 2004" "hcid - HCI daemon" "System management commands" +.SH "NAME" +hcid \- Bluetooth Host Controller Interface Daemon + +.SH "SYNOPSIS" +.B hcid +[ +.B \-n +] [ +.B \-f +.I config\-file +] + +.SH "DESCRIPTION" +This manual page documents briefly the +.B hcid +daemon, which manages all the Bluetooth devices. +.B hcid +itself does not accept many command\-line options, as most of its +configuration is done in the +.B hcid.conf +file, which has its own man page. +.SH "OPTIONS" +.TP +.B \-n +Don't fork to run daemon in background. +.TP +.BI \-f\ config\-file +Use alternate configuration file instead of /etc/bluetooth/hcid.conf +.SH "FILES" +.TP +.I /etc/bluetooth/hcid.conf +Default location of the global configuration file. + +.SH "SEE ALSO" +\fBhcid.conf\fR(5) +.SH "AUTHOR" +This manual page was written by Philipp Matthias Hahn. diff --git a/hcid/hcid.conf.5 b/hcid/hcid.conf.5 new file mode 100644 index 00000000..4bac6de1 --- /dev/null +++ b/hcid/hcid.conf.5 @@ -0,0 +1,232 @@ +.TH "HCID.CONF" "5" "March 2004" "hcid.conf - HCI daemon" "System management commands" +.SH "NAME" +/etc/bluetooth/hcid.conf \- Configuration file for the hcid Bluetooth HCI daemon + +.SH "DESCRIPTION" +/etc/bluetooth/hcid.conf contains all the options needed by the Bluetooth Host Controller Interface daemon. + +It consists of sections and parameters. A section begins with +the name of the section followed by optional specifiers and the +parameters inside curly brackets. Sections contain parameters of +the form: +.TP +\fIname\fP \fIvalue1\fP, \fIvalue2\fP ... ; + +.PP +Any character after a hash ('#') character is ignored until newline. +Whitespace is also ignored. + + +The valid section names for +.B hcid.conf +are, at the moment: + +.TP +.B options +contains generic options for hcid and the pairing policy. +.TP +.B device +contains lower\-level options for the hci devices connected to the computer. +.SH "OPTIONS SECTION" +The following parameters may be present in an option section: + + +.TP +\fBautoinit\fP yes|no + +Automatically initialize newly connected devices. The default is \fIno\fP. + + +.TP +\fBpairing\fP none|multi|once + +\fInone\fP means that pairing is disabled. \fImulti\fP allows pairing +with already paired devices. \fIonce\fP allows pairing once and denies +successive attempts. The default hcid configuration is shipped with \fBmulti\fP +enabled + +.TP +\fBpin_helper\fP "\fIfile\fP" + +The path to the PIN helper application. The default is "/bin/bluepin". +The following output is expected from the PIN helper: + +PIN:12345678 + +Or, when no PIN is available: + +ERR + +.TP +\fBsecurity\fP none|auto|user + +\fInone\fP means the security manager is disabled. \fIauto\fP uses +local PIN for incoming connections. \fIuser\fP always asks the user +for a PIN. + +.SH "DEVICE SECTION" +Parameters within a device section with no specifier, the default +device section, will be applied to all devices and device sections +where these are unspecified. The following optional device specifiers +are supported: + +.TP +\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP + +Parameters specified within this section will be applied to the device +with this \fIdevice bluetooth address\fP. All other parameters are applied from +the default section. + +.TP +\fBhci\fIn\fP + +Parameters specified within this section will be applied to the device +with this \fIdevice interface\fP, unless that device is matched by a +\fIdevice address\fP section. All other parameters are applied from +the default section. + + +.PP +\fBNote\fP: Most of the options supported in the \fBdevice\fP section are described to some extent in the bluetooth specification version 1.2 Vol2, Part E section 6. Please refer to it for technical details. + +.PP +The following parameters may be present in a device section: + +.TP +\fBname\fP "\fIname\fP" + +The device name. \fI%d\fP inserts the device id. \fI%h\fP inserts +the host name. + + +.TP +\fBauth\fP enable|disable +Enables or disables authentication between local and remote devices when they connect. + +Authentication is done following a challenge\-response mechanism described in the Bluetooth Specification 1.2 volume 2 part C section 4.2, and uses the link key generated during pairing as the shared secret. + +.TP +\fBencrypt\fP enable|disable +Enable or disable link encryption. Should be set to enable in most cases, unless one of the devices does not support encryption for some reason. + +Encryption can only occur on authenticated connections, as a shared secret key is necessary for encryption to work. The detailed encryption mechanism is described in the bluetooth specification as mentioned above. + + +.TP +\fBclass\fP 0x\fISSDDdd\fP (three bytes) + +The Bluetooth Device Class is described in the Bluetooth Specification section 1.2 ("Assigned Numbers \- Bluetooth Baseband"). + +The default shipped with hcid is 0x000100 which simply stands for "Computer". + +The Bluetooth device class is a high\-level description of the bluetooth device, composed of three bytes: the "Major Service Class" (byte "SS" above), the "Major Device Class" (byte "DD" above) and the "Minor Device Class" (byte "dd" above). These classes describe the high\-level capabilities of the device, such as "Networking Device", "Computer", etc. This information is often used by clients who are looking for a certain type of service around them. + +Where it becomes tricky is that another type of mechanism for service discovery exists: "SDP", as in "Service Discovery Protocol". + +In practice, most Bluetooth clients scan their surroundings in two successive steps: they first look for all bluetooth devices around them and find out their "class". You can do this on Linux with the \fBhcitool scan\fP command. Then, they use SDP in order to check if a device in a given class offers the type of service that they want. + +This means that the hcid.conf "class" parameter needs to be set up properly if particular services are running on the host, such as "PAN", or "OBEX Obect Push", etc: in general a device looking for a service such as "Network Access Point" will only scan for this service on devices containing "Networking" in their major service class. + + +.IP +Major service class byte allocation (from LSB to MSB): + +Bit 1: Positioning (Location identification) + +Bit 2: Networking (LAN, Ad hoc, ...) + +Bit 3: Rendering (Printing, Speaker, ...) + +Bit 4: Capturing (Scanner, Microphone, ...) + +Bit 5: Object Transfer (v\-Inbox, v\-Folder, ...) + +Bit 6: Audio (Speaker, Microphone, Headset service, ...) + +Bit 7: Telephony (Cordless telephony, Modem, Headset service, ...) + +Bit 8: Information (WEB\-server, WAP\-server, ...) + +.IP +Example: class 0x02hhhh : the device offers networking service + + +.IP +Major device class allocation: + +0x00: Miscellaneous + +0x01: Computer (desktop,notebook, PDA, organizers, .... ) + +0x02: Phone (cellular, cordless, payphone, modem, ...) + +0x03: LAN /Network Access point + +0x04: Audio/Video (headset,speaker,stereo, video display, vcr..... + +0x05: Peripheral (mouse, joystick, keyboards, ..... ) + +0x06: Imaging (printing, scanner, camera, display, ...) + +Other values are not defined (refer to the Bluetooth specification for more details + +.IP +Minor device class allocation: the meaning of this byte depends on the major class allocation, please refer to the Bluetooth specifications for more details). + +.IP +.B Example: +if PAND runs on your server, you need to set up at least \fBclass 0x020100\fP, which stands for "Service Class: Networking" and "Device Class: Computer, Uncategorized". + + +.TP +\fBiscan\fP enable|disable +.TP +\fBpscan\fP enable|disable + +Bluetooth devices discover and connect to each other through the use of two special Bluetooth channels, the Inquiry and Page channels (described in the Bluetooth Spec Volume 1, Part A, Section 3.3.3, page 35). These two options enable the channels on the bluetooth device. + +\fBiscan enable\fP: makes the bluetooth device "discoverable" by enabling it to answer "inquiries" from other nearby bluetooth devices. + +\fBpscan enable\fP: makes the bluetooth device "connectable to" by enabling the use of the "page scan" channel. + +.TP +\fBlm\fP none|accept,master + +\fInone\fP means no specific policy. \fIaccept\fP means always accept +incoming connections. \fImaster\fP means become master on incoming +connections and deny role switch on outgoing connections. + +.TP +\fBlp\fP none|rswitch,hold,sniff,park + +\fInone\fP means no specific policy. \fIrswitch\fP means allow role +switch. \fIhold\fP means allow hold mode. \fIsniff\fP means allow +sniff mode. \fIpark\fP means allow park mode. Several options can be +combined. + +This option determines the various operational modes that are allowed for this device when it participates to a piconet. Normally hold and sniff should be enabled for standard operations. + +hold: this mode is related to synchronous communications (SCO voice channel for example). + +sniff: when in this mode, a device is only present on the piconet during determined slots of time, allowing it to do other things when it is "absent", for example to scan for other bluetooth devices. + +park: this is a mode where the device is put on standby on the piconet, for power\-saving purposes for example. + +rswitch: this is a mode that enables role\-switch (master <\-> slave) between two devices in a piconet. It is not clear whether this needs to be enabled in order to make the "lm master" setting work properly or not. + + + + +.TP +\fBpkt_type\fP DH1,DM1,HV1, etc. + +This fairly obscure option determines the packet types that the bluetooth device will send or accept. This is a very low\-level option that should probably not be changed for normal use. You do not need to specify defaults. + +You can check the Bluetooth specification version 1.2 Volume 2, Part B section 6 for more details about this. +.SH "FILES" +.TP +.I /etc/bluetooth/hcid.conf +Default location of the global configuration file. + +.SH "AUTHOR" +This manual page was written by Edouard Lafargue, Fredrik Noring and Maxim Krasnyansky. -- cgit From e474c968aa61a2cfdddb31372f27c420f0b03e08 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 17:23:00 +0000 Subject: Remove autoconf and automake specific files and update others --- AUTHORS | 1 + COPYING | 92 +- INSTALL | 182 +++ config.guess | 1371 ---------------- config.sub | 1362 ---------------- install-sh | 251 --- ltmain.sh | 4946 --------------------------------------------------------- missing | 198 --- mkinstalldirs | 40 - 9 files changed, 247 insertions(+), 8196 deletions(-) delete mode 100755 config.guess delete mode 100755 config.sub delete mode 100755 install-sh delete mode 100644 ltmain.sh delete mode 100755 missing delete mode 100755 mkinstalldirs diff --git a/AUTHORS b/AUTHORS index 209ae29a..1c4fa22e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -27,6 +27,7 @@ Martin Leopold Stephen Crane Support for human readable class of device display. + SDP server and sdptool fixes. Wolfgang Heidrich Support for displaying link quality (hcitool). diff --git a/COPYING b/COPYING index 357e7469..5b6e7c66 100644 --- a/COPYING +++ b/COPYING @@ -1,27 +1,3 @@ - - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. - - ------------------------------------------------------------------------- - GNU GENERAL PUBLIC LICENSE Version 2, June 1991 @@ -79,7 +55,7 @@ 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 @@ -134,7 +110,7 @@ above, provided that you also meet all of these conditions: 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 @@ -192,7 +168,7 @@ 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 @@ -249,7 +225,7 @@ 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 @@ -302,3 +278,63 @@ 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. + + + Copyright (C) + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. + + , 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 Library General +Public License instead of this License. diff --git a/INSTALL b/INSTALL index e69de29b..b42a17ac 100644 --- a/INSTALL +++ b/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/config.guess b/config.guess deleted file mode 100755 index ba661651..00000000 --- a/config.guess +++ /dev/null @@ -1,1371 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. - -timestamp='2001-04-20' - -# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Written by Per Bothner . -# Please send patches to . -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - - -dummy=dummy-$$ -trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int dummy(){}" > $dummy.c - for c in cc gcc c89 ; do - ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 - if test $? = 0 ; then - CC_FOR_BUILD="$c"; break - fi - done - rm -f $dummy.c $dummy.o $dummy.rel - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 8/24/94.) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # Netbsd (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # Determine the machine/vendor (is the vendor relevant). - case "${UNAME_MACHINE}" in - amiga) machine=m68k-unknown ;; - arm32) machine=arm-unknown ;; - atari*) machine=m68k-atari ;; - sun3*) machine=m68k-sun ;; - mac68k) machine=m68k-apple ;; - macppc) machine=powerpc-apple ;; - hp3[0-9][05]) machine=m68k-hp ;; - ibmrt|romp-ibm) machine=romp-ibm ;; - *) machine=${UNAME_MACHINE}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE}" in - i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - cat <$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - esac - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit 0;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; - arc64:OpenBSD:*:*) - echo mips64el-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hkmips:OpenBSD:*:*) - echo mips-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mips-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit 0;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit 0 ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit 0 ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit 0 ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; - atari*:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; - sun3*:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit 0 ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy \ - && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit 0 ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit 0 ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit 0 ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit 0 ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit 0 ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit 0 ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit 0 ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit 0 ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit 0 ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit 0 ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo rs6000-ibm-aix3.2.5 - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit 0 ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit 0 ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit 0 ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit 0 ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit 0 ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - case "${HPUX_REV}" in - 11.[0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - esac ;; - esac - fi ;; - esac - if [ "${HP_ARCH}" = "" ]; then - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy - fi ;; - esac - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; - 3050*:HI-UX:*:*) - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit 0 ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit 0 ;; - *9??*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit 0 ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit 0 ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit 0 ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit 0 ;; - hppa*:OpenBSD:*:*) - echo hppa-unknown-openbsd - exit 0 ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit 0 ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit 0 ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit 0 ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit 0 ;; - CRAY*X-MP:*:*:*) - echo xmp-cray-unicos - exit 0 ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} - exit 0 ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ - exit 0 ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY-2:*:*:*) - echo cray2-cray-unicos - exit 0 ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - exit 0 ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix - exit 0 ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - cat >$dummy.c < /* for printf() prototype */ -int main (int argc, char *argv[]) { -#else -int main (argc, argv) int argc; char *argv[]; { -#endif -#ifdef __MIPSEB__ - printf ("%s-unknown-linux-gnu\n", argv[1]); -#endif -#ifdef __MIPSEL__ - printf ("%sel-unknown-linux-gnu\n", argv[1]); -#endif - return 0; -} -EOF - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - ;; - ppc:Linux:*:*) - # Determine Lib Version - cat >$dummy.c < -#if defined(__GLIBC__) -extern char __libc_version[]; -extern char __libc_release[]; -#endif -main(argc, argv) - int argc; - char *argv[]; -{ -#if defined(__GLIBC__) - printf("%s %s\n", __libc_version, __libc_release); -#else - printf("unknown\n"); -#endif - return 0; -} -EOF - LIBC="" - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null - if test "$?" = 0 ; then - ./$dummy | grep 1\.99 > /dev/null - if test "$?" = 0 ; then LIBC="libc1" ; fi - fi - rm -f $dummy.c $dummy - echo powerpc-unknown-linux-gnu${LIBC} - exit 0 ;; - alpha:Linux:*:*) - cat <$dummy.s - .data - \$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - .text - .globl main - .align 4 - .ent main - main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - LIBC="" - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) UNAME_MACHINE="alpha" ;; - 1-0) UNAME_MACHINE="alphaev5" ;; - 1-1) UNAME_MACHINE="alphaev56" ;; - 1-101) UNAME_MACHINE="alphapca56" ;; - 2-303) UNAME_MACHINE="alphaev6" ;; - 2-307) UNAME_MACHINE="alphaev67" ;; - esac - objdump --private-headers $dummy | \ - grep ld.so.1 > /dev/null - if test "$?" = 0 ; then - LIBC="libc1" - fi - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - ld_supported_emulations=`cd /; ld --help 2>&1 \ - | sed -ne '/supported emulations:/!d - s/[ ][ ]*/ /g - s/.*supported emulations: *// - s/ .*// - p'` - case "$ld_supported_emulations" in - i*86linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 - ;; - elf_i*86) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - i*86coff) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 - ;; - esac - # Either a pre-BFD a.out linker (linux-gnuoldld) - # or one that does not give us useful --help. - # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. - # If ld does not provide *any* "supported emulations:" - # that means it is gnuoldld. - test -z "$ld_supported_emulations" && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 - case "${UNAME_MACHINE}" in - i*86) - VENDOR=pc; - ;; - *) - VENDOR=unknown; - ;; - esac - # Determine whether the default compiler is a.out or elf - cat >$dummy.c < -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif -#ifdef __ELF__ -# ifdef __GLIBC__ -# if __GLIBC__ >= 2 - printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); -# else - printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); -# endif -# else - printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); -# endif -#else - printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); -#endif - return 0; -} -EOF - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; -# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions -# are messed up and put the nodename in both sysname and nodename. - i*86:DYNIX/ptx:4*:*) - echo i386-sequent-sysv4 - exit 0 ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i*86:*:5:7*) - # Fixed at (any) Pentium or better - UNAME_MACHINE=i586 - if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then - echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} - fi - exit 0 ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` - (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit 0 ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit 0 ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit 0 ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit 0 ;; - PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit 0 ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit 0 ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit 0 ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit 0 ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit 0 ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit 0 ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit 0 ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - if test "${UNAME_MACHINE}" = "x86pc"; then - UNAME_MACHINE=pc - fi - echo `uname -p`-${UNAME_MACHINE}-nto-qnx - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-[KW]:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit 0 ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit 0 ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit 0 ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit 0 ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit 0 ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit 0 ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 -rm -f $dummy.c $dummy - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit 0 ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - c34*) - echo c34-convex-bsd - exit 0 ;; - c38*) - echo c38-convex-bsd - exit 0 ;; - c4*) - echo c4-convex-bsd - exit 0 ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/config.sub b/config.sub deleted file mode 100755 index a06a480a..00000000 --- a/config.sub +++ /dev/null @@ -1,1362 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. - -timestamp='2001-04-20' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file 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., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Please send patches to . -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit 0;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | storm-chaos* | os2-emx*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \ - | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \ - | pyramid | mn10200 | mn10300 | tron | a29k \ - | 580 | i960 | h8300 \ - | x86 | ppcbe | mipsbe | mipsle | shbe | shle \ - | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ - | hppa64 \ - | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ - | alphaev6[78] \ - | we32k | ns16k | clipper | i370 | sh | sh[34] \ - | powerpc | powerpcle \ - | 1750a | dsp16xx | pdp10 | pdp11 \ - | mips16 | mips64 | mipsel | mips64el \ - | mips64orion | mips64orionel | mipstx39 | mipstx39el \ - | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ - | mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \ - | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \ - | v850 | c4x \ - | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \ - | pj | pjl | h8500) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | w65) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - # FIXME: clean up the formatting here. - vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ - | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \ - | arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \ - | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ - | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ - | xmp-* | ymp-* \ - | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \ - | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ - | hppa2.0n-* | hppa64-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ - | alphaev6[78]-* \ - | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ - | clipper-* | orion-* \ - | sparclite-* | pdp10-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ - | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \ - | mips16-* | mips64-* | mipsel-* \ - | mips64el-* | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ - | mipstx39-* | mipstx39el-* | mcore-* \ - | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \ - | [cjt]90-* \ - | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ - | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \ - | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | ymp) - basic_machine=ymp-cray - os=-unicos - ;; - cray2) - basic_machine=cray2-cray - os=-unicos - ;; - [cjt]90) - basic_machine=${basic_machine}-cray - os=-unicos - ;; - crds | unos) - basic_machine=m68k-crds - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mipsel*-linux*) - basic_machine=mipsel-unknown - os=-linux-gnu - ;; - mips*-linux*) - basic_machine=mips-unknown - os=-linux-gnu - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon) - basic_machine=i686-pc - ;; - pentiumii | pentium2) - basic_machine=i686-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sparclite-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=t3e-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xmp) - basic_machine=xmp-cray - os=-unicos - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - mips) - if [ x$os = x-linux-gnu ]; then - basic_machine=mips-unknown - else - basic_machine=mips-mips - fi - ;; - romp) - basic_machine=romp-ibm - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh3 | sh4) - basic_machine=sh-unknown - ;; - sparc | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - c4x*) - basic_machine=c4x-none - os=-coff - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto*) - os=-nto-qnx - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-ibm) - os=-aix - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -vxsim* | -vxworks*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/install-sh b/install-sh deleted file mode 100755 index e9de2384..00000000 --- a/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/ltmain.sh b/ltmain.sh deleted file mode 100644 index 2393e14d..00000000 --- a/ltmain.sh +++ /dev/null @@ -1,4946 +0,0 @@ -# ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun configure. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Check that we have a working $echo. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell, and then maybe $echo will work. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <&2 - echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 -fi - -# Global variables. -mode=$default_mode -nonopt= -prev= -prevopt= -run= -show="$echo" -show_help= -execute_dlfiles= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" - -# Parse our command line options once, thoroughly. -while test $# -gt 0 -do - arg="$1" - shift - - case $arg in - -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - execute_dlfiles) - execute_dlfiles="$execute_dlfiles $arg" - ;; - *) - eval "$prev=\$arg" - ;; - esac - - prev= - prevopt= - continue - fi - - # Have we seen a non-optional argument yet? - case $arg in - --help) - show_help=yes - ;; - - --version) - echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" - exit 0 - ;; - - --config) - sed -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 - exit 0 - ;; - - --debug) - echo "$progname: enabling shell trace mode" - set -x - ;; - - --dry-run | -n) - run=: - ;; - - --features) - echo "host: $host" - if test "$build_libtool_libs" = yes; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - exit 0 - ;; - - --finish) mode="finish" ;; - - --mode) prevopt="--mode" prev=mode ;; - --mode=*) mode="$optarg" ;; - - --quiet | --silent) - show=: - ;; - - -dlopen) - prevopt="-dlopen" - prev=execute_dlfiles - ;; - - -*) - $echo "$modename: unrecognized option \`$arg'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - - *) - nonopt="$arg" - break - ;; - esac -done - -if test -n "$prevopt"; then - $echo "$modename: option \`$prevopt' requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 -fi - -if test -z "$show_help"; then - - # Infer the operation mode. - if test -z "$mode"; then - case $nonopt in - *cc | *++ | gcc* | *-gcc*) - mode=link - for arg - do - case $arg in - -c) - mode=compile - break - ;; - esac - done - ;; - *db | *dbx | *strace | *truss) - mode=execute - ;; - *install*|cp|mv) - mode=install - ;; - *rm) - mode=uninstall - ;; - *) - # If we have no mode, but dlfiles were specified, then do execute mode. - test -n "$execute_dlfiles" && mode=execute - - # Just use the default operation mode. - if test -z "$mode"; then - if test -n "$nonopt"; then - $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 - else - $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 - fi - fi - ;; - esac - fi - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - $echo "$modename: unrecognized option \`-dlopen'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$modename --help --mode=$mode' for more information." - - # These modes are in order of execution frequency so that they run quickly. - case $mode in - # libtool compile mode - compile) - modename="$modename: compile" - # Get the compilation command and the source file. - base_compile= - prev= - lastarg= - srcfile="$nonopt" - suppress_output= - - user_target=no - for arg - do - case $prev in - "") ;; - xcompiler) - # Aesthetically quote the previous argument. - prev= - lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - - case $arg in - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - - # Add the previous argument to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - continue - ;; - esac - - # Accept any command-line options. - case $arg in - -o) - if test "$user_target" != "no"; then - $echo "$modename: you cannot specify \`-o' more than once" 1>&2 - exit 1 - fi - user_target=next - ;; - - -static) - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` - lastarg= - IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - lastarg="$lastarg $arg" - done - IFS="$save_ifs" - lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` - - # Add the arguments to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - continue - ;; - esac - - case $user_target in - next) - # The next one is the -o target name - user_target=yes - continue - ;; - yes) - # We got the output file - user_target=set - libobj="$arg" - continue - ;; - esac - - # Accept the current argument as the source file. - lastarg="$srcfile" - srcfile="$arg" - - # Aesthetically quote the previous argument. - - # Backslashify any backslashes, double quotes, and dollar signs. - # These are the only characters that are still specially - # interpreted inside of double-quoted scrings. - lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $lastarg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - lastarg="\"$lastarg\"" - ;; - esac - - # Add the previous argument to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - done - - case $user_target in - set) - ;; - no) - # Get the name of the library object. - libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` - ;; - *) - $echo "$modename: you must specify a target with \`-o'" 1>&2 - exit 1 - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - xform='[cCFSfmso]' - case $libobj in - *.ada) xform=ada ;; - *.adb) xform=adb ;; - *.ads) xform=ads ;; - *.asm) xform=asm ;; - *.c++) xform=c++ ;; - *.cc) xform=cc ;; - *.cpp) xform=cpp ;; - *.cxx) xform=cxx ;; - *.f90) xform=f90 ;; - *.for) xform=for ;; - esac - - libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - - case $libobj in - *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; - *) - $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 - exit 1 - ;; - esac - - if test -z "$base_compile"; then - $echo "$modename: you must specify a compilation command" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $libobj" - else - removelist="$libobj" - fi - - $run $rm $removelist - trap "$run $rm $removelist; exit 1" 1 2 15 - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - removelist="$removelist $output_obj $lockfile" - trap "$run $rm $removelist; exit 1" 1 2 15 - else - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $run ln "$0" "$lockfile" 2>/dev/null; do - $show "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - echo "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - echo $srcfile > "$lockfile" - fi - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - # All platforms use -DPIC, to notify preprocessed assembler code. - command="$base_compile $srcfile $pic_flag -DPIC" - else - # Don't build PIC code - command="$base_compile $srcfile" - fi - if test "$build_old_libs" = yes; then - lo_libobj="$libobj" - dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$libobj"; then - dir="$objdir" - else - dir="$dir/$objdir" - fi - libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` - - if test -d "$dir"; then - $show "$rm $libobj" - $run $rm $libobj - else - $show "$mkdir $dir" - $run $mkdir $dir - status=$? - if test $status -ne 0 && test ! -d $dir; then - exit $status - fi - fi - fi - if test "$compiler_o_lo" = yes; then - output_obj="$libobj" - command="$command -o $output_obj" - elif test "$compiler_c_o" = yes; then - output_obj="$obj" - command="$command -o $output_obj" - fi - - $run $rm "$output_obj" - $show "$command" - if $run eval "$command"; then : - else - test -n "$output_obj" && $run $rm $removelist - exit 1 - fi - - if test "$need_locks" = warn && - test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then - echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed, then go on to compile the next one - if test x"$output_obj" != x"$libobj"; then - $show "$mv $output_obj $libobj" - if $run $mv $output_obj $libobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # If we have no pic_flag, then copy the object into place and finish. - if (test -z "$pic_flag" || test "$pic_mode" != default) && - test "$build_old_libs" = yes; then - # Rename the .lo from within objdir to obj - if test -f $obj; then - $show $rm $obj - $run $rm $obj - fi - - $show "$mv $libobj $obj" - if $run $mv $libobj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` - libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - # Now arrange that obj and lo_libobj become the same file - $show "(cd $xdir && $LN_S $baseobj $libobj)" - if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then - exit 0 - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Allow error messages only from the first compilation. - suppress_output=' >/dev/null 2>&1' - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $srcfile" - else - # All platforms use -DPIC, to notify preprocessed assembler code. - command="$base_compile $srcfile $pic_flag -DPIC" - fi - if test "$compiler_c_o" = yes; then - command="$command -o $obj" - output_obj="$obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - command="$command$suppress_output" - $run $rm "$output_obj" - $show "$command" - if $run eval "$command"; then : - else - $run $rm $removelist - exit 1 - fi - - if test "$need_locks" = warn && - test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then - echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed - if test x"$output_obj" != x"$obj"; then - $show "$mv $output_obj $obj" - if $run $mv $output_obj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Create an invalid libtool object if no PIC, so that we do not - # accidentally link it into a program. - if test "$build_libtool_libs" != yes; then - $show "echo timestamp > $libobj" - $run eval "echo timestamp > \$libobj" || exit $? - else - # Move the .lo from within objdir - $show "$mv $libobj $lo_libobj" - if $run $mv $libobj $lo_libobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - fi - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - $run $rm "$lockfile" - fi - - exit 0 - ;; - - # libtool link mode - link | relink) - modename="$modename: link" - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invokation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args="$nonopt" - compile_command="$nonopt" - finalize_command="$nonopt" - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - - avoid_version=no - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -all-static | -static) - if test "X$arg" = "X-all-static"; then - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - else - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - fi - build_libtool_libs=no - build_old_libs=yes - prefer_static_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test $# -gt 0; do - arg="$1" - shift - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test - ;; - *) qarg=$arg ;; - esac - libtool_args="$libtool_args $qarg" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - compile_command="$compile_command @OUTPUT@" - finalize_command="$finalize_command @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - compile_command="$compile_command @SYMFILE@" - finalize_command="$finalize_command @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - if test ! -f "$arg"; then - $echo "$modename: symbol file \`$arg' does not exist" - exit 1 - fi - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n $prev - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 - continue - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: more than one -exported-symbols argument is not allowed" - exit 1 - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix*) - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - ;; - esac - continue - ;; - - -L*) - dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 - exit 1 - fi - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$dir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-pw32* | *-*-beos*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-mingw* | *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # The PATH hackery in wrapper scripts is required on Windows - # in order for the loader to find any dlls it needs. - $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 - $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -o) prev=output ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -static) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` - arg= - IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Wl,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` - arg= - IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $wl$flag" - linker_flags="$linker_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - # Some other compiler flag. - -* | +*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - - *.lo | *.$objext) - # A library or standard object. - if test "$prev" = dlfiles; then - # This file was specified with -dlopen. - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $arg" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` - prev= - else - case $arg in - *.lo) libobjs="$libobjs $arg" ;; - *) objs="$objs $arg" ;; - esac - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - done # argument parsing loop - - if test -n "$prev"; then - $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - - # calculate the name of the file, without its directory - outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - # Create the object directory. - if test ! -d $output_objdir; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - status=$? - if test $status -ne 0 && test ! -d $output_objdir; then - exit $status - fi - fi - - # Determine the type of output - case $output in - "") - $echo "$modename: you must specify an output file" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - libs="$libs $deplib" - done - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - case $linkmode in - lib) - passes="conv link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 - exit 1 - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - for pass in $passes; do - if test "$linkmode" = prog; then - # Determine which files to process - case $pass in - dlopen) - libs="$dlfiles" - save_deplibs="$deplibs" # Collect dlpreopened libraries - deplibs= - ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - for deplib in $libs; do - lib= - found=no - case $deplib in - -l*) - if test "$linkmode" = oldlib && test "$linkmode" = obj; then - $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 - continue - fi - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` - for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do - # Search the libtool library - lib="$searchdir/lib${name}.la" - if test -f "$lib"; then - found=yes - break - fi - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - ;; # -l - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - ;; - *) - $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - if test "$deplibs_check_method" != pass_all; then - echo - echo "*** Warning: This library needs some functionality provided by $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - else - echo - echo "*** Warning: Linking the shared library $output against the" - echo "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - if test $found = yes || test -f "$lib"; then : - else - $echo "$modename: cannot find the library \`$lib'" 1>&2 - exit 1 - fi - - # Check to see that this really is a libtool archive. - if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - # If the library was installed with an old release of libtool, - # it will not redefine variable installed. - installed=yes - - # Read the .la file - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" = oldlib && test "$linkmode" = obj; }; then - # Add dl[pre]opened files of deplib - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - tmp_libs="$tmp_libs $deplib" - done - elif test "$linkmode" != prog && test "$linkmode" != lib; then - $echo "$modename: \`$lib' is not a convenience library" 1>&2 - exit 1 - fi - continue - fi # $pass = conv - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. - dlprefiles="$dlprefiles $lib" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - abs_ladir="$ladir" - fi - ;; - esac - laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - $echo "$modename: warning: library \`$lib' was moved." 1>&2 - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi # $installed = yes - name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" - fi - continue - fi - - if test "$linkmode" = prog && test "$pass" != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test - esac - # Need to link against all dependency_libs? - if test $linkalldeplibs = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - link_static=no # Whether the deplib will be linked statically - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - # Link against this shared library - - if test "$linkmode,$pass" = "prog,link" || - { test "$linkmode" = lib && test "$hardcode_into_libs" = yes; }; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - if test "$linkmode" = prog; then - # We need to hardcode the library path - if test -n "$shlibpath_var"; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *" $absdir "*) ;; - *) temp_rpath="$temp_rpath $dir" ;; - esac - fi - fi - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - realname="$2" - shift; shift - libname=`eval \\$echo \"$libname_spec\"` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin*) - major=`expr $current - $age` - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - soname=`echo $soroot | sed -e 's/^.*\///'` - newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a" - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - $show "extracting exported symbol list from \`$soname'" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - eval cmds=\"$extract_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - $show "generating import library for \`$soname'" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - eval cmds=\"$old_archive_from_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n $old_archive_from_expsyms_cmds - - if test "$linkmode" = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit 1 - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && \ - test "$hardcode_minus_L" != yes && \ - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - - # Try to link the static library - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - echo "*** Warning: This library needs some functionality provided by $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - echo "*** Therefore, libtool will create a static module, that should work " - echo "*** as long as the dlopening application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - convenience="$convenience $dir/$old_library" - old_convenience="$old_convenience $dir/$old_library" - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || test $build_old_libs = yes || - test $link_static = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - tmp_libs="$tmp_libs $deplib" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$deplib" && dir="." - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - fi - ;; - esac - if grep "^installed=no" $deplib > /dev/null; then - path="-L$absdir/$objdir" - else - eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - if test "$absdir" != "$libdir"; then - $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 - fi - path="-L$absdir" - fi - ;; - *) continue ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$deplibs $path" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - test "$pass" != scan && dependency_libs="$newdependency_libs" - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - *) - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - if test "$pass" = "conv" && - { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then - libs="$deplibs" # reset libs - deplibs= - fi - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 - fi - - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 - fi - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - eval libname=\"$libname_spec\" - ;; - *) - if test "$module" = no; then - $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - eval libname=\"$libname_spec\" - else - libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 - exit 1 - else - echo - echo "*** Warning: Linking the shared library $output against the non-libtool" - echo "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - if test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 - fi - - set dummy $rpath - if test $# -gt 2; then - $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 - fi - install_libdir="$2" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - libext=al - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 - fi - else - - # Parse the version information argument. - IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - IFS="$save_ifs" - - if test -n "$8"; then - $echo "$modename: too many parameters to \`-version-info'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - current="$2" - revision="$3" - age="$4" - - # Check that each of the things are valid numbers. - case $current in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $revision in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $age in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - if test $age -gt $current; then - $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - - irix) - major=`expr $current - $age + 1` - verstring="sgi$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test $loop != 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` - verstring="sgi$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - ;; - - osf) - major=`expr $current - $age` - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test $loop != 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - major=`expr $current - $age` - versuffix="-$major" - ;; - - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - verstring="0.0" - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - fi - - if test "$mode" != relink; then - # Remove our outputs. - $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" - $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - for path in $notinst_path; do - lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'` - deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'` - dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'` - done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test $hardcode_into_libs != yes || test $build_old_libs = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs -framework System" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behaviour. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $rm conftest.c - cat > conftest.c </dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null \ - | grep " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | sed 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | sed 10q \ - | egrep "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - echo "*** Warning: This library needs some functionality provided by $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name="`expr $a_deplib : '-l\(.*\)'`" - # If $name is empty we are operating on a -L argument. - if test -n "$name" && test "$name" != "0"; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - if eval echo \"$potent_lib\" 2>/dev/null \ - | sed 10q \ - | egrep "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - echo "*** Warning: This library needs some functionality provided by $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ - -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | - grep . >/dev/null; then - echo - if test "X$deplibs_check_method" = "Xnone"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - echo "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test $allow_undefined = no; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval library_names=\"$library_names_spec\" - set dummy $library_names - realname="$2" - shift; shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - test -z "$dlname" && dlname=$soname - - lib="$output_objdir/$realname" - for link - do - linknames="$linknames $link" - done - - # Ensure that we have .o objects for linkers which dislike .lo - # (e.g. aix) in case we are running --disable-static - for obj in $libobjs; do - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - if test ! -f $xdir/$oldobj; then - $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" - $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? - fi - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - eval cmds=\"$export_symbols_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - if test -n "$export_symbols_regex"; then - $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" - $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - $show "$mv \"${export_symbols}T\" \"$export_symbols\"" - $run eval '$mv "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' - fi - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval cmds=\"$archive_expsym_cmds\" - else - eval cmds=\"$archive_cmds\" - fi - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? - exit 0 - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 - fi - - case $output in - *.lo) - if test -n "$objs$old_deplibs"; then - $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 - exit 1 - fi - libobj="$output" - obj=`$echo "X$output" | $Xsed -e "$lo2o"` - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $run $rm $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${obj}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - eval cmds=\"$reload_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - $show "echo timestamp > $libobj" - $run eval "echo timestamp > $libobj" || exit $? - exit 0 - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - eval cmds=\"$reload_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - else - # Just create a symlink. - $show $rm $libobj - $run $rm $libobj - xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$libobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - $show "(cd $xdir && $LN_S $oldobj $baseobj)" - $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? - fi - - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - ;; - - prog) - case $host in - *cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;; - esac - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 - fi - - if test "$preload" = yes; then - if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && - test "$dlopen_self_static" = unknown; then - $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi - fi - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$libdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - dlsyms="${outputname}S.c" - else - $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 - fi - fi - - if test -n "$dlsyms"; then - case $dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${outputname}.nm" - - $show "$rm $nlist ${nlist}S ${nlist}T" - $run $rm "$nlist" "${nlist}S" "${nlist}T" - - # Parse the name list into a source file. - $show "creating $output_objdir/$dlsyms" - - test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ -/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ -/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* Prevent the only kind of declaration conflicts we can make. */ -#define lt_preloaded_symbols some_other_symbol - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - $show "generating symbol list for \`$output'" - - test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for arg in $progfiles; do - $show "extracting global C symbols from \`$arg'" - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - if test -n "$export_symbols_regex"; then - $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$output.exp" - $run $rm $export_symbols - $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - else - $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' - $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' - $run eval 'mv "$nlist"T "$nlist"' - fi - fi - - for arg in $dlprefiles; do - $show "extracting global C symbols from \`$arg'" - name=`echo "$arg" | sed -e 's%^.*/%%'` - $run eval 'echo ": $name " >> "$nlist"' - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -z "$run"; then - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $mv "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then - : - else - grep -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$dlsyms" - fi - - $echo >> "$output_objdir/$dlsyms" "\ - -#undef lt_preloaded_symbols - -#if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * -#else -# define lt_ptr_t char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr_t address; -} -lt_preloaded_symbols[] = -{\ -" - - sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \ - -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \ - < "$nlist" >> "$output_objdir/$dlsyms" - - $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr_t) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - fi - - pic_flag_for_symtable= - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? - - # Clean up the generated files. - $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" - $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" - - # Transform the symbol file into the correct name. - compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - ;; - *) - $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 - exit 1 - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` - fi - - if test $need_relink = no || test "$build_libtool_libs" != yes; then - # Replace the output file specification. - compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - $show "$link_command" - $run eval "$link_command" - status=$? - - # Delete the generated files. - if test -n "$dlsyms"; then - $show "$rm $output_objdir/${outputname}S.${objext}" - $run $rm "$output_objdir/${outputname}S.${objext}" - fi - - exit $status - fi - - if test -n "$shlibpath_var"; then - # We should set the shlibpath_var - rpath= - for dir in $temp_rpath; do - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) - # Absolute path. - rpath="$rpath$dir:" - ;; - *) - # Relative path: add a thisdir entry. - rpath="$rpath\$thisdir/$dir:" - ;; - esac - done - temp_rpath="$rpath" - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $run $rm $output - # Link the executable and exit - $show "$link_command" - $run eval "$link_command" || exit $? - exit 0 - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 - $echo "$modename: \`$output' will be relinked during installation" 1>&2 - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname - - $show "$link_command" - $run eval "$link_command" || exit $? - - # Now create the wrapper script. - $show "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - relink_command="cd `pwd`; $relink_command" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - fi - - # Quote $echo for shipping. - if test "X$echo" = "X$SHELL $0 --fallback-echo"; then - case $0 in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; - *) qecho="$SHELL `pwd`/$0 --fallback-echo";; - esac - qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if our run command is non-null. - if test -z "$run"; then - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) output=`echo $output|sed 's,.exe$,,'` ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) exeext=.exe ;; - *) exeext= ;; - esac - $rm $output - trap "$rm $output; exit 1" 1 2 15 - - $echo > $output "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variable: - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$echo are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - echo=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$echo works! - : - else - # Restart under the correct shell, and then maybe \$echo will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $echo >> $output "\ - - # Find the directory that this script lives in. - thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` - done - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - echo >> $output "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $mkdir \"\$progdir\" - else - $rm \"\$progdir/\$file\" - fi" - - echo >> $output "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if (eval \$relink_command); then : - else - $rm \"\$progdir/\$file\" - exit 1 - fi - fi - - $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $rm \"\$progdir/\$program\"; - $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $rm \"\$progdir/\$file\" - fi" - else - echo >> $output "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - echo >> $output "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $echo >> $output "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $echo >> $output "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $echo >> $output "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # win32 systems need to use the prog path for dll - # lookup to work - *-*-cygwin* | *-*-pw32*) - $echo >> $output "\ - exec \$progdir/\$program \${1+\"\$@\"} -" - ;; - - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2*) - $echo >> $output "\ - exec \$progdir\\\\\$program \${1+\"\$@\"} -" - ;; - - *) - $echo >> $output "\ - # Export the path to the program. - PATH=\"\$progdir:\$PATH\" - export PATH - - exec \$program \${1+\"\$@\"} -" - ;; - esac - $echo >> $output "\ - \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" - exit 1 - fi - else - # The program doesn't exist. - \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 - \$echo \"This script is just a wrapper for \$program.\" 1>&2 - echo \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" - chmod +x $output - fi - exit 0 - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - # Add in members from convenience archives. - for xlib in $addlibs; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` - done - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - eval cmds=\"$old_archive_from_new_cmds\" - else - # Ensure that we have .o objects in place in case we decided - # not to build a shared library, and have fallen back to building - # static libs even though --disable-static was passed! - for oldobj in $oldobjs; do - if test ! -f $oldobj; then - xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$oldobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` - obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - $show "(cd $xdir && ${LN_S} $obj $baseobj)" - $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? - fi - done - - eval cmds=\"$old_archive_cmds\" - fi - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$generated"; then - $show "${rm}r$generated" - $run ${rm}r$generated - fi - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - $show "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="cd `pwd`; $SHELL $0 --mode=relink $libtool_args" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - - # Only create the output if not a dry run. - if test -z "$run"; then - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` - eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdependency_libs="$newdependency_libs $libdir/$name" - ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - for lib in $dlfiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlfiles="$newdlfiles $libdir/$name" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlprefiles="$newdlprefiles $libdir/$name" - done - dlprefiles="$newdlprefiles" - fi - $rm $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - $echo > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test $need_relink = yes; then - $echo >> $output "\ -relink_command=\"$relink_command\"" - fi - done - fi - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? - ;; - esac - exit 0 - ;; - - # libtool install mode - install) - modename="$modename: install" - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then - # Aesthetically quote it. - arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$arg " - arg="$1" - shift - else - install_prog= - arg="$nonopt" - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog$arg" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest="$arg" - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) prev="-f" ;; - -g) prev="-g" ;; - -m) prev="-m" ;; - -o) prev="-o" ;; - -s) - stripme=" -s" - continue - ;; - -*) ;; - - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest="$arg" - continue - fi - ;; - esac - - # Aesthetically quote the argument. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog $arg" - done - - if test -z "$install_prog"; then - $echo "$modename: you must specify an install program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -n "$prev"; then - $echo "$modename: the \`$prev' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -z "$files"; then - if test -z "$dest"; then - $echo "$modename: no file or destination specified" 1>&2 - else - $echo "$modename: you must specify a destination" 1>&2 - fi - $echo "$help" 1>&2 - exit 1 - fi - - # Strip any trailing slash from the destination. - dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` - test "X$destdir" = "X$dest" && destdir=. - destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` - - # Not a directory, so check to see that there is only one file specified. - set dummy $files - if test $# -gt 2; then - $echo "$modename: \`$dest' is not a directory" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - library_names= - old_library= - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ - test "X$dir" = "X$file/" && dir= - dir="$dir$objdir" - - if test -n "$relink_command"; then - $echo "$modename: warning: relinking \`$file'" 1>&2 - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - continue - fi - fi - - # See the names of the shared library. - set dummy $library_names - if test -n "$2"; then - realname="$2" - shift - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - $show "$install_prog $dir/$srcname $destdir/$realname" - $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? - if test -n "$stripme" && test -n "$striplib"; then - $show "$striplib $destdir/$realname" - $run eval "$striplib $destdir/$realname" || exit $? - fi - - if test $# -gt 0; then - # Delete the old symlinks, and create new ones. - for linkname - do - if test "$linkname" != "$realname"; then - $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - fi - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - eval cmds=\"$postinstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Install the pseudo-library for information purposes. - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - instname="$dir/$name"i - $show "$install_prog $instname $destdir/$name" - $run eval "$install_prog $instname $destdir/$name" || exit $? - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - - # Install the libtool object if requested. - if test -n "$destfile"; then - $show "$install_prog $file $destfile" - $run eval "$install_prog $file $destfile" || exit $? - fi - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` - - $show "$install_prog $staticobj $staticdest" - $run eval "$install_prog \$staticobj \$staticdest" || exit $? - fi - exit 0 - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Do a test to see if this is really a libtool program. - if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - notinst_deplibs= - relink_command= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Check the variables that should have been set. - if test -z "$notinst_deplibs"; then - $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 - exit 1 - fi - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - # If there is no directory component, then add one. - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - fi - libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 - finalize=no - fi - done - - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - if test "$finalize" = yes && test -z "$run"; then - tmpdir="/tmp" - test -n "$TMPDIR" && tmpdir="$TMPDIR" - tmpdir="$tmpdir/libtool-$$" - if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : - else - $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 - continue - fi - file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` - - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - ${rm}r "$tmpdir" - continue - fi - file="$outputname" - else - $echo "$modename: warning: cannot relink \`$file'" 1>&2 - fi - else - # Install the binary that we compiled earlier. - file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyways - case $install_prog,$host in - /usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - destfile=`echo $destfile | sed -e 's,.exe$,,'` - ;; - esac - ;; - esac - $show "$install_prog$stripme $file $destfile" - $run eval "$install_prog\$stripme \$file \$destfile" || exit $? - test -n "$outputname" && ${rm}r "$tmpdir" - ;; - esac - done - - for file in $staticlibs; do - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - $show "$install_prog $file $oldlib" - $run eval "$install_prog \$file \$oldlib" || exit $? - - if test -n "$stripme" && test -n "$striplib"; then - $show "$old_striplib $oldlib" - $run eval "$old_striplib $oldlib" || exit $? - fi - - # Do each command in the postinstall commands. - eval cmds=\"$old_postinstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$future_libdirs"; then - $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 - fi - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - test -n "$run" && current_libdirs=" -n$current_libdirs" - exec $SHELL $0 --finish$current_libdirs - exit 1 - fi - - exit 0 - ;; - - # libtool finish mode - finish) - modename="$modename: finish" - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - eval cmds=\"$finish_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || admincmds="$admincmds - $cmd" - done - IFS="$save_ifs" - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $run eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - test "$show" = ":" && exit 0 - - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - echo " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - echo " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - echo " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - echo - echo "See any operating system documentation about shared libraries for" - echo "more information, such as the ld(1) and ld.so(8) manual pages." - echo "----------------------------------------------------------------------" - exit 0 - ;; - - # libtool execute mode - execute) - modename="$modename: execute" - - # The first argument is the command name. - cmd="$nonopt" - if test -z "$cmd"; then - $echo "$modename: you must specify a COMMAND" 1>&2 - $echo "$help" - exit 1 - fi - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - if test ! -f "$file"; then - $echo "$modename: \`$file' is not a file" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Read the libtool library. - dlname= - library_names= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" - continue - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 - exit 1 - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - ;; - - *) - $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` - args="$args \"$file\"" - done - - if test -z "$run"; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved enviroment variables - if test "${save_LC_ALL+set}" = set; then - LC_ALL="$save_LC_ALL"; export LC_ALL - fi - if test "${save_LANG+set}" = set; then - LANG="$save_LANG"; export LANG - fi - - # Now actually exec the command. - eval "exec \$cmd$args" - - $echo "$modename: cannot exec \$cmd$args" - exit 1 - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $echo "$cmd$args" - exit 0 - fi - ;; - - # libtool clean and uninstall mode - clean | uninstall) - modename="$modename: $mode" - rm="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) rm="$rm $arg"; rmforce=yes ;; - -*) rm="$rm $arg" ;; - *) files="$files $arg" ;; - esac - done - - if test -z "$rm"; then - $echo "$modename: you must specify an RM program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - rmdirs= - - for file in $files; do - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$file"; then - dir=. - objdir="$objdir" - else - objdir="$dir/$objdir" - fi - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - test $mode = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test $mode = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if (test -L "$file") >/dev/null 2>&1 \ - || (test -h "$file") >/dev/null 2>&1 \ - || test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - . $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - - if test $mode = uninstall; then - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - eval cmds=\"$postuninstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test $? != 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - eval cmds=\"$old_postuninstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test $? != 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - # FIXME: should reinstall the best remaining shared library. - fi - fi - ;; - - *.lo) - if test "$build_old_libs" = yes; then - oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` - rmfiles="$rmfiles $dir/$oldobj" - fi - ;; - - *) - # Do a test to see if this is a libtool program. - if test $mode = clean && - (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - relink_command= - . $dir/$file - - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - fi - ;; - esac - $show "$rm $rmfiles" - $run $rm $rmfiles || exit_status=1 - done - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - $show "rmdir $dir" - $run rmdir $dir >/dev/null 2>&1 - fi - done - - exit $exit_status - ;; - - "") - $echo "$modename: you must specify a MODE" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 - ;; - esac - - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 -fi # test -z "$show_help" - -# We need to display help for each of the modes. -case $mode in -"") $echo \ -"Usage: $modename [OPTION]... [MODE-ARG]... - -Provide generalized library-building support services. - - --config show all configuration variables - --debug enable verbose shell tracing --n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --finish same as \`--mode=finish' - --help display this help message and exit - --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] - --quiet same as \`--silent' - --silent don't print informational messages - --version print version information - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for -a more detailed description of MODE." - exit 0 - ;; - -clean) - $echo \ -"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - -compile) - $echo \ -"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -static always build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - -execute) - $echo \ -"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - -finish) - $echo \ -"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - -install) - $echo \ -"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - -link) - $echo \ -"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -static do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - -uninstall) - $echo \ -"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - -*) - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; -esac - -echo -$echo "Try \`$modename --help' for more information about other modes." - -exit 0 - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/missing b/missing deleted file mode 100755 index d46f79f6..00000000 --- a/missing +++ /dev/null @@ -1,198 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. -# Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc. -# Franc,ois Pinard , 1996. - -# 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, 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., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.in; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -case "$1" in - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - yacc create \`y.tab.[ch]', if possible, from existing .[ch]" - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing - GNU libit 0.0" - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - - aclocal) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acinclude.m4' or \`$configure_ac'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`$configure_ac'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acconfig.h' or \`$configure_ac'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case "$f" in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if [ ! -f y.tab.h ]; then - echo >y.tab.h - fi - if [ ! -f y.tab.c ]; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if [ ! -f lex.yy.c ]; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - makeinfo) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` - fi - touch $file - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequirements for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 diff --git a/mkinstalldirs b/mkinstalldirs deleted file mode 100755 index 6b3b5fc5..00000000 --- a/mkinstalldirs +++ /dev/null @@ -1,40 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Public domain - -# $Id$ - -errstatus=0 - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d - do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# mkinstalldirs ends here -- cgit From 280cca9f112cbc2f86a9b7653a2ad003769e4fcb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 20:14:52 +0000 Subject: Add sdptool utility --- tools/Makefile.am | 7 +- tools/sdptool.1 | 116 +++ tools/sdptool.c | 2072 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2192 insertions(+), 3 deletions(-) create mode 100644 tools/sdptool.1 create mode 100644 tools/sdptool.c diff --git a/tools/Makefile.am b/tools/Makefile.am index 180c0cc1..4ddeb5c9 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -5,12 +5,13 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = hciattach hciconfig -bin_PROGRAMS = hcitool l2ping + +bin_PROGRAMS = hcitool l2ping sdptool hciconfig_SOURCES = hciconfig.c csr.h csr.c -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 noinst_PROGRAMS = ppporc -EXTRA_DIST = $(man_MANS) +EXTRA_DIST = $(man_MANS) diff --git a/tools/sdptool.1 b/tools/sdptool.1 new file mode 100644 index 00000000..8f938f92 --- /dev/null +++ b/tools/sdptool.1 @@ -0,0 +1,116 @@ +.\" $Header$ +.\" +.\" transcript compatibility for postscript use. +.\" +.\" synopsis: .P! +.\" +.de P! +.fl +\!!1 setgray +.fl +\\&.\" +.fl +\!!0 setgray +.fl \" force out current output buffer +\!!save /psv exch def currentpoint translate 0 0 moveto +\!!/showpage{}def +.fl \" prolog +.sy sed -e 's/^/!/' \\$1\" bring in postscript file +\!!psv restore +. +.de pF +.ie \\*(f1 .ds f1 \\n(.f +.el .ie \\*(f2 .ds f2 \\n(.f +.el .ie \\*(f3 .ds f3 \\n(.f +.el .ie \\*(f4 .ds f4 \\n(.f +.el .tm ? font overflow +.ft \\$1 +.. +.de fP +.ie !\\*(f4 \{\ +. ft \\*(f4 +. ds f4\" +' br \} +.el .ie !\\*(f3 \{\ +. ft \\*(f3 +. ds f3\" +' br \} +.el .ie !\\*(f2 \{\ +. ft \\*(f2 +. ds f2\" +' br \} +.el .ie !\\*(f1 \{\ +. ft \\*(f1 +. ds f1\" +' br \} +.el .tm ? font underflow +.. +.ds f1\" +.ds f2\" +.ds f3\" +.ds f4\" +'\" t +.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n +.TH "sdptool" "1" +.SH "NAME" +sdptool \(em control and interrogate SDP servers +.SH "SYNOPSIS" +.PP +\fBsdptool\fR [\fIoptions\fR] {\fIcommand\fR} [\fIcommand parameters\fR \&...] +.SH "DESCRIPTION" +.PP +\fBsdptool\fR provides the interface for +performing SDP queries on Bluetooth devices, and administering a +local \fBsdpd\fR. +.SH "COMMANDS" +.PP +The following commands are available. +.IP "\fBsearch [--bdaddr bdaddr] [--tree] service\fP" 10 +Search for services.. +.IP "" 10 +Known service names are SP< DUN, LAN, FAX, OPUSH, +FTRN, NAP, GN, HID, CIP. +.IP "\fBbrowse [--tree] [bdaddr]\fP" 10 +Browse all available services on the device +specified by a Bluetooth address as a parameter. +.IP "\fBadd [ --channel=N ]\fP" 10 +Add a service to the local +\fBsdpd\fR. +.IP "" 10 +You can specify a channel to add the service on +using the \fB--channel\fP option. +.IP "\fBdel record_handle\fP" 10 +Remove a service from the local +\fBsdpd\fR. +.IP "\fBget [--tree] [--bdaddr bdaddr] record_handle\fP" 10 +Retrieve a service from the local +\fBsdpd\fR. +.IP "\fBsetattr record_handle attrib_id attrib_value\fP" 10 +Set or add an attribute to an SDP record. + +.IP "\fBsetseq record_handle attrib_id attrib_values\fP" 10 +Set or add an attribute sequence to an +SDP record. +.SH "OPTIONS" +.IP "\fB--help\fP" 10 +Displays help on using sdptool. + +.SH "EXAMPLES" +.PP +sdptool browse 00:80:98:24:15:6D +.PP +sdptool add DUN +.PP +sdptool del LAN +.SH "BUGS" +.PP +Documentation needs improving. +.SH "AUTHOR" +.PP +Maxim Krasnyansky . Man page written +by Edd Dumbill . + +.SH "SEE ALSO" +.PP +sdpd(8) +.\" created by instant / docbook-to-man, Thu 15 Jan 2004, 21:01 diff --git a/tools/sdptool.c b/tools/sdptool.c new file mode 100644 index 00000000..5340ab1b --- /dev/null +++ b/tools/sdptool.c @@ -0,0 +1,2072 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky + Copyright (C) 2002 Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1) + +/* + * Convert a string to a BDADDR, with a few "enhancements" - Jean II + */ +int estr2ba(char *str, bdaddr_t *ba) +{ + /* Only trap "local", "any" is already dealt with */ + if(!strcmp(str, "local")) { + bacpy(ba, BDADDR_LOCAL); + return 0; + } + return str2ba(str, ba); +} + +/* Pass args to the inquiry/search handler */ +struct search_context { + char *svc; /* Service */ + uuid_t group; /* Browse group */ + int tree; /* Display full attribute tree */ + uint32_t handle; /* Service record handle */ +}; + +typedef int (*handler_t)(bdaddr_t *bdaddr, struct search_context *arg); + +static char UUID_str[MAX_LEN_UUID_STR]; +static bdaddr_t interface; + +/* Definition of attribute members */ +struct member_def { + char *name; +}; + +/* Definition of an attribute */ +struct attrib_def { + int num; /* Numeric ID - 16 bits */ + char * name; /* User readable name */ + struct member_def * members; /* Definition of attribute args */ + int member_max; /* Max of attribute arg definitions */ +}; + +/* Definition of a service or protocol */ +struct uuid_def { + int num; /* Numeric ID - 16 bits */ + char * name; /* User readable name */ + struct attrib_def * attribs; /* Specific attribute definitions */ + int attrib_max; /* Max of attribute definitions */ +}; + +/* Context information about current attribute */ +struct attrib_context { + struct uuid_def * service; /* Service UUID, if known */ + struct attrib_def * attrib; /* Description of the attribute */ + int member_index; /* Index of current attribute member */ +}; + +/* Context information about the whole service */ +struct service_context { + struct uuid_def * service; /* Service UUID, if known */ +}; + +/* Allow us to do nice formatting of the lists */ +static char *indent_spaces = " "; + +/* ID of the service attribute. + * Most attributes after 0x200 are defined based on the service, so + * we need to find what is the service (which is messy) - Jean II */ +#define SERVICE_ATTR 0x1 + +/* Definition of the optional arguments in protocol list */ +static struct member_def protocol_members[] = { + { "Protocol" }, + { "Channel/Port" }, + { "Version" }, +}; + +/* Definition of the optional arguments in profile list */ +static struct member_def profile_members[] = { + { "Profile" }, + { "Version" }, +}; + +/* Definition of the optional arguments in Language list */ +static struct member_def language_members[] = { + { "Code ISO639" }, + { "Encoding" }, + { "Base Offset" }, +}; + +/* Name of the various common attributes. See BT assigned numbers */ +static struct attrib_def attrib_names[] = { + { 0x0, "ServiceRecordHandle", NULL, 0 }, + { 0x1, "ServiceClassIDList", NULL, 0 }, + { 0x2, "ServiceRecordState", NULL, 0 }, + { 0x3, "ServiceID", NULL, 0 }, + { 0x4, "ProtocolDescriptorList", + protocol_members, sizeof(protocol_members)/sizeof(struct member_def) }, + { 0x5, "BrowseGroupList", NULL, 0 }, + { 0x6, "LanguageBaseAttributeIDList", + language_members, sizeof(language_members)/sizeof(struct member_def) }, + { 0x7, "ServiceInfoTimeToLive", NULL, 0 }, + { 0x8, "ServiceAvailability", NULL, 0 }, + { 0x9, "BluetoothProfileDescriptorList", + profile_members, sizeof(profile_members)/sizeof(struct member_def) }, + { 0xA, "DocumentationURL", NULL, 0 }, + { 0xB, "ClientExecutableURL", NULL, 0 }, + { 0xC, "IconURL", NULL, 0 }, + { 0xD, "AdditionalProtocolDescriptorLists", NULL, 0 }, + /* Definitions after that are tricky (per profile or offset) */ +}; + +const int attrib_max = sizeof(attrib_names)/sizeof(struct attrib_def); + +/* Name of the various SPD attributes. See BT assigned numbers */ +static struct attrib_def sdp_attrib_names[] = { + { 0x200, "VersionNumberList", NULL, 0 }, + { 0x201, "ServiceDatabaseState", NULL, 0 }, +}; + +/* Name of the various SPD attributes. See BT assigned numbers */ +static struct attrib_def browse_attrib_names[] = { + { 0x200, "GroupID", NULL, 0 }, +}; + +/* Name of the various PAN attributes. See BT assigned numbers */ +/* Note : those need to be double checked - Jean II */ +static struct attrib_def pan_attrib_names[] = { + { 0x200, "IpSubnet", NULL, 0 }, /* Obsolete ??? */ + { 0x30A, "SecurityDescription", NULL, 0 }, + { 0x30B, "NetAccessType", NULL, 0 }, + { 0x30C, "MaxNetAccessrate", NULL, 0 }, + { 0x30D, "IPv4Subnet", NULL, 0 }, + { 0x30E, "IPv6Subnet", NULL, 0 }, +}; + +/* Name of the various Generic-Audio attributes. See BT assigned numbers */ +/* Note : totally untested - Jean II */ +static struct attrib_def audio_attrib_names[] = { + { 0x302, "Remote audio volume control", NULL, 0 }, +}; + +/* Same for the UUIDs. See BT assigned numbers */ +static struct uuid_def uuid16_names[] = { + /* -- Protocols -- */ + { 0x1, "SDP (Service Discovery Protocol)", NULL, 0 }, + { 0x2, "UDP", NULL, 0 }, + { 0x3, "RFCOMM", NULL, 0 }, + { 0x4, "TCP", NULL, 0 }, + { 0x5, "TCS-BIN", NULL, 0 }, + { 0x6, "TCS-AT", NULL, 0 }, + { 0x8, "OBEX", NULL, 0 }, + { 0x9, "IP", NULL, 0 }, + { 0xA, "FTP", NULL, 0 }, + { 0xC, "HTTP", NULL, 0 }, + { 0xE, "WSP", NULL, 0 }, + { 0xF, "BNEP (PAN/BNEP)", NULL, 0 }, + { 0x10, "UPnP/ESDP", NULL, 0 }, + { 0x11, "HIDP", NULL, 0 }, + { 0x12, "HardcopyControlChannel", NULL, 0 }, + { 0x14, "HardcopyDataChannel", NULL, 0 }, + { 0x16, "HardcopyNotification", NULL, 0 }, + { 0x17, "AVCTP", NULL, 0 }, + { 0x19, "AVDTP", NULL, 0 }, + { 0x1B, "CMTP", NULL, 0 }, + { 0x1D, "UDI_C-Plane", NULL, 0 }, + { 0x100, "L2CAP", NULL, 0 }, + /* -- Services -- */ + { 0x1000, "ServiceDiscoveryServerServiceClassID (SDP)", + sdp_attrib_names, sizeof(sdp_attrib_names)/sizeof(struct attrib_def) }, + { 0x1001, "BrowseGroupDescriptorServiceClassID (SDP)", + browse_attrib_names, + sizeof(browse_attrib_names)/sizeof(struct attrib_def) }, + { 0x1002, "PublicBrowseGroup (SDP)", NULL, 0 }, + { 0x1101, "SerialPort", NULL, 0 }, + { 0x1102, "LANAccessUsingPPP", NULL, 0 }, + { 0x1103, "DialupNetworking (DUN)", NULL, 0 }, + { 0x1104, "IrMCSync", NULL, 0 }, + { 0x1105, "OBEXObjectPush", NULL, 0 }, + { 0x1106, "OBEXFileTransfer", NULL, 0 }, + { 0x1107, "IrMCSyncCommand", NULL, 0 }, + { 0x1108, "Headset", + audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, + { 0x1109, "CordlessTelephony", NULL, 0 }, + /* ... */ + { 0x110F, "VideoConferencing", NULL, 0 }, + { 0x1110, "Intercom", NULL, 0 }, + { 0x1111, "Fax", NULL, 0 }, + { 0x1112, "HeadsetAudioGateway", NULL, 0 }, + { 0x1113, "WAP", NULL, 0 }, + { 0x1114, "WAP_CLIENT", NULL, 0 }, + { 0x1115, "PANU (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1116, "NAP (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1117, "GN (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1118, "DirectPrinting (BPP)", NULL, 0 }, + { 0x1119, "ReferencePrinting (BPP)", NULL, 0 }, + /* ... */ + { 0x111e, "Handsfree", NULL, 0 }, + { 0x111f, "HandsfreeAudioGateway", NULL, 0 }, + { 0x1120, "DirectPrintingReferenceObjectsService (BPP)", NULL, 0 }, + { 0x1121, "ReflectedUI (BPP)", NULL, 0 }, + { 0x1122, "BasicPrinting (BPP)", NULL, 0 }, + { 0x1123, "PrintingStatus (BPP)", NULL, 0 }, + { 0x1124, "HumanInterfaceDeviceService (HID)", NULL, 0 }, + { 0x1125, "HardcopyCableReplacement (HCR)", NULL, 0 }, + { 0x1126, "HCR_Print (HCR)", NULL, 0 }, + { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, + { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, + { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, + /* ... */ + { 0x1200, "PnPInformation", NULL, 0 }, + { 0x1201, "GenericNetworking", NULL, 0 }, + { 0x1202, "GenericFileTransfer", NULL, 0 }, + { 0x1203, "GenericAudio", + audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, + { 0x1204, "GenericTelephony", NULL, 0 }, +}; + +const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); + +void sdp_data_printf(sdp_data_t *, struct attrib_context *, int); + +/* + * Parse a UUID. + * The BT assigned numbers only list UUID16, so I'm not sure the + * other types will ever get used... + */ +void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int indent) +{ + if (uuid) { + if (uuid->type == SDP_UUID16) { + uint16_t uuidNum = uuid->value.uuid16; + struct uuid_def *uuidDef = NULL; + int i; + + for(i = 0; i < uuid16_max; i++) + if(uuid16_names[i].num == uuidNum) { + uuidDef = &uuid16_names[i]; + break; + } + + /* Check if it's the service attribute */ + if (context->attrib && context->attrib->num == SERVICE_ATTR) { + /* We got the service ID !!! */ + context->service = uuidDef; + } + + if(uuidDef) + printf("%.*sUUID16 : 0x%.4x - %s\n", + indent, indent_spaces, + uuidNum, uuidDef->name); + else + printf("%.*sUUID16 : 0x%.4x\n", + indent, indent_spaces, uuidNum); + } else if (uuid->type == SDP_UUID32) { + printf("%.*sUUID32 : 0x%.8x\n", + indent, indent_spaces, uuid->value.uuid32); + } else if (uuid->type == SDP_UUID128) { + unsigned int data0; + unsigned short data1; + unsigned short data2; + unsigned short data3; + unsigned int data4; + unsigned short data5; + + memcpy(&data0, &uuid->value.uuid128.data[0], 4); + memcpy(&data1, &uuid->value.uuid128.data[4], 2); + memcpy(&data2, &uuid->value.uuid128.data[6], 2); + memcpy(&data3, &uuid->value.uuid128.data[8], 2); + memcpy(&data4, &uuid->value.uuid128.data[10], 4); + memcpy(&data5, &uuid->value.uuid128.data[14], 2); + + printf("%.*sUUID128 : 0x%.8x-%.4x-%.4x-%.4x-%.8x-%.4x\n", + indent, indent_spaces, + ntohl(data0), ntohs(data1), ntohs(data2), + ntohs(data3), ntohl(data4), ntohs(data5)); + } else + printf("%.*sEnum type of UUID not set\n", + indent, indent_spaces); + } else + printf("%.*sNull passed to print UUID\n", + indent, indent_spaces); +} + +/* + * Parse a sequence of data elements (i.e. a list) + */ +static void printf_dataseq(sdp_data_t * pData, + struct attrib_context *context, + int indent) +{ + sdp_data_t *sdpdata = NULL; + + sdpdata = pData; + if (sdpdata) { + context->member_index = 0; + do { + sdp_data_printf(sdpdata, context, indent + 2); + sdpdata = sdpdata->next; + context->member_index++; + } while (sdpdata); + } else { + printf("%.*sBroken dataseq link\n", indent, indent_spaces); + } +} + +/* + * Parse a single data element (either in the attribute or in a data + * sequence). + */ +void sdp_data_printf(sdp_data_t *sdpdata, + struct attrib_context *context, + int indent) +{ + char *member_name = NULL; + + /* Find member name. Almost black magic ;-) */ + if (context->attrib && context->attrib->members && + context->member_index < context->attrib->member_max) { + member_name = context->attrib->members[context->member_index].name; + } + + switch (sdpdata->dtd) { + case SDP_DATA_NIL: + printf("%.*sNil\n", indent, indent_spaces); + break; + case SDP_BOOL: + case SDP_UINT8: + case SDP_UINT16: + case SDP_UINT32: + case SDP_UINT64: + case SDP_UINT128: + case SDP_INT8: + case SDP_INT16: + case SDP_INT32: + case SDP_INT64: + case SDP_INT128: + if (member_name) { + printf("%.*s%s (Integer) : 0x%x\n", + indent, indent_spaces, + member_name, sdpdata->val.uint32); + } else { + printf("%.*sInteger : 0x%x\n", indent, indent_spaces, + sdpdata->val.uint32); + } + break; + + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + //printf("%.*sUUID\n", indent, indent_spaces); + sdp_uuid_printf(&sdpdata->val.uuid, context, indent); + break; + + case SDP_TEXT_STR8: + case SDP_TEXT_STR16: + case SDP_TEXT_STR32: + printf("%.*sText : \"%s\"\n", indent, indent_spaces, + sdpdata->val.str); + break; + case SDP_URL_STR8: + case SDP_URL_STR16: + case SDP_URL_STR32: + printf("%.*sURL : %s\n", indent, indent_spaces, + sdpdata->val.str); + break; + + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + printf("%.*sData Sequence\n", indent, indent_spaces); + printf_dataseq(sdpdata->val.dataseq, context, indent); + break; + + case SDP_ALT8: + case SDP_ALT16: + case SDP_ALT32: + printf("%.*sData Sequence Alternates\n", indent, indent_spaces); + printf_dataseq(sdpdata->val.dataseq, context, indent); + break; + } +} + +/* + * Parse a single attribute. + */ +void sdp_attr_printf_func(void *value, void *userData) +{ + sdp_data_t *sdpdata = NULL; + uint16_t attrId; + struct service_context *service = (struct service_context *) userData; + struct attrib_context context; + struct attrib_def *attrDef = NULL; + int i; + + sdpdata = (sdp_data_t *)value; + attrId = sdpdata->attrId; + /* Search amongst the generic attributes */ + for (i = 0; i < attrib_max; i++) + if (attrib_names[i].num == attrId) { + attrDef = &attrib_names[i]; + break; + } + /* Search amongst the specific attributes of this service */ + if ((attrDef == NULL) && + (service->service != NULL) && + (service->service->attribs != NULL)) { + struct attrib_def *svc_attribs = service->service->attribs; + int svc_attrib_max = service->service->attrib_max; + for (i = 0; i < svc_attrib_max; i++) + if (svc_attribs[i].num == attrId) { + attrDef = &svc_attribs[i]; + break; + } + } + + if (attrDef) + printf("Attribute Identifier : 0x%x - %s\n", + attrId, attrDef->name); + else + printf("Attribute Identifier : 0x%x\n", attrId); + /* Build context */ + context.service = service->service; + context.attrib = attrDef; + context.member_index = 0; + /* Parse attribute members */ + if (sdpdata) + sdp_data_printf(sdpdata, &context, 2); + else + printf(" NULL value\n"); + /* Update service */ + service->service = context.service; +} + +/* + * Main entry point of this library. Parse a SDP record. + * We assume the record has already been read, parsed and cached + * locally. Jean II + */ +void sdp_printf_service_attr(sdp_record_t *rec) +{ + if (rec && rec->attrlist) { + struct service_context service = { NULL }; + sdp_list_foreach(rec->attrlist, sdp_attr_printf_func, &service); + } +} + +/* + * Set attributes with single values in SDP record + * Jean II + */ +int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *value) +{ + sdp_list_t *attrid_list; + uint32_t range = 0x0000ffff; + sdp_record_t *rec; + + /* Get the old SDP record */ + attrid_list = sdp_list_append(NULL, &range); + rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attrid_list); + + if (!rec) { + printf("Service get request failed.\n"); + return -1; + } + + /* Check the type of attribute */ + if (!strncasecmp(value, "u0x", 3)) { + /* UUID16 */ + uint16_t value_int = 0; + uuid_t value_uuid; + value_int = strtoul(value + 3, NULL, 16); + sdp_uuid16_create(&value_uuid, value_int); + printf("Adding attrib 0x%X uuid16 0x%X to record 0x%X\n", + attrib, value_int, handle); + + sdp_attr_add_new(rec, attrib, SDP_UUID16, &value_uuid.value.uuid16); + } else if (!strncasecmp(value, "0x", 2)) { + /* Int */ + uint32_t value_int; + value_int = strtoul(value + 2, NULL, 16); + printf("Adding attrib 0x%X int 0x%X to record 0x%X\n", + attrib, value_int, handle); + + sdp_attr_add_new(rec, attrib, SDP_UINT32, &value_int); + } else { + /* String */ + printf("Adding attrib 0x%X string \"%s\" to record 0x%X\n", + attrib, value, handle); + + /* Add/Update our attribute to the record */ + sdp_attr_add_new(rec, attrib, SDP_TEXT_STR8, value); + } + + /* Update on the server */ + if (sdp_record_update(sess, rec)) { + printf("Service Record update failed (%d).\n", errno); + return -1; + } + return 0; +} + +static struct option set_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *set_help = + "Usage:\n" + "\tget record_handle attrib_id attrib_value\n"; + +/* + * Add an attribute to an existing SDP record on the local SDP server + */ +int cmd_setattr(int argc, char **argv) +{ + int opt, status; + uint32_t handle; + uint16_t attrib; + sdp_session_t *sess; + + for_each_opt(opt, set_options, NULL) { + switch(opt) { + default: + printf(set_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 3) { + printf(set_help); + return -1; + } + + /* Convert command line args */ + handle = strtoul(argv[0], NULL, 16); + attrib = strtoul(argv[1], NULL, 16); + + /* Do it */ + sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); + if (!sess) + return -1; + status = set_attrib(sess, handle, attrib, argv[2]); + sdp_close(sess); + return status; +} + +/* + * We do only simple data sequences. Sequence of sequences is a pain ;-) + * Jean II + */ +int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attrib, int argc, char **argv) +{ + sdp_list_t *attrid_list; + uint32_t range = 0x0000ffff; + sdp_record_t *rec; + sdp_data_t *pSequenceHolder = NULL; + void **dtdArray; + void **valueArray; + void **allocArray; + uint8_t uuid16 = SDP_UUID16; + uint8_t uint32 = SDP_UINT32; + uint8_t str8 = SDP_TEXT_STR8; + int i; + + /* Get the old SDP record */ + attrid_list = sdp_list_append(NULL, &range); + rec = sdp_service_attr_req(session, handle, SDP_ATTR_REQ_RANGE, attrid_list); + + if (!rec) { + printf("Service get request failed.\n"); + return -1; + } + + /* Create arrays */ + dtdArray = (void **)malloc(argc * sizeof(void *)); + valueArray = (void **)malloc(argc * sizeof(void *)); + allocArray = (void **)malloc(argc * sizeof(void *)); + + /* Loop on all args, add them in arrays */ + for (i = 0; i < argc; i++) { + /* Check the type of attribute */ + if (!strncasecmp(argv[i], "u0x", 3)) { + /* UUID16 */ + uint16_t value_int = strtoul((argv[i]) + 3, NULL, 16); + uuid_t *value_uuid = (uuid_t *)malloc(sizeof(uuid_t)); + allocArray[i] = value_uuid; + sdp_uuid16_create(value_uuid, value_int); + + printf("Adding uuid16 0x%X to record 0x%X\n", + value_int, handle); + dtdArray[i] = &uuid16; + valueArray[i] = &value_uuid->value.uuid16; + } else if (!strncasecmp(argv[i], "0x", 2)) { + /* Int */ + uint32_t *value_int = (int *)malloc(sizeof(int)); + allocArray[i] = value_int; + *value_int = strtoul((argv[i]) + 2, NULL, 16); + + printf("Adding int 0x%X to record 0x%X\n", + *value_int, handle); + dtdArray[i] = &uint32; + valueArray[i] = value_int; + } else { + /* String */ + printf("Adding string \"%s\" to record 0x%X\n", + argv[i], handle); + dtdArray[i] = &str8; + valueArray[i] = argv[i]; + } + } + + /* Add this sequence to the attrib list */ + pSequenceHolder = sdp_seq_alloc(dtdArray, valueArray, argc); + if (pSequenceHolder) { + sdp_attr_replace(rec, attrib, pSequenceHolder); + + /* Update on the server */ + if (sdp_record_update(session, rec)) { + printf("Service Record update failed (%d).\n", errno); + return -1; + } + } else { + printf("Failed to create pSequenceHolder\n"); + } + + /* Cleanup */ + for (i = 0; i < argc; i++) + free(allocArray[i]); + free(dtdArray); + free(valueArray); + + return 0; +} + +static struct option seq_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *seq_help = + "Usage:\n" + "\tget record_handle attrib_id attrib_values\n"; + +/* + * Add an attribute sequence to an existing SDP record + * on the local SDP server + */ +int cmd_setseq(int argc, char **argv) +{ + int opt, status; + uint32_t handle; + uint16_t attrib; + sdp_session_t *sess; + + for_each_opt(opt, seq_options, NULL) { + switch(opt) { + default: + printf(seq_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 3) { + printf(seq_help); + return -1; + } + + /* Convert command line args */ + handle = strtoul(argv[0], NULL, 16); + attrib = strtoul(argv[1], NULL, 16); + + argc -= 2; + argv += 2; + + /* Do it */ + sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); + if (!sess) + return -1; + status = set_attribseq(sess, handle, attrib, argc, argv); + sdp_close(sess); + return status; +} + +static void print_service_class(void *value, void *userData) +{ + char ServiceClassUUID_str[MAX_LEN_SERVICECLASS_UUID_STR]; + uuid_t *uuid = (uuid_t *)value; + + sdp_uuid2strn(uuid, UUID_str, MAX_LEN_UUID_STR); + sdp_svclass_uuid2strn(uuid, ServiceClassUUID_str, MAX_LEN_SERVICECLASS_UUID_STR); + printf(" \"%s\" (0x%s)\n", ServiceClassUUID_str, UUID_str); +} + +static void print_service_desc(void *value, void *user) +{ + char str[MAX_LEN_PROTOCOL_UUID_STR]; + sdp_data_t *p = (sdp_data_t *)value, *s; + int i = 0, proto = 0; + + for (; p; p = p->next, i++) { + switch (p->dtd) { + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + sdp_uuid2strn(&p->val.uuid, UUID_str, MAX_LEN_UUID_STR); + sdp_proto_uuid2strn(&p->val.uuid, str, sizeof(str)); + proto = sdp_uuid_to_proto(&p->val.uuid); + printf(" \"%s\" (0x%s)\n", str, UUID_str); + break; + case SDP_UINT8: + if (proto == RFCOMM_UUID) + printf(" Channel: %d\n", p->val.uint8); + else + printf(" uint8: 0x%x\n", p->val.uint8); + break; + case SDP_UINT16: + if (proto == L2CAP_UUID) { + if (i == 1) + printf(" PSM: %d\n", p->val.uint16); + else + printf(" Version: 0x%04x\n", p->val.uint16); + } else if (proto == BNEP_UUID) + if (i == 1) + printf(" Version: 0x%04x\n", p->val.uint16); + else + printf(" uint16: 0x%x\n", p->val.uint16); + else + printf(" uint16: 0x%x\n", p->val.uint16); + break; + case SDP_SEQ16: + printf(" SEQ16:"); + for (s = p->val.dataseq; s; s = s->next) + printf(" %x", s->val.uint16); + printf("\n"); + break; + case SDP_SEQ8: + printf(" SEQ8:"); + for (s = p->val.dataseq; s; s = s->next) + printf(" %x", s->val.uint8); + printf("\n"); + break; + default: + printf(" FIXME: dtd=0%x\n", p->dtd); + break; + } + } +} + +void print_lang_attr(void *value, void *user) +{ + sdp_lang_attr_t *lang = (sdp_lang_attr_t *)value; + printf(" code_ISO639: 0x%02x\n", lang->code_ISO639); + printf(" encoding: 0x%02x\n", lang->encoding); + printf(" base_offset: 0x%02x\n", lang->base_offset); +} + +void print_access_protos(value, userData) +{ + sdp_list_t *protDescSeq = (sdp_list_t *)value; + sdp_list_foreach(protDescSeq, print_service_desc, 0); +} + +void print_profile_desc(void *value, void *userData) +{ + sdp_profile_desc_t *desc = (sdp_profile_desc_t *)value; + char str[MAX_LEN_PROFILEDESCRIPTOR_UUID_STR]; + + sdp_uuid2strn(&desc->uuid, UUID_str, MAX_LEN_UUID_STR); + sdp_profile_uuid2strn(&desc->uuid, str, MAX_LEN_PROFILEDESCRIPTOR_UUID_STR); + + printf(" \"%s\" (0x%s)\n", str, UUID_str); + if (desc->version) + printf(" Version: 0x%04x\n", desc->version); +} + +/* + * Parse a SDP record in user friendly form. + */ +void print_service_attr(sdp_record_t *rec) +{ + sdp_list_t *list = 0, *proto = 0; + + sdp_record_print(rec); + + printf("Service RecHandle: 0x%x\n", rec->handle); + + if (sdp_get_service_classes(rec, &list) == 0) { + printf("Service Class ID List:\n"); + sdp_list_foreach(list, print_service_class, 0); + sdp_list_free(list, free); + } + if (sdp_get_access_protos(rec, &proto) == 0) { + printf("Protocol Descriptor List:\n"); + sdp_list_foreach(proto, print_access_protos, 0); + sdp_list_free(proto, (sdp_free_func_t)sdp_data_free); + } + if (sdp_get_lang_attr(rec, &list) == 0) { + printf("Language Base Attr List:\n"); + sdp_list_foreach(list, print_lang_attr, 0); + sdp_list_free(list, free); + } + if (sdp_get_profile_descs(rec, &list) == 0) { + printf("Profile Descriptor List:\n"); + sdp_list_foreach(list, print_profile_desc, 0); + sdp_list_free(list, free); + } +} + +/* + * Support for Service (de)registration + */ +typedef struct { + char *name; + char *provider; + char *desc; + + unsigned int class; + unsigned int profile; + unsigned int channel; +} svc_info_t; + +static int add_sp(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto; + uuid_t root_uuid, sp_uuid, l2cap, rfcomm; + sdp_profile_desc_t profile; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 1; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + sdp_list_free(root, 0); + + sdp_uuid16_create(&sp_uuid, SERIAL_PORT_SVCLASS_ID); + svclass_id = sdp_list_append(0, &sp_uuid); + sdp_set_service_classes(&record, svclass_id); + sdp_list_free(svclass_id, 0); + + sdp_uuid16_create(&profile.uuid, SERIAL_PORT_PROFILE_ID); + profile.version = 0x0100; + profiles = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, profiles); + sdp_list_free(profiles, 0); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Serial Port", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Serial Port service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_dun(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root, *aproto; + uuid_t rootu, dun, gn, l2cap, rfcomm; + sdp_profile_desc_t profile; + sdp_list_t *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 1; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&rootu, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &rootu); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&dun, DIALUP_NET_SVCLASS_ID); + svclass_id = sdp_list_append(0, &dun); + sdp_uuid16_create(&gn, GENERIC_NETWORKING_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &gn); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, DIALUP_NET_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Dial-Up Networking", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Dial-Up Networking service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_lan(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 2; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, LAN_ACCESS_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, LAN_ACCESS_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "LAN Access over PPP", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("LAN Access service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + + +static int add_headset(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 5; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, HEADSET_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Headset", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Headset service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_handsfree(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 3; + uint16_t u16 = 0x31; + sdp_data_t *channel, *features; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, HANDSFREE_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID); + profile.version = 0x0101; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + features = sdp_data_alloc(SDP_UINT16, &u16); + sdp_attr_add(&record, SDP_SUPPORTED_FEATURES, features); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Handsfree service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + + +static int add_fax(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, fax_uuid, tel_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 3; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&fax_uuid, FAX_SVCLASS_ID); + svclass_id = sdp_list_append(0, &fax_uuid); + sdp_uuid16_create(&tel_uuid, GENERIC_TELEPHONY_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &tel_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, FAX_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Fax", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Fax service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_opush(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, opush_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[3]; + sdp_record_t record; + uint8_t chan = si->channel? si->channel: 4; + sdp_data_t *channel; + uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + //uint8_t formats[] = { 0xff }; + void *dtds[sizeof(formats)], *values[sizeof(formats)]; + int i; + uint8_t dtd = SDP_UINT8; + sdp_data_t *sflist; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&opush_uuid, OBEX_OBJPUSH_SVCLASS_ID); + svclass_id = sdp_list_append(0, &opush_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, OBEX_OBJPUSH_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &chan); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + sdp_uuid16_create(&obex_uuid, OBEX_UUID); + proto[2] = sdp_list_append(0, &obex_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + for (i = 0; i < sizeof(formats); i++) { + dtds[i] = &dtd; + values[i] = &formats[i]; + } + sflist = sdp_seq_alloc(dtds, values, sizeof(formats)); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FORMATS_LIST, sflist); + + sdp_set_info_attr(&record, "OBEX Object Push", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("OBEX Object Push service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(proto[2], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_file_trans(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, ftrn_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[3]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 4; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&ftrn_uuid, OBEX_FILETRANS_SVCLASS_ID); + svclass_id = sdp_list_append(0, &ftrn_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, OBEX_FILETRANS_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + sdp_uuid16_create(&obex_uuid, OBEX_UUID); + proto[2] = sdp_list_append(0, &obex_uuid); + apseq = sdp_list_append(apseq, proto[2]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "OBEX File Transfer", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("OBEX File Transfer service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(proto[2], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_nap(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint16_t lp = 0x000f, ver = 0x0100; + sdp_data_t *psm, *version; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&ftrn_uuid, NAP_SVCLASS_ID); + svclass_id = sdp_list_append(0, &ftrn_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&bnep_uuid, BNEP_UUID); + proto[1] = sdp_list_append(0, &bnep_uuid); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + + { + uint16_t ptype[4] = { 0x0010, 0x0020, 0x0030, 0x0040 }; + sdp_data_t *head, *pseq; + int p; + + for (p = 0, head = NULL; p < 4; p++) { + sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]); + head = sdp_seq_append(head, data); + } + pseq = sdp_data_alloc(SDP_SEQ16, head); + proto[1] = sdp_list_append(proto[1], pseq); + } + + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Network Access Point Service", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("NAP service registered\n"); +end: + sdp_data_free(version); + sdp_data_free(psm); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_gn(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint16_t lp = 0x000f, ver = 0x0100; + sdp_data_t *psm, *version; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&ftrn_uuid, GN_SVCLASS_ID); + svclass_id = sdp_list_append(0, &ftrn_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&bnep_uuid, BNEP_UUID); + proto[1] = sdp_list_append(0, &bnep_uuid); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Group Network Service", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("GN service registered\n"); +end: + sdp_data_free(version); + sdp_data_free(psm); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_hid(sdp_session_t *sess, svc_info_t *si) +{ + return -1; +} + +static int add_cip(sdp_session_t *sess, svc_info_t *si) +{ + return -1; +} + +static int add_ctp(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, tcsbin, ctp; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t netid = 0x02; // 0x01-0x07 cf. p120 profile document + sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&ctp, CORDLESS_TELEPHONY_SVCLASS_ID); + svclass_id = sdp_list_append(0, &ctp); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, CORDLESS_TELEPHONY_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&tcsbin, TCS_BIN_UUID); + proto[1] = sdp_list_append(0, &tcsbin); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_attr_add(&record, SDP_EXTERNAL_NETWORK, network); + + sdp_set_info_attr(&record, "Cordless Telephony", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("CTP service registered\n"); +end: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + sdp_data_free(network); + return ret; +} + +struct { + char *name; + uint16_t class; + int (*add)(sdp_session_t *sess, svc_info_t *si); +} service[] = { + { "SP", SERIAL_PORT_SVCLASS_ID, add_sp }, + { "DUN", DIALUP_NET_SVCLASS_ID, add_dun }, + { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, + { "FAX", FAX_SVCLASS_ID, add_fax }, + { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, + { "FTRN", OBEX_FILETRANS_SVCLASS_ID, add_file_trans }, + + { "HS", HEADSET_SVCLASS_ID, add_headset }, + { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, + + { "NAP", NAP_SVCLASS_ID, add_nap }, + { "GN", GN_SVCLASS_ID, add_gn }, + + { "HID", HID_SVCLASS_ID, add_hid }, + { "CIP", CIP_SVCLASS_ID, add_cip }, + { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, + + { 0 } +}; + +/* Add local service */ +int add_service(bdaddr_t *bdaddr, svc_info_t *si) +{ + int i; + sdp_session_t *sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); + + if (!sess) + return -1; + if (si->name) + for (i=0; service[i].name; i++) + if (!strcasecmp(service[i].name, si->name)) { + int ret = service[i].add(sess, si); + free(si->name); + sdp_close(sess); + return ret; + } + printf("Unknown service name: %s\n", si->name); + free(si->name); + sdp_close(sess); + return -1; +} + +static struct option add_options[] = { + {"help", 0,0, 'h'}, + {"channel", 1,0, 'c'}, + {0, 0, 0, 0} +}; + +static char *add_help = + "Usage:\n" + "\tadd [--channel=CHAN] service\n"; + +int cmd_add(int argc, char **argv) +{ + svc_info_t si; + int opt; + + memset(&si, 0, sizeof(si)); + for_each_opt(opt, add_options, 0) { + switch(opt) { + case 'c': + si.channel = atoi(optarg); + break; + default: + printf(add_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(add_help); + return -1; + } + + si.name = strdup(argv[0]); + return add_service(0, &si); +} + +/* Delete local service */ +int del_service(bdaddr_t *bdaddr, void *arg) +{ + uint32_t handle, range = 0x0000ffff; + sdp_list_t *attr; + sdp_session_t *sess; + sdp_record_t *rec; + + if (!arg) { + printf("Record handle was not specified.\n"); + return -1; + } + sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); + if (!sess) { + printf("No local SDP server!\n"); + return -1; + } + handle = strtoul((char *)arg, 0, 16); + attr = sdp_list_append(0, &range); + rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attr); + sdp_list_free(attr, 0); + if (!rec) { + printf("Service Record not found.\n"); + sdp_close(sess); + return -1; + } + if (sdp_record_unregister(sess, rec)) { + printf("Failed to unregister service record: %s\n", strerror(errno)); + sdp_close(sess); + return -1; + } + printf("Service Record deleted.\n"); + sdp_close(sess); + return 0; +} + +static struct option del_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *del_help = + "Usage:\n" + "\tdel record_handle\n"; + +int cmd_del(int argc, char **argv) +{ + int opt; + + for_each_opt(opt, del_options, 0) { + switch(opt) { + default: + printf(del_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(del_help); + return -1; + } + return del_service(0, argv[0]); +} + +/* + * Perform an inquiry and search/browse all peer found. + */ +static void inquiry(handler_t handler, void *arg) +{ + inquiry_info ii[20]; + uint8_t count = 0; + int i; + + printf("Inquiring ...\n"); + if (sdp_general_inquiry(ii, 20, 8, &count) < 0) { + printf("Inquiry failed\n"); + return; + } + for (i=0; isvc) + printf("Searching for %s on %s ...\n", context->svc, str); + else + printf("Browsing %s ...\n", str); + + attrid = sdp_list_append(0, &range); + search = sdp_list_append(0, &context->group); + if (sdp_service_search_attr_req(sess, search, SDP_ATTR_REQ_RANGE, attrid, &seq)) { + printf("Service Search failed: %s\n", strerror(errno)); + sdp_close(sess); + return -1; + } + sdp_list_free(attrid, 0); + sdp_list_free(search, 0); + + for (; seq; seq = next) { + sdp_record_t *rec = (sdp_record_t *) seq->data; + struct search_context sub_context; + + if (context->tree) { + /* Display full tree */ + sdp_printf_service_attr(rec); + } else { + /* Display user friendly form */ + print_service_attr(rec); + } + printf("\n"); + + if (sdp_get_group_id(rec, &sub_context.group) != -1) { + /* Set the subcontext for browsing the sub tree */ + memcpy(&sub_context, context, sizeof(struct search_context)); + /* Browse the next level down if not done */ + if (sub_context.group.value.uuid16 != context->group.value.uuid16) + do_search(bdaddr, &sub_context); + } + next = seq->next; + free(seq); + sdp_record_free(rec); + } + sdp_close(sess); + return 0; +} + +static struct option browse_options[] = { + {"help", 0,0, 'h'}, + {"tree", 0,0, 't'}, + {0, 0, 0, 0} +}; + +static char *browse_help = + "Usage:\n" + "\tbrowse [--tree] [bdaddr]\n"; + +/* + * Browse the full SDP database (i.e. list all services starting from the + * root/top-level). + */ +int cmd_browse(int argc, char **argv) +{ + struct search_context context; + int opt; + + /* Initialise context */ + memset(&context, '\0', sizeof(struct search_context)); + /* We want to browse the top-level/root */ + sdp_uuid16_create(&(context.group), PUBLIC_BROWSE_GROUP); + + for_each_opt(opt, browse_options, 0) { + switch(opt) { + case 't': + context.tree = 1; + break; + default: + printf(browse_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc >= 1) { + bdaddr_t bdaddr; + estr2ba(argv[0], &bdaddr); + return do_search(&bdaddr, &context); + } + return do_search(0, &context); +} + +static struct option search_options[] = { + {"help", 0,0, 'h'}, + {"bdaddr", 1,0, 'b'}, + {"tree", 0,0, 't'}, + {0, 0, 0, 0} +}; + +static char *search_help = + "Usage:\n" + "\tsearch [--bdaddr bdaddr] [--tree] SERVICE\n" + "SERVICE is a name (string) or UUID (0x1002)\n"; + +/* + * Search for a specific SDP service + * + * Note : we should support multiple services on the command line : + * sdptool search 0x0100 0x000f 0x1002 + * (this would search a service supporting both L2CAP and BNEP directly in + * the top level browse group) + */ +int cmd_search(int argc, char **argv) +{ + struct search_context context; + uint16_t class = 0; + bdaddr_t bdaddr; + int has_addr = 0; + int i; + int opt; + + /* Initialise context */ + memset(&context, '\0', sizeof(struct search_context)); + + for_each_opt(opt, search_options, 0) { + switch(opt) { + case 'b': + estr2ba(optarg, &bdaddr); + has_addr = 1; + break; + case 't': + context.tree = 1; + break; + default: + printf(search_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(search_help); + return -1; + } + /* Note : we need to find a way to support search combining + * multiple services - Jean II */ + context.svc = strdup(argv[0]); + if (!strncasecmp(context.svc, "0x", 2)) { + int num; + /* This is a UUID16, just convert to int */ + sscanf(context.svc + 2, "%X", &num); + class = num; + printf("Class 0x%X\n", class); + } else { + /* Convert class name to an UUID */ + + for (i=0; service[i].name; i++) + if (strcasecmp(context.svc, service[i].name) == 0) { + class = service[i].class; + break; + } + if (!class) { + printf("Unknown service %s\n", context.svc); + return -1; + } + } + + sdp_uuid16_create(&context.group, class); + + if (has_addr) + return do_search(&bdaddr, &context); + return do_search(0, &context); +} + +/* + * Show how to get a specific SDP record by its handle. + * Not really useful to the user, just show how it can be done... + * Jean II + */ +int get_service(bdaddr_t *bdaddr, struct search_context *context) +{ + sdp_list_t *attrid; + uint32_t range = 0x0000ffff; + sdp_record_t *rec; + sdp_session_t *session = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY); + + if (!session) { + char str[20]; + ba2str(bdaddr, str); + printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno)); + return -1; + } + attrid = sdp_list_append(0, &range); + rec = sdp_service_attr_req(session, context->handle, SDP_ATTR_REQ_RANGE, attrid); + sdp_list_free(attrid, 0); + sdp_close(session); + if (!rec) { + printf("Service get request failed.\n"); + return -1; + } + if (context->tree) { + /* Display full tree */ + sdp_printf_service_attr(rec); + } else { + /* Display user friendly form */ + print_service_attr(rec); + } + printf("\n"); + sdp_record_free(rec); + return 0; +} + +static struct option get_options[] = { + {"help", 0,0, 'h'}, + {"bdaddr", 1,0, 'b'}, + {"tree", 0,0, 't'}, + {0, 0, 0, 0} +}; + +static char *get_help = + "Usage:\n" + "\tget [--tree] [--bdaddr bdaddr] record_handle\n"; + +/* + * Get a specific SDP record on the local SDP server + */ +int cmd_get(int argc, char **argv) +{ + struct search_context context; + bdaddr_t bdaddr; + int has_addr = 0; + int opt; + + /* Initialise context */ + memset(&context, '\0', sizeof(struct search_context)); + + for_each_opt(opt, get_options, 0) { + switch(opt) { + case 'b': + estr2ba(optarg, &bdaddr); + has_addr = 1; + break; + case 't': + context.tree = 1; + break; + default: + printf(get_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(get_help); + return -1; + } + /* Convert command line parameters */ + context.handle = strtoul(argv[0], 0, 16); + + return get_service(has_addr? &bdaddr: BDADDR_LOCAL, &context); +} + +struct { + char *cmd; + int (*func)(int argc, char **argv); + char *doc; +} command[] = { + { "search", cmd_search, "Search for a service" }, + { "browse", cmd_browse, "Browse all available services" }, + { "add", cmd_add, "Add local service" }, + { "del", cmd_del, "Delete local service" }, + { "get", cmd_get, "Get local service" }, + { "setattr", cmd_setattr, "Set/Add attribute to a SDP record" }, + { "setseq", cmd_setseq, "Set/Add attribute sequence to a SDP record" }, + { 0, 0, 0} +}; + +static void usage(void) +{ + int i; + + printf("sdptool - SDP Tool v%s\n", VERSION); + printf("Usage:\n" + "\tsdptool [options] [command parameters]\n"); + printf("Options:\n" + "\t--help\t\tDisplay help\n" + "\t--source\tSpecify source interface\n"); + + printf("Commands:\n"); + for (i=0; command[i].cmd; i++) + printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc); + + printf("\nServices:\n\t"); + for (i=0; service[i].name; i++) + printf("%s ", service[i].name); + printf("\n"); +} + +static struct option main_options[] = { + {"help", 0, 0, 'h'}, + {"source", 1, 0, 'S'}, + {0, 0, 0, 0} +}; + +int main(int argc, char **argv) +{ + int opt, i; + + bacpy(&interface, BDADDR_ANY); + while ((opt=getopt_long(argc, argv, "+hS:", main_options, 0)) != -1) { + switch(opt) { + case 'S': + str2ba(optarg, &interface); + break; + case 'h': + default: + usage(); + return -1; + } + } + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + return -1; + } + for (i=0; command[i].cmd; i++) + if (strncmp(command[i].cmd, argv[0], 4) == 0) + return command[i].func(argc, argv); + return -1; +} -- cgit From 5a8fbb23664d5b346164f058c9f57d5b01c0a1bb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 20:29:10 +0000 Subject: Add sdpd subdirectory --- Makefile.am | 2 +- configure.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index 308ede8d..1824ac2d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -SUBDIRS := hcid tools rfcomm test scripts pcmcia +SUBDIRS := hcid tools rfcomm sdpd test scripts pcmcia DISTCLEANFILES = conftest.c conftest diff --git a/configure.in b/configure.in index 19be6b53..56b4132f 100644 --- a/configure.in +++ b/configure.in @@ -73,4 +73,4 @@ fi AM_CONDITIONAL(ENABLE_DBUS, test x$BLUEZ_DBUS = xyes) -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) -- cgit From c787259b854f12bd827d1e05ccde53d748d22b30 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 20:37:21 +0000 Subject: Add sdpd server daemon --- sdpd/Makefile.am | 9 + sdpd/cstate.c | 96 +++++++ sdpd/main.c | 471 ++++++++++++++++++++++++++++++ sdpd/request.c | 849 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ sdpd/sdpd.h | 75 +++++ sdpd/service.c | 241 ++++++++++++++++ sdpd/servicedb.c | 209 ++++++++++++++ 7 files changed, 1950 insertions(+) create mode 100644 sdpd/Makefile.am create mode 100644 sdpd/cstate.c create mode 100644 sdpd/main.c create mode 100644 sdpd/request.c create mode 100644 sdpd/sdpd.h create mode 100644 sdpd/service.c create mode 100644 sdpd/servicedb.c diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am new file mode 100644 index 00000000..9536bf04 --- /dev/null +++ b/sdpd/Makefile.am @@ -0,0 +1,9 @@ +# +# $Id$ +# + +mandir = $(prefix)/usr/share/man + +sbin_PROGRAMS = sdpd + +sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h diff --git a/sdpd/cstate.c b/sdpd/cstate.c new file mode 100644 index 00000000..e9b51832 --- /dev/null +++ b/sdpd/cstate.c @@ -0,0 +1,96 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + Fixes: + Guruprasad Krishnamurthy +*/ + +/* + * $Id$ + */ + +#include +#include + +#include +#include +#include + +#include "sdpd.h" + +typedef struct _sdp_cstate_list sdp_cstate_list_t; + +struct _sdp_cstate_list { + sdp_cstate_list_t *next; + long timestamp; + sdp_buf_t buf; +}; + +static sdp_cstate_list_t *cstates; + +// FIXME: should probably remove it when it's found +sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) +{ + sdp_cstate_list_t *p; + + for (p = cstates; p; p = p->next) + if (p->timestamp == cstate->timestamp) + return &p->buf; + return 0; +} + +long sdp_cstate_alloc_buf(sdp_buf_t *buf) +{ + sdp_cstate_list_t *cstate = (sdp_cstate_list_t *)malloc(sizeof(sdp_cstate_list_t)); + char *data = (char *)malloc(buf->data_size); + + memcpy(data, buf->data, buf->data_size); + memset((char *)cstate, 0, sizeof(sdp_cstate_list_t)); + cstate->buf.data = data; + cstate->buf.data_size = buf->data_size; + cstate->buf.buf_size = buf->data_size; + cstate->timestamp = sdp_get_time(); + cstate->next = cstates; + cstates = cstate; + return cstate->timestamp; +} + +/* + * A simple function which returns the time of day in + * seconds. Used for updating the service db state + * attribute of the service record of the SDP server + */ +long sdp_get_time() +{ + /* + * To handle failure in gettimeofday, so an old + * value is returned and service does not fail + */ + static struct timeval tm; + + gettimeofday(&tm, NULL); + return tm.tv_sec; +} diff --git a/sdpd/main.c b/sdpd/main.c new file mode 100644 index 00000000..fea283f2 --- /dev/null +++ b/sdpd/main.c @@ -0,0 +1,471 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + SDP server initialization and connection handling + + Fixes: + Guruprasad Krishnamurthy + Imre Deak +*/ + +/* + * $Id$ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "sdpd.h" + +static int l2cap_sock, unix_sock; +static fd_set active_fdset; +static int active_maxfd; + +sdp_record_t *server; + +/* + * List of version numbers supported by the SDP server. + * Add to this list when newer versions are supported. + */ +static sdp_version_t sdpVnumArray[1] = { + {1, 0} +}; +const int sdpServerVnumEntries = 1; + +/* + * The service database state is an attribute of the service record + * of the SDP server itself. This attribute is guaranteed to + * change if any of the contents of the service repository + * changes. This function updates the timestamp of value of + * the svcDBState attribute + * Set the SDP server DB. Simply a timestamp which is the marker + * when the DB was modified. + */ +void update_db_timestamp(void) +{ + uint32_t dbts = sdp_get_time(); + sdp_data_t *d = sdp_data_alloc(SDP_UINT32, &dbts); + sdp_attr_replace(server, SDP_ATTR_SVCDB_STATE, d); +} + +static void add_lang_attr(sdp_record_t *r) +{ + sdp_lang_attr_t base_lang; + sdp_list_t *langs = 0; + + base_lang.code_ISO639 = (0x65 << 8) | 0x6e; + // UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) + base_lang.encoding = 106; + base_lang.base_offset = SDP_PRIMARY_LANG_BASE; + langs = sdp_list_append(0, &base_lang); + sdp_set_lang_attr(r, langs); + sdp_list_free(langs, 0); +} + +static void register_public_browse_group(void) +{ + sdp_list_t *browselist; + uuid_t bgscid, pbgid; + sdp_data_t *sdpdata; + sdp_record_t *browse = sdp_record_alloc(); + + browse->handle = (uint32_t)browse; + sdp_record_add(browse); + sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); + sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); + + add_lang_attr(browse); + sdp_set_info_attr(browse, "Public Browse Group Root", "BlueZ", "Root of public browse hierarchy"); + + sdp_uuid16_create(&bgscid, BROWSE_GRP_DESC_SVCLASS_ID); + browselist = sdp_list_append(0, &bgscid); + sdp_set_service_classes(browse, browselist); + sdp_list_free(browselist, 0); + + sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); + sdp_set_group_id(browse, pbgid); +} + +/* + * The SDP server must present its own service record to + * the service repository. This can be accessed by service + * discovery clients. This method constructs a service record + * and stores it in the repository + */ +static void register_server_service(void) +{ + int i; + sdp_list_t *classIDList, *browseList; + sdp_list_t *access_proto = 0; + uuid_t l2cap, classID, browseGroupId, sdpSrvUUID; + void **versions, **versionDTDs; + uint8_t dtd; + uint16_t version, port; + sdp_data_t *pData, *port_data, *version_data; + sdp_list_t *pd, *seq; + + server = sdp_record_alloc(); + server->pattern = NULL; + + /* Force the record to be SDP_SERVER_RECORD_HANDLE */ + server->handle = SDP_SERVER_RECORD_HANDLE; + + sdp_record_add(server); + sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, sdp_data_alloc(SDP_UINT32, &server->handle)); + + /* + * Add all attributes to service record. (No need to commit since we + * are the server and this record is already in the database.) + */ + add_lang_attr(server); + sdp_set_info_attr(server, "SDP Server", "BlueZ", "Bluetooth service discovery server"); + + sdp_uuid16_create(&classID, SDP_SERVER_SVCLASS_ID); + classIDList = sdp_list_append(0, &classID); + sdp_set_service_classes(server, classIDList); + sdp_list_free(classIDList, 0); + + /* + * Set the version numbers supported, these are passed as arguments + * to the server on command line. Now defaults to 1.0 + * Build the version number sequence first + */ + versions = (void **)malloc(sdpServerVnumEntries * sizeof(void *)); + versionDTDs = (void **)malloc(sdpServerVnumEntries * sizeof(void *)); + dtd = SDP_UINT16; + for (i = 0; i < sdpServerVnumEntries; i++) { + uint16_t *version = (uint16_t *)malloc(sizeof(uint16_t)); + *version = sdpVnumArray[i].major; + *version = (*version << 8); + *version |= sdpVnumArray[i].minor; + versions[i] = version; + versionDTDs[i] = &dtd; + } + pData = sdp_seq_alloc(versionDTDs, versions, sdpServerVnumEntries); + for (i = 0; i < sdpServerVnumEntries; i++) + free(versions[i]); + free(versions); + free(versionDTDs); + sdp_attr_add(server, SDP_ATTR_VERSION_NUM_LIST, pData); + + sdp_uuid16_create(&sdpSrvUUID, SDP_UUID); + sdp_set_service_id(server, sdpSrvUUID); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + pd = sdp_list_append(0, &l2cap); + port = SDP_PSM; + port_data = sdp_data_alloc(SDP_UINT16, &port); + pd = sdp_list_append(pd, port_data); + version = 1; + version_data = sdp_data_alloc(SDP_UINT16, &version); + pd = sdp_list_append(pd, version_data); + seq = sdp_list_append(0, pd); + + access_proto = sdp_list_append(0, seq); + sdp_set_access_protos(server, access_proto); + sdp_list_free(access_proto, free); + sdp_data_free(port_data); + sdp_data_free(version_data); + sdp_list_free(pd, 0); + + sdp_uuid16_create(&browseGroupId, PUBLIC_BROWSE_GROUP); + browseList = sdp_list_append(0, &browseGroupId); + sdp_set_browse_groups(server, browseList); + sdp_list_free(browseList, 0); + + update_db_timestamp(); +} + +/* + * SDP server initialization on startup includes creating the + * l2cap and unix sockets over which discovery and registration clients + * access us respectively + */ +int init_server(int master) +{ + struct sockaddr_l2 l2addr; + struct sockaddr_un unaddr; + + /* Register the public browse group root */ + register_public_browse_group(); + + /* Register the SDP server's service record */ + register_server_service(); + + /* Create L2CAP socket */ + l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (l2cap_sock == -1) { + SDPERR("opening L2CAP socket: %s", strerror(errno)); + return -1; + } + + l2addr.l2_bdaddr = *BDADDR_ANY; + l2addr.l2_family = AF_BLUETOOTH; + l2addr.l2_psm = htobs(SDP_PSM); + if (0 > bind(l2cap_sock, (struct sockaddr *)&l2addr, sizeof(l2addr))) { + SDPERR("binding L2CAP socket: %s", strerror(errno)); + return -1; + } + + if (master) { + int opt = L2CAP_LM_MASTER; + if (0 > setsockopt(l2cap_sock, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt))) { + SDPERR("setsockopt: %s", strerror(errno)); + return -1; + } + } + listen(l2cap_sock, 5); + FD_SET(l2cap_sock, &active_fdset); + active_maxfd = l2cap_sock; + + /* Create local Unix socket */ + unix_sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (unix_sock == -1) { + SDPERR("opening UNIX socket: %s", strerror(errno)); + return -1; + } + unaddr.sun_family = AF_UNIX; + strcpy(unaddr.sun_path, SDP_UNIX_PATH); + unlink(unaddr.sun_path); + if (0 > bind(unix_sock, (struct sockaddr *)&unaddr, sizeof(unaddr))) { + SDPERR("binding UNIX socket: %s", strerror(errno)); + return -1; + } + listen(unix_sock, 5); + FD_SET(unix_sock, &active_fdset); + active_maxfd = unix_sock; + chmod(SDP_UNIX_PATH, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + return 0; +} + +void sig_term(int sig) +{ + SDPINF("terminating... \n"); + sdp_svcdb_reset(); + close(l2cap_sock); + close(unix_sock); + exit(0); +} + +int become_daemon(void) +{ + int fd; + + if (getppid() != 1) { + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + if (fork()) + return 0; + setsid(); + } + for (fd = 0; fd < 3; fd++) + close(fd); + + chdir("/"); + return 1; +} + +static inline void handle_request(int sk, char *data, int len) +{ + struct sockaddr_l2 sa; + int size; + sdp_req_t req; + + size = sizeof(sa); + if (getpeername(sk, (struct sockaddr *)&sa, &size) < 0) + return; + + if (sa.l2_family == AF_BLUETOOTH) { + struct l2cap_options lo; + size = sizeof(lo); + getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size); + req.bdaddr = sa.l2_bdaddr; + req.mtu = lo.omtu; + req.local = 0; + } else { + req.bdaddr = *BDADDR_LOCAL; + req.mtu = 2048; + req.local = 1; + } + req.sock = sk; + req.buf = data; + req.len = len; + process_request(&req); +} + +static void close_sock(int fd, int r) +{ + if (r < 0) + SDPERR("Read error: %s", strerror(errno)); + FD_CLR(fd, &active_fdset); + close(fd); + sdp_svcdb_collect_all(fd); + if (fd == active_maxfd) + active_maxfd--; +} + +static void check_active(fd_set *mask, int num) +{ + sdp_pdu_hdr_t hdr; + int size, fd, count, r; + char *buf; + + for (fd = 0, count = 0; fd <= active_maxfd && count < num; fd++) { + if (fd == l2cap_sock || fd == unix_sock || !FD_ISSET(fd, mask)) + continue; + + count++; + + r = recv(fd, (void *)&hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK); + if (r <= 0) { + close_sock(fd, r); + continue; + } + + size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen); + buf = malloc(size); + if (!buf) + continue; + + r = recv(fd, buf, size, 0); + if (r <= 0) + close_sock(fd, r); + else + handle_request(fd, buf, r); + } +} + +void usage(void) +{ + printf("sdpd version %s\n", VERSION); + printf("Usage:\n" + "sdpd [-n] [-m]\n" + ); +} + +static struct option main_options[] = { + {"help", 0,0, 'h'}, + {"nodaemon", 0,0, 'n'}, + {"master", 0,0, 'm'}, + {0, 0, 0, 0} +}; + +int main(int argc, char **argv) +{ + int daemon = 1; + int master = 0; + int opt; + + while ((opt = getopt_long(argc, argv, "nm", main_options, NULL)) != -1) + switch (opt) { + case 'n': + daemon = 0; + break; + case 'm': + master = 1; + break; + default: + usage(); + exit(0); + } + openlog("sdpd", LOG_PID | LOG_NDELAY, LOG_DAEMON); + + if (daemon && !become_daemon()) + return 0; + + argc -= optind; + argv += optind; + + if (init_server(master) < 0) { + SDPERR("Server initialization failed"); + return -1; + } + + SDPINF("sdpd v%s started", VERSION); + + signal(SIGINT, sig_term); + signal(SIGTERM, sig_term); + signal(SIGABRT, sig_term); + signal(SIGQUIT, sig_term); + signal(SIGPIPE, SIG_IGN); + + for (;;) { + int num, nfd; + fd_set mask; + + FD_ZERO(&mask); + mask = active_fdset; + + num = select(active_maxfd + 1, &mask, NULL, NULL, NULL); + if (num <= 0) { + SDPDBG("Select error:%s", strerror(errno)); + goto exit; + } + + if (FD_ISSET(l2cap_sock, &mask)) { + /* New L2CAP connection */ + struct sockaddr_l2 caddr; + socklen_t len = sizeof(caddr); + + nfd = accept(l2cap_sock, (struct sockaddr *)&caddr, &len); + if (nfd >= 0) { + if (nfd > active_maxfd) + active_maxfd = nfd; + FD_SET(nfd, &active_fdset); + } + } else if (FD_ISSET(unix_sock, &mask)) { + /* New unix connection */ + struct sockaddr_un caddr; + socklen_t len = sizeof(caddr); + + nfd = accept(unix_sock, (struct sockaddr *)&caddr, &len); + if (nfd != -1) { + if (nfd > active_maxfd) + active_maxfd = nfd; + FD_SET(nfd, &active_fdset); + } + } else + check_active(&mask, num); + } +exit: + sdp_svcdb_reset(); + return 0; +} diff --git a/sdpd/request.c b/sdpd/request.c new file mode 100644 index 00000000..2354e40e --- /dev/null +++ b/sdpd/request.c @@ -0,0 +1,849 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + SDP request handling code. + + Fixes: + Guruprasad Krishnamurthy + Dmitry Kasatkin - Continuation mechanism +*/ + +/* + * $Id$ + */ + +#include + +#include +#include +#include + +#include "sdpd.h" + +#define MIN(x, y) ((x) < (y))? (x): (y) + +/* Additional values for checking datatype (not in spec) */ +#define SDP_TYPE_UUID 0xfe +#define SDP_TYPE_ANY 0xff + +/* + * Generic data element sequence extractor. Builds + * a list whose elements are those found in the + * sequence. The data type of elements found in the + * sequence is returned in the reference pDataType + */ +static int extract_des(char *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType) +{ + uint8_t seqType; + int data_size = 0; + int scanned = sdp_extract_seqtype(buf, &seqType, &data_size); + short numberOfElements = 0; + int seqlen = 0; + sdp_list_t *pSeq = NULL; + uint8_t dataType; + int status = 0; + const char *p; + + SDPDBG("Seq type : %d\n", seqType); + if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) { + SDPERR("Unknown seq type \n"); + return -1; + } + p = buf + scanned; + + SDPDBG("Data size : %d\n", data_size); + for (;;) { + char *pElem = NULL; + int localSeqLength = 0; + + dataType = *(uint8_t *)p; + SDPDBG("Data type: 0x%02x\n", dataType); + + if (expectedType == SDP_TYPE_UUID) { + if (dataType != SDP_UUID16 && dataType != SDP_UUID32 && dataType != SDP_UUID128) { + SDPDBG("->Unexpected Data type (expected UUID_ANY)\n"); + return -1; + } + } else if (expectedType != SDP_TYPE_ANY && dataType != expectedType) { + SDPDBG("->Unexpected Data type (expected 0x%02x)\n", expectedType); + return -1; + } + + switch (dataType) { + case SDP_UINT16: + p += sizeof(uint8_t); + seqlen += sizeof(uint8_t); + pElem = (char *)malloc(sizeof(uint16_t)); + sdp_put_unaligned(ntohs(sdp_get_unaligned((uint16_t *)p)), (uint16_t *)pElem); + p += sizeof(uint16_t); + seqlen += sizeof(uint16_t); + break; + case SDP_UINT32: + p += sizeof(uint8_t); + seqlen += sizeof(uint8_t); + pElem = (char *)malloc(sizeof(uint32_t)); + sdp_put_unaligned(ntohl(sdp_get_unaligned((uint32_t *)p)), (uint32_t *)pElem); + p += sizeof(uint32_t); + seqlen += sizeof(uint32_t); + break; + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + pElem = (char *)malloc(sizeof(uuid_t)); + status = sdp_uuid_extract(p, (uuid_t *)pElem, &localSeqLength); + if (status == 0) { + seqlen += localSeqLength; + p += localSeqLength; + } + break; + } + if (status == 0) { + pSeq = sdp_list_append(pSeq, pElem); + numberOfElements++; + SDPDBG("No of elements : %d\n", numberOfElements); + + if (seqlen == data_size) + break; + else if (seqlen > data_size) + return -1; + } else + free(pElem); + } + *svcReqSeq = pSeq; + scanned += seqlen; + *pDataType = dataType; + return scanned; +} + +static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate) +{ + char *pdata = buf->data + buf->data_size; + int length = 0; + + if (cstate) { + SDPDBG("Non null sdp_cstate_t id : 0x%lx\n", cstate->timestamp); + *(uint8_t *)pdata = sizeof(sdp_cont_state_t); + pdata += sizeof(uint8_t); + length += sizeof(uint8_t); + memcpy(pdata, cstate, sizeof(sdp_cont_state_t)); + length += sizeof(sdp_cont_state_t); + } else { + // set "null" continuation state + *(uint8_t *)pdata = 0; + pdata += sizeof(uint8_t); + length += sizeof(uint8_t); + } + buf->data_size += length; + return length; +} + +static sdp_cont_state_t *sdp_cstate_get(char *buffer) +{ + char *pdata = buffer; + uint8_t cStateSize = *(uint8_t *)pdata; + + /* + * Check if continuation state exists, if yes attempt + * to get response remainder from cache, else send error + */ + SDPDBG("Continuation State size : %d\n", cStateSize); + + pdata += sizeof(uint8_t); + if (cStateSize != 0) { + sdp_cont_state_t *cstate = (sdp_cont_state_t *)pdata; + SDPDBG("Cstate TS : 0x%lx\n", cstate->timestamp); + SDPDBG("Bytes sent : %d\n", cstate->cStateValue.maxBytesSent); + return cstate; + } + return NULL; +} + +/* + * The matching process is defined as "each and every UUID + * specified in the "search pattern" must be present in the + * "target pattern". Here "search pattern" is the set of UUIDs + * specified by the service discovery client and "target pattern" + * is the set of UUIDs present in a service record. + * + * Return 1 if each and every UUID in the search + * pattern exists in the target pattern, 0 if the + * match succeeds and -1 on error. + */ +static int sdp_match_uuid(sdp_list_t *search, sdp_list_t *pattern) +{ + /* + * The target is a sorted list, so we need not look + * at all elements to confirm existence of an element + * from the search pattern + */ + int patlen = sdp_list_len(pattern); + + SDPDBG(""); + + if (patlen < sdp_list_len(search)) + return -1; + for (; search; search = search->next) { + uuid_t *uuid128; + void *data = search->data; + sdp_list_t *list; + if (data == NULL) + return -1; + + // create 128-bit form of the search UUID + uuid128 = sdp_uuid_to_uuid128((uuid_t *)data); + list = sdp_list_find(pattern, uuid128, sdp_uuid128_cmp); + free(uuid128); + if (!list) + return 0; + } + return 1; +} + +/* + * Service search request PDU. This method extracts the search pattern + * (a sequence of UUIDs) and calls the matching function + * to find matching services + */ +static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) +{ + int status = 0, i, plen, mlen; + sdp_list_t *pattern = NULL; + int expected, actual; + uint8_t dtd; + sdp_cont_state_t *cstate = NULL; + char *pCacheBuffer = NULL; + int handleSize = 0; + long cStateId = -1; + short rsp_count = 0; + short *pTotalRecordCount, *pCurrentRecordCount; + int mtu; + char *pdata = req->buf + sizeof(sdp_pdu_hdr_t); + int scanned = extract_des(pdata, &pattern, &dtd, SDP_TYPE_UUID); + + SDPDBG(""); + + if (scanned == -1) { + status = SDP_INVALID_SYNTAX; + goto done; + } + pdata += scanned; + + plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen); + mlen = scanned + sizeof(uint16_t) + 1; + // ensure we don't read past buffer + if (plen < mlen || plen != mlen + *(uint8_t *)(pdata+sizeof(uint16_t))) { + status = SDP_INVALID_SYNTAX; + goto done; + } + + expected = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + + SDPDBG("Expected count: %d\n", expected); + SDPDBG("Bytes scanned : %d\n", scanned); + + pdata += sizeof(uint16_t); + + /* + * Check if continuation state exists, if yes attempt + * to get rsp remainder from cache, else send error + */ + cstate = sdp_cstate_get(pdata); + + mtu = req->mtu - sizeof(sdp_pdu_hdr_t) - sizeof(uint16_t) - sizeof(uint16_t) - SDP_CONT_STATE_SIZE; + actual = MIN(expected, mtu >> 2); + + /* make space in the rsp buffer for total and current record counts */ + pdata = buf->data; + + /* total service record count = 0 */ + pTotalRecordCount = (short *)pdata; + sdp_put_unaligned(0, (uint16_t *)pdata); + pdata += sizeof(uint16_t); + buf->data_size += sizeof(uint16_t); + + /* current service record count = 0 */ + pCurrentRecordCount = (short *)pdata; + sdp_put_unaligned(0, (uint16_t *)pdata); + pdata += sizeof(uint16_t); + buf->data_size += sizeof(uint16_t); + + if (cstate == NULL) { + /* for every record in the DB, do a pattern search */ + sdp_list_t *list = sdp_get_record_list(); + + handleSize = 0; + for (; list && rsp_count < expected; list = list->next) { + sdp_record_t *rec = (sdp_record_t *)list->data; + + SDPDBG("Checking svcRec : 0x%x\n", rec->handle); + + if (sdp_match_uuid(pattern, rec->pattern) > 0) { + rsp_count++; + sdp_put_unaligned(htonl(rec->handle), (uint32_t *)pdata); + pdata += sizeof(uint32_t); + handleSize += sizeof(uint32_t); + } + } + + SDPDBG("Match count: %d\n", rsp_count); + + buf->data_size += handleSize; + sdp_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); + sdp_put_unaligned(htons(rsp_count), (uint16_t *)pCurrentRecordCount); + + if (rsp_count > actual) { + /* cache the rsp and generate a continuation state */ + cStateId = sdp_cstate_alloc_buf(buf); + /* + * subtract handleSize since we now send only + * a subset of handles + */ + buf->data_size -= handleSize; + } else { + /* NULL continuation state */ + sdp_set_cstate_pdu(buf, NULL); + } + } + + /* under both the conditions below, the rsp buffer is not built yet */ + if (cstate || cStateId != -1) { + short lastIndex = 0; + + if (cstate) { + /* + * Get the previous sdp_cont_state_t and obtain + * the cached rsp + */ + sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); + if (pCache) { + pCacheBuffer = pCache->data; + /* get the rsp_count from the cached buffer */ + rsp_count = ntohs(sdp_get_unaligned((uint16_t *)pCacheBuffer)); + + /* get index of the last sdp_record_t sent */ + lastIndex = cstate->cStateValue.lastIndexSent; + } else { + status = SDP_INVALID_CSTATE; + goto done; + } + } else { + pCacheBuffer = buf->data; + lastIndex = 0; + } + + /* + * Set the local buffer pointer to after the + * current record count and increment the cached + * buffer pointer to beyond the counters + */ + pdata = (char *)pCurrentRecordCount + sizeof(uint16_t); + + /* increment beyond the totalCount and the currentCount */ + pCacheBuffer += 2 * sizeof(uint16_t); + + if (cstate) { + handleSize = 0; + for (i = lastIndex; (i - lastIndex) < actual && i < rsp_count; i++) { + sdp_put_unaligned(sdp_get_unaligned((uint32_t *)(pCacheBuffer + i * sizeof(uint32_t))), (uint32_t *)pdata); + pdata += sizeof(uint32_t); + handleSize += sizeof(uint32_t); + } + } else { + handleSize = actual << 2; + i = actual; + } + + buf->data_size += handleSize; + sdp_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount); + sdp_put_unaligned(htons(i - lastIndex), (uint16_t *)pCurrentRecordCount); + + if (i == rsp_count) { + /* set "null" continuationState */ + sdp_set_cstate_pdu(buf, NULL); + } else { + /* + * there's more: set lastIndexSent to + * the new value and move on + */ + sdp_cont_state_t newState; + + SDPDBG("Setting non-NULL sdp_cstate_t\n"); + + if (cstate) + memcpy((char *)&newState, cstate, sizeof(sdp_cont_state_t)); + else { + memset((char *)&newState, 0, sizeof(sdp_cont_state_t)); + newState.timestamp = cStateId; + } + newState.cStateValue.lastIndexSent = i; + sdp_set_cstate_pdu(buf, &newState); + } + } + +done: + if (pattern) + sdp_list_free(pattern, free); + + return status; +} + +/* + * Extract attribute identifiers from the request PDU. + * Clients could request a subset of attributes (by id) + * from a service record, instead of the whole set. The + * requested identifiers are present in the PDU form of + * the request + */ +static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_buf_t *buf) +{ + if (!rec) + return SDP_INVALID_RECORD_HANDLE; + +#ifdef SDP_DEBUG + if (seq) + SDPDBG("Entries in attr seq : %d\n", sdp_list_len(seq)); + else + SDPDBG("NULL attribute descriptor\n"); + SDPDBG("AttrDataType : %d\n", dtd); +#endif + if (seq == NULL) { + SDPDBG("Attribute sequence is NULL\n"); + return 0; + } + if (dtd == SDP_UINT16) + for (; seq; seq = seq->next) { + uint16_t attr = sdp_get_unaligned((uint16_t *)seq->data); + sdp_data_t *a = (sdp_data_t *)sdp_data_get(rec, attr); + if (a) + sdp_append_to_pdu(buf, a); + } + else if (dtd == SDP_UINT32) { + sdp_buf_t pdu; + sdp_gen_record_pdu(rec, &pdu); + for (; seq; seq = seq->next) { + uint32_t range = sdp_get_unaligned((uint32_t *)seq->data); + uint16_t attr; + uint16_t low = (0xffff0000 & range) >> 16; + uint16_t high = 0x0000ffff & range; + + SDPDBG("attr range : 0x%x\n", range); + SDPDBG("Low id : 0x%x\n", low); + SDPDBG("High id : 0x%x\n", high); + + if (low == 0x0000 && high == 0xffff && pdu.data_size <= buf->buf_size) { + /* copy it */ + memcpy(buf->data, pdu.data, pdu.data_size); + buf->data_size = pdu.data_size; + break; + } + /* (else) sub-range of attributes */ + for (attr = low; attr <= high; attr++) { + sdp_data_t *a = (sdp_data_t *)sdp_data_get(rec, attr); + if (a) + sdp_append_to_pdu(buf, a); + } + } + free(pdu.data); + } else { + SDPERR("Unexpected data type : 0x%x\n", dtd); + SDPERR("Expect uint16_t or uint32_t\n"); + return SDP_INVALID_SYNTAX; + } + return 0; +} + +/* + * A request for the attributes of a service record. + * First check if the service record (specified by + * service record handle) exists, then call the attribute + * streaming function + */ +static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) +{ + sdp_cont_state_t *cstate = NULL; + char *pResponse = NULL; + short cstate_size = 0; + sdp_list_t *seq = NULL; + uint8_t dtd = 0; + int scanned = 0; + int max_rsp_size; + int status = 0, plen, mlen; + char *pdata = req->buf + sizeof(sdp_pdu_hdr_t); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)pdata)); + + SDPDBG(""); + + pdata += sizeof(uint32_t); + max_rsp_size = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + pdata += sizeof(uint16_t); + + /* extract the attribute list */ + scanned = extract_des(pdata, &seq, &dtd, SDP_TYPE_ANY); + if (scanned == -1) { + status = SDP_INVALID_SYNTAX; + goto done; + } + pdata += scanned; + + plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen); + mlen = scanned + sizeof(uint32_t) + sizeof(uint16_t) + 1; + // ensure we don't read past buffer + if (plen < mlen || plen != mlen + *(uint8_t *)pdata) { + status = SDP_INVALID_SYNTAX; + goto done; + } + + /* + * if continuation state exists, attempt + * to get rsp remainder from cache, else send error + */ + cstate = sdp_cstate_get(pdata); + + SDPDBG("SvcRecHandle : 0x%x\n", handle); + SDPDBG("max_rsp_size : %d\n", max_rsp_size); + + /* + * Calculate Attribute size acording to MTU + * We can send only (MTU - sizeof(sdp_pdu_hdr_t) - sizeof(sdp_cont_state_t)) + */ + max_rsp_size = MIN(max_rsp_size, req->mtu - sizeof(sdp_pdu_hdr_t) - + sizeof(uint32_t) - SDP_CONT_STATE_SIZE - sizeof(uint16_t)); + + /* pull header for AttributeList byte count */ + buf->data += sizeof(uint16_t); + buf->buf_size -= sizeof(uint16_t); + + if (cstate) { + sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); + + SDPDBG("Obtained cached rsp : %p\n", pCache); + + if (pCache) { + short sent = MIN(max_rsp_size, pCache->data_size - cstate->cStateValue.maxBytesSent); + pResponse = pCache->data; + memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); + buf->data_size += sent; + cstate->cStateValue.maxBytesSent += sent; + + SDPDBG("Response size : %d sending now : %d bytes sent so far : %d\n", + pCache->data_size, sent, cstate->cStateValue.maxBytesSent); + if (cstate->cStateValue.maxBytesSent == pCache->data_size) + cstate_size = sdp_set_cstate_pdu(buf, NULL); + else + cstate_size = sdp_set_cstate_pdu(buf, cstate); + } else { + status = SDP_INVALID_CSTATE; + SDPERR("NULL cache buffer and non-NULL continuation state\n"); + } + } else { + sdp_record_t *rec = sdp_record_find(handle); + status = extract_attrs(rec, seq, dtd, buf); + if (buf->data_size > max_rsp_size) { + sdp_cont_state_t newState; + + memset((char *)&newState, 0, sizeof(sdp_cont_state_t)); + newState.timestamp = sdp_cstate_alloc_buf(buf); + /* + * Reset the buffer size to the maximum expected and + * set the sdp_cont_state_t + */ + SDPDBG("Creating continuation state of size : %d\n", buf->data_size); + buf->data_size = max_rsp_size; + newState.cStateValue.maxBytesSent = max_rsp_size; + cstate_size = sdp_set_cstate_pdu(buf, &newState); + } else { + if (buf->data_size == 0) + sdp_append_to_buf(buf, 0, 0); + cstate_size = sdp_set_cstate_pdu(buf, NULL); + } + } + + // push header + buf->data -= sizeof(uint16_t); + buf->buf_size += sizeof(uint16_t); + +done: + if (seq) + sdp_list_free(seq, free); + if (status) + return status; + + /* set attribute list byte count */ + sdp_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data); + buf->data_size += sizeof(uint16_t); + return 0; +} + +/* + * combined service search and attribute extraction + */ +static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) +{ + int status = 0, plen, totscanned; + char *pdata, *pResponse = NULL; + int scanned, max, rsp_count = 0; + sdp_list_t *pattern = NULL, *seq = NULL, *svcList; + sdp_cont_state_t *cstate = NULL; + short cstate_size = 0; + uint8_t dtd = 0; + sdp_buf_t tmpbuf; + + tmpbuf.data = NULL; + pdata = req->buf + sizeof(sdp_pdu_hdr_t); + scanned = extract_des(pdata, &pattern, &dtd, SDP_TYPE_UUID); + if (scanned == -1) { + status = SDP_INVALID_SYNTAX; + goto done; + } + totscanned = scanned; + + SDPDBG("Bytes scanned: %d", scanned); + + pdata += scanned; + max = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + pdata += sizeof(uint16_t); + + SDPDBG("Max Attr expected: %d", max); + + /* extract the attribute list */ + scanned = extract_des(pdata, &seq, &dtd, SDP_TYPE_ANY); + if (scanned == -1) { + status = SDP_INVALID_SYNTAX; + goto done; + } + pdata += scanned; + totscanned += scanned + sizeof(uint16_t) + 1; + + plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen); + if (plen < totscanned || plen != totscanned + *(uint8_t *)pdata) { + status = SDP_INVALID_SYNTAX; + goto done; + } + + /* + * if continuation state exists attempt + * to get rsp remainder from cache, else send error + */ + cstate = sdp_cstate_get(pdata); // continuation information + + svcList = sdp_get_record_list(); + + tmpbuf.data = (char *)malloc(USHRT_MAX); + tmpbuf.data_size = 0; + tmpbuf.buf_size = USHRT_MAX; + memset(tmpbuf.data, 0, USHRT_MAX); + + /* + * Calculate Attribute size acording to MTU + * We can send only (MTU - sizeof(sdp_pdu_hdr_t) - sizeof(sdp_cont_state_t)) + */ + max = MIN(max, req->mtu - sizeof(sdp_pdu_hdr_t) - SDP_CONT_STATE_SIZE - sizeof(uint16_t)); + + /* pull header for AttributeList byte count */ + buf->data += sizeof(uint16_t); + buf->buf_size -= sizeof(uint16_t); + + if (cstate == NULL) { + /* no continuation state -> create new response */ + sdp_list_t *p; + for (p = svcList; p; p = p->next) { + sdp_record_t *rec = (sdp_record_t *)p->data; + if (sdp_match_uuid(pattern, rec->pattern) > 0) { + rsp_count++; + status = extract_attrs(rec, seq, dtd, &tmpbuf); + + SDPDBG("Response count : %d\n", rsp_count); + SDPDBG("Local PDU size : %d\n", tmpbuf.data_size); + if (status) { + SDPDBG("Extract attr from record returns err\n"); + break; + } + if (buf->data_size + tmpbuf.data_size < buf->buf_size) { + // to be sure no relocations + sdp_append_to_buf(buf, tmpbuf.data, tmpbuf.data_size); + tmpbuf.data_size = 0; + memset(tmpbuf.data, 0, USHRT_MAX); + } else { + SDPERR("Relocation needed\n"); + break; + } + SDPDBG("Net PDU size : %d\n", buf->data_size); + } + } + if (buf->data_size > max) { + sdp_cont_state_t newState; + + memset((char *)&newState, 0, sizeof(sdp_cont_state_t)); + newState.timestamp = sdp_cstate_alloc_buf(buf); + /* + * Reset the buffer size to the maximum expected and + * set the sdp_cont_state_t + */ + buf->data_size = max; + newState.cStateValue.maxBytesSent = max; + cstate_size = sdp_set_cstate_pdu(buf, &newState); + } else + cstate_size = sdp_set_cstate_pdu(buf, NULL); + } else { + /* continuation State exists -> get from cache */ + sdp_buf_t *pCache = sdp_get_cached_rsp(cstate); + if (pCache) { + uint16_t sent = MIN(max, pCache->data_size - cstate->cStateValue.maxBytesSent); + pResponse = pCache->data; + memcpy(buf->data, pResponse + cstate->cStateValue.maxBytesSent, sent); + buf->data_size += sent; + cstate->cStateValue.maxBytesSent += sent; + if (cstate->cStateValue.maxBytesSent == pCache->data_size) + cstate_size = sdp_set_cstate_pdu(buf, NULL); + else + cstate_size = sdp_set_cstate_pdu(buf, cstate); + } else { + status = SDP_INVALID_CSTATE; + SDPDBG("Non-null continuation state, but null cache buffer\n"); + } + } + + if (!rsp_count && !cstate) { + // found nothing + buf->data_size = 0; + sdp_append_to_buf(buf, tmpbuf.data, tmpbuf.data_size); + sdp_set_cstate_pdu(buf, NULL); + } + + // push header + buf->data -= sizeof(uint16_t); + buf->buf_size += sizeof(uint16_t); + + if (!status) { + /* set attribute list byte count */ + sdp_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data); + buf->data_size += sizeof(uint16_t); + } + +done: + if (tmpbuf.data) + free(tmpbuf.data); + if (pattern) + sdp_list_free(pattern, free); + if (seq) + sdp_list_free(seq, free); + return status; +} + +/* + * Top level request processor. Calls the appropriate processing + * function based on request type. Handles service registration + * client requests also. + */ +void process_request(sdp_req_t *req) +{ + sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)req->buf; + sdp_pdu_hdr_t *rsphdr; + sdp_buf_t rsp; + char *buf = (char *)malloc(USHRT_MAX); + int sent = 0; + int status = SDP_INVALID_SYNTAX; + + SDPDBG(""); + + memset((void *)buf, 0, USHRT_MAX); + rsp.data = buf + sizeof(sdp_pdu_hdr_t); + rsp.data_size = 0; + rsp.buf_size = USHRT_MAX - sizeof(sdp_pdu_hdr_t); + rsphdr = (sdp_pdu_hdr_t *)buf; + + if (ntohs(reqhdr->plen) != req->len - sizeof(sdp_pdu_hdr_t)) { + status = SDP_INVALID_PDU_SIZE; + goto send_rsp; + } + switch (reqhdr->pdu_id) { + case SDP_SVC_SEARCH_REQ: + SDPDBG("Got a svc srch req\n"); + status = service_search_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_SEARCH_RSP; + break; + case SDP_SVC_ATTR_REQ: + SDPDBG("Got a svc attr req\n"); + status = service_attr_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_ATTR_RSP; + break; + case SDP_SVC_SEARCH_ATTR_REQ: + SDPDBG("Got a svc srch attr req\n"); + status = service_search_attr_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_SEARCH_ATTR_RSP; + break; + /* Following requests are allowed only for local connections */ + case SDP_SVC_REGISTER_REQ: + SDPDBG("Service register request\n"); + if (req->local) { + status = service_register_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_REGISTER_RSP; + } + break; + case SDP_SVC_UPDATE_REQ: + SDPDBG("Service update request\n"); + if (req->local) { + status = service_update_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_UPDATE_RSP; + } + break; + case SDP_SVC_REMOVE_REQ: + SDPDBG("Service removal request\n"); + if (req->local) { + status = service_remove_req(req, &rsp); + rsphdr->pdu_id = SDP_SVC_REMOVE_RSP; + } + break; + default: + SDPERR("Unknown PDU ID : 0x%x received\n", reqhdr->pdu_id); + status = SDP_INVALID_SYNTAX; + break; + } + +send_rsp: + if (status) { + rsphdr->pdu_id = SDP_ERROR_RSP; + sdp_put_unaligned(htons(status), (uint16_t *)rsp.data); + rsp.data_size = sizeof(uint16_t); + } + + SDPDBG("Sending rsp. status %d", status); + + rsphdr->tid = reqhdr->tid; + rsphdr->plen = htons(rsp.data_size); + + /* point back to the real buffer start and set the real rsp length */ + rsp.data_size += sizeof(sdp_pdu_hdr_t); + rsp.data = buf; + + /* stream the rsp PDU */ + sent = send(req->sock, rsp.data, rsp.data_size, 0); + + SDPDBG("Bytes Sent : %d\n", sent); + + free(rsp.data); + free(req->buf); +} diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h new file mode 100644 index 00000000..1f0d7e47 --- /dev/null +++ b/sdpd/sdpd.h @@ -0,0 +1,75 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ + +#ifndef SDPD_H +#define SDPD_H + +typedef struct request { + bdaddr_t bdaddr; + int local; + int sock; + int mtu; + int flags; + char *buf; + int len; +} sdp_req_t; + +void process_request(sdp_req_t *req); + +int service_register_req(sdp_req_t *req, sdp_buf_t *rsp); +int service_update_req(sdp_req_t *req, sdp_buf_t *rsp); +int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp); + +typedef struct { + long timestamp; + union { + uint16_t maxBytesSent; + uint16_t lastIndexSent; + } cStateValue; +} sdp_cont_state_t; + +#define SDP_CONT_STATE_SIZE (sizeof(uint8_t) + sizeof(sdp_cont_state_t)) + +sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate); +void sdp_cstate_cache_init(void); +void sdp_cstate_clean_buf(void); +long sdp_cstate_alloc_buf(sdp_buf_t *buf); + +void sdp_svcdb_reset(void); +void sdp_svcdb_collect_all(int sock); +void sdp_svcdb_set_collectable(sdp_record_t *rec, int sock); +void sdp_svcdb_collect(sdp_record_t *rec); +sdp_record_t *sdp_record_find(uint32_t handle); +void sdp_record_add(sdp_record_t *rec); +int sdp_record_remove(uint32_t handle); +sdp_list_t *sdp_get_record_list(); + +long sdp_get_time(); + +#endif diff --git a/sdpd/service.c b/sdpd/service.c new file mode 100644 index 00000000..171a086d --- /dev/null +++ b/sdpd/service.c @@ -0,0 +1,241 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + Service registration requests. + + Fixes: + Guruprasad Krishnamurthy +*/ + +/* + * $Id$ + */ + +#include +#include +#include + +#include "sdpd.h" + +extern void update_db_timestamp(void); + +// FIXME: refactor for server-side +static sdp_record_t *extract_pdu_server(char *p, uint32_t handleExpected, int *scanned) +{ + int extractStatus = -1, localExtractedLength = 0; + uint8_t dtd; + int seqlen = 0; + sdp_record_t *rec = NULL; + uint16_t attrId, lookAheadAttrId; + sdp_data_t *pAttr = NULL; + uint32_t handle = 0xffffffff; + + *scanned = sdp_extract_seqtype(p, &dtd, &seqlen); + p += *scanned; + lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *)(p + sizeof(uint8_t)))); + + SDPDBG("Look ahead attr id : %d\n", lookAheadAttrId); + + if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { + handle = ntohl(sdp_get_unaligned((uint32_t *)(p + + sizeof(uint8_t) + sizeof(uint16_t) + + sizeof(uint8_t)))); + SDPDBG("SvcRecHandle : 0x%x\n", handle); + rec = sdp_record_find(handle); + } else if (handleExpected != 0xffffffff) + rec = sdp_record_find(handleExpected); + + if (rec == NULL) { + rec = sdp_record_alloc(); + rec->attrlist = NULL; + if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { + rec->handle = handle; + sdp_record_add(rec); + } else if (handleExpected != 0xffffffff) { + rec->handle = handleExpected; + sdp_record_add(rec); + } + } + + while (localExtractedLength < seqlen) { + int attrSize = sizeof(uint8_t); + int attrValueLength = 0; + + SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength); + dtd = *(uint8_t *)p; + + attrId = ntohs(sdp_get_unaligned((uint16_t *)(p + attrSize))); + attrSize += sizeof(uint16_t); + + SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attrId); + + pAttr = sdp_extract_attr(p + attrSize, &attrValueLength, rec); + + SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attrId, attrValueLength); + + attrSize += attrValueLength; + if (pAttr == NULL) { + SDPDBG("Terminating extraction of attributes"); + break; + } + localExtractedLength += attrSize; + p += attrSize; + sdp_attr_replace(rec, attrId, pAttr); + extractStatus = 0; + SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d", + seqlen, localExtractedLength); + } + + if (extractStatus == 0) { + SDPDBG("Successful extracting of Svc Rec attributes\n"); +#ifdef SDP_DEBUG + sdp_print_service_attr(rec->attrlist); +#endif + *scanned += seqlen; + } + return rec; +} + +/* + * Add the newly created service record to the service repository + */ +int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) +{ + int scanned = 0; + sdp_data_t *handle; + char *p = req->buf + sizeof(sdp_pdu_hdr_t); + sdp_record_t *rec; + + req->flags = *p++; + + // save image of PDU: we need it when clients request this attribute + rec = extract_pdu_server(p, 0xffffffff, &scanned); + if (rec == NULL) { + sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *)rsp->data); + rsp->data_size = sizeof(uint16_t); + return -1; + } + + rec->handle = (uint32_t)rec; + sdp_record_add(rec); + if (!(req->flags & SDP_RECORD_PERSIST)) + sdp_svcdb_set_collectable(rec, req->sock); + handle = sdp_data_alloc(SDP_UINT32, &rec->handle); + sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, handle); + /* + * if the browse group descriptor is NULL, + * ensure that the record belongs to the ROOT group + */ + if (sdp_data_get(rec, SDP_ATTR_BROWSE_GRP_LIST) == NULL) { + uuid_t uuid; + sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); + sdp_pattern_add_uuid(rec, &uuid); + } + update_db_timestamp(); + + /* Build a rsp buffer */ + sdp_put_unaligned(htonl(rec->handle), (uint32_t *)rsp->data); + rsp->data_size = sizeof(uint32_t); + return 0; +} + +/* + * Update a service record + */ +int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) +{ + sdp_record_t *orec; + int status = 0, scanned = 0; + char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + + SDPDBG(""); + + SDPDBG("Svc Rec Handle: 0x%x\n", handle); + + p += sizeof(uint32_t); + + orec = sdp_record_find(handle); + + SDPDBG("SvcRecOld: 0x%x\n", (uint32_t)orec); + + if (orec) { + sdp_record_t *nrec = extract_pdu_server(p, handle, &scanned); + if (nrec && handle == nrec->handle) + update_db_timestamp(); + else { + SDPDBG("SvcRecHandle : 0x%x\n", handle); + SDPDBG("SvcRecHandleNew : 0x%x\n", nrec->handle); + SDPDBG("SvcRecNew : 0x%x\n", (uint32_t) nrec); + SDPDBG("SvcRecOld : 0x%x\n", (uint32_t) orec); + SDPDBG("Failure to update, restore old value\n"); + + if (nrec) + sdp_record_free(nrec); + status = SDP_INVALID_SYNTAX; + } + } else + status = SDP_INVALID_RECORD_HANDLE; + + p = rsp->data; + sdp_put_unaligned(htons(status), (uint16_t *)p); + rsp->data_size = sizeof(uint16_t); + return status; +} + +/* + * Remove a registered service record + */ +int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) +{ + char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + sdp_record_t *rec; + int status = 0; + + SDPDBG(""); + + /* extract service record handle */ + p += sizeof(uint32_t); + + rec = sdp_record_find(handle); + if (rec) { + sdp_svcdb_collect(rec); + status = sdp_record_remove(handle); + sdp_record_free(rec); + if (status == 0) + update_db_timestamp(); + } else { + status = SDP_INVALID_RECORD_HANDLE; + SDPDBG("Could not find record : 0x%x\n", handle); + } + + p = rsp->data; + sdp_put_unaligned(htons(status), (uint16_t *)p); + rsp->data_size = sizeof(uint16_t); + + return status; +} diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c new file mode 100644 index 00000000..d0b2b85e --- /dev/null +++ b/sdpd/servicedb.c @@ -0,0 +1,209 @@ +/* + Service Discovery Protocol (SDP) + Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane + + Based on original SDP implementation by Nokia Corporation. + Copyright (C) 2001,2002 Nokia Corporation. + Original author Guruprasad Krishnamurthy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + Service repository. + Has methods to create and clean the repository, besides + methods to add/find/modify/delete individual entries + + Fixes: + Guruprasad Krishnamurthy + Manel Guerrero Zapata +*/ + +/* + * $Id$ + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "sdpd.h" + +static sdp_list_t *service_db; + +/* + * Ordering function called when inserting a service record. + * The service repository is a linked list in sorted order + * and the service record handle is the sort key + */ +static int record_sort(const void *r1, const void *r2) +{ + const sdp_record_t *rec1 = (const sdp_record_t *)r1; + const sdp_record_t *rec2 = (const sdp_record_t *)r2; + + if (!rec1 || !rec2) { + SDPERR("NULL RECORD LIST FATAL\n"); + return -1; + } + return rec1->handle - rec2->handle; +} + +/* + * Reset the service repository by deleting its contents + */ +void sdp_svcdb_reset() +{ + sdp_list_free(service_db, (sdp_free_func_t)sdp_record_free); +} + +typedef struct _indexed { + int sock; + sdp_record_t *record; +} sdp_indexed_t; + +static sdp_list_t *socket_index; + +/* + * collect all services registered over this socket + */ +void sdp_svcdb_collect_all(int sock) +{ + sdp_list_t *p, *q; + + for (p=socket_index, q=0; p; ) { + sdp_indexed_t *item = (sdp_indexed_t *)p->data; + if (item->sock == sock) { + sdp_list_t *next = p->next; + sdp_record_remove(item->record->handle); + free(item); + if (q) + q->next = next; + else + socket_index = next; + free(p); + p = next; + } else if (item->sock > sock) + return; + else { + q = p; + p = p->next; + } + } +} + +void sdp_svcdb_collect(sdp_record_t *rec) +{ + sdp_list_t *p, *q; + + for (p=socket_index, q=0; p; q=p, p=p->next) { + sdp_indexed_t *item = (sdp_indexed_t *)p->data; + if (rec == item->record) { + free(item); + if (q) + q->next = p->next; + else + socket_index = p->next; + free(p); + return; + } + } +} + +static int compare_indices(const void *i1, const void *i2) +{ + const sdp_indexed_t *s1 = (const sdp_indexed_t *)i1; + const sdp_indexed_t *s2 = (const sdp_indexed_t *)i2; + return s1->sock - s2->sock; +} + +void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) +{ + sdp_indexed_t *item = (sdp_indexed_t *)malloc(sizeof(sdp_indexed_t)); + item->sock = sock; + item->record = record; + socket_index = sdp_list_insert_sorted(socket_index, item, compare_indices); +} + +/* + * Add a service record to the repository + */ +void sdp_record_add(sdp_record_t *rec) +{ +#ifdef SDP_DEBUG + SDPDBG("Adding rec : 0x%lx\n", (long)rec); + SDPDBG("with handle : 0x%lx\n", (long)rec->handle); +#endif + service_db = sdp_list_insert_sorted(service_db, rec, record_sort); +} + +static sdp_list_t *record_locate(uint32_t handle) +{ + if (service_db) { + sdp_list_t *p; + sdp_record_t r; + + r.handle = handle; + p = sdp_list_find(service_db, &r, record_sort); + return p; + } + SDPDBG("Could not find svcRec for : 0x%x\n", handle); + return 0; +} + +/* + * Given a service record handle, find the record associated with it. + */ +sdp_record_t *sdp_record_find(uint32_t handle) +{ + sdp_list_t *p = record_locate(handle); + + if (p) + return (sdp_record_t *)p->data; + SDPDBG("Couldn't find record for : 0x%x\n", handle); + return 0; +} + +/* + * Given a service record handle, remove its record from the repository + */ +int sdp_record_remove(uint32_t handle) +{ + sdp_list_t *p = record_locate(handle); + + if (p) { + sdp_record_t *r = (sdp_record_t *)p->data; + if (r) { + service_db = sdp_list_remove(service_db, r); + return 0; + } + } + SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); + return -1; +} + +/* + * Return a pointer to the linked list containing the records in sorted order + */ +sdp_list_t *sdp_get_record_list() +{ + return service_db; +} -- cgit From 32c5dbc2343b258dd9f6f59ab69cdf0b958b5e2c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 20:39:30 +0000 Subject: Correct the path for sdpd --- scripts/bluetooth.rc.deb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bluetooth.rc.deb b/scripts/bluetooth.rc.deb index 01ae1b56..b0b6dc8c 100755 --- a/scripts/bluetooth.rc.deb +++ b/scripts/bluetooth.rc.deb @@ -10,7 +10,7 @@ HCID=/sbin/hcid HCID_CONF=/etc/bluetooth/hcid.conf HCIATTACH=/sbin/hciattach UART_CONF=/etc/bluetooth/uart -SDPD=/usr/sbin/sdpd +SDPD=/sbin/sdpd RFCOMM=/bin/rfcomm RFCOMM_CONF=/etc/bluetooth/rfcomm.conf -- cgit From df713b4db4fb851b197d982d9e91cd85df50839d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 21:32:22 +0000 Subject: Add the ciptool utility --- tools/Makefile.am | 4 +- tools/ciptool.1 | 68 ++++++++ tools/ciptool.c | 479 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 549 insertions(+), 2 deletions(-) create mode 100644 tools/ciptool.1 create mode 100644 tools/ciptool.c diff --git a/tools/Makefile.am b/tools/Makefile.am index 4ddeb5c9..44b30990 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -6,11 +6,11 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = hciattach hciconfig -bin_PROGRAMS = hcitool l2ping sdptool +bin_PROGRAMS = hcitool l2ping sdptool ciptool hciconfig_SOURCES = hciconfig.c csr.h csr.c -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 noinst_PROGRAMS = ppporc diff --git a/tools/ciptool.1 b/tools/ciptool.1 new file mode 100644 index 00000000..982f414b --- /dev/null +++ b/tools/ciptool.1 @@ -0,0 +1,68 @@ +.\" +.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH CIPTOOL 1 "JUNE 6, 2003" "" "" + +.SH NAME +ciptool \- Bluetooth Common ISDN Access Profile (CIP) +.SH SYNOPSIS +.BR "ciptool +[ +.I options +] < +.I command +> +.SH DESCRIPTION +.B ciptool +is used to set up, maintain, and inspect the CIP configuration +of the Bluetooth subsystem in the Linux kernel. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands. +.TP +.BI -i " | " +The command is applied to device +.I +hciX +, which must be the name or the address of an installed Bluetooth +device. If not specified, the command will be use the first +available Bluetooth device. +.SH COMMANDS +.TP +.BI show +Display information about the connected devices. +.TP +.BI search +Search for Bluetooth devices and connect to first one that +offers CIP support. +.TP +.BI connect " [psm]" +Connect the local device to the remote Bluetooth device on the +specified PSM number. If no PSM is specified, it will use the +SDP to retrieve it from the remote device. +.TP +.BI release " [bdaddr]" +Release a connection to the specific device. If no address is +given and only one device is connected this will be released. +.TP +.BI loopback " [psm]" +Create a connection to the remote device for Bluetooth testing. +This command will not provide a CAPI controller, because it is +only for testing the CAPI Message Transport Protocol. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/ciptool.c b/tools/ciptool.c new file mode 100644 index 00000000..31984985 --- /dev/null +++ b/tools/ciptool.c @@ -0,0 +1,479 @@ +/* + * + * Bluetooth Common ISDN Access Profile (CIP) + * + * Copyright (C) 2002-2003 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ + return; +} + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + +static char *cmtp_state[] = { + "unknown", + "connected", + "open", + "bound", + "listening", + "connecting", + "connecting", + "config", + "disconnecting", + "closed" +}; + +static char *cmtp_flagstostr(uint32_t flags) +{ + static char str[100] = ""; + + strcat(str, "["); + + if (flags & (1 << CMTP_LOOPBACK)) + strcat(str, "loopback"); + + strcat(str, "]"); + + return str; +} + +static int get_psm(bdaddr_t *src, bdaddr_t *dst, unsigned short *psm) +{ + sdp_session_t *s; + sdp_list_t *srch, *attrs, *rsp; + uuid_t svclass; + uint16_t attr; + int err; + + if (!(s = sdp_connect(src, dst, 0))) + return -1; + + sdp_uuid16_create(&svclass, CIP_SVCLASS_ID); + srch = sdp_list_append(NULL, &svclass); + + attr = SDP_ATTR_PROTO_DESC_LIST; + attrs = sdp_list_append(NULL, &attr); + + err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); + + sdp_close(s); + + if (err) + return 0; + + for (; rsp; rsp = rsp->next) { + sdp_record_t *rec = (sdp_record_t *) rsp->data; + sdp_list_t *protos; + + if (!sdp_get_access_protos(rec, &protos)) { + unsigned short p = sdp_get_proto_port(protos, L2CAP_UUID); + if (p > 0) { + *psm = p; + return 1; + } + } + } + + return 0; +} + +static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigned short psm, uint32_t flags) +{ + struct cmtp_connadd_req req; + struct hci_dev_info di; + struct sockaddr_l2 addr; + struct l2cap_options opts; + int sk, size; + + hci_devinfo(dev_id, &di); + if (!(di.link_policy & HCI_LP_RSWITCH)) { + printf("Local device is not accepting role switch\n"); + } + + if ((sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) { + perror("Can't create L2CAP socket"); + exit(1); + } + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, src); + addr.l2_psm = 0; + + if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror("Can't bind L2CAP socket"); + close(sk); + exit(1); + } + + size = sizeof(opts); + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) { + perror("Can't get L2CAP options"); + close(sk); + exit(1); + } + + opts.imtu = CMTP_DEFAULT_MTU; + opts.omtu = CMTP_DEFAULT_MTU; + opts.flush_to = 0xffff; + + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { + perror("Can't set L2CAP options"); + close(sk); + exit(1); + } + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, dst); + addr.l2_psm = psm; + + if (connect(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror("Can't connect L2CAP socket"); + close(sk); + exit(1); + } + + req.sock = sk; + req.flags = flags; + + if (ioctl(ctl, CMTPCONNADD, &req) < 0) { + perror("Can't create connection"); + exit(1); + } + + return sk; +} + +static void cmd_show(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + struct cmtp_connlist_req req; + struct cmtp_conninfo ci[16]; + char addr[18]; + int i; + + req.cnum = 16; + req.ci = ci; + + if (ioctl(ctl, CMTPGETCONNLIST, &req) < 0) { + perror("Can't get connection list"); + exit(1); + } + + for (i = 0; i < req.cnum; i++) { + ba2str(&ci[i].bdaddr, addr); + printf("%d %s %s %s\n", ci[i].num, addr, + cmtp_state[ci[i].state], + ci[i].flags ? cmtp_flagstostr(ci[i].flags) : ""); + } +} + +static void cmd_search(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + inquiry_info *info = NULL; + bdaddr_t src, dst; + unsigned short psm; + int i, dev_id, num_rsp, length, flags; + char addr[18]; + uint8_t class[3]; + + ba2str(bdaddr, addr); + dev_id = hci_devid(addr); + if (dev_id < 0) { + dev_id = hci_get_route(NULL); + hci_devba(dev_id, &src); + } else + bacpy(&src, bdaddr); + + length = 8; /* ~10 seconds */ + num_rsp = 0; + flags = 0; + + printf("Searching ...\n"); + + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + + for (i = 0; i < num_rsp; i++) { + memcpy(class, (info+i)->dev_class, 3); + if ((class[1] == 2) && ((class[0] / 4) == 5)) { + bacpy(&dst, &(info+i)->bdaddr); + ba2str(&dst, addr); + + printf("\tChecking service for %s\n", addr); + if (!get_psm(&src, &dst, &psm)) + continue; + + free(info); + + printf("\tConnecting to device %s\n", addr); + do_connect(ctl, dev_id, &src, &dst, psm, 0); + return; + } + } + + free(info); + fprintf(stderr, "\tNo devices in range or visible\n"); + exit(1); +} + +static void cmd_create(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + bdaddr_t src, dst; + unsigned short psm; + int dev_id; + char addr[18]; + + if (argc < 2) + return; + + str2ba(argv[1], &dst); + + ba2str(bdaddr, addr); + dev_id = hci_devid(addr); + if (dev_id < 0) { + dev_id = hci_get_route(&dst); + hci_devba(dev_id, &src); + } else + bacpy(&src, bdaddr); + + if (argc < 3) { + if (!get_psm(&src, &dst, &psm)) + psm = htobs(4099); + } else + psm = htobs(atoi(argv[2])); + + do_connect(ctl, dev_id, &src, &dst, psm, 0); +} + +static void cmd_release(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + struct cmtp_conndel_req req; + struct cmtp_connlist_req cl; + struct cmtp_conninfo ci[16]; + + if (argc < 2) { + cl.cnum = 16; + cl.ci = ci; + + if (ioctl(ctl, CMTPGETCONNLIST, &cl) < 0) { + perror("Can't get connection list"); + exit(1); + } + + if (cl.cnum == 0) + return; + + if (cl.cnum != 1) { + fprintf(stderr, "You have to specifiy the device address.\n"); + exit(1); + } + + bacpy(&req.bdaddr, &ci[0].bdaddr); + } else + str2ba(argv[1], &req.bdaddr); + + if (ioctl(ctl, CMTPCONNDEL, &req) < 0) { + perror("Can't release connection"); + exit(1); + } +} + +static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) +{ + struct cmtp_conndel_req req; + struct sigaction sa; + struct pollfd p; + bdaddr_t src, dst; + unsigned short psm; + int dev_id, sk; + char addr[18]; + + if (argc < 2) + return; + + str2ba(argv[1], &dst); + + ba2str(bdaddr, addr); + dev_id = hci_devid(addr); + if (dev_id < 0) { + dev_id = hci_get_route(&dst); + hci_devba(dev_id, &src); + } else + bacpy(&src, bdaddr); + + ba2str(&dst, addr); + printf("Connecting to %s in loopback mode\n", addr); + + if (argc < 3) { + if (!get_psm(&src, &dst, &psm)) + psm = htobs(4099); + } else + psm = htobs(atoi(argv[2])); + + sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK)); + + printf("Press CTRL-C for hangup\n"); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + p.fd = sk; + p.events = POLLERR | POLLHUP; + + while (!__io_canceled) { + p.revents = 0; + if (poll(&p, 1, 100)) + break; + } + + bacpy(&req.bdaddr, &dst); + ioctl(ctl, CMTPCONNDEL, &req); +} + + +static struct { + char *cmd; + char *alt; + void (*func)(int ctl, bdaddr_t *bdaddr, int argc, char **argv); + char *opt; + char *doc; +} command[] = { + { "show", "list", cmd_show, 0, "Show remote connections" }, + { "search", "scan", cmd_search, 0, "Search for a remote device" }, + { "connect", "create", cmd_create, "", "Connect a remote device" }, + { "release", "disconnect", cmd_release, "[bdaddr]", "Disconnect the remote device" }, + { "loopback", "test", cmd_loopback, "", "Loopback test of a device" }, + { NULL, NULL, NULL, 0, 0 } +}; + +static void usage(void) +{ + int i; + + printf("ciptool - Bluetooth Common ISDN Access Profile (CIP)\n\n"); + + printf("Usage:\n" + "\tciptool [options] [command]\n" + "\n"); + + printf("Options:\n" + "\t-i [hciX|bdaddr] Local HCI device or BD Address\n" + "\t-h, --help Display help\n" + "\n"); + + printf("Commands:\n"); + for (i = 0; command[i].cmd; i++) + printf("\t%-8s %-10s\t%s\n", command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); + printf("\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + bdaddr_t bdaddr; + int i, opt, ctl; + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt = getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch(opt) { + case 'i': + if (!strncmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); + break; + case 'h': + usage(); + exit(0); + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + return 0; + } + + if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_CMTP)) < 0 ) { + perror("Can't open CMTP control socket"); + exit(1); + } + + for (i = 0; command[i].cmd; i++) { + if (strncmp(command[i].cmd, argv[0], 4) && strncmp(command[i].alt, argv[0], 4)) + continue; + command[i].func(ctl, &bdaddr, argc, argv); + close(ctl); + exit(0); + } + + usage(); + + close(ctl); + + return 0; +} -- cgit From 15ddb98b422f139ab70f03e96b090f9a80f62e2d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 21:39:09 +0000 Subject: Add sdpd manpage --- sdpd/Makefile.am | 4 +++ sdpd/sdpd.8 | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 sdpd/sdpd.8 diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 9536bf04..8f50c596 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -7,3 +7,7 @@ mandir = $(prefix)/usr/share/man sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h + +man_MANS = sdpd.8 + +EXTRA_DIST = $(man_MANS) diff --git a/sdpd/sdpd.8 b/sdpd/sdpd.8 new file mode 100644 index 00000000..34ce987d --- /dev/null +++ b/sdpd/sdpd.8 @@ -0,0 +1,88 @@ +.\" $Header$ +.\" +.\" transcript compatibility for postscript use. +.\" +.\" synopsis: .P! +.\" +.de P! +.fl +\!!1 setgray +.fl +\\&.\" +.fl +\!!0 setgray +.fl \" force out current output buffer +\!!save /psv exch def currentpoint translate 0 0 moveto +\!!/showpage{}def +.fl \" prolog +.sy sed -e 's/^/!/' \\$1\" bring in postscript file +\!!psv restore +. +.de pF +.ie \\*(f1 .ds f1 \\n(.f +.el .ie \\*(f2 .ds f2 \\n(.f +.el .ie \\*(f3 .ds f3 \\n(.f +.el .ie \\*(f4 .ds f4 \\n(.f +.el .tm ? font overflow +.ft \\$1 +.. +.de fP +.ie !\\*(f4 \{\ +. ft \\*(f4 +. ds f4\" +' br \} +.el .ie !\\*(f3 \{\ +. ft \\*(f3 +. ds f3\" +' br \} +.el .ie !\\*(f2 \{\ +. ft \\*(f2 +. ds f2\" +' br \} +.el .ie !\\*(f1 \{\ +. ft \\*(f1 +. ds f1\" +' br \} +.el .tm ? font underflow +.. +.ds f1\" +.ds f2\" +.ds f3\" +.ds f4\" +'\" t +.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n +.TH "sdpd" "8" +.SH "NAME" +sdpd \(em SDP daemon +.SH "SYNOPSIS" +.PP +\fBsdpd\fR [\fIoptions\fR] +.SH "DESCRIPTION" +.PP +\fBsdpd\fR allows Bluetooth devices +connected to the host to advertise via SDP the Bluetooth services +available. + +.SH "OPTIONS" +.IP "\fB-n\fP" 10 +Don't detach from the controlling terminal. + +.SH "BUGS" +.PP +None yet known. +.SH "AUTHOR" +.PP +Maxim Krasnyansky , +Stephen Crane . Man page written +by Edd Dumbill . + +.PP +Based on work done by Guruprasad Krishnamurthy +, Dmitry Kasatkin + and Manel Guerrero Zapata +. + +.SH "SEE ALSO" +.PP +sdptool(1) +.\" created by instant / docbook-to-man, Thu 15 Jan 2004, 21:01 -- cgit From ae589e848ef11d21ef9882e56dedf0dad7b47b8d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 21:42:12 +0000 Subject: Update RPM spec file --- utils.spec | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/utils.spec b/utils.spec index 1ea074f9..3fd4ccd8 100644 --- a/utils.spec +++ b/utils.spec @@ -28,6 +28,9 @@ Bluetooth utilities (bluez-utils): - hciattach - hciconfig - hcid + - sdpd + - sdptool + - ciptool - l2ping - start scripts (RedHat) - pcmcia configuration files @@ -65,11 +68,19 @@ rm -rf $RPM_BUILD_ROOT /sbin/hciattach /sbin/hciconfig /sbin/hcid +/sbin/sdpd +/bin/sdptool +/bin/ciptool %{_mandir}/man8/hciattach.8.gz %{_mandir}/man8/hciconfig.8.gz +%{_mandir}/man5/hcid.conf.5.gz +%{_mandir}/man8/hcid.8.gz +%{_mandir}/man8/sdpd.8.gz %{_mandir}/man1/hcitool.1.gz -%{_mandir}/man1/l2ping.1.gz +%{_mandir}/man1/sdptool.1.gz +%{_mandir}/man1/ciptool.1.gz %{_mandir}/man1/rfcomm.1.gz +%{_mandir}/man1/l2ping.1.gz %{_sysconfdir}/bluetooth/* %{_sysconfdir}/pcmcia/bluetooth.conf %{_sysconfdir}/pcmcia/bluetooth -- cgit From a16293f34e175408334275267776142408032d45 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 14:28:28 +0000 Subject: Display string as hex bytes if it is longer than strlen() --- tools/sdptool.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 5340ab1b..abb8b439 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -396,8 +396,15 @@ void sdp_data_printf(sdp_data_t *sdpdata, case SDP_TEXT_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: - printf("%.*sText : \"%s\"\n", indent, indent_spaces, - sdpdata->val.str); + if (sdpdata->unitSize > strlen(sdpdata->val.str)) { + int i; + printf("%.*sData :", indent, indent_spaces); + for (i = 0; i < sdpdata->unitSize; i++) + printf(" %02x", (unsigned char) sdpdata->val.str[i]); + printf("\n"); + } else + printf("%.*sText : \"%s\"\n", indent, indent_spaces, + sdpdata->val.str); break; case SDP_URL_STR8: case SDP_URL_STR16: -- cgit From 32fc232a8bfd1f5541a2667f02fa476d95c95dd3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 21:10:23 +0000 Subject: Update the manpage --- tools/hcitool.1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/hcitool.1 b/tools/hcitool.1 index bb52e1ba..f23cf7f5 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -158,6 +158,10 @@ is 0. .BI auth " " Request authentication for the device with Bluetooth address .IR bdaddr . +.TP +.BI enc " [encrypt enable]" +Enable or disable the encryption for the device with Bluetooth address +.IR bdaddr . .SH AUTHORS Written by Maxim Krasnyansky .PP -- cgit From b4e62d0942cc975be9f427d444231d5f104c87d0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 21:19:18 +0000 Subject: Change default prefix to /usr --- configure.in | 8 ++++---- hcid/Makefile.am | 2 +- rfcomm/Makefile.am | 2 +- sdpd/Makefile.am | 2 +- tools/Makefile.am | 2 +- utils.spec | 20 ++++++++++---------- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/configure.in b/configure.in index 56b4132f..0c086693 100644 --- a/configure.in +++ b/configure.in @@ -9,13 +9,10 @@ AM_MAINTAINER_MODE AM_INIT_AUTOMAKE(bluez-utils, 2.5) -AC_SUBST(DISTRO) -AC_SUBST(PCMCIA) +AC_PREFIX_DEFAULT(/usr) CFLAGS="-Wall -g -O2" -AC_PREFIX_DEFAULT() - AC_PROG_CC AC_PROG_INSTALL AC_PROG_YACC @@ -49,6 +46,9 @@ AC_SEARCH_LIB(bluetooth, hci_open_dev, $BLUEZ_LIBDIR,, Please compile and install bluez-libs package.) ) +AC_SUBST(DISTRO) +AC_SUBST(PCMCIA) + DISTRO=unknown if test "$cross_compiling" != yes; then diff --git a/hcid/Makefile.am b/hcid/Makefile.am index ba00df7e..d08f5fcd 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -mandir = $(prefix)/usr/share/man +mandir = $(prefix)/share/man sbin_PROGRAMS = hcid diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index aa0c5462..262dbc4c 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -mandir = $(prefix)/usr/share/man +mandir = $(prefix)/share/man confdir = $(sysconfdir)/bluetooth bin_PROGRAMS = rfcomm diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 8f50c596..c1dcb253 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -mandir = $(prefix)/usr/share/man +mandir = $(prefix)/share/man sbin_PROGRAMS = sdpd diff --git a/tools/Makefile.am b/tools/Makefile.am index 44b30990..1ff3c9bc 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -mandir = $(prefix)/usr/share/man +mandir = $(prefix)/share/man sbin_PROGRAMS = hciattach hciconfig diff --git a/utils.spec b/utils.spec index 3fd4ccd8..b9ea0c35 100644 --- a/utils.spec +++ b/utils.spec @@ -61,16 +61,16 @@ rm -rf $RPM_BUILD_ROOT %defattr(-, root, root) /etc/rc.d/init.d/bluetooth -/bin/hcitool -/bin/l2ping -/bin/bluepin -/bin/rfcomm -/sbin/hciattach -/sbin/hciconfig -/sbin/hcid -/sbin/sdpd -/bin/sdptool -/bin/ciptool +/usr/bin/hcitool +/usr/bin/l2ping +/usr/bin/bluepin +/usr/bin/rfcomm +/usr/sbin/hciattach +/usr/sbin/hciconfig +/usr/sbin/hcid +/usr/sbin/sdpd +/usr/bin/sdptool +/usr/bin/ciptool %{_mandir}/man8/hciattach.8.gz %{_mandir}/man8/hciconfig.8.gz %{_mandir}/man5/hcid.conf.5.gz -- cgit From 645b703bed7a352838451e5ca934c605fafebfec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 21:28:40 +0000 Subject: Change default prefix to /usr --- scripts/bluetooth.rc.deb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/bluetooth.rc.deb b/scripts/bluetooth.rc.deb index b0b6dc8c..4c216c31 100755 --- a/scripts/bluetooth.rc.deb +++ b/scripts/bluetooth.rc.deb @@ -6,12 +6,12 @@ NAME=bluetooth DESC="Bluetooth subsystem" PATH=/sbin:/bin:/usr/sbin:/usr/bin -HCID=/sbin/hcid +HCID=/usr/sbin/hcid HCID_CONF=/etc/bluetooth/hcid.conf -HCIATTACH=/sbin/hciattach +HCIATTACH=/usr/sbin/hciattach UART_CONF=/etc/bluetooth/uart -SDPD=/sbin/sdpd -RFCOMM=/bin/rfcomm +SDPD=/usr/sbin/sdpd +RFCOMM=/usr/bin/rfcomm RFCOMM_CONF=/etc/bluetooth/rfcomm.conf set -e -- cgit From 757548a6710ddd0beb29e82c84749160b4dff1cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 21:31:11 +0000 Subject: Update changelog and bump version number --- ChangeLog | 10 ++++++++++ configure.in | 2 +- utils.spec | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0ca09ee..d8dc5717 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +ver 2.6: + Change default prefix to /usr. + Add manpages for hcid and hcid.conf. + Add the sdpd server daemon. + Add the sdptool utility. + Add the ciptool utility. + + Note: + This version needs at least bluez-libs-2.6 + ver 2.5: hcitool changes: Support for requesting authentication. diff --git a/configure.in b/configure.in index 0c086693..594db109 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT() AM_MAINTAINER_MODE -AM_INIT_AUTOMAKE(bluez-utils, 2.5) +AM_INIT_AUTOMAKE(bluez-utils, 2.6) AC_PREFIX_DEFAULT(/usr) diff --git a/utils.spec b/utils.spec index b9ea0c35..5ec5d210 100644 --- a/utils.spec +++ b/utils.spec @@ -1,5 +1,5 @@ # Note that this is NOT a relocatable package -%define ver 2.5 +%define ver 2.6 %define RELEASE 1 %define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} %define prefix / -- cgit From a5b3f19c5d1722fa60ce5ab423be81c85c6bbc54 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 22:37:52 +0000 Subject: Make use of $(sysconfdir) --- pcmcia/Makefile.am | 2 +- scripts/Makefile.am | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pcmcia/Makefile.am b/pcmcia/Makefile.am index 485bb06b..e3336541 100644 --- a/pcmcia/Makefile.am +++ b/pcmcia/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -pcmciadir = /etc/pcmcia +pcmciadir = $(sysconfdir)/pcmcia EXTRA_DIST = bluetooth bluetooth.conf diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 812f160a..8c6e56d2 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -12,9 +12,9 @@ unknown: -echo Unknown distribution redhat: - $(mkinstalldirs) $(DESTDIR)/etc/rc.d/init.d - $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)/etc/rc.d/init.d/bluetooth + $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/rc.d/init.d + $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)$(sysconfdir)/rc.d/init.d/bluetooth debian: - $(mkinstalldirs) $(DESTDIR)/etc/init.d - $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.deb $(DESTDIR)/etc/init.d/bluetooth + $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/init.d + $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.deb $(DESTDIR)$(sysconfdir)/init.d/bluetooth -- cgit From b84d9d2389c47c841502b7f4ef3acca8f9f19246 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 23:29:12 +0000 Subject: Update the autoconf stuff --- configure.in | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 594db109..60fb7e10 100644 --- a/configure.in +++ b/configure.in @@ -3,16 +3,32 @@ dnl $Id$ dnl dnl Process this file with autoconf to produce a configure script. dnl -AC_INIT() -AM_MAINTAINER_MODE +AC_PREREQ(2.50) +AC_INIT() AM_INIT_AUTOMAKE(bluez-utils, 2.6) +AM_MAINTAINER_MODE + AC_PREFIX_DEFAULT(/usr) +if test "$prefix" = "NONE"; then + dnl no prefix and no sysconfdir, so default to /etc + if test "$sysconfdir" = '${prefix}/etc'; then + AC_SUBST([sysconfdir], ['/etc']) + fi + + dnl no prefix and no mandir, so use ${prefix}/share/man as default + if test "$mandir" = '${prefix}/man'; then + AC_SUBST([mandir], ['${prefix}/share/man']) + fi +fi + CFLAGS="-Wall -g -O2" +AC_LANG_C + AC_PROG_CC AC_PROG_INSTALL AC_PROG_YACC -- cgit From 50e3f700e51d2fc58483882aa62671682f08c1f9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 23:45:14 +0000 Subject: Update the installation information --- README | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/README b/README index 69bc3145..7bfa32df 100644 --- a/README +++ b/README @@ -1,35 +1,34 @@ BlueZ - Bluetooth protocol stack for Linux -Copyright (C) 2000-2001 Qualcomm Incorporated -Written 2000,2001 by Maxim Krasnyansky +Copyright (C) 2000-2001 Qualcomm Incorporated +Copyright (C) 2002-2003 Maxim Krasnyansky +Copyright (C) 2002-2004 Marcel Holtmann Bluetooth utilities -1. Compilation and Installation. -In order to compile Bluetooth utilies you need following software packages: - - Linux kernel 2.4.X source code - - GCC compiler - - Lexical Analyzer (flex, lex) - - YACC (yacc, bison, byacc) +1. Compilation and installation. + +In order to compile Bluetooth utilities you need following software packages: + - Linux Bluetooth protocol stack (BlueZ) + - GCC compiler + - Lexical Analyzer (flex, lex) + - YACC (yacc, bison, byacc) To configure run: - ./configure + ./configure --prefix=/usr --sysconfdir=/etc Configure automatically searches for all required components and packages. To compile and install run: - make install + make install + -2.0 Information +2. Information Mailing lists: - bluez-announce@lists.sourceforge.net - BlueZ announcements - bluez-users@lists.sourceforge.net - BlueZ general questions and discussions - bluez-devel@lists.sourceforge.net - BlueZ development - bluez-commit@lists.sourceforge.net - BlueZ commits to the CVS repository + bluez-users@lists.sourceforge.net - BlueZ general questions and discussions + bluez-devel@lists.sourceforge.net - BlueZ development For additional information about the project visit BlueZ web site: - http://bluez.sf.net - -Maxim Krasnyansky + http://www.bluez.org -- cgit From 719873a6b8d26c78b0a9a2380647e83c8e4bc05c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Apr 2004 00:08:19 +0000 Subject: Modifying $mandir is no longer needed --- hcid/Makefile.am | 2 -- rfcomm/Makefile.am | 1 - sdpd/Makefile.am | 2 -- tools/Makefile.am | 2 -- 4 files changed, 7 deletions(-) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index d08f5fcd..0a5a5448 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -2,8 +2,6 @@ # $Id$ # -mandir = $(prefix)/share/man - sbin_PROGRAMS = hcid if ENABLE_DBUS diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index 262dbc4c..f525fc4f 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -2,7 +2,6 @@ # $Id$ # -mandir = $(prefix)/share/man confdir = $(sysconfdir)/bluetooth bin_PROGRAMS = rfcomm diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index c1dcb253..81c248ce 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -2,8 +2,6 @@ # $Id$ # -mandir = $(prefix)/share/man - sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h diff --git a/tools/Makefile.am b/tools/Makefile.am index 1ff3c9bc..ca7369a2 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,8 +2,6 @@ # $Id$ # -mandir = $(prefix)/share/man - sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping sdptool ciptool -- cgit From 1f72ace38b1c7575e4ace602975a3e6915716952 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Apr 2004 15:32:01 +0000 Subject: Fix PSM value for big endian machines --- tools/ciptool.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/ciptool.c b/tools/ciptool.c index 31984985..d9aa0085 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -167,7 +167,7 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, dst); - addr.l2_psm = psm; + addr.l2_psm = htobs(psm); if (connect(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Can't connect L2CAP socket"); @@ -279,9 +279,9 @@ static void cmd_create(int ctl, bdaddr_t *bdaddr, int argc, char **argv) if (argc < 3) { if (!get_psm(&src, &dst, &psm)) - psm = htobs(4099); + psm = 4099; } else - psm = htobs(atoi(argv[2])); + psm = atoi(argv[2]); do_connect(ctl, dev_id, &src, &dst, psm, 0); } @@ -347,9 +347,9 @@ static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) if (argc < 3) { if (!get_psm(&src, &dst, &psm)) - psm = htobs(4099); + psm = 4099; } else - psm = htobs(atoi(argv[2])); + psm = atoi(argv[2]); sk = do_connect(ctl, dev_id, &src, &dst, psm, (1 << CMTP_LOOPBACK)); -- cgit From b215047988241418ccbcaa41c07366ea637678c7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 05:26:15 +0000 Subject: Use automake config header feature --- bootstrap | 2 +- configure.in | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/bootstrap b/bootstrap index 019a160f..c9042454 100755 --- a/bootstrap +++ b/bootstrap @@ -1,2 +1,2 @@ #! /bin/sh -aclocal && automake --copy --add-missing && autoconf +aclocal && autoheader && automake --copy --add-missing && autoconf diff --git a/configure.in b/configure.in index 60fb7e10..3115ee0e 100644 --- a/configure.in +++ b/configure.in @@ -1,13 +1,12 @@ dnl dnl $Id$ dnl -dnl Process this file with autoconf to produce a configure script. -dnl AC_PREREQ(2.50) AC_INIT() AM_INIT_AUTOMAKE(bluez-utils, 2.6) +AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From 1d3715db11f573060cb02a2b7b7c44f06607d337 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 06:04:35 +0000 Subject: Update BlueZ library configuration --- acinclude.m4 | 117 ++++++++++++----------------------------------------- configure.in | 46 +++------------------ hcid/Makefile.am | 4 ++ hcid/main.c | 4 ++ rfcomm/Makefile.am | 4 ++ rfcomm/main.c | 4 ++ sdpd/Makefile.am | 4 ++ sdpd/main.c | 8 +++- sdpd/sdpd.h | 9 +++++ test/Makefile.am | 4 ++ tools/Makefile.am | 4 ++ tools/ciptool.c | 4 ++ tools/hciattach.c | 4 ++ tools/hciconfig.c | 4 ++ tools/hcitool.c | 4 ++ tools/sdptool.c | 6 ++- 16 files changed, 97 insertions(+), 133 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index a2fa7784..ea030ae2 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,101 +1,36 @@ -dnl Test file -AC_DEFUN([AC_TEST_FILE], -[ - if test -f $1; then - ifelse([$2], , :,[$2]) - else - ifelse([$3], , :,[$3]) - fi -]) +dnl +dnl $Id$ +dnl -dnl Test dir -AC_DEFUN([AC_TEST_DIR], -[ - if test -d $1; then - ifelse([$2], , :,[$2]) - else - ifelse([$3], , :,[$3]) - fi -]) +AC_DEFUN(AC_PATH_BLUEZ, [ + BLUEZ_INCLUDES="" + BLUEZ_LDFLAGS="" + BLUEZ_LIBS="" -dnl Test files -AC_DEFUN([AC_TEST_FILES], -[ - ac_file_found=yes - for f in $1; do - if test ! -f $2/$f; then - ac_file_found=no - break; - fi - done + ac_save_CFLAGS=$CFLAGS + test -n "$bluez_includes" && CFLAGS="$CFLAGS -I$bluez_includes" - if test "$ac_file_found" = "yes" ; then - ifelse([$3], , :,[$3]) - else - ifelse([$4], , :,[$4]) - fi -]) + ac_save_LDFLAGS=$LDFLAGS + test -n "$bluez_libraries" && LDFLAGS="$LDFLAGS -L$bluez_libraries" -dnl Search for headers, add path to CPPFLAGS if found -AC_DEFUN([AC_SEARCH_HEADERS], -[ - AC_MSG_CHECKING("for $1") - ac_hdr_found=no - for p in $2; do - test -d $p || continue; - p=`cd $p && pwd` - AC_TEST_FILES($1, $p, - [ - ac_hdr_found=yes - break - ] - ) - done - if test "$ac_hdr_found" = "yes" ; then - CPPFLAGS="$CPPFLAGS -I$p" - AC_MSG_RESULT( [($p) yes] ) - ifelse([$3], , :,[$3]) - else - AC_MSG_RESULT("no") - ifelse([$4], , :,[$4]) - fi -]) + AC_CHECK_HEADER(bluetooth/bluetooth.h,, + AC_MSG_ERROR(Bluetooth header files not found)) -dnl Search for library, add path to LIBS if found -AC_DEFUN([AC_SEARCH_LIB], -[ - AC_MSG_CHECKING("for lib$1") + AC_CHECK_LIB(bluetooth, hci_open_dev, + BLUEZ_LIBS="$BLUEZ_LIBS -lbluetooth", + AC_MSG_ERROR(Bluetooth library not found)) - ac_save_LDFLAGS=$LDFLAGS + AC_CHECK_LIB(sdp, sdp_connect, + BLUEZ_LIBS="$BLUEZ_LIBS -lsdp") - ac_lib_found=no - for p in $3; do - test -d $p || continue; - p=`cd $p && pwd` + CFLAGS=$ac_save_CFLAGS + test -n "$bluez_includes" && BLUEZ_INCLUDES="-I$bluez_includes" - # Check for libtool library - if test -f $p/lib$1.la; then - path=$p/.libs - else - path=$p - fi - - LDFLAGS="-L$path -l$1" - AC_TRY_LINK_FUNC($2, - [ - LIBS="$LIBS -L$p -l$1" - ac_lib_found=yes - break - ] - ) - done - if test "$ac_lib_found" = "yes" ; then - AC_MSG_RESULT( [($p) yes] ) - ifelse([$4], , :,[$4]) - else - AC_MSG_RESULT("no") - ifelse([$5], , :,[$5]) - fi + LDFLAGS=$ac_save_LDFLAGS + test -n "$bluez_libraries" && BLUEZ_LDFLAGS="-L$bluez_libraries" + test -n "$bluez_libraries" && BLUEZ_LIBS="-L$bluez_libraries $BLUEZ_LIBS" - LDFLAGS=$ac_save_LDFLAGS + AC_SUBST(BLUEZ_INCLUDES) + AC_SUBST(BLUEZ_LDFLAGS) + AC_SUBST(BLUEZ_LIBS) ]) diff --git a/configure.in b/configure.in index 3115ee0e..0c26d6a3 100644 --- a/configure.in +++ b/configure.in @@ -33,52 +33,18 @@ AC_PROG_INSTALL AC_PROG_YACC AM_PROG_LEX -AC_ARG_WITH(bluez-libs, - --with-bluez-libs=DIR BlueZ libraries, - BLUEZ_LIBDIR="$withval", - BLUEZ_LIBDIR='../libs/src /usr/lib' -) +AC_ARG_WITH(bluez, [ --with-bluez=DIR BlueZ library is installed in DIR], [ + bluez_includes=$withval/include + bluez_libraries=$withval/lib +]) -AC_ARG_WITH(bluez-includes, - --with-bluez-includes=DIR BlueZ header files, - BLUEZ_INCDIR="$withval", - BLUEZ_INCDIR='../libs/include /usr/include' -) +AC_PATH_BLUEZ -AC_ARG_ENABLE(dbus, - --enable-dbus use D-BUS, +AC_ARG_ENABLE(dbus, [ --enable-dbus use D-BUS], BLUEZ_DBUS="$enableval", BLUEZ_DBUS="no" ) -AC_SEARCH_HEADERS(bluetooth/bluetooth.h, $BLUEZ_INCDIR,, - AC_MSG_ERROR(Bluetooth headers not found. - Please compile and install bluez-libs package.) -) - -AC_SEARCH_LIB(bluetooth, hci_open_dev, $BLUEZ_LIBDIR,, - AC_MSG_ERROR(Bluetooth library not found. - Please compile and install bluez-libs package.) -) - -AC_SUBST(DISTRO) -AC_SUBST(PCMCIA) - -DISTRO=unknown - -if test "$cross_compiling" != yes; then - AC_TEST_FILE(/etc/redhat-release, DISTRO=redhat) - AC_TEST_FILE(/etc/mandrake-release, DISTRO=redhat) - AC_TEST_FILE(/etc/debian_version, DISTRO=debian) -fi - -AC_ARG_ENABLE(pcmcia, - --enable-pcmcia Always install PCMCIA support files, - [PCMCIA=pcmcia], - [ if test "$cross_compiling" != yes; then - AC_TEST_DIR(/etc/pcmcia, PCMCIA=pcmcia, PCMCIA=) - fi ]) - if test x"$BLUEZ_DBUS" == "xyes"; then PKG_CHECK_MODULES(DBUS, dbus-1, have_dbus=yes, have_dbus=no) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 0a5a5448..f356b9b6 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -13,6 +13,10 @@ endif hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) hcid_CONFIG = hcid.conf +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + man_MANS = hcid.8 hcid.conf.5 YFLAGS = -d diff --git a/hcid/main.c b/hcid/main.c index 2d1d5686..72453958 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -25,6 +25,10 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index f525fc4f..980b0900 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -9,6 +9,10 @@ bin_PROGRAMS = rfcomm rfcomm_SOURCES = main.c parser.h parser.y lexer.l kword.h kword.c rfcomm_CONFIG = rfcomm.conf +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + man_MANS = rfcomm.1 YFLAGS = -d diff --git a/rfcomm/main.c b/rfcomm/main.c index 68396b5e..52701d40 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -21,6 +21,10 @@ * */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 81c248ce..97f9b9e1 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -6,6 +6,10 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + man_MANS = sdpd.8 EXTRA_DIST = $(man_MANS) diff --git a/sdpd/main.c b/sdpd/main.c index fea283f2..132539d5 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -34,23 +34,29 @@ /* * $Id$ */ + +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include #include -#include #include "sdpd.h" diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 1f0d7e47..37c685e2 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -30,6 +30,15 @@ #ifndef SDPD_H #define SDPD_H +#define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg) +#define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg) + +#ifdef SDP_DEBUG +#define SDPDBG(fmt, arg...) syslog(LOG_DEBUG, "%s: " fmt "\n", __func__ , ## arg) +#else +#define SDPDBG(fmt...) +#endif + typedef struct request { bdaddr_t bdaddr; int local; diff --git a/test/Makefile.am b/test/Makefile.am index ec6b7779..79386603 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,4 +4,8 @@ noinst_PROGRAMS = l2test scotest rctest attest hstest +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + EXTRA_DIST = hsplay hsmicro diff --git a/tools/Makefile.am b/tools/Makefile.am index ca7369a2..354f841c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -8,6 +8,10 @@ bin_PROGRAMS = hcitool l2ping sdptool ciptool hciconfig_SOURCES = hciconfig.c csr.h csr.c +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 noinst_PROGRAMS = ppporc diff --git a/tools/ciptool.c b/tools/ciptool.c index d9aa0085..bec3fc2b 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -21,6 +21,10 @@ * */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/tools/hciattach.c b/tools/hciattach.c index 799e338d..926e3fab 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -24,6 +24,10 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 39804e45..6ab7f190 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -25,6 +25,10 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/tools/hcitool.c b/tools/hcitool.c index 8fd7b83d..667212fe 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -25,6 +25,10 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/tools/sdptool.c b/tools/sdptool.c index abb8b439..87646cab 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -28,14 +28,18 @@ * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include #include +#include #include #include -#include #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1) -- cgit From f06f701cd50b80c01081b40e69943adbb405e665 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 06:11:19 +0000 Subject: Don't include sdp_internal.h --- sdpd/cstate.c | 1 - sdpd/request.c | 3 ++- sdpd/service.c | 3 ++- sdpd/servicedb.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sdpd/cstate.c b/sdpd/cstate.c index e9b51832..494292ac 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -37,7 +37,6 @@ #include #include -#include #include "sdpd.h" diff --git a/sdpd/request.c b/sdpd/request.c index 2354e40e..ff3b5642 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -36,10 +36,11 @@ */ #include +#include +#include #include #include -#include #include "sdpd.h" diff --git a/sdpd/service.c b/sdpd/service.c index 171a086d..4d03c917 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -34,9 +34,10 @@ * $Id$ */ +#include + #include #include -#include #include "sdpd.h" diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index d0b2b85e..36035a81 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -38,13 +38,13 @@ */ #include +#include #include #include #include #include #include -#include #include "sdpd.h" -- cgit From 138996fe1350b28f551edc24ecc6c498d20c64f5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 06:20:54 +0000 Subject: Simplify autoconf stuff --- acinclude.m4 | 21 +++++++++++++++++++++ configure.in | 19 +------------------ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index ea030ae2..67506577 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -2,7 +2,28 @@ dnl dnl $Id$ dnl +AC_DEFUN(AC_PREFIX_BLUEZ, [ + AC_PREFIX_DEFAULT(/usr) + + if test "$prefix" = "NONE"; then + dnl no prefix and no sysconfdir, so default to /etc + if test "$sysconfdir" = '${prefix}/etc'; then + AC_SUBST([sysconfdir], ['/etc']) + fi + + dnl no prefix and no mandir, so use ${prefix}/share/man as default + if test "$mandir" = '${prefix}/man'; then + AC_SUBST([mandir], ['${prefix}/share/man']) + fi + fi +]) + AC_DEFUN(AC_PATH_BLUEZ, [ + AC_ARG_WITH(bluez, [ --with-bluez=DIR BlueZ library is installed in DIR], [ + bluez_includes=$withval/include + bluez_libraries=$withval/lib + ]) + BLUEZ_INCLUDES="" BLUEZ_LDFLAGS="" BLUEZ_LIBS="" diff --git a/configure.in b/configure.in index 0c26d6a3..e0211d39 100644 --- a/configure.in +++ b/configure.in @@ -10,19 +10,7 @@ AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -AC_PREFIX_DEFAULT(/usr) - -if test "$prefix" = "NONE"; then - dnl no prefix and no sysconfdir, so default to /etc - if test "$sysconfdir" = '${prefix}/etc'; then - AC_SUBST([sysconfdir], ['/etc']) - fi - - dnl no prefix and no mandir, so use ${prefix}/share/man as default - if test "$mandir" = '${prefix}/man'; then - AC_SUBST([mandir], ['${prefix}/share/man']) - fi -fi +AC_PREFIX_BLUEZ CFLAGS="-Wall -g -O2" @@ -33,11 +21,6 @@ AC_PROG_INSTALL AC_PROG_YACC AM_PROG_LEX -AC_ARG_WITH(bluez, [ --with-bluez=DIR BlueZ library is installed in DIR], [ - bluez_includes=$withval/include - bluez_libraries=$withval/lib -]) - AC_PATH_BLUEZ AC_ARG_ENABLE(dbus, [ --enable-dbus use D-BUS], -- cgit From cfd9a803fbfff5d6332000fd515bc92a10001acf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 08:01:04 +0000 Subject: Use own check for D-BUS support --- acinclude.m4 | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.in | 14 +------------ hcid/Makefile.am | 8 +++++--- 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 67506577..f088ecc3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -55,3 +55,65 @@ AC_DEFUN(AC_PATH_BLUEZ, [ AC_SUBST(BLUEZ_LDFLAGS) AC_SUBST(BLUEZ_LIBS) ]) + +AC_DEFUN(AC_PATH_DBUS, [ + AC_ARG_ENABLE(dbus, [ --enable-dbus enable D-BUS support], + dbus_enable=$enableval, + dbus_enable=no + ) + + AC_ARG_WITH(dbus, [ --with-dbus=DIR D-BUS library is installed in DIR], [ + dbus_includes=$withval/include + dbus_libraries=$withval/lib + dbus_enable=yes + ]) + + DBUS_INCLUDES="" + DBUS_LDFLAGS="" + DBUS_LIBS="" + + ac_save_CFLAGS=$CFLAGS + if test -n "$dbus_includes"; then + CFLAGS="$CFLAGS -I$dbus_includes -I$dbus_includes/dbus-1.0" + else + CFLAGS="$CFLAGS -I/usr/include/dbus-1.0" + fi + CFLAGS="$CFLAGS -DDBUS_API_SUBJECT_TO_CHANGE" + + ac_save_LDFLAGS=$LDFLAGS + if test -n "$dbus_libraries"; then + CFLAGS="$CFLAGS -I$dbus_libraries/dbus-1.0/include" + LDFLAGS="$LDFLAGS -L$dbus_libraries" + else + CFLAGS="$CFLAGS -I/usr/lib/dbus-1.0/include" + fi + + AC_CHECK_HEADER(dbus/dbus.h,, + dbus_enable=no) + + AC_CHECK_LIB(dbus-1, dbus_error_init, + DBUS_LIBS="$DBUS_LIBS -ldbus-1", + dbus_enable=no) + + CFLAGS=$ac_save_CFLAGS + if test -n "$dbus_includes"; then + DBUS_INCLUDES="-I$dbus_includes -I$dbus_includes/dbus-1.0" + else + DBUS_INCLUDES="-I/usr/include/dbus-1.0" + fi + + LDFLAGS=$ac_save_LDFLAGS + if test -n "$dbus_libraries"; then + DBUS_INCLUDES="$DBUS_INCLUDES -I$dbus_libraries/dbus-1.0/include" + DBUS_LDFLAGS="-L$dbus_libraries" + DBUS_LIBS="-L$dbus_libraries $DBUS_LIBS" + else + DBUS_INCLUDES="$DBUS_INCLUDES -I/usr/lib/dbus-1.0/include" + fi + + AC_SUBST(DBUS_INCLUDES) + AC_SUBST(DBUS_LDFLAGS) + AC_SUBST(DBUS_LIBS) + + AM_CONDITIONAL(DBUS, test "$dbus_enable" = "yes") +]) diff --git a/configure.in b/configure.in index e0211d39..c9c11be5 100644 --- a/configure.in +++ b/configure.in @@ -23,18 +23,6 @@ AM_PROG_LEX AC_PATH_BLUEZ -AC_ARG_ENABLE(dbus, [ --enable-dbus use D-BUS], - BLUEZ_DBUS="$enableval", - BLUEZ_DBUS="no" -) - -if test x"$BLUEZ_DBUS" == "xyes"; then - PKG_CHECK_MODULES(DBUS, dbus-1, have_dbus=yes, have_dbus=no) - - CFLAGS="$CFLAGS $DBUS_CFLAGS -DENABLE_DBUS" - LIBS="$LIBS $DBUS_LIBS" -fi - -AM_CONDITIONAL(ENABLE_DBUS, test x$BLUEZ_DBUS = xyes) +AC_PATH_DBUS AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index f356b9b6..b720e5cc 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -4,18 +4,20 @@ sbin_PROGRAMS = hcid -if ENABLE_DBUS +if DBUS dbus_hcid_sources = dbus.c +dbus_hcid_ldflags = @DBUS_LIBS@ else dbus_hcid_sources = +dbus_hcid_ldflags = endif hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) hcid_CONFIG = hcid.conf -LDFLAGS = @BLUEZ_LIBS@ +LDFLAGS = @BLUEZ_LIBS@ $(dbus_hcid_ldflags) -INCLUDES = @BLUEZ_INCLUDES@ +INCLUDES = @BLUEZ_INCLUDES@ @DBUS_INCLUDES@ man_MANS = hcid.8 hcid.conf.5 -- cgit From 6f84ccd25d72e5b1a836bd2c44b95798a3972a6c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 08:11:50 +0000 Subject: Use default values if needed --- acinclude.m4 | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index f088ecc3..e223c08e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -20,8 +20,13 @@ AC_DEFUN(AC_PREFIX_BLUEZ, [ AC_DEFUN(AC_PATH_BLUEZ, [ AC_ARG_WITH(bluez, [ --with-bluez=DIR BlueZ library is installed in DIR], [ - bluez_includes=$withval/include - bluez_libraries=$withval/lib + if (test "$withval" = "yes"); then + bluez_includes=/usr/include + bluez_libraries=/usr/lib + else + bluez_includes=$withval/include + bluez_libraries=$withval/lib + fi ]) BLUEZ_INCLUDES="" @@ -63,8 +68,13 @@ AC_DEFUN(AC_PATH_DBUS, [ ) AC_ARG_WITH(dbus, [ --with-dbus=DIR D-BUS library is installed in DIR], [ - dbus_includes=$withval/include - dbus_libraries=$withval/lib + if (test "$withval" = "yes"); then + dbus_includes=/usr/include + dbus_libraries=/usr/lib + else + dbus_includes=$withval/include + dbus_libraries=$withval/lib + fi dbus_enable=yes ]) -- cgit From f3b2f00568b83b26308e0e84bf20316f65747f86 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 08:27:06 +0000 Subject: Use unaligned access functions from core library --- sdpd/request.c | 2 ++ sdpd/sdpd.h | 3 +++ sdpd/service.c | 2 ++ 3 files changed, 7 insertions(+) diff --git a/sdpd/request.c b/sdpd/request.c index ff3b5642..f587cada 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -38,7 +38,9 @@ #include #include #include +#include +#include #include #include diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 37c685e2..c669e603 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -30,6 +30,9 @@ #ifndef SDPD_H #define SDPD_H +#define sdp_get_unaligned bt_get_unaligned +#define sdp_put_unaligned bt_put_unaligned + #define SDPINF(fmt, arg...) syslog(LOG_INFO, fmt "\n", ## arg) #define SDPERR(fmt, arg...) syslog(LOG_ERR, "%s: " fmt "\n", __func__ , ## arg) diff --git a/sdpd/service.c b/sdpd/service.c index 4d03c917..c69aa509 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -35,7 +35,9 @@ */ #include +#include +#include #include #include -- cgit From e35ae5a897dc9ebd0263e40b8e3ef6f7e12eba15 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 09:50:37 +0000 Subject: Always install the PCMCIA stuff --- pcmcia/Makefile.am | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pcmcia/Makefile.am b/pcmcia/Makefile.am index e3336541..22098446 100644 --- a/pcmcia/Makefile.am +++ b/pcmcia/Makefile.am @@ -2,13 +2,13 @@ # $Id$ # -pcmciadir = $(sysconfdir)/pcmcia +pcmciadir = $(sysconfdir)/pcmcia EXTRA_DIST = bluetooth bluetooth.conf -install-data-local: @PCMCIA@ - -pcmcia: +install-data-local: $(mkinstalldirs) $(DESTDIR)$(pcmciadir) - $(INSTALL) -m 755 $(srcdir)/bluetooth $(DESTDIR)$(pcmciadir) - $(INSTALL) -m 644 $(srcdir)/bluetooth.conf $(DESTDIR)$(pcmciadir) + [ -f $(DESTDIR)$(pcmciadir)/bluetooth ] || \ + $(INSTALL_DATA) $(srcdir)/bluetooth $(DESTDIR)$(pcmciadir) + [ -f $(DESTDIR)$(pcmciadir)/bluetooth.conf ] || \ + $(INSTALL_DATA) $(srcdir)/bluetooth.conf $(DESTDIR)$(pcmciadir) -- cgit From fc97038015af1e86b5daa8880ee36d0fbfa9ed6b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 09:51:21 +0000 Subject: Simplify init script installation --- scripts/Makefile.am | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 8c6e56d2..8e05086b 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -4,17 +4,10 @@ bin_SCRIPTS = bluepin -EXTRA_DIST = bluepin bluetooth.rc.rh bluetooth.rc.deb create_dev +EXTRA_DIST = bluepin bluetooth.rc.rh bluetooth.rc.deb create_dev -install-data-local: @DISTRO@ - -unknown: - -echo Unknown distribution - -redhat: - $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/rc.d/init.d - $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)$(sysconfdir)/rc.d/init.d/bluetooth - -debian: - $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/init.d - $(INSTALL) -m 755 $(srcdir)/bluetooth.rc.deb $(DESTDIR)$(sysconfdir)/init.d/bluetooth +install-data-local: + [ ! -f /etc/redhat-release -o ! -f /etc/mandrake-release ] || \ + $(INSTALL) -D -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)$(sysconfdir)/rc.d/init.d/bluetooth + [ ! -f /etc/debian_version ] || \ + $(INSTALL) -D -m 755 $(srcdir)/bluetooth.rc.deb $(DESTDIR)$(sysconfdir)/init.d/bluetooth -- cgit From 83e17dd1c277876889fee5334ef9eb09713f5331 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Apr 2004 09:02:31 +0000 Subject: Add entry for Anycom CF-300 card --- pcmcia/bluetooth.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 84f8e985..42f824fa 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -65,6 +65,10 @@ card "LSE039 Bluetooth Compact Flash Card" version "WSS", "LSE039" bind "bluecard_cs" +card "LSE139 Bluetooth Compact Flash Card" + version "BTCFCARD", "LSE139" + bind "bluecard_cs" + card "AmbiCom BT2000E Bluetooth Card" version "AmbiCom,Inc", "BT2000E" -- cgit From fb022821661f5cc051061fe01818d58bad4cfd06 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Apr 2004 15:37:46 +0000 Subject: Try to release the TTY if no device node is found --- rfcomm/main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rfcomm/main.c b/rfcomm/main.c index 52701d40..5d061fb7 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -323,14 +323,21 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg } snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); - if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); - while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { if (try--) { + snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); sleep(1); continue; } perror("Can't open RFCOMM device"); + + memset(&req, 0, sizeof(req)); + req.dev_id = dev; + req.flags = (1 << RFCOMM_HANGUP_NOW); + ioctl(ctl, RFCOMMRELEASEDEV, &req); + close(sk); return; } -- cgit From 44d98edef4ab08644f87ebfb67ab6d5fb41ffa14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 Apr 2004 13:12:13 +0000 Subject: Fix more endian bugs for the ACL handle --- tools/hcitool.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 667212fe..37450098 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -447,7 +447,7 @@ static void cmd_info(int dev_id, int argc, char **argv) } cc = 1; } else - handle = cr->conn_info->handle; + handle = htobs(cr->conn_info->handle); printf("\tBD Address: %s\n", argv[0]); @@ -721,7 +721,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (hci_disconnect(dd, cr->conn_info->handle, HCI_OE_USER_ENDED_CONNECTION, 100) < 0) + if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 100) < 0) perror("Disconnect failed"); close(dd); @@ -827,6 +827,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) struct hci_request rq; read_rssi_rp rp; bdaddr_t bdaddr; + uint16_t handle; int opt, dd; for_each_opt(opt, rssi_options, NULL) { @@ -871,10 +872,12 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } + handle = htobs(cr->conn_info->handle); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_READ_RSSI; - rq.cparam = &cr->conn_info->handle; + rq.cparam = &handle; rq.clen = 2; rq.rparam = &rp; rq.rlen = READ_RSSI_RP_SIZE; @@ -911,6 +914,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) struct hci_request rq; get_link_quality_rp rp; bdaddr_t bdaddr; + uint16_t handle; int opt, dd; for_each_opt(opt, lq_options, NULL) { @@ -955,10 +959,12 @@ static void cmd_lq(int dev_id, int argc, char **argv) exit(1); } + handle = htobs(cr->conn_info->handle); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_STATUS_PARAM; rq.ocf = OCF_GET_LINK_QUALITY; - rq.cparam = &cr->conn_info->handle; + rq.cparam = &handle; rq.clen = 2; rq.rparam = &rp; rq.rlen = GET_LINK_QUALITY_RP_SIZE; @@ -1041,7 +1047,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; @@ -1131,7 +1137,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); cp.pkt_type = ptype; memset(&rq, 0, sizeof(rq)); @@ -1170,6 +1176,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) read_link_supervision_timeout_rp rp; write_link_supervision_timeout_cp cp; bdaddr_t bdaddr; + uint16_t handle; int opt, dd; for_each_opt(opt, lst_options, NULL) { @@ -1214,11 +1221,13 @@ static void cmd_lst(int dev_id, int argc, char **argv) exit(1); } + handle = htobs(cr->conn_info->handle); + if (argc == 1) { memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; - rq.cparam = &cr->conn_info->handle; + rq.cparam = &handle; rq.clen = 2; rq.rparam = &rp; rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; @@ -1239,7 +1248,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) else printf("Link supervision timeout never expires\n"); } else { - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); cp.link_sup_to = strtol(argv[1], NULL, 10); memset(&rq, 0, sizeof(rq)); @@ -1320,7 +1329,7 @@ static void cmd_auth(int dev_id, int argc, char **argv) exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; @@ -1402,7 +1411,7 @@ static void cmd_enc(int dev_id, int argc, char **argv) exit(1); } - cp.handle = cr->conn_info->handle; + cp.handle = htobs(cr->conn_info->handle); cp.encrypt = (argc > 1) ? atoi(argv[1]) : 1; memset(&rq, 0, sizeof(rq)); -- cgit From 8e0ea134300e2c9fab5ab18d0610f4bec1e79bef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 11:16:58 +0000 Subject: Add hid2hci utility --- tools/Makefile.am | 20 ++- tools/hid2hci.8 | 42 ++++++ tools/hid2hci.c | 419 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 476 insertions(+), 5 deletions(-) create mode 100644 tools/hid2hci.8 create mode 100644 tools/hid2hci.c diff --git a/tools/Makefile.am b/tools/Makefile.am index 354f841c..c45f5635 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,18 +2,28 @@ # $Id$ # -sbin_PROGRAMS = hciattach hciconfig +sbin_PROGRAMS = hciattach hciconfig hid2hci bin_PROGRAMS = hcitool l2ping sdptool ciptool +noinst_PROGRAMS = ppporc + hciconfig_SOURCES = hciconfig.c csr.h csr.c -LDFLAGS = @BLUEZ_LIBS@ +hciconfig_LDFLAGS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +hcitool_LDFLAGS = @BLUEZ_LIBS@ + +l2ping_LDFLAGS = @BLUEZ_LIBS@ + +sdptool_LDFLAGS = @BLUEZ_LIBS@ -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 +ciptool_LDFLAGS = @BLUEZ_LIBS@ + +ppporc_LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ -noinst_PROGRAMS = ppporc +man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 EXTRA_DIST = $(man_MANS) diff --git a/tools/hid2hci.8 b/tools/hid2hci.8 new file mode 100644 index 00000000..8f7ea4fe --- /dev/null +++ b/tools/hid2hci.8 @@ -0,0 +1,42 @@ +.\" +.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH HID2HCI 8 "JUNE 6, 2003" "" "" + +.SH NAME +hid2hci \- Bluetooth HID to HCI mode switching utility +.SH SYNOPSIS +.BR "hid2hci +[ +.I options +] +.SH DESCRIPTION +.B hid2hci +is used to set up switch HID proxy Bluetooth dongle into the HCI +mode and back. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible options. +.TP +.BI -0 +Switches the device into HCI mode. +.TP +.BI -1 +Switches the device into HID mode. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/hid2hci.c b/tools/hid2hci.c new file mode 100644 index 00000000..95a7c7d6 --- /dev/null +++ b/tools/hid2hci.c @@ -0,0 +1,419 @@ +/* + * + * Bluetooth HID to HCI mode switching utility + * + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static char usbpath[PATH_MAX + 1] = "/proc/bus/usb"; + +struct usb_device_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__ ((packed)); + +struct usb_ctrltransfer { + uint8_t bRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; + + uint32_t timeout; /* in milliseconds */ + void *data; /* pointer to data */ +}; + +#define IOCTL_USB_CONTROL _IOWR('U', 0, struct usb_ctrltransfer) + +#define USB_RECIP_DEVICE 0x00 +#define USB_TYPE_VENDOR 0x40 +#define USB_DIR_OUT 0x00 + + +static char devpath[PATH_MAX + 1] = "/dev"; + +struct hiddev_devinfo { + unsigned int bustype; + unsigned int busnum; + unsigned int devnum; + unsigned int ifnum; + short vendor; + short product; + short version; + unsigned num_applications; +}; + +struct hiddev_report_info { + unsigned report_type; + unsigned report_id; + unsigned num_fields; +}; + +typedef __signed__ int __s32; + +struct hiddev_usage_ref { + unsigned report_type; + unsigned report_id; + unsigned field_index; + unsigned usage_index; + unsigned usage_code; + __s32 value; +}; + +#define HIDIOCGDEVINFO _IOR('H', 0x03, struct hiddev_devinfo) +#define HIDIOCINITREPORT _IO('H', 0x05) +#define HIDIOCSREPORT _IOW('H', 0x08, struct hiddev_report_info) +#define HIDIOCSUSAGE _IOW('H', 0x0C, struct hiddev_usage_ref) + +#define HID_REPORT_TYPE_OUTPUT 2 + + +#define HCI 0 +#define HID 1 + +struct device_info; + +struct device_id { + int mode; + uint16_t vendor; + uint16_t product; + int (*func)(struct device_info *dev); +}; + +struct device_info { + uint16_t busnum; + uint16_t devnum; + struct device_id *id; +}; + + +static int switch_hidproxy(struct device_info *dev) +{ + struct usb_ctrltransfer ctrl; + char devname[PATH_MAX + 1]; + int fd, err; + + snprintf(devname, PATH_MAX, "%s/%03d/%03d", + usbpath, dev->busnum, dev->devnum); + + fd = open(devname, O_RDWR); + if (fd < 0) + return fd; + + ctrl.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; + ctrl.bRequest = 0; + ctrl.wValue = dev->id->mode; + ctrl.wIndex = 0; + ctrl.wLength = 0; + + ctrl.data = NULL; + ctrl.timeout = 10000; + + err = ioctl(fd, IOCTL_USB_CONTROL, &ctrl); + + if (err == 0) { + err = -1; + errno = EALREADY; + } else { + if (errno == ETIMEDOUT) + err = 0; + } + + close(fd); + + return err; +} + +static int send_report(int fd, const unsigned char *buf, size_t size) +{ + struct hiddev_report_info rinfo; + struct hiddev_usage_ref uref; + int i, err; + + for (i = 0; i < size; i++) { + memset(&uref, 0, sizeof(uref)); + uref.report_type = HID_REPORT_TYPE_OUTPUT; + uref.report_id = 0x10; + uref.field_index = 0; + uref.usage_index = i; + uref.usage_code = 0xff000001; + uref.value = buf[i]; + err = ioctl(fd, HIDIOCSUSAGE, &uref); + if (err < 0) + return err; + } + + memset(&rinfo, 0, sizeof(rinfo)); + rinfo.report_type = HID_REPORT_TYPE_OUTPUT; + rinfo.report_id = 0x10; + rinfo.num_fields = 1; + err = ioctl(fd, HIDIOCSREPORT, &rinfo); + + return err; +} + +static int switch_logitech(struct device_info *dev) +{ + char devname[PATH_MAX + 1]; + int i, fd, err = -1; + + for (i = 0; i < 16; i++) { + struct hiddev_devinfo dinfo; + char rep1[] = { 0xff, 0x80, 0x80, 0x01, 0x00, 0x00 }; + char rep2[] = { 0xff, 0x80, 0x00, 0x00, 0x30, 0x00 }; + char rep3[] = { 0xff, 0x81, 0x80, 0x00, 0x00, 0x00 }; + + sprintf(devname, "%s/hiddev%d", devpath, i); + fd = open(devname, O_RDWR); + if (fd < 0) { + sprintf(devname, "%s/usb/hiddev%d", devpath, i); + fd = open(devname, O_RDWR); + if (fd < 0) { + sprintf(devname, "%s/usb/hid/hiddev%d", devpath, i); + fd = open(devname, O_RDWR); + if (fd < 0) + continue; + } + } + + memset(&dinfo, 0, sizeof(dinfo)); + err = ioctl(fd, HIDIOCGDEVINFO, &dinfo); + if (err < 0 || dinfo.busnum != dev->busnum || + dinfo.devnum != dev->devnum) { + close(fd); + continue; + } + + err = ioctl(fd, HIDIOCINITREPORT, 0); + if (err < 0) { + close(fd); + break; + } + + err = send_report(fd, rep1, sizeof(rep1)); + if (err < 0) { + close(fd); + break; + } + + err = send_report(fd, rep2, sizeof(rep2)); + if (err < 0) { + close(fd); + break; + } + + err = send_report(fd, rep3, sizeof(rep3)); + close(fd); + break; + } + + return err; +} + +static struct device_id device_list[] = { + { HCI, 0x0a12, 0x1000, switch_hidproxy }, + { HID, 0x0a12, 0x0001, switch_hidproxy }, + { HCI, 0x05ac, 0x1000, switch_hidproxy }, + { HID, 0x05ac, 0x8203, switch_hidproxy }, + { HCI, 0x046d, 0xc703, switch_logitech }, + { HCI, 0x046d, 0xc704, switch_logitech }, + { HCI, 0x046d, 0xc705, switch_logitech }, + { -1 } +}; + +static struct device_id *match_device(int mode, uint16_t vendor, uint16_t product) +{ + int i; + + for (i = 0; device_list[i].mode >= 0; i++) { + if (mode != device_list[i].mode) + continue; + if (vendor == device_list[i].vendor && + product == device_list[i].product) + return &device_list[i]; + } + + return NULL; +} + +static int find_devices(int mode, struct device_info *dev, size_t size) +{ + DIR *busdir, *devdir; + struct dirent *entry; + struct usb_device_descriptor desc; + struct device_id *id; + int fd, len, busnum, devnum, count = 0; + char buspath[PATH_MAX + 1]; + char devname[PATH_MAX + 1]; + + if (!(busdir = opendir(usbpath))) + return -1; + + while ((entry = readdir(busdir))) { + if (entry->d_name[0] == '.') + continue; + + if (!strchr("0123456789", + entry->d_name[strlen(entry->d_name) - 1])) + continue; + + busnum = atoi(entry->d_name); + snprintf(buspath, PATH_MAX, "%s/%s", usbpath, entry->d_name); + if (!(devdir = opendir(buspath))) + continue; + + while ((entry = readdir(devdir))) { + if (entry->d_name[0] == '.') + continue; + + if (!strchr("0123456789", + entry->d_name[strlen(entry->d_name) - 1])) + continue; + + devnum = atoi(entry->d_name); + snprintf(devname, PATH_MAX, "%s/%s", + buspath, entry->d_name); + + if ((fd = open(devname, O_RDONLY)) < 0) + continue; + + len = read(fd, &desc, sizeof(desc)); + if (len < 0 || len != sizeof(desc)) + continue; + + id = match_device(mode, desc.idVendor, desc.idProduct); + if (!id) + continue; + + if (count < size) { + dev[count].busnum = busnum; + dev[count].devnum = devnum; + dev[count].id = id; + count++; + } + } + + closedir(devdir); + } + + closedir(busdir); + + return count; +} + + +static void usage(void) +{ + printf("hid2hci - Bluetooth HID to HCI mode switching utility\n\n"); + + printf("Usage:\n" + "\thid2hci [options]\n" + "\n"); + + printf("Options:\n" + "\t-h, --help Display help\n" + "\t-0, --tohci Switch to HCI mode (default)\n" + "\t-1, --tohid Switch to HID mode\n" + "\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "tohci", 0, 0, '0' }, + { "tohid", 0, 0, '1' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct device_info dev[16]; + int i, opt, num, mode = HCI; + + while ((opt = getopt_long(argc, argv, "+01h", main_options, NULL)) != -1) { + switch (opt) { + case '0': + mode = HCI; + break; + case '1': + mode = HID; + break; + case 'h': + usage(); + exit(0); + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + num = find_devices(mode, dev, sizeof(dev) / sizeof(dev[0])); + if (num <= 0) { + fprintf(stderr, "No devices in %s mode found\n", + mode ? "HID" : "HCI"); + exit(1); + } + + for (i = 0; i < num; i++) { + struct device_id *id = dev[i].id; + + printf("Switching device %04x:%04x to %s mode ", + id->vendor, id->product, mode ? "HID" : "HCI"); + fflush(stdout); + + if (id->func(&dev[i]) < 0) + printf("failed (%s)\n", strerror(errno)); + else + printf("was successful\n"); + } + + return 0; +} -- cgit From ecbe15c8f763206abf39b17252ef8270f3d5b507 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 11:18:19 +0000 Subject: Add CVS $Id line --- tools/ciptool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/ciptool.c b/tools/ciptool.c index bec3fc2b..fc23bf2e 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -19,6 +19,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * + * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From fab001c1250c40ef96b85a60a7b8111596688452 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 11:22:47 +0000 Subject: Fix warning in hcisecfilter --- tools/Makefile.am | 2 +- tools/hcisecfilter.c | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index c45f5635..c1eb4564 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -6,7 +6,7 @@ sbin_PROGRAMS = hciattach hciconfig hid2hci bin_PROGRAMS = hcitool l2ping sdptool ciptool -noinst_PROGRAMS = ppporc +noinst_PROGRAMS = ppporc hcisecfilter hciconfig_SOURCES = hciconfig.c csr.h csr.c diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 2ff5c48a..9aaead0f 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -15,7 +15,7 @@ int main(void) memset((void *)&type_mask, 0, sizeof(type_mask)); hci_set_bit(HCI_EVENT_PKT, &type_mask); - printf("Type mask: { 0x%lx }\n", type_mask); + printf("Type mask: { 0x%x }\n", type_mask); // Events memset((void *)event_mask, 0, sizeof(event_mask)); @@ -36,7 +36,7 @@ int main(void) hci_set_bit(EVT_READ_REMOTE_VERSION_COMPLETE, event_mask); hci_set_bit(EVT_REMOTE_NAME_REQ_COMPLETE, event_mask); - printf("Event mask: { 0x%lx, 0x%lx }\n", event_mask[0], event_mask[1]); + printf("Event mask: { 0x%x, 0x%x }\n", event_mask[0], event_mask[1]); // OGF_LINK_CTL memset((void *) ocf_mask, 0, sizeof(ocf_mask)); @@ -45,7 +45,7 @@ int main(void) hci_set_bit(OCF_READ_REMOTE_FEATURES, ocf_mask); hci_set_bit(OCF_READ_REMOTE_VERSION, ocf_mask); - printf("OGF_LINK_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + printf("OGF_LINK_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); // OGF_LINK_POLICY @@ -53,7 +53,7 @@ int main(void) hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); - printf("OGF_LINK_POLICY: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + printf("OGF_LINK_POLICY: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); // OGF_HOST_CTL @@ -65,7 +65,7 @@ int main(void) hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); hci_set_bit(OCF_READ_TRANSMIT_POWER_LEVEL, ocf_mask); - printf("OGF_HOST_CTL: { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n", + printf("OGF_HOST_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); // OGF_INFO_PARAM @@ -76,7 +76,7 @@ int main(void) hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); - printf("OGF_INFO_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", + printf("OGF_INFO_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); // OGF_INFO_PARAM @@ -86,6 +86,8 @@ int main(void) hci_set_bit(OCF_GET_LINK_QUALITY, ocf_mask); hci_set_bit(OCF_READ_RSSI, ocf_mask); - printf("OGF_STATUS_PARAM: { 0x%lx, 0x%lx, 0x%lx, 0x%lx}\n", + printf("OGF_STATUS_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + + return 0; } -- cgit From 7b44fb1986b0bae4fc37130c22a975972261f851 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 14:12:26 +0000 Subject: The lmp_featurestostr() now uses a character number as width --- tools/hciconfig.c | 2 +- tools/hcitool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 6ab7f190..7e6f6849 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -113,7 +113,7 @@ void print_dev_features(struct hci_dev_info *di, int format) di->features[2], di->features[3], di->features[4], di->features[5], di->features[6], di->features[7], - lmp_featurestostr(di->features, "\t\t", 3)); + lmp_featurestostr(di->features, "\t\t", 63)); } } diff --git a/tools/hcitool.c b/tools/hcitool.c index 37450098..b01f78d6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -465,7 +465,7 @@ static void cmd_info(int dev_id, int argc, char **argv) printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7], - lmp_featurestostr(features, "\t\t", 3)); + lmp_featurestostr(features, "\t\t", 63)); } if (cc) -- cgit From 241112a349dde07429e27098be760476c99f556d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 15:09:01 +0000 Subject: Add support for inquiry mode --- tools/hciconfig.8 | 6 ++++++ tools/hciconfig.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index aac5e98a..8e9fb257 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -121,6 +121,12 @@ With no prints the current IAC setting. Otherwise, sets the IAC to .IR iac . .TP +.BI inqmode " [mode]" +With no +.IR mode , +prints out the current inquiry mode. Otherwise, sets inquiry mode to +.IR mode . +.TP .BI inqparms " [win:int]" With no .IR win:int , diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 7e6f6849..7134bfc1 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -649,6 +649,59 @@ void cmd_version(int ctl, int hdev, char *opt) bt_compidtostr(ver.manufacturer), ver.manufacturer); } +void cmd_inq_mode(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + write_inquiry_mode_cp cp; + + cp.mode = atoi(opt); + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQUIRY_MODE; + rq.cparam = &cp; + rq.clen = WRITE_INQUIRY_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("Can't set inquiry mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + read_inquiry_mode_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_INQUIRY_MODE; + rq.rparam = &rp; + rq.rlen = READ_INQUIRY_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("Can't read inquiry mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read inquiry mode on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + + print_dev_hdr(&di); + printf("\tInquiry mode: %s\n", + rp.mode == 1 ? "Inquiry with RSSI" : "Standard Inquiry"); + } +} + void cmd_inq_parms(int ctl, int hdev, char *opt) { struct hci_request rq; @@ -1011,6 +1064,7 @@ struct { { "class", cmd_class, "[class]", "Get/Set class of device" }, { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, + { "inqmode", cmd_inq_mode, "[mode]", "Get/set inquiry mode" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, -- cgit From 2facfcf46852253bfd96c3888128a419d3a04c6a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 19:10:25 +0000 Subject: Add support for AFH mode --- tools/hciconfig.8 | 6 ++++++ tools/hciconfig.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 8e9fb257..b8b780ee 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -157,6 +157,12 @@ to to slots. .TP +.BI afhmode " [mode]" +With no +.IR mode , +prints out the current AFH mode. Otherwise, sets AFH mode to +.IR mode . +.TP .BI aclmtu " " Sets ACL MTU to to diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 7134bfc1..6393764b 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -898,6 +898,58 @@ void cmd_page_to(int ctl, int hdev, char *opt) } } +void cmd_afh_mode(int ctl, int hdev, char *opt) +{ + struct hci_request rq; + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + + memset(&rq, 0, sizeof(rq)); + + if (opt) { + write_afh_mode_cp cp; + + cp.mode = atoi(opt); + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_AFH_MODE; + rq.cparam = &cp; + rq.clen = WRITE_AFH_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("Can't set AFH mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + read_afh_mode_rp rp; + + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_AFH_MODE; + rq.rparam = &rp; + rq.rlen = READ_AFH_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("Can't read AFH mode on hci%d. %s(%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + if (rp.status) { + printf("Read AFH mode on hci%d returned status %d\n", + hdev, rp.status); + exit(1); + } + + print_dev_hdr(&di); + printf("\tAFH mode: %s\n", rp.mode == 1 ? "Enabled" : "Disabled"); + } +} + static void print_rev_ericsson(int dd) { struct hci_request rq; @@ -1068,6 +1120,7 @@ struct { { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, + { "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" }, { "aclmtu", cmd_aclmtu, "", "Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "", "Set SCO MTU and number of packets" }, { "features", cmd_features, 0, "Display device features" }, -- cgit From 56cbbde9aaecbfdd1f1e4c820de92110355aa365 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 19:11:20 +0000 Subject: Add support for getting the AFH channel map --- tools/hcitool.1 | 4 +++ tools/hcitool.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/tools/hcitool.1 b/tools/hcitool.1 index f23cf7f5..1d87b9a0 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -139,6 +139,10 @@ for the current transmit power level (which is default) or .BR 1 for the maximum transmit power level. .TP +.BI afh " " +Display AFH channel map for the connection to the device with Bluetooth address +.IR bdaddr . +.TP .BI lst " [value]" With no .IR value , diff --git a/tools/hcitool.c b/tools/hcitool.c index b01f78d6..99355861 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1074,6 +1074,102 @@ static void cmd_tpl(int dev_id, int argc, char **argv) free(cr); } +/* Get AFH channel map */ + +static struct option afh_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *afh_help = + "Usage:\n" + "\tafh \n"; + +static void cmd_afh(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + struct hci_request rq; + read_afh_map_rp rp; + bdaddr_t bdaddr; + uint16_t handle; + int opt, dd; + + for_each_opt(opt, afh_options, NULL) { + switch(opt) { + default: + printf(afh_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(afh_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + handle = htobs(cr->conn_info->handle); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_AFH_MAP; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_AFH_MAP_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + perror("HCI read AFH map request failed"); + exit(1); + } + + if (rp.status) { + fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", + rp.status); + exit(1); + } + + if (rp.mode == 0x01) { + int i; + printf("AFH map: 0x"); + for (i = 0; i < 10; i++) + printf("%02x", rp.map[i]); + printf("\n"); + } else + printf("AFH disabled\n"); + + close(dd); + free(cr); +} + /* Set connection packet type */ static struct option cpt_options[] = { @@ -1451,6 +1547,7 @@ static struct { { "rssi", cmd_rssi, "Display connection RSSI" }, { "lq", cmd_lq, "Display link quality" }, { "tpl", cmd_tpl, "Display transmit power level" }, + { "afh", cmd_afh, "Display AFH channel map" }, { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, { "enc", cmd_enc, "Set connection encryption" }, -- cgit From 965c347ab154fd36ca98cd1fd29b048068d70dab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 21:54:11 +0000 Subject: Add the pand utility --- Makefile.am | 2 +- configure.in | 2 +- pand/Makefile.am | 15 ++ pand/bnep.c | 305 ++++++++++++++++++++++++++++ pand/main.c | 604 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ pand/pand.1 | 59 ++++++ pand/pand.h | 44 ++++ pand/sdp.c | 201 ++++++++++++++++++ 8 files changed, 1230 insertions(+), 2 deletions(-) create mode 100644 pand/Makefile.am create mode 100644 pand/bnep.c create mode 100644 pand/main.c create mode 100644 pand/pand.1 create mode 100644 pand/pand.h create mode 100644 pand/sdp.c diff --git a/Makefile.am b/Makefile.am index 1824ac2d..6a87b06c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -SUBDIRS := hcid tools rfcomm sdpd test scripts pcmcia +SUBDIRS := hcid tools rfcomm sdpd pand test scripts pcmcia DISTCLEANFILES = conftest.c conftest diff --git a/configure.in b/configure.in index c9c11be5..c2868a9d 100644 --- a/configure.in +++ b/configure.in @@ -25,4 +25,4 @@ AC_PATH_BLUEZ AC_PATH_DBUS -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile pand/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/pand/Makefile.am b/pand/Makefile.am new file mode 100644 index 00000000..20b99270 --- /dev/null +++ b/pand/Makefile.am @@ -0,0 +1,15 @@ +# +# $Id$ +# + +bin_PROGRAMS = pand + +pand_SOURCES = main.c pand.h bnep.c sdp.c + +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + +man_MANS = pand.1 + +EXTRA_DIST = $(man_MANS) diff --git a/pand/bnep.c b/pand/bnep.c new file mode 100644 index 00000000..6833f941 --- /dev/null +++ b/pand/bnep.c @@ -0,0 +1,305 @@ +/* + pand - Bluetooth PAN daemon for BlueZ + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include "pand.h" + +static int ctl; + +/* Compatibility with old ioctls */ +#define OLD_BNEPCONADD 1 +#define OLD_BNEPCONDEL 2 +#define OLD_BNEPGETCONLIST 3 +#define OLD_BNEPGETCONINFO 4 + +static unsigned long bnepconnadd; +static unsigned long bnepconndel; +static unsigned long bnepgetconnlist; +static unsigned long bnepgetconninfo; + +static struct { + char *str; + uint16_t uuid; +} __svc[] = { + { "PANU", BNEP_SVC_PANU }, + { "NAP", BNEP_SVC_NAP }, + { "GN", BNEP_SVC_GN }, + { NULL } +}; + +int bnep_str2svc(char *svc, uint16_t *uuid) +{ + int i; + for (i=0; __svc[i].str; i++) + if (!strcasecmp(svc, __svc[i].str)) { + *uuid = __svc[i].uuid; + return 0; + } + return -1; +} + +char *bnep_svc2str(uint16_t uuid) +{ + int i; + for (i=0; __svc[i].str; i++) + if (__svc[i].uuid == uuid) + return __svc[i].str; + return NULL; +} + +int bnep_init(void) +{ + ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); + if (ctl < 0) { + perror("Failed to open control socket"); + return 1; + } + + /* Temporary ioctl compatibility hack */ + { + struct bnep_connlist_req req; + struct bnep_conninfo ci[1]; + + req.cnum = 1; + req.ci = ci; + + if (!ioctl(ctl, BNEPGETCONNLIST, &req)) { + /* New ioctls */ + bnepconnadd = BNEPCONNADD; + bnepconndel = BNEPCONNDEL; + bnepgetconnlist = BNEPGETCONNLIST; + bnepgetconninfo = BNEPGETCONNINFO; + } else { + /* Old ioctls */ + bnepconnadd = OLD_BNEPCONADD; + bnepconndel = OLD_BNEPCONDEL; + bnepgetconnlist = OLD_BNEPGETCONLIST; + bnepgetconninfo = OLD_BNEPGETCONINFO; + } + } + + return 0; +} + +int bnep_cleanup(void) +{ + close(ctl); + return 0; +} + +int bnep_show_connections(void) +{ + struct bnep_connlist_req req; + struct bnep_conninfo ci[48]; + int i; + + req.cnum = 48; + req.ci = ci; + if (ioctl(ctl, bnepgetconnlist, &req)) { + perror("Failed to get connection list"); + return -1; + } + + for (i=0; i < req.cnum; i++) { + printf("%s %s %s\n", ci[i].device, + batostr((bdaddr_t *) ci[i].dst), + bnep_svc2str(ci[i].role)); + } + return 0; +} + +int bnep_kill_connection(uint8_t *dst) +{ + struct bnep_conndel_req req; + + memcpy(req.dst, dst, ETH_ALEN); + req.flags = 0; + if (ioctl(ctl, bnepconndel, &req)) { + perror("Failed to kill connection"); + return -1; + } + return 0; +} + +int bnep_kill_all_connections(void) +{ + struct bnep_connlist_req req; + struct bnep_conninfo ci[48]; + int i; + + req.cnum = 48; + req.ci = ci; + if (ioctl(ctl, bnepgetconnlist, &req)) { + perror("Failed to get connection list"); + return -1; + } + + for (i=0; i < req.cnum; i++) { + struct bnep_conndel_req req; + memcpy(req.dst, ci[i].dst, ETH_ALEN); + req.flags = 0; + ioctl(ctl, bnepconndel, &req); + } + return 0; +} + +static int bnep_connadd(int sk, uint16_t role, char *dev) +{ + struct bnep_connadd_req req; + + strcpy(req.device, dev); + req.sock = sk; + req.role = role; + if (ioctl(ctl, bnepconnadd, &req)) + return -1; + strcpy(dev, req.device); + return 0; +} + +struct __service_16 { + uint16_t dst; + uint16_t src; +} __attribute__ ((packed)); + +struct __service_32 { + uint16_t unused1; + uint16_t dst; + uint16_t unused2; + uint16_t src; +} __attribute__ ((packed)); + +struct __service_128 { + uint16_t unused1; + uint16_t dst; + uint16_t unused2[8]; + uint16_t src; + uint16_t unused3[7]; +} __attribute__ ((packed)); + +int bnep_accept_connection(int sk, uint16_t role, char *dev) +{ + struct bnep_setup_conn_req *req; + struct bnep_control_rsp *rsp; + unsigned char pkt[BNEP_MTU]; + int r; + + r = recv(sk, pkt, BNEP_MTU, 0); + if (r <= 0) + return -1; + + errno = EPROTO; + + if (r < sizeof(*req)) + return -1; + + req = (void *) pkt; + if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) + return -1; + + /* FIXME: Check role UUIDs */ + + rsp = (void *) pkt; + rsp->type = BNEP_CONTROL; + rsp->ctrl = BNEP_SETUP_CONN_RSP; + rsp->resp = htons(BNEP_SUCCESS); + if (send(sk, rsp, sizeof(*rsp), 0) < 0) + return -1; + + return bnep_connadd(sk, role, dev); +} + +/* Create BNEP connection + * sk - Connect L2CAP socket + * role - Local role + * service - Remote service + * dev - Network device (contains actual dev name on return) + */ +int bnep_create_connection(int sk, uint16_t role, uint16_t svc, char *dev) +{ + struct bnep_setup_conn_req *req; + struct bnep_control_rsp *rsp; + struct __service_16 *s; + unsigned char pkt[BNEP_MTU]; + int r; + + /* Send request */ + req = (void *) pkt; + req->type = BNEP_CONTROL; + req->ctrl = BNEP_SETUP_CONN_REQ; + req->uuid_size = 2; //16bit UUID + s = (void *) req->service; + s->dst = htons(svc); + s->src = htons(role); + + if (send(sk, pkt, sizeof(*req) + sizeof(*s), 0) < 0) + return -1; + +receive: + /* Get response */ + r = recv(sk, pkt, BNEP_MTU, 0); + if (r <= 0) + return -1; + + errno = EPROTO; + + if (r < sizeof(*rsp)) + return -1; + + rsp = (void *) pkt; + if (rsp->type != BNEP_CONTROL) + return -1; + + if (rsp->ctrl != BNEP_SETUP_CONN_RSP) + goto receive; + + r = ntohs(rsp->resp); + + switch (r) { + case BNEP_SUCCESS: + break; + + case BNEP_CONN_INVALID_DST: + case BNEP_CONN_INVALID_SRC: + case BNEP_CONN_INVALID_SVC: + errno = EPROTO; + return -1; + + case BNEP_CONN_NOT_ALLOWED: + errno = EACCES; + return -1; + } + + return bnep_connadd(sk, role, dev); +} diff --git a/pand/main.c b/pand/main.c new file mode 100644 index 00000000..91a9a92c --- /dev/null +++ b/pand/main.c @@ -0,0 +1,604 @@ +/* + pand - Bluetooth PAN daemon for BlueZ + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "pand.h" + +static uint16_t role = BNEP_SVC_PANU; // Local role (ie service) +static uint16_t service = BNEP_SVC_NAP; // Remote service + +static int detach = 1; +static int persist; +static int use_sdp = 1; +static int use_cache; +static int encrypt; +static int master; +static int search_duration = 10; + +static struct { + int valid; + char dst[40]; + bdaddr_t bdaddr; +} cache; + +static char netdev[16] = "bnep%d"; + +static bdaddr_t src_addr = *BDADDR_ANY; +static int src_dev = -1; + +volatile int terminate; + +enum { + NONE, + SHOW, + LISTEN, + CONNECT, + KILL +} modes; + +static void run_devup(char *dev, char *dst) +{ + char *argv[4], prog[40]; + + sprintf(prog, "%s/%s", PAND_CONFIG_DIR, PAND_DEVUP_CMD); + + if (access(prog, R_OK | X_OK)) + return; + + if (fork()) + return; + + argv[0] = prog; + argv[1] = dev; + argv[2] = dst; + argv[3] = NULL; + execv(prog, argv); + exit(1); +} + +static int do_listen(void) +{ + struct l2cap_options l2o; + struct sockaddr_l2 l2a; + int sk, olen, lm; + + if (use_sdp) + bnep_sdp_register(role); + + // Create L2CAP socket and bind it to PSM BNEP + sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (sk < 0) { + syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", + strerror(errno), errno); + return -1; + } + + l2a.l2_family = AF_BLUETOOTH; + l2a.l2_psm = htobs(BNEP_PSM); + l2a.l2_bdaddr = src_addr; + + if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno); + return -1; + } + + /* Setup L2CAP options according to BNEP spec */ + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) { + syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)", + strerror(errno), errno); + return -1; + } + + l2o.imtu = l2o.omtu = BNEP_MTU; + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) { + syslog(LOG_ERR, "Failed to set L2CAP options. %s(%d)", + strerror(errno), errno); + return -1; + } + + /* Set link mode */ + lm = 0; + if (master) + lm |= L2CAP_LM_MASTER; + + if (encrypt) + lm |= L2CAP_LM_ENCRYPT; + + if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { + syslog(LOG_ERR, "Failed to set link mode. %s(%d)", strerror(errno), errno); + return -1; + } + + listen(sk, 10); + + while (!terminate) { + int alen = sizeof(l2a); + int nsk; + nsk = accept(sk, (struct sockaddr *) &l2a, &alen); + if (nsk < 0) { + syslog(LOG_ERR, "Accept failed. %s(%d)", strerror(errno), errno); + continue; + } + + switch (fork()) { + case 0: + break; + case -1: + syslog(LOG_ERR, "Fork failed. %s(%d)", strerror(errno), errno); + default: + close(nsk); + continue; + } + + if (!bnep_accept_connection(nsk, role, netdev)) { + char str[40]; + ba2str(&l2a.l2_bdaddr, str); + + syslog(LOG_INFO, "New connection from %s %s", str, netdev); + + run_devup(netdev, str); + } else { + syslog(LOG_ERR, "Connection failed. %s(%d)", + strerror(errno), errno); + } + + close(nsk); + exit(0); + } + + if (use_sdp) + bnep_sdp_unregister(); + return 0; +} + +/* Wait for disconnect or error condition on the socket */ +static int w4_hup(int sk) +{ + struct pollfd pf; + int n; + + while (!terminate) { + pf.fd = sk; + pf.events = POLLERR | POLLHUP; + n = poll(&pf, 1, -1); + if (n < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + syslog(LOG_ERR, "Poll failed. %s(%d)", + strerror(errno), errno); + return 1; + } + + if (n) { + int err = 0, olen = sizeof(err); + getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &olen); + syslog(LOG_INFO, "%s disconnected%s%s", netdev, + err ? " : " : "", err ? strerror(err) : ""); + + close(sk); + return 0; + } + } + return 0; +} + +/* Connect and initiate BNEP session + * Returns: + * -1 - critical error (exit persist mode) + * 1 - non critical error + * 0 - success + */ +static int create_connection(char *dst, bdaddr_t *bdaddr) +{ + struct l2cap_options l2o; + struct sockaddr_l2 l2a; + int sk, olen, r = 0; + + syslog(LOG_INFO, "Connecting to %s", dst); + + sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (sk < 0) { + syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", + strerror(errno), errno); + return -1; + } + + /* Setup L2CAP options according to BNEP spec */ + getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); + l2o.imtu = l2o.omtu = BNEP_MTU; + setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); + + l2a.l2_family = AF_BLUETOOTH; + + /* Set local address */ + l2a.l2_psm = 0; + l2a.l2_bdaddr = src_addr; + + if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) + syslog(LOG_ERR, "Bind failed. %s(%d)", + strerror(errno), errno); + + l2a.l2_psm = htobs(BNEP_PSM); + l2a.l2_bdaddr = *bdaddr; + + if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) && + !bnep_create_connection(sk, role, service, netdev)) { + + syslog(LOG_INFO, "%s connected", netdev); + + run_devup(netdev, dst); + + if (persist) + w4_hup(sk); + + r = 0; + } else { + syslog(LOG_ERR, "Connect to %s failed. %s(%d)", + dst, strerror(errno), errno); + r = 1; + } + + close(sk); + + if (use_cache) { + if (!r) { + /* Succesesful connection, validate cache */ + strcpy(cache.dst, dst); + bacpy(&cache.bdaddr, bdaddr); + cache.valid = use_cache; + } else + cache.valid--; + } + + return r; +} + +/* Search and connect + * Returns: + * -1 - critical error (exit persist mode) + * 1 - non critical error + * 0 - success + */ +static int do_connect(void) +{ + inquiry_info *ii; + int reconnect = 0; + int i, n, r = 0; + + do { + if (reconnect) + sleep(persist); + reconnect = 1; + + if (cache.valid > 0) { + /* Use cached bdaddr */ + r = create_connection(cache.dst, &cache.bdaddr); + if (r < 0) { + terminate = 1; + break; + } + continue; + } + + syslog(LOG_INFO, "Inquiring"); + + /* FIXME: Should we use non general LAP here ? */ + + ii = NULL; + n = hci_inquiry(src_dev, search_duration, 10, NULL, &ii, 0); + if (n < 0) { + syslog(LOG_ERR, "Inquiry failed. %s(%d)", strerror(errno), errno); + continue; + } + + for (i = 0; i < n; i++) { + char dst[40]; + ba2str(&ii[i].bdaddr, dst); + + if (use_sdp) { + syslog(LOG_INFO, "Searching for %s on %s", + bnep_svc2str(service), dst); + + if (bnep_sdp_search(&src_addr, &ii[i].bdaddr, service) <= 0) + continue; + } + + r = create_connection(dst, &ii[i].bdaddr); + if (r < 0) { + terminate = 1; + break; + } + } + free(ii); + } while (!terminate && persist); + + return r; +} + +static void do_show(void) +{ + bnep_show_connections(); +} + +static void do_kill(char *dst) +{ + if (dst) + bnep_kill_connection((void *) strtoba(dst)); + else + bnep_kill_all_connections(); +} + +void sig_hup(int sig) +{ + return; +} + +void sig_term(int sig) +{ + terminate = 1; +} + +static struct option main_lopts[] = { + { "help", 0, 0, 'h' }, + { "listen", 0, 0, 's' }, + { "connect", 1, 0, 'c' }, + { "search", 2, 0, 'Q' }, + { "kill", 1, 0, 'k' }, + { "killall", 0, 0, 'K' }, + { "role", 1, 0, 'r' }, + { "service", 1, 0, 'd' }, + { "device", 1, 0, 'i' }, + { "source", 1, 0, 'S' }, + { "nosdp", 0, 0, 'D' }, + { "list", 0, 0, 'l' }, + { "show", 0, 0, 'l' }, + { "nodetach", 0, 0, 'n' }, + { "persist", 2, 0, 'p' }, + { "encrypt", 0, 0, 'E' }, + { "master", 0, 0, 'M' }, + { "cache", 0, 0, 'C' }, + { 0, 0, 0, 0 } +}; + +static char main_sopts[] = "hsc:k:Kr:i:S:lnp::DQ::EMC::"; + +static char main_help[] = + "PAN daemon version " VERSION " \n" + "Usage:\n" + "\tpand \n" + "Options:\n" + "\t--show --list -l Show active PAN connections\n" + "\t--listen -s Listen for PAN connections\n" + "\t--connect -c Create PAN connection\n" + "\t--search -Q[duration] Search and connect\n" + "\t--kill -k Kill PAN connection\n" + "\t--killall -K Kill all PAN connections\n" + "\t--role -r Local PAN role (PANU, NAP, GN)\n" + "\t--service -d Remote PAN service (PANU, NAP, GN)\n" + "\t--device -i Network interface name\n" + "\t--source -S Source bdaddr\n" + "\t--nosdp -D Disable SDP\n" + "\t--encrypt -E Enable encryption\n" + "\t--master -M Become the master of a piconet\n" + "\t--nodetach -n Do not become a daemon\n" + "\t--persist -p[interval] Persist mode\n" + "\t--cache -C[valid] Cache addresses\n"; + +int main(int argc, char **argv) +{ + char *dst = NULL, *src = NULL; + struct sigaction sa; + int mode = NONE; + int opt; + + while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) { + switch(opt) { + case 'l': + mode = SHOW; + detach = 0; + break; + + case 's': + mode = LISTEN; + break; + + case 'c': + mode = CONNECT; + dst = strdup(optarg); + break; + + case 'Q': + mode = CONNECT; + dst = NULL; + if (optarg) + search_duration = atoi(optarg); + break; + + case 'k': + mode = KILL; + detach = 0; + dst = strdup(optarg); + break; + + case 'K': + mode = KILL; + detach = 0; + dst = NULL; + break; + + case 'S': + src = strdup(optarg); + break; + + case 'r': + bnep_str2svc(optarg, &role); + break; + + case 'd': + bnep_str2svc(optarg, &service); + break; + + case 'D': + use_sdp = 0; + break; + + case 'E': + encrypt = 1; + break; + + case 'M': + master = 1; + break; + + case 'i': + strcpy(netdev, optarg); + break; + + case 'n': + detach = 0; + break; + + case 'p': + if (optarg) + persist = atoi(optarg); + else + persist = 5; + break; + + case 'C': + if (optarg) + use_cache = atoi(optarg); + else + use_cache = 2; + break; + + case 'h': + default: + printf(main_help); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (bnep_init()) + return -1; + + /* Check non daemon modes first */ + switch (mode) { + case SHOW: + do_show(); + return 0; + + case KILL: + do_kill(dst); + return 0; + + case NONE: + printf(main_help); + return 0; + } + + /* Initialize signals */ + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + if (detach) { + if (fork()) exit(0); + + /* Direct stdin,stdout,stderr to '/dev/null' */ + { + int fd = open("/dev/null", O_RDWR); + dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); + close(fd); + } + + setsid(); + chdir("/"); + } + + openlog("pand", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); + syslog(LOG_INFO, "PAN daemon ver %s", VERSION); + + if (src) { + src_dev = hci_devid(src); + if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) { + syslog(LOG_ERR, "Invalid source. %s(%d)", strerror(errno), errno); + return -1; + } + } + + if (dst) { + /* Disable cache invalidation */ + use_cache = 0; + + strncpy(cache.dst, dst, sizeof(cache.dst) - 1); + str2ba(dst, &cache.bdaddr); + cache.valid = 1; + } + + switch (mode) { + case CONNECT: + do_connect(); + break; + + case LISTEN: + do_listen(); + break; + } + + return 0; +} diff --git a/pand/pand.1 b/pand/pand.1 new file mode 100644 index 00000000..a11a33c0 --- /dev/null +++ b/pand/pand.1 @@ -0,0 +1,59 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. +.TH BlueZ "1" "February 2003" "PAN daemon" "User Commands" +.SH NAME +pand \- BlueZ Bluetooth PAN daemon +.SH DESCRIPTION +The pand PAN daemon allows your computer to connect to ethernet +networks using Bluetooth. +.SH SYNPOSIS +pand +.SH OPTIONS +.TP +\fB\-\-show\fR \fB\-\-list\fR \fB\-l\fR +Show active PAN connections +.TP +\fB\-\-listen\fR \fB\-s\fR +Listen for PAN connections +.TP +\fB\-\-connect\fR \fB\-c\fR +Create PAN connection +.TP +\fB\-\-search\fR \fB\-Q[duration]\fR +Search and connect +.TP +\fB\-\-kill\fR \fB\-k\fR +Kill PAN connection +.TP +\fB\-\-killall\fR \fB\-K\fR +Kill all PAN connections +.TP +\fB\-\-role\fR \fB\-r\fR +Local PAN role (PANU, NAP, GN) +.TP +\fB\-\-service\fR \fB\-d\fR +Remote PAN service (PANU, NAP, GN) +.TP +\fB\-\-device\fR \fB\-i\fR +Network interface name +.TP +\fB\-\-source\fR \fB\-S\fR +Source bdaddr +.TP +\fB\-\-nosdp\fR \fB\-D\fR +Disable SDP +.TP +\fB\-\-encrypt\fR \fB\-E\fR +Enable encryption +.TP +\fB\-\-master\fR \fB\-M\fR +Become the master of a piconet +.TP +\fB\-\-nodetach\fR \fB\-n\fR +Do not become a daemon +.TP +\fB\-\-persist\fR \fB\-p[interval]\fR +Persist mode +.TP +\fB\-\-cache\fR \fB\-C[valid]\fR +Cache addresses + diff --git a/pand/pand.h b/pand/pand.h new file mode 100644 index 00000000..268316de --- /dev/null +++ b/pand/pand.h @@ -0,0 +1,44 @@ +/* + pand - Bluetooth PAN daemon for BlueZ + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * $Id$ + */ + +/* PAN scripts & commands */ +#define PAND_CONFIG_DIR "/etc/bluetooth/pan" +#define PAND_DEVUP_CMD "dev-up" + +/* BNEP functions */ +int bnep_init(void); +int bnep_cleanup(void); + +int bnep_str2svc(char *svc, uint16_t *uuid); +char *bnep_svc2str(uint16_t uuid); + +int bnep_show_connections(void); +int bnep_kill_connection(uint8_t *dst); +int bnep_kill_all_connections(void); + +int bnep_accept_connection(int sk, uint16_t role, char *dev); +int bnep_create_connection(int sk, uint16_t role, uint16_t svc, char *dev); + +/* SDP functions */ +int bnep_sdp_register(uint16_t role); +void bnep_sdp_unregister(void); +int bnep_sdp_search(bdaddr_t *src, bdaddr_t *dst, uint16_t service); diff --git a/pand/sdp.c b/pand/sdp.c new file mode 100644 index 00000000..16f092d9 --- /dev/null +++ b/pand/sdp.c @@ -0,0 +1,201 @@ +/* + pand - Bluetooth PAN daemon for BlueZ + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pand.h" + +static sdp_record_t *record; +static sdp_session_t *session; + +void bnep_sdp_unregister(void) +{ + if (record && sdp_record_unregister(session, record)) + syslog(LOG_ERR, "Service record unregistration failed."); + + sdp_close(session); +} + +int bnep_sdp_register(uint16_t role) +{ + sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; + uuid_t root_uuid, pan, l2cap, bnep; + sdp_profile_desc_t profile[1]; + sdp_list_t *proto[2]; + uint16_t psm = 15, version = 0x0100; + int status; + + session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); + if (!session) { + syslog(LOG_ERR, "Failed to connect to the local SDP server. %s(%d)", + strerror(errno), errno); + return -1; + } + + record = sdp_record_alloc(); + if (!record) { + syslog(LOG_ERR, "Failed to allocate service record %s(%d)", + strerror(errno), errno); + sdp_close(session); + return -1; + } + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(record, root); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(NULL, &l2cap); + proto[0] = sdp_list_append(proto[0], sdp_data_alloc(SDP_UINT16, &psm)); + apseq = sdp_list_append(NULL, proto[0]); + + sdp_uuid16_create(&bnep, BNEP_UUID); + proto[1] = sdp_list_append(NULL, &bnep); + proto[1] = sdp_list_append(proto[1], sdp_data_alloc(SDP_UINT16, &version)); + + /* Supported protocols */ + { + uint16_t ptype[4] = { + 0x0800, /* IPv4 */ + 0x0806, /* ARP */ + }; + sdp_data_t *head, *pseq; + int p; + + for (p = 0, head = NULL; p < 2; p++) { + sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]); + if (head) + sdp_seq_append(head, data); + else + head = data; + } + pseq = sdp_data_alloc(SDP_SEQ16, head); + proto[1] = sdp_list_append(proto[1], pseq); + } + + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(NULL, apseq); + sdp_set_access_protos(record, aproto); + + switch (role) { + case BNEP_SVC_NAP: + sdp_uuid16_create(&pan, NAP_SVCLASS_ID); + svclass = sdp_list_append(NULL, &pan); + sdp_set_service_classes(record, svclass); + + sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(record, pfseq); + + sdp_set_info_attr(record, "Network Access Point", NULL, NULL); + break; + + case BNEP_SVC_GN: + sdp_uuid16_create(&pan, GN_SVCLASS_ID); + svclass = sdp_list_append(NULL, &pan); + sdp_set_service_classes(record, svclass); + + sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(record, pfseq); + + sdp_set_info_attr(record, "Group Network Service", NULL, NULL); + break; + + case BNEP_SVC_PANU: + sdp_uuid16_create(&pan, PANU_SVCLASS_ID); + svclass = sdp_list_append(NULL, &pan); + sdp_set_service_classes(record, svclass); + + sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(record, pfseq); + + sdp_set_info_attr(record, "PAN User", NULL, NULL); + break; + } + + status = sdp_record_register(session, record, 0); + if (status) { + syslog(LOG_ERR, "SDP registration failed."); + sdp_record_free(record); record = NULL; + sdp_close(session); + return -1; + } + return 0; +} + +// Search for PAN service. +// Returns 1 if service is found and 0 otherwise. +int bnep_sdp_search(bdaddr_t *src, bdaddr_t *dst, uint16_t service) +{ + sdp_list_t *srch, *rsp = NULL; + sdp_session_t *s; + uuid_t svclass; + int err; + + switch (service) { + case BNEP_SVC_PANU: + sdp_uuid16_create(&svclass, PANU_SVCLASS_ID); + break; + case BNEP_SVC_NAP: + sdp_uuid16_create(&svclass, NAP_SVCLASS_ID); + break; + case BNEP_SVC_GN: + sdp_uuid16_create(&svclass, GN_SVCLASS_ID); + break; + } + + srch = sdp_list_append(NULL, &svclass); + + s = sdp_connect(src, dst, 0); + if (!s) { + syslog(LOG_ERR, "Failed to connect to the SDP server. %s(%d)", + strerror(errno), errno); + return 0; + } + + err = sdp_service_search_req(s, srch, 1, &rsp); + sdp_close(s); + + /* Assume that search is successeful + * if at least one record is found */ + if (!err && sdp_list_len(rsp)) + return 1; + + return 0; +} -- cgit From bc4cb70ddb8fe59d8b097a62029b0f24849163a3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 22:03:05 +0000 Subject: Add the dund utility --- Makefile.am | 2 +- configure.in | 2 +- dund/Makefile.am | 15 ++ dund/dun.c | 308 ++++++++++++++++++++++++++++++ dund/dund.1 | 49 +++++ dund/dund.h | 44 +++++ dund/lib.h | 95 ++++++++++ dund/main.c | 558 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ dund/msdun.c | 145 +++++++++++++++ dund/sdp.c | 146 +++++++++++++++ 10 files changed, 1362 insertions(+), 2 deletions(-) create mode 100644 dund/Makefile.am create mode 100644 dund/dun.c create mode 100644 dund/dund.1 create mode 100644 dund/dund.h create mode 100644 dund/lib.h create mode 100644 dund/main.c create mode 100644 dund/msdun.c create mode 100644 dund/sdp.c diff --git a/Makefile.am b/Makefile.am index 6a87b06c..0d627329 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -SUBDIRS := hcid tools rfcomm sdpd pand test scripts pcmcia +SUBDIRS := hcid tools rfcomm sdpd dund pand test scripts pcmcia DISTCLEANFILES = conftest.c conftest diff --git a/configure.in b/configure.in index c2868a9d..9a6a9630 100644 --- a/configure.in +++ b/configure.in @@ -25,4 +25,4 @@ AC_PATH_BLUEZ AC_PATH_DBUS -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile pand/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/dund/Makefile.am b/dund/Makefile.am new file mode 100644 index 00000000..9c967ce0 --- /dev/null +++ b/dund/Makefile.am @@ -0,0 +1,15 @@ +# +# $Id$ +# + +bin_PROGRAMS = dund + +dund_SOURCES = main.c dun.c dund.h sdp.c lib.h msdun.c + +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + +man_MANS = dund.1 + +EXTRA_DIST = $(man_MANS) diff --git a/dund/dun.c b/dund/dun.c new file mode 100644 index 00000000..8ef72ce6 --- /dev/null +++ b/dund/dun.c @@ -0,0 +1,308 @@ +/* + dund - Bluetooth LAN/DUN daemon for BlueZ + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "dund.h" +#include "lib.h" + +#define PROC_BASE "/proc" + +static int for_each_port(int (*func)(struct rfcomm_dev_info *, unsigned long), unsigned long arg) +{ + struct rfcomm_dev_list_req *dl; + struct rfcomm_dev_info *di; + long r = 0; + int sk, i; + + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM); + if (sk < 0 ) { + perror("Can't open RFCOMM control socket"); + exit(1); + } + + dl = malloc(sizeof(*dl) + RFCOMM_MAX_DEV * sizeof(*di)); + if (!dl) { + perror("Can't allocate request memory"); + close(sk); + exit(1); + } + + dl->dev_num = RFCOMM_MAX_DEV; + di = dl->dev_info; + + if (ioctl(sk, RFCOMMGETDEVLIST, (void *) dl) < 0) { + perror("Can't get device list"); + exit(1); + } + + for (i = 0; i < dl->dev_num; i++) { + r = func(di + i, arg); + if (r) break; + } + + close(sk); + return r; +} + +static int uses_rfcomm(char *path, char *dev) +{ + struct dirent *de; + DIR *dir; + + dir = opendir(path); + if (!dir) + return 0; + chdir(path); + + while ((de = readdir(dir)) != NULL) { + char link[PATH_MAX + 1]; + int len = readlink(de->d_name, link, sizeof(link)); + if (len > 0) { + link[len] = 0; + if (strstr(link, dev)) + return 1; + } + } + closedir(dir); + return 0; +} + +static int find_pppd(int id, pid_t *pid) +{ + struct dirent *de; + char path[PATH_MAX + 1]; + char dev[10]; + int empty = 1; + DIR *dir; + + dir = opendir(PROC_BASE); + if (!dir) { + perror(PROC_BASE); + return -1; + } + + sprintf(dev, "rfcomm%d", id); + + *pid = 0; + while ((de = readdir(dir)) != NULL) { + empty = 0; + if (isdigit(de->d_name[0])) { + sprintf(path, "%s/%s/fd", PROC_BASE, de->d_name); + if (uses_rfcomm(path, dev)) { + *pid = atoi(de->d_name); + break; + } + } + } + closedir(dir); + + if (empty) + fprintf(stderr, "%s is empty (not mounted ?)\n", PROC_BASE); + + return *pid != 0; +} + +static int dun_exec(char *tty, char *prog, char **args) +{ + int pid = fork(); + int fd; + + switch (pid) { + case -1: + return -1; + + case 0: + break; + + default: + return pid; + } + + setsid(); + + /* Close all FDs */ + for (fd=3; fd < 20; fd++) + close(fd); + + execvp(prog, args); + exit(1); +} + +static int dun_create_tty(int sk, char *tty, int size) +{ + struct sockaddr_rc sa; + struct stat st; + int id, alen; + + struct rfcomm_dev_req req = { + flags: (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP), + dev_id: -1 + }; + + alen = sizeof(sa); + if (getpeername(sk, (struct sockaddr *) &sa, &alen) < 0) + return -1; + bacpy(&req.dst, &sa.rc_bdaddr); + + alen = sizeof(sa); + if (getsockname(sk, (struct sockaddr *) &sa, &alen) < 0) + return -1; + bacpy(&req.src, &sa.rc_bdaddr); + req.channel = sa.rc_channel; + + id = ioctl(sk, RFCOMMCREATEDEV, &req); + if (id < 0) + return id; + + snprintf(tty, size, "/dev/rfcomm%d", id); + if (stat(tty, &st) < 0) { + snprintf(tty, size, "/dev/bluetooth/rfcomm/%d", id); + if (stat(tty, &st) < 0) { + snprintf(tty, size, "/dev/rfcomm%d", id); + return -1; + } + } + + return id; +} + +int dun_init(void) +{ + return 0; +} + +int dun_cleanup(void) +{ + return 0; +} + +static int show_conn(struct rfcomm_dev_info *di, unsigned long arg) +{ + pid_t pid; + + if (di->state == BT_CONNECTED && + (di->flags & (1<flags & (1<flags & (1<id, &pid)) { + char dst[18]; + ba2str(&di->dst, dst); + + printf("rfcomm%d: %s channel %d pppd pid %d\n", + di->id, dst, di->channel, pid); + } + } + return 0; +} + +static int kill_conn(struct rfcomm_dev_info *di, unsigned long arg) +{ + bdaddr_t *dst = (bdaddr_t *) arg; + pid_t pid; + + if (di->state == BT_CONNECTED && + (di->flags & (1<flags & (1<flags & (1<dst, dst)) + return 0; + + if (find_pppd(di->id, &pid)) { + if (kill(pid, SIGINT) < 0) + perror("Kill"); + + if (!dst) + return 0; + return 1; + } + } + return 0; +} + +int dun_show_connections(void) +{ + for_each_port(show_conn, 0); + return 0; +} + +int dun_kill_connection(uint8_t *dst) +{ + for_each_port(kill_conn, (unsigned long) dst); + return 0; +} + +int dun_kill_all_connections(void) +{ + for_each_port(kill_conn, 0); + return 0; +} + +int dun_open_connection(int sk, char *pppd, char **args, int wait) +{ + char tty[100]; + int pid; + + if (dun_create_tty(sk, tty, sizeof(tty) - 1) < 0) { + syslog(LOG_ERR, "RFCOMM TTY creation failed. %s(%d)", strerror(errno), errno); + return -1; + } + + args[0] = "pppd"; + args[1] = tty; + args[2] = "nodetach"; + + pid = dun_exec(tty, pppd, args); + if (pid < 0) { + syslog(LOG_ERR, "Exec failed. %s(%d)", strerror(errno), errno); + return -1; + } + + if (wait) { + int status; + waitpid(pid, &status, 0); + /* FIXME: Check for waitpid errors */ + } + + return 0; +} diff --git a/dund/dund.1 b/dund/dund.1 new file mode 100644 index 00000000..ad2b775c --- /dev/null +++ b/dund/dund.1 @@ -0,0 +1,49 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.29. +.TH BlueZ "1" "February 2003" "DUN daemon" "User Commands" +.SH NAME +dund \- BlueZ Bluetooth dial-up networking daemon +.SH DESCRIPTION +DUN daemon +.SH SYNOPSIS +dund +.SH OPTIONS +.TP +\fB\-\-show\fR \fB\-\-list\fR \fB\-l\fR +Show active DUN connections +.TP +\fB\-\-listen\fR \fB\-s\fR +Listen for DUN connections +.TP +\fB\-\-connect\fR \fB\-c\fR +Create DUN connection +.TP +\fB\-\-search\fR \fB\-Q[duration]\fR +Search and connect +.TP +\fB\-\-kill\fR \fB\-k\fR +Kill DUN connection +.TP +\fB\-\-killall\fR \fB\-K\fR +Kill all DUN connections +.TP +\fB\-\-channel\fR \fB\-C\fR +RFCOMM channel +.TP +\fB\-\-source\fR \fB\-S\fR +Source bdaddr +.TP +\fB\-\-sdp\fR \fB\-D\fR +Enable SDP +.TP +\fB\-\-encrypt\fR \fB\-E\fR +Enable encryption +.TP +\fB\-\-master\fR \fB\-M\fR +Become the master of a piconet +.TP +\fB\-\-nodetach\fR \fB\-n\fR +Do not become a daemon +.TP +\fB\-\-persist\fR \fB\-p[interval]\fR +Persist mode + diff --git a/dund/dund.h b/dund/dund.h new file mode 100644 index 00000000..d7c6d408 --- /dev/null +++ b/dund/dund.h @@ -0,0 +1,44 @@ +/* + dund - Bluetooth LAN/DUN daemon for BlueZ + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * $Id$ + */ + +/* DUN scripts & commands */ +#define DUN_CONFIG_DIR "/etc/bluetooth/dun" + +#define DUN_DEFAULT_CHANNEL 1 + +#define DUN_MAX_PPP_OPTS 40 + +/* DUN functions */ +int dun_init(void); +int dun_cleanup(void); + +int dun_show_connections(void); +int dun_kill_connection(uint8_t *dst); +int dun_kill_all_connections(void); + +int dun_open_connection(int sk, char *pppd, char **pppd_opts, int wait); + +/* SDP functions */ +int dun_sdp_register(uint8_t channel); +void dun_sdp_unregister(void); +int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel); + diff --git a/dund/lib.h b/dund/lib.h new file mode 100644 index 00000000..5de0ba0f --- /dev/null +++ b/dund/lib.h @@ -0,0 +1,95 @@ +/* + RFCOMMd - RFCOMM daemon. + Copyright (C) 2001 Qualcomm Incorporated + + Written 2001 by Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, + OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER + RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. +*/ + +/* + * $Id$ + */ +#ifndef _DUND_LIB_H +#define _DUND_LIB_H + +#include +#include +#include + +#ifndef min +#define min(a,b) ( (a)<(b) ? (a):(b) ) +#endif + +/* IO cancelation */ +extern volatile sig_atomic_t __io_canceled; + +static inline void io_init(void) +{ + __io_canceled = 0; +} + +static inline void io_cancel(void) +{ + __io_canceled = 1; +} + +/* Read exactly len bytes (Signal safe)*/ +static inline int read_n(int fd, char *buf, int len) +{ + register int t = 0, w; + + while (!__io_canceled && len > 0) { + if ((w = read(fd, buf, len)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!w) + return 0; + len -= w; + buf += w; + t += w; + } + + return t; +} + +/* Write exactly len bytes (Signal safe)*/ +static inline int write_n(int fd, char *buf, int len) +{ + register int t = 0, w; + + while (!__io_canceled && len > 0) { + if ((w = write(fd, buf, len)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } + if (!w) + return 0; + len -= w; + buf += w; + t += w; + } + + return t; +} + +int ms_dun(int fd, int server, int timeo); + +#endif /* _DUND_LIB_H */ diff --git a/dund/main.c b/dund/main.c new file mode 100644 index 00000000..50bebf0f --- /dev/null +++ b/dund/main.c @@ -0,0 +1,558 @@ +/* + dund - Bluetooth LAN/DUN daemon for BlueZ + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "dund.h" +#include "lib.h" + +volatile sig_atomic_t __io_canceled; + +/* MS dialup networking support (i.e. CLIENT / CLIENTSERVER thing) */ +static int msdun = 0; + +static char *pppd = "/usr/sbin/pppd"; +static char *pppd_opts[DUN_MAX_PPP_OPTS] = + { + /* First 3 are reserved */ + "", "", "", + "noauth", + "noipdefault", + NULL + }; + +static int detach = 1; +static int persist; +static int use_sdp = 1; +static int encrypt; +static int master; +static int search_duration = 10; +static uint use_cache; + +static int channel; + +static struct { + uint valid; + char dst[40]; + bdaddr_t bdaddr; + int channel; +} cache; + +static bdaddr_t src_addr = *BDADDR_ANY; +static int src_dev = -1; + +volatile int terminate; + +enum { + NONE, + SHOW, + LISTEN, + CONNECT, + KILL +} modes; + +static int do_listen(void) +{ + struct sockaddr_rc sa; + int sk; + + if (!channel) + channel = DUN_DEFAULT_CHANNEL; + + if (use_sdp) + dun_sdp_register(channel); + + // Create RFCOMM socket + sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (sk < 0) { + syslog(LOG_ERR, "Cannot create RFCOMM socket. %s(%d)", + strerror(errno), errno); + return -1; + } + + sa.rc_family = AF_BLUETOOTH; + sa.rc_channel = channel; + sa.rc_bdaddr = src_addr; + + if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) { + syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno); + return -1; + } + + listen(sk, 10); + + while (!terminate) { + int alen = sizeof(sa), nsk; + char ba[40]; + char ch[10]; + + nsk = accept(sk, (struct sockaddr *) &sa, &alen); + if (nsk < 0) { + syslog(LOG_ERR, "Accept failed. %s(%d)", strerror(errno), errno); + continue; + } + + switch (fork()) { + case 0: + break; + case -1: + syslog(LOG_ERR, "Fork failed. %s(%d)", strerror(errno), errno); + default: + close(nsk); + continue; + } + + if (msdun && ms_dun(nsk, 1, msdun) < 0) { + syslog(LOG_ERR, "MSDUN failed. %s(%d)", strerror(errno), errno); + exit(0); + } + + ba2str(&sa.rc_bdaddr, ba); + sprintf(ch, "%d", channel); + + /* Setup environment */ + setenv("DUN_BDADDR", ba, 1); + setenv("DUN_CHANNEL", ch, 1); + + if (!dun_open_connection(nsk, pppd, pppd_opts, 0)) + syslog(LOG_INFO, "New connection from %s", ba); + + close(nsk); + exit(0); + } + + if (use_sdp) + dun_sdp_unregister(); + return 0; +} + +/* Connect and initiate RFCOMM session + * Returns: + * -1 - critical error (exit persist mode) + * 1 - non critical error + * 0 - success + */ +static int create_connection(char *dst, bdaddr_t *bdaddr) +{ + struct sockaddr_rc sa; + int sk, err = 0, ch; + + if (use_cache && cache.valid && cache.channel) { + /* Use cached channel */ + ch = cache.channel; + + } else if (!channel) { + syslog(LOG_INFO, "Searching for %s on %s", "LAP", dst); + + if (dun_sdp_search(&src_addr, bdaddr, &ch) <= 0) + return 0; + } else + ch = channel; + + syslog(LOG_INFO, "Connecting to %s channel %d", dst, ch); + + sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (sk < 0) { + syslog(LOG_ERR, "Cannot create RFCOMM socket. %s(%d)", + strerror(errno), errno); + return -1; + } + + sa.rc_family = AF_BLUETOOTH; + sa.rc_channel = 0; + sa.rc_bdaddr = src_addr; + + if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) + syslog(LOG_ERR, "Bind failed. %s(%d)", + strerror(errno), errno); + + sa.rc_channel = ch; + sa.rc_bdaddr = *bdaddr; + + if (!connect(sk, (struct sockaddr *) &sa, sizeof(sa)) ) { + syslog(LOG_INFO, "Connection established"); + + if (msdun && ms_dun(sk, 0, msdun) < 0) { + syslog(LOG_ERR, "MSDUN failed. %s(%d)", strerror(errno), errno); + err = 1; + goto out; + } + + if (!dun_open_connection(sk, pppd, pppd_opts, (persist > 0))) + err = 0; + else + err = 1; + } else { + syslog(LOG_ERR, "Connect to %s failed. %s(%d)", + dst, strerror(errno), errno); + err = 1; + } + +out: + if (use_cache) { + if (!err) { + /* Succesesful connection, validate cache */ + strcpy(cache.dst, dst); + bacpy(&cache.bdaddr, bdaddr); + cache.channel = ch; + cache.valid = use_cache; + } else { + cache.channel = 0; + cache.valid--; + } + } + + close(sk); + return err; +} + +/* Search and connect + * Returns: + * -1 - critical error (exit persist mode) + * 1 - non critical error + * 0 - success + */ +static int do_connect(void) +{ + inquiry_info *ii; + int reconnect = 0; + int i, n, r = 0; + + do { + if (reconnect) + sleep(persist); + reconnect = 1; + + if (cache.valid) { + /* Use cached bdaddr */ + r = create_connection(cache.dst, &cache.bdaddr); + if (r < 0) { + terminate = 1; + break; + } + continue; + } + + syslog(LOG_INFO, "Inquiring"); + + /* FIXME: Should we use non general LAP here ? */ + + ii = NULL; + n = hci_inquiry(src_dev, search_duration, 10, NULL, &ii, 0); + if (n < 0) { + syslog(LOG_ERR, "Inquiry failed. %s(%d)", strerror(errno), errno); + continue; + } + + for (i = 0; i < n; i++) { + char dst[40]; + ba2str(&ii[i].bdaddr, dst); + + r = create_connection(dst, &ii[i].bdaddr); + if (r < 0) { + terminate = 1; + break; + } + } + free(ii); + } while (!terminate && persist); + + return r; +} + +static void do_show(void) +{ + dun_show_connections(); +} + +static void do_kill(char *dst) +{ + if (dst) { + bdaddr_t ba; + str2ba(dst, &ba); + dun_kill_connection((void *) &ba); + } else + dun_kill_all_connections(); +} + +void sig_hup(int sig) +{ + return; +} + +void sig_term(int sig) +{ + io_cancel(); + terminate = 1; +} + +static struct option main_lopts[] = { + { "help", 0, 0, 'h' }, + { "listen", 0, 0, 's' }, + { "connect", 1, 0, 'c' }, + { "search", 2, 0, 'Q' }, + { "kill", 1, 0, 'k' }, + { "killall", 0, 0, 'K' }, + { "channel", 1, 0, 'P' }, + { "source", 1, 0, 'S' }, + { "nosdp", 0, 0, 'D' }, + { "list", 0, 0, 'l' }, + { "show", 0, 0, 'l' }, + { "nodetach", 0, 0, 'n' }, + { "persist", 2, 0, 'p' }, + { "encrypt", 0, 0, 'E' }, + { "master", 0, 0, 'M' }, + { "cache", 0, 0, 'C' }, + { "pppd", 1, 0, 'd' }, + { "msdun", 2, 0, 'X' }, + { 0, 0, 0, 0 } +}; + +static char main_sopts[] = "hsc:k:Kr:S:lnp::DQ::EMP:C::P:X"; + +static char main_help[] = + "LAP (LAN Access over PPP) daemon version " VERSION " \n" + "Usage:\n" + "\tdund [pppd options]\n" + "Options:\n" + "\t--show --list -l Show active LAP connections\n" + "\t--listen -s Listen for LAP connections\n" + "\t--connect -c Create LAP connection\n" + "\t--search -Q[duration] Search and connect\n" + "\t--kill -k Kill LAP connection\n" + "\t--killall -K Kill all LAP connections\n" + "\t--channel -P RFCOMM channel\n" + "\t--source -S Source bdaddr\n" + "\t--nosdp -D Disable SDP\n" + "\t--nodetach -n Do not become a daemon\n" + "\t--persist -p[interval] Persist mode\n" + "\t--pppd -d Location of the PPP daemon (pppd)\n" + "\t--msdun -X[timeo] Enable Microsoft dialup networking support\n" + "\t--cache -C[valid] Enable addess cache\n"; + +int main(int argc, char **argv) +{ + char *dst = NULL, *src = NULL; + struct sigaction sa; + int mode = NONE; + int opt; + + while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) { + switch(opt) { + case 'l': + mode = SHOW; + detach = 0; + break; + + case 's': + mode = LISTEN; + break; + + case 'c': + mode = CONNECT; + dst = strdup(optarg); + break; + + case 'Q': + mode = CONNECT; + dst = NULL; + if (optarg) + search_duration = atoi(optarg); + break; + + case 'k': + mode = KILL; + detach = 0; + dst = strdup(optarg); + break; + + case 'K': + mode = KILL; + detach = 0; + dst = NULL; + break; + + case 'P': + channel = atoi(optarg); + break; + + case 'S': + src = strdup(optarg); + break; + + case 'D': + use_sdp = 0; + break; + + case 'E': + encrypt = 1; + break; + + case 'M': + master = 1; + break; + + case 'n': + detach = 0; + break; + + case 'p': + if (optarg) + persist = atoi(optarg); + else + persist = 5; + break; + + case 'C': + if (optarg) + use_cache = atoi(optarg); + else + use_cache = 2; + break; + + case 'd': + pppd = strdup(optarg); + break; + + case 'X': + if (optarg) + msdun = atoi(optarg); + else + msdun = 10; + break; + + case 'h': + default: + printf(main_help); + exit(0); + } + } + + argc -= optind; + argv += optind; + + /* The rest is pppd options */ + if (argc > 0) { + for (opt = 3; argc && opt < DUN_MAX_PPP_OPTS; argc--, opt++) + pppd_opts[opt] = *argv++; + pppd_opts[opt] = NULL; + } + + io_init(); + + if (dun_init()) + return -1; + + /* Check non daemon modes first */ + switch (mode) { + case SHOW: + do_show(); + return 0; + + case KILL: + do_kill(dst); + return 0; + + case NONE: + printf(main_help); + return 0; + } + + /* Initialize signals */ + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + if (detach) { + int fd; + + if (fork()) exit(0); + + /* Direct stdin,stdout,stderr to '/dev/null' */ + fd = open("/dev/null", O_RDWR); + dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); + close(fd); + + setsid(); + chdir("/"); + } + + openlog("dund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); + syslog(LOG_INFO, "DUN daemon ver %s", VERSION); + + if (src) { + src_dev = hci_devid(src); + if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) { + syslog(LOG_ERR, "Invalid source. %s(%d)", strerror(errno), errno); + return -1; + } + } + + if (dst) { + strncpy(cache.dst, dst, sizeof(cache.dst) - 1); + str2ba(dst, &cache.bdaddr); + + /* Disable cache invalidation */ + use_cache = cache.valid = ~0; + } + + switch (mode) { + case CONNECT: + do_connect(); + break; + + case LISTEN: + do_listen(); + break; + } + + return 0; +} diff --git a/dund/msdun.c b/dund/msdun.c new file mode 100644 index 00000000..89fa3ff0 --- /dev/null +++ b/dund/msdun.c @@ -0,0 +1,145 @@ +/* + dund - Bluetooth LAN/DUN daemon for BlueZ + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lib.h" + +#define MS_PPP 2 +#define MS_SUCCESS 1 +#define MS_FAILED -1 +#define MS_TIMEOUT -2 + +static sigjmp_buf jmp; +static int retry; +static int timeout; + +static void sig_alarm(int sig) +{ + siglongjmp(jmp, MS_TIMEOUT); +} + +static int w4_str(int fd, char *str) +{ + char buf[40]; + int r, len = 0; + + while (1) { + r = read(fd, buf + len, sizeof(buf) - len - 1); + if (r < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + break; + } + if (!r) + break; + + len += r; + + if (len < strlen(str)) + continue; + buf[len] = 0; + + if (strstr(buf, str)) + return MS_SUCCESS; + + /* Detect PPP */ + if (strchr(buf, '~')) + return MS_PPP; + } + return MS_FAILED; +} + +static int ms_server(int fd) +{ + switch (w4_str(fd, "CLIENT")) { + case MS_SUCCESS: + write_n(fd, "CLIENTSERVER", 12); + case MS_PPP: + return MS_SUCCESS; + default: + return MS_FAILED; + } +} + +static int ms_client(int fd) +{ + write_n(fd, "CLIENT", 6); + return w4_str(fd, "CLIENTSERVER"); +} + +int ms_dun(int fd, int server, int timeo) +{ + sig_t osig; + + retry = 4; + timeout = timeo; + + if (!server) + timeout /= retry; + + osig = signal(SIGALRM, sig_alarm); + + while (1) { + int r = sigsetjmp(jmp, 1); + if (r) { + if (r == MS_TIMEOUT && !server && --retry) + continue; + + alarm(0); + signal(SIGALRM, osig); + + switch (r) { + case MS_SUCCESS: + case MS_PPP: + errno = 0; + return 0; + + case MS_FAILED: + errno = EPROTO; + break; + + case MS_TIMEOUT: + errno = ETIMEDOUT; + break; + } + return -1; + } + + alarm(timeout); + + if (server) + r = ms_server(fd); + else + r = ms_client(fd); + + siglongjmp(jmp, r); + } +} diff --git a/dund/sdp.c b/dund/sdp.c new file mode 100644 index 00000000..9cac4efa --- /dev/null +++ b/dund/sdp.c @@ -0,0 +1,146 @@ +/* + dund - Bluetooth LAN/DUN daemon for BlueZ + Copyright (C) 2002 Maxim Krasnyansky + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, as + published by the Free Software Foundation. + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * $Id$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "dund.h" + +static sdp_record_t *record; +static sdp_session_t *session; + +void dun_sdp_unregister(void) +{ + if (record && sdp_record_unregister(session, record)) + syslog(LOG_ERR, "Service record unregistration failed."); + sdp_close(session); +} + +int dun_sdp_register(uint8_t channel) +{ + sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; + uuid_t root_uuid, l2cap, rfcomm, dun; + sdp_profile_desc_t profile[1]; + sdp_list_t *proto[2]; + int status; + + session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); + if (!session) { + syslog(LOG_ERR, "Failed to connect to the local SDP server. %s(%d)", + strerror(errno), errno); + return -1; + } + + record = sdp_record_alloc(); + if (!record) { + syslog(LOG_ERR, "Failed to alloc service record"); + return -1; + } + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(record, root); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(NULL, &l2cap); + apseq = sdp_list_append(NULL, proto[0]); + + sdp_uuid16_create(&rfcomm, RFCOMM_UUID); + proto[1] = sdp_list_append(NULL, &rfcomm); + proto[1] = sdp_list_append(proto[1], sdp_data_alloc(SDP_UINT8, &channel)); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(NULL, apseq); + sdp_set_access_protos(record, aproto); + + sdp_uuid16_create(&dun, LAN_ACCESS_SVCLASS_ID); + svclass = sdp_list_append(NULL, &dun); + sdp_set_service_classes(record, svclass); + + sdp_uuid16_create(&profile[0].uuid, LAN_ACCESS_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(record, pfseq); + + sdp_set_info_attr(record, "LAN Access Point", NULL, NULL); + + status = sdp_record_register(session, record, 0); + if (status) { + syslog(LOG_ERR, "SDP registration failed."); + sdp_record_free(record); record = NULL; + return -1; + } + return 0; +} + +int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel) +{ + sdp_session_t *s; + sdp_list_t *srch, *attrs, *rsp; + uuid_t svclass; + uint16_t attr; + int err; + + s = sdp_connect(src, dst, 0); + if (!s) { + syslog(LOG_ERR, "Failed to connect to the SDP server. %s(%d)", + strerror(errno), errno); + return -1; + } + + sdp_uuid16_create(&svclass, LAN_ACCESS_SVCLASS_ID); + srch = sdp_list_append(NULL, &svclass); + + attr = SDP_ATTR_PROTO_DESC_LIST; + attrs = sdp_list_append(NULL, &attr); + + err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); + + sdp_close(s); + + if (err) + return 0; + + for(; rsp; rsp = rsp->next) { + sdp_record_t *rec = (sdp_record_t *) rsp->data; + sdp_list_t *protos; + + if (!sdp_get_access_protos(rec, &protos)) { + int ch = sdp_get_proto_port(protos, RFCOMM_UUID); + if (ch > 0) { + *channel = ch; + return 1; + } + } + } + + return 0; +} -- cgit From 9bcd7f5fcd06191f5e15f8933ffdad99e792f0cf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 26 Apr 2004 00:10:17 +0000 Subject: Run D-BUS checks only if enabled --- acinclude.m4 | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index e223c08e..dc885de8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -98,12 +98,14 @@ AC_DEFUN(AC_PATH_DBUS, [ CFLAGS="$CFLAGS -I/usr/lib/dbus-1.0/include" fi - AC_CHECK_HEADER(dbus/dbus.h,, - dbus_enable=no) + if test "$dbus_enable" = "yes"; then + AC_CHECK_HEADER(dbus/dbus.h,, + dbus_enable=no) - AC_CHECK_LIB(dbus-1, dbus_error_init, - DBUS_LIBS="$DBUS_LIBS -ldbus-1", - dbus_enable=no) + AC_CHECK_LIB(dbus-1, dbus_error_init, + DBUS_LIBS="$DBUS_LIBS -ldbus-1", + dbus_enable=no) + fi CFLAGS=$ac_save_CFLAGS if test -n "$dbus_includes"; then -- cgit From c501002e53909aea28b654277ec6ee06a7dee336 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 26 Apr 2004 00:13:25 +0000 Subject: Change link order if D-BUS is enabled --- hcid/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index b720e5cc..3a5e766a 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -15,7 +15,7 @@ endif hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) hcid_CONFIG = hcid.conf -LDFLAGS = @BLUEZ_LIBS@ $(dbus_hcid_ldflags) +LDFLAGS = $(dbus_hcid_ldflags) @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ @DBUS_INCLUDES@ -- cgit From 6e58cec633c1a73ab11a2720dff4da094070b6f6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 10:23:02 +0000 Subject: Add new Bluetooth init.d script --- scripts/bluetooth.default | 34 ++++++++++++++++ scripts/bluetooth.init | 102 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 scripts/bluetooth.default create mode 100644 scripts/bluetooth.init diff --git a/scripts/bluetooth.default b/scripts/bluetooth.default new file mode 100644 index 00000000..d96342c6 --- /dev/null +++ b/scripts/bluetooth.default @@ -0,0 +1,34 @@ +# Bluetooth configuraton file + +# Start of hcid (allowed values are "true" and "false") +HCID_ENABLE=true + +# Config file for hcid +HCID_CONFIG="/etc/bluetooth/hcid.conf" + +# Start sdpd (allowed values are "true" and "false") +SDPD_ENABLE=true + +# Start hidd (allowed values are "true" and "false") +HIDD_ENABLE=true + +# Run hid2hci (allowed values are "true" and "false") +HID2HCI_ENABLE=true + +# Bind rfcomm devices (allowed values are "true" and "false") +RFCOMM_ENABLE=true + +# Config file for rfcomm +RFCOMM_CONFIG="/etc/bluetooth/rfcomm.conf" + +# Start dund (allowed values are "true" and "false") +DUND_ENABLE=false + +# Arguments to dund +DUND_OPTIONS="--listen --persist" + +# Start pand (allowed values are "true" and "false") +PAND_ENABLE=false + +# Arguments to pand +PAND_OPTIONS="--listen --role NAP" diff --git a/scripts/bluetooth.init b/scripts/bluetooth.init new file mode 100644 index 00000000..d0b053cf --- /dev/null +++ b/scripts/bluetooth.init @@ -0,0 +1,102 @@ +#!/bin/sh +# +# Start/stop the Bluetooth daemons +# + +set -e + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +NAME=bluetooth +DESC="Bluetooth subsystem" + +HCID_NAME=hcid +SDPD_NAME=sdpd +HIDD_NAME=hidd +HID2HCI_NAME=hid2hci +RFCOMM_NAME=rfcomm +PAND_NAME=pand +DUND_NAME=dund + +HCID_EXEC="`which $HCID_NAME || true`" +SDPD_EXEC="`which $SDPD_NAME || true`" +HIDD_EXEC="`which $HIDD_NAME || true`" +HID2HCI_EXEC="`which $HIDD_NAME || true`" +RFCOMM_EXEC="`which $RFCOMM_NAME || true`" +PAND_EXEC="`which $PAND_NAME || true`" +DUND_EXEC="`which $DUND_NAME || true`" + +HCID_ENABLE=true +SDPD_ENABLE=true +HIDD_ENABLE=false +HID2HCI_ENABLE=false +RFCOMM_ENABLE=true +DUND_ENABLE=false +PAND_ENABLE=false + +HCID_CONFIG="/etc/bluetooth/hcid.conf" +RFCOMM_CONFIG="/etc/bluetooth/rfcomm.conf" + +DUND_OPTIONS="" +PAND_OPTIONS="" + +[ -e /etc/default/bluetooth ] && . /etc/default/bluetooth + +case "$1" in + start) + echo -n "Starting $DESC:" + if $HCID_ENABLE && [ -x "$HCID_EXEC" -a -f "$HCID_CONFIG" ] ; then + $HCID_EXEC -f $HCID_CONFIG + echo -n " $HCID_NAME" + fi + if $SDPD_ENABLE && [ -x "$SDPD_EXEC" ] ; then + $SDPD_EXEC + echo -n " $SDPD_NAME" + fi + if $HIDD_ENABLE && [ -x "$HIDD_EXEC" ] ; then + $HIDD_EXEC --tohci + echo -n " $HIDD_NAME" + fi + if $HID2HCI_ENABLE && [ -x "$HID2HCI_EXEC" ] ; then + $HID2HCI_EXEC + echo -n " $HID2HCI_NAME" + fi + if $RFCOMM_ENABLE && [ -x "$RFCOMM_EXEC" -a -f "$RFCOMM_CONFIG" ] ; then + $RFCOMM_EXEC -f $RFCOMM_CONFIG bind all + echo -n " $RFCOMM_NAME" + fi + if $DUND_ENABLE && [ -x "$DUND_EXEC" -a -n "$DUND_OPTIONS" ] ; then + $DUND_EXEC $DUND_OPTIONS + echo -n " $DUND_NAME" + fi + if $PAND_ENABLE && [ -x "$PAND_EXEC" -a -n "$PAND_OPTIONS" ] ; then + $PAND_EXEC $PAND_OPTIONS + echo -n " $PAND_NAME" + fi + echo "." + ;; + stop) + echo -n "Stopping $DESC:" + killall $PAND_EXEC > /dev/null 2>&1 || true + echo -n " $PAND_NAME" + killall $DUND_EXEC > /dev/null 2>&1 || true + echo -n " $DUND_NAME" + if [ -x "$RFCOMM_EXEC" ] ; then + $RFCOMM_EXEC release all + echo -n " $RFCOMM_NAME" + fi + killall $HIDD_EXEC > /dev/null 2>&1 || true + echo -n " $HIDD_NAME" + killall $SDPD_EXEC > /dev/null 2>&1 || true + echo -n " $SDPD_NAME" + killall $HCID_EXEC > /dev/null 2>&1 || true + echo -n " $HCID_NAME" + echo "." + ;; + *) + N=/etc/init.d/$NAME + echo "Usage: $N {start|stop}" >&2 + exit 1 + ;; +esac + +exit 0 -- cgit From b66d3f9b2cb8934a0eb7ac07f347001984488ac6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 10:39:47 +0000 Subject: Unify copyright and license information --- rfcomm/kword.c | 33 ++++++++++++-------- rfcomm/kword.h | 31 ++++++++++--------- rfcomm/lexer.l | 33 ++++++++++++-------- rfcomm/main.c | 31 +++++++++++-------- rfcomm/parser.y | 37 +++++++++++++--------- tools/ciptool.c | 29 +++++++++--------- tools/csr.c | 34 ++++++++++++-------- tools/csr.h | 29 ++++++++++-------- tools/hciattach.c | 52 ++++++++++++++++--------------- tools/hciconfig.c | 51 +++++++++++++++--------------- tools/hcisecfilter.c | 63 ++++++++++++++++++++++++++++--------- tools/hcitool.c | 51 +++++++++++++++--------------- tools/hid2hci.c | 30 +++++++++--------- tools/l2ping.c | 87 ++++++++++++++++++++++++++++------------------------ tools/ppporc.c | 50 ++++++++++++++---------------- tools/sdptool.c | 55 +++++++++++++++++---------------- 16 files changed, 395 insertions(+), 301 deletions(-) diff --git a/rfcomm/kword.c b/rfcomm/kword.c index f0aaed4f..0747eef3 100644 --- a/rfcomm/kword.c +++ b/rfcomm/kword.c @@ -1,26 +1,35 @@ /* * - * RFCOMM configuration utility + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2003 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include diff --git a/rfcomm/kword.h b/rfcomm/kword.h index f8e4210e..c0acd946 100644 --- a/rfcomm/kword.h +++ b/rfcomm/kword.h @@ -1,29 +1,33 @@ /* * - * RFCOMM configuration utility + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2003 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ extern int lineno; - struct keyword_t { char *string; int type; @@ -33,7 +37,6 @@ extern struct keyword_t rfcomm_keyword[]; int rfcomm_find_keyword(struct keyword_t *keyword, char *string); - #define MAXCOMMENTLEN 100 struct rfcomm_opts { diff --git a/rfcomm/lexer.l b/rfcomm/lexer.l index 46b76d13..89c41828 100644 --- a/rfcomm/lexer.l +++ b/rfcomm/lexer.l @@ -1,27 +1,36 @@ %{ /* * - * RFCOMM configuration utility + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2003 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include diff --git a/rfcomm/main.c b/rfcomm/main.c index 5d061fb7..dbb74869 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -1,24 +1,29 @@ /* * - * RFCOMM configuration utility + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2003 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ #ifdef HAVE_CONFIG_H @@ -554,7 +559,7 @@ static void usage(void) "\n"); printf("Commands:\n"); - for (i = 0; command[i].cmd; i++) + for (i = 0; command[i].cmd; i++) printf("\t%-8s %-24s\t%s\n", command[i].cmd, command[i].opt ? command[i].opt : " ", diff --git a/rfcomm/parser.y b/rfcomm/parser.y index f7ee3d70..58bc74c0 100644 --- a/rfcomm/parser.y +++ b/rfcomm/parser.y @@ -1,27 +1,36 @@ %{ /* * - * RFCOMM configuration utility + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2003 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -162,6 +171,6 @@ int rfcomm_read_config(char *filename) yyparse(); fclose(yyin); - - return 0; + + return 0; } diff --git a/tools/ciptool.c b/tools/ciptool.c index fc23bf2e..d0b6625d 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -1,23 +1,26 @@ /* * - * Bluetooth Common ISDN Access Profile (CIP) + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2003 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * * * $Id$ @@ -46,7 +49,6 @@ #include #include - static volatile sig_atomic_t __io_canceled = 0; static void sig_hup(int sig) @@ -387,7 +389,6 @@ static void cmd_loopback(int ctl, bdaddr_t *bdaddr, int argc, char **argv) ioctl(ctl, CMTPCONNDEL, &req); } - static struct { char *cmd; char *alt; diff --git a/tools/csr.c b/tools/csr.c index e2069cd7..60cba66b 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -1,26 +1,35 @@ /* * - * CSR BlueCore specific functions + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003 Marcel Holtmann + * Copyright (C) 2003-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -32,7 +41,6 @@ #include "csr.h" - static struct { uint16_t id; char *str; diff --git a/tools/csr.h b/tools/csr.h index 254f108e..b96dd0f7 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -1,24 +1,29 @@ /* * - * CSR BlueCore specific functions + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003 Marcel Holtmann + * Copyright (C) 2003-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ #define CSR_VARID_BUILDID 0x2819 diff --git a/tools/hciattach.c b/tools/hciattach.c index 926e3fab..7194ad6a 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -1,27 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H @@ -47,8 +51,8 @@ #include #include -#include #include +#include struct uart_t { char *type; diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 6393764b..d7b7513a 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1,28 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 9aaead0f..fd296afd 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -1,3 +1,36 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include @@ -11,23 +44,23 @@ int main(void) uint32_t event_mask[2]; uint32_t ocf_mask[4]; - // Packet types + /* Packet types */ memset((void *)&type_mask, 0, sizeof(type_mask)); hci_set_bit(HCI_EVENT_PKT, &type_mask); - + printf("Type mask: { 0x%x }\n", type_mask); - // Events + /* Events */ memset((void *)event_mask, 0, sizeof(event_mask)); - hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); - hci_set_bit(EVT_INQUIRY_RESULT, event_mask); + hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); + hci_set_bit(EVT_INQUIRY_RESULT, event_mask); - hci_set_bit(EVT_CONN_COMPLETE, event_mask); - hci_set_bit(EVT_CONN_REQUEST, event_mask); - hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); + hci_set_bit(EVT_CONN_COMPLETE, event_mask); + hci_set_bit(EVT_CONN_REQUEST, event_mask); + hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); - hci_set_bit(EVT_AUTH_COMPLETE, event_mask); - hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); + hci_set_bit(EVT_AUTH_COMPLETE, event_mask); + hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); hci_set_bit(EVT_CMD_COMPLETE, event_mask); hci_set_bit(EVT_CMD_STATUS, event_mask); @@ -38,7 +71,7 @@ int main(void) printf("Event mask: { 0x%x, 0x%x }\n", event_mask[0], event_mask[1]); - // OGF_LINK_CTL + /* OGF_LINK_CTL */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_INQUIRY, ocf_mask); hci_set_bit(OCF_REMOTE_NAME_REQ, ocf_mask); @@ -48,7 +81,7 @@ int main(void) printf("OGF_LINK_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - // OGF_LINK_POLICY + /* OGF_LINK_POLICY */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); @@ -56,7 +89,7 @@ int main(void) printf("OGF_LINK_POLICY: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - // OGF_HOST_CTL + /* OGF_HOST_CTL */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_READ_AUTH_ENABLE, ocf_mask); hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); @@ -68,7 +101,7 @@ int main(void) printf("OGF_HOST_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - // OGF_INFO_PARAM + /* OGF_INFO_PARAM */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_READ_LOCAL_VERSION, ocf_mask); hci_set_bit(OCF_READ_LOCAL_FEATURES, ocf_mask); @@ -79,7 +112,7 @@ int main(void) printf("OGF_INFO_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - // OGF_INFO_PARAM + /* OGF_INFO_PARAM */ memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); hci_set_bit(OCF_RESET_FAILED_CONTACT_COUNTER, ocf_mask); diff --git a/tools/hcitool.c b/tools/hcitool.c index 99355861..5cecdf7e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1,28 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 95a7c7d6..73b7e12c 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -1,23 +1,26 @@ /* * - * Bluetooth HID to HCI mode switching utility + * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2003-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * * * $Id$ @@ -38,7 +41,6 @@ #include #include - static char usbpath[PATH_MAX + 1] = "/proc/bus/usb"; struct usb_device_descriptor { @@ -75,7 +77,6 @@ struct usb_ctrltransfer { #define USB_TYPE_VENDOR 0x40 #define USB_DIR_OUT 0x00 - static char devpath[PATH_MAX + 1] = "/dev"; struct hiddev_devinfo { @@ -113,7 +114,6 @@ struct hiddev_usage_ref { #define HID_REPORT_TYPE_OUTPUT 2 - #define HCI 0 #define HID 1 @@ -132,7 +132,6 @@ struct device_info { struct device_id *id; }; - static int switch_hidproxy(struct device_info *dev) { struct usb_ctrltransfer ctrl; @@ -347,7 +346,6 @@ static int find_devices(int mode, struct device_info *dev, size_t size) return count; } - static void usage(void) { printf("hid2hci - Bluetooth HID to HCI mode switching utility\n\n"); diff --git a/tools/l2ping.c b/tools/l2ping.c index d5d7748b..85d12eee 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -1,30 +1,37 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -93,20 +100,20 @@ static void ping(char *svr) memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; addr.l2_bdaddr = bdaddr; - if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("Can't bind socket."); exit(1); - } + } str2ba(svr, &addr.l2_bdaddr); - if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("Can't connect."); exit(1); } /* Get local address */ opt = sizeof(addr); - if( getsockname(s, (struct sockaddr *)&addr, &opt) < 0 ) { + if (getsockname(s, (struct sockaddr *)&addr, &opt) < 0) { perror("Can't get local address."); exit(1); } @@ -115,7 +122,7 @@ static void ping(char *svr) printf("Ping: %s from %s (data size %d) ...\n", svr, str, size); /* Initialize buffer */ - for(i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) + for (i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) buf[i]=(i%40)+'A'; id = ident; @@ -132,34 +139,34 @@ static void ping(char *svr) gettimeofday(&tv_send, NULL); /* Send Echo Request */ - if( send(s, buf, size + L2CAP_CMD_HDR_SIZE, 0) <= 0 ){ + if (send(s, buf, size + L2CAP_CMD_HDR_SIZE, 0) <= 0) { perror("Send failed"); exit(1); } /* Wait for Echo Response */ lost = 0; - while( 1 ) { + while (1) { struct pollfd pf[1]; register int err; pf[0].fd = s; pf[0].events = POLLIN; - if( (err = poll(pf, 1, 10*1000)) < 0 ) { + if ((err = poll(pf, 1, 10*1000)) < 0) { perror("Poll failed"); exit(1); } - if( !err ){ + if (!err) { lost = 1; break; } - if( (err = recv(s, buf, sizeof(buf), 0)) < 0 ) { + if ((err = recv(s, buf, sizeof(buf), 0)) < 0) { perror("Recv failed"); exit(1); } - if( !err ){ + if (!err){ printf("Disconnected\n"); exit(1); } @@ -171,9 +178,9 @@ static void ping(char *svr) continue; /* Check type */ - if( cmd->code == L2CAP_ECHO_RSP ) + if (cmd->code == L2CAP_ECHO_RSP) break; - if( cmd->code == L2CAP_COMMAND_REJ ){ + if (cmd->code == L2CAP_COMMAND_REJ) { printf("Peer doesn't support Echo packets\n"); exit(1); } @@ -181,7 +188,7 @@ static void ping(char *svr) } sent_pkt++; - if( !lost ){ + if (!lost) { recv_pkt++; gettimeofday(&tv_recv, NULL); @@ -189,12 +196,12 @@ static void ping(char *svr) printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id, tv2fl(tv_diff)); - if( delay ) sleep(delay); + if (delay) sleep(delay); } else { printf("no response from %s: id %d\n", svr, id); } - if( ++id > 254 ) id = ident; + if (++id > 254) id = ident; } stat(0); } diff --git a/tools/ppporc.c b/tools/ppporc.c index 514ceb65..60aefd39 100644 --- a/tools/ppporc.c +++ b/tools/ppporc.c @@ -1,26 +1,35 @@ /* * - * PPP over Bluetooth RFCOMM + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -35,11 +44,9 @@ #include #include - extern int optind, opterr, optopt; extern char *optarg; - /* IO cancelation */ static volatile sig_atomic_t __io_canceled; @@ -53,7 +60,6 @@ static inline void io_cancel(void) __io_canceled = 1; } - /* Signal functions */ static void sig_hup(int sig) { @@ -66,7 +72,6 @@ static void sig_term(int sig) io_cancel(); } - /* Read exactly len bytes (Signal safe)*/ static inline int read_n(int fd, char *buf, int len) { @@ -88,7 +93,6 @@ static inline int read_n(int fd, char *buf, int len) return t; } - /* Write exactly len bytes (Signal safe)*/ static inline int write_n(int fd, char *buf, int len) { @@ -110,7 +114,6 @@ static inline int write_n(int fd, char *buf, int len) return t; } - /* Create the RFCOMM connection */ static int create_connection(bdaddr_t *bdaddr, uint8_t channel) { @@ -142,7 +145,6 @@ static int create_connection(bdaddr_t *bdaddr, uint8_t channel) return fd; } - /* Process the data from socket and pseudo tty */ static int process_data(int fd) { @@ -157,7 +159,7 @@ static int process_data(int fd) p[1].events = POLLIN | POLLERR | POLLHUP | POLLNVAL; err = 0; - + while (!__io_canceled) { p[0].revents = 0; p[1].revents = 0; @@ -186,7 +188,7 @@ static int process_data(int fd) if (p[1].revents) { if (p[1].revents & (POLLERR | POLLHUP | POLLNVAL)) - break; + break; r = read(fd, buf, sizeof(buf)); if (r < 0) { if (errno != EINTR && errno != EAGAIN) { @@ -204,13 +206,11 @@ static int process_data(int fd) return err; } - static void usage(void) { printf("Usage:\tppporc [channel]\n"); } - int main(int argc, char** argv) { struct sigaction sa; @@ -219,7 +219,6 @@ int main(int argc, char** argv) bdaddr_t bdaddr; uint8_t channel; - /* Parse command line options */ while ((opt = getopt(argc, argv, "h")) != EOF) { switch(opt) { @@ -246,12 +245,10 @@ int main(int argc, char** argv) exit(0); } - /* Initialize syslog */ openlog("ppporc", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); syslog(LOG_INFO, "PPP over RFCOMM"); - /* Initialize signals */ memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; @@ -266,7 +263,6 @@ int main(int argc, char** argv) sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); - syslog(LOG_INFO, "Connecting to %s", argv[0]); if ((fd = create_connection(&bdaddr, channel)) < 0) { diff --git a/tools/sdptool.c b/tools/sdptool.c index 87646cab..1dcdf8e4 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1,31 +1,32 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky - Copyright (C) 2002 Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From 72074e1e63e6cbe934c1e5eb9fd583ec81057a22 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 12:09:32 +0000 Subject: Unify copyright and license information --- hcid/dbus.c | 37 +++++++++++++++++++++++++++- hcid/hcid.h | 51 ++++++++++++++++++++------------------ hcid/kword.c | 56 ++++++++++++++++++++++++------------------ hcid/kword.h | 52 +++++++++++++++++++++------------------ hcid/lexer.l | 55 +++++++++++++++++++++++------------------ hcid/lib.c | 76 +++++++++++++++++++++++++++++++-------------------------- hcid/lib.h | 50 ++++++++++++++++++++----------------- hcid/main.c | 51 ++++++++++++++++++++------------------ hcid/parser.y | 55 +++++++++++++++++++++++------------------ hcid/security.c | 54 +++++++++++++++++++++++----------------- 10 files changed, 312 insertions(+), 225 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 3be67d26..a1756cc6 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -1,3 +1,37 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -9,9 +43,10 @@ #define DBUS_API_SUBJECT_TO_CHANGE #include -#include "hcid.h" #include "glib-ectomy.h" +#include "hcid.h" + static DBusConnection *connection; #define TIMEOUT (30 * 1000) // 30 seconds diff --git a/hcid/hcid.h b/hcid/hcid.h index f8233d70..41b62419 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -1,28 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #include diff --git a/hcid/kword.c b/hcid/kword.c index 09ad0573..13adfcc2 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -1,28 +1,36 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ /* - * $Id$ - */ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif #include #include diff --git a/hcid/kword.h b/hcid/kword.h index 67baaf13..88ceb8d1 100644 --- a/hcid/kword.h +++ b/hcid/kword.h @@ -1,28 +1,32 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ /* - * $Id$ - */ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ struct kword { char *str; diff --git a/hcid/lexer.l b/hcid/lexer.l index 3c9ed308..7f10ffda 100644 --- a/hcid/lexer.l +++ b/hcid/lexer.l @@ -1,31 +1,38 @@ %{ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include diff --git a/hcid/lib.c b/hcid/lib.c index bb85feb4..5fb4b5f2 100644 --- a/hcid/lib.c +++ b/hcid/lib.c @@ -1,28 +1,36 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ /* - * $Id$ - */ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif #include #include @@ -45,7 +53,7 @@ volatile sig_atomic_t __io_canceled; * Device name expansion * %d - device id */ -char * expand_name(char *dst, char *str, int dev_id) +char *expand_name(char *dst, char *str, int dev_id) { register int sp, np, olen; char *opt, buf[10]; @@ -75,16 +83,16 @@ char * expand_name(char *dst, char *str, int dev_id) default: sp++; continue; - } + } if (opt) { /* substitute */ olen = strlen(opt); - memcpy(dst + np, opt, olen); - np += olen; - } - sp += 2; - continue; + memcpy(dst + np, opt, olen); + np += olen; + } + sp += 2; + continue; case '\\': sp++; @@ -93,9 +101,9 @@ char * expand_name(char *dst, char *str, int dev_id) dst[np++] = str[sp++]; break; } - } - dst[np] = '\0'; - return dst; + } + dst[np] = '\0'; + return dst; } /* Returns current host name */ diff --git a/hcid/lib.h b/hcid/lib.h index 17f21a71..7091fb0d 100644 --- a/hcid/lib.h +++ b/hcid/lib.h @@ -1,27 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #include diff --git a/hcid/main.c b/hcid/main.c index 72453958..c679159d 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -1,28 +1,31 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/hcid/parser.y b/hcid/parser.y index 1848bd04..eb81ab22 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -1,31 +1,38 @@ %{ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/hcid/security.c b/hcid/security.c index 98f075f6..7ac0dc79 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -1,29 +1,37 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include -- cgit From e343e0fee7fdaf96156fb35b431ddb0503755843 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 12:15:04 +0000 Subject: Unify copyright and license information --- sdpd/cstate.c | 67 ++++++++++++++++++++++++++++--------------------------- sdpd/main.c | 62 +++++++++++++++++++++++---------------------------- sdpd/request.c | 66 ++++++++++++++++++++++++++---------------------------- sdpd/sdpd.h | 56 ++++++++++++++++++++++++---------------------- sdpd/service.c | 65 ++++++++++++++++++++++++++--------------------------- sdpd/servicedb.c | 68 ++++++++++++++++++++++++++------------------------------ 6 files changed, 187 insertions(+), 197 deletions(-) diff --git a/sdpd/cstate.c b/sdpd/cstate.c index 494292ac..8f9db218 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -1,37 +1,38 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - Fixes: - Guruprasad Krishnamurthy -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include @@ -44,8 +45,8 @@ typedef struct _sdp_cstate_list sdp_cstate_list_t; struct _sdp_cstate_list { sdp_cstate_list_t *next; - long timestamp; - sdp_buf_t buf; + long timestamp; + sdp_buf_t buf; }; static sdp_cstate_list_t *cstates; diff --git a/sdpd/main.c b/sdpd/main.c index 132539d5..b2262acd 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -1,38 +1,32 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - SDP server initialization and connection handling - - Fixes: - Guruprasad Krishnamurthy - Imre Deak -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/sdpd/request.c b/sdpd/request.c index f587cada..7bdecb7a 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -1,40 +1,38 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - SDP request handling code. - - Fixes: - Guruprasad Krishnamurthy - Dmitry Kasatkin - Continuation mechanism -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index c669e603..30eb1de3 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -1,30 +1,32 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifndef SDPD_H @@ -47,7 +49,7 @@ typedef struct request { int local; int sock; int mtu; - int flags; + int flags; char *buf; int len; } sdp_req_t; diff --git a/sdpd/service.c b/sdpd/service.c index c69aa509..0834122d 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -1,39 +1,38 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - Service registration requests. - - Fixes: - Guruprasad Krishnamurthy -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 36035a81..5a6469f5 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -1,42 +1,38 @@ /* - Service Discovery Protocol (SDP) - Copyright (C) 2002 Maxim Krasnyansky , Stephen Crane - - Based on original SDP implementation by Nokia Corporation. - Copyright (C) 2001,2002 Nokia Corporation. - Original author Guruprasad Krishnamurthy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - -/* - Service repository. - Has methods to create and clean the repository, besides - methods to add/find/modify/delete individual entries - - Fixes: - Guruprasad Krishnamurthy - Manel Guerrero Zapata -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Nokia Corporation + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2003 Stephen Crane + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include -- cgit From 1c78dbe58cb701c7a0463b3bafadadb3d08461f1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 12:30:24 +0000 Subject: Unify copyright and license information --- dund/dun.c | 51 ++++++++++++++++++++++++++++------------------- dund/dund.h | 45 +++++++++++++++++++++++------------------ dund/lib.h | 51 +++++++++++++++++++++++++---------------------- dund/main.c | 59 ++++++++++++++++++++++++++++++------------------------ dund/msdun.c | 49 +++++++++++++++++++++++++++------------------ dund/sdp.c | 49 +++++++++++++++++++++++++++------------------ pand/bnep.c | 55 ++++++++++++++++++++++++++++++-------------------- pand/main.c | 65 +++++++++++++++++++++++++++++++++--------------------------- pand/pand.h | 45 +++++++++++++++++++++++------------------ pand/sdp.c | 53 +++++++++++++++++++++++++++++-------------------- 10 files changed, 304 insertions(+), 218 deletions(-) diff --git a/dund/dun.c b/dund/dun.c index 8ef72ce6..1486d515 100644 --- a/dund/dun.c +++ b/dund/dun.c @@ -1,25 +1,36 @@ /* - dund - Bluetooth LAN/DUN daemon for BlueZ - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -239,7 +250,7 @@ static int kill_conn(struct rfcomm_dev_info *di, unsigned long arg) { bdaddr_t *dst = (bdaddr_t *) arg; pid_t pid; - + if (di->state == BT_CONNECTED && (di->flags & (1<flags & (1< - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ /* DUN scripts & commands */ diff --git a/dund/lib.h b/dund/lib.h index 5de0ba0f..3835d41c 100644 --- a/dund/lib.h +++ b/dund/lib.h @@ -1,29 +1,32 @@ -/* - RFCOMMd - RFCOMM daemon. - Copyright (C) 2001 Qualcomm Incorporated - - Written 2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ + #ifndef _DUND_LIB_H #define _DUND_LIB_H diff --git a/dund/main.c b/dund/main.c index 50bebf0f..e953ef28 100644 --- a/dund/main.c +++ b/dund/main.c @@ -1,23 +1,30 @@ /* - dund - Bluetooth LAN/DUN daemon for BlueZ - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H @@ -101,7 +108,7 @@ static int do_listen(void) if (use_sdp) dun_sdp_register(channel); - // Create RFCOMM socket + /* Create RFCOMM socket */ sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); if (sk < 0) { syslog(LOG_ERR, "Cannot create RFCOMM socket. %s(%d)", @@ -179,7 +186,7 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) if (use_cache && cache.valid && cache.channel) { /* Use cached channel */ ch = cache.channel; - + } else if (!channel) { syslog(LOG_INFO, "Searching for %s on %s", "LAP", dst); @@ -404,21 +411,21 @@ int main(int argc, char **argv) detach = 0; dst = strdup(optarg); break; - + case 'K': mode = KILL; detach = 0; dst = NULL; break; - + case 'P': channel = atoi(optarg); break; - + case 'S': src = strdup(optarg); break; - + case 'D': use_sdp = 0; break; @@ -515,7 +522,7 @@ int main(int argc, char **argv) int fd; if (fork()) exit(0); - + /* Direct stdin,stdout,stderr to '/dev/null' */ fd = open("/dev/null", O_RDWR); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); diff --git a/dund/msdun.c b/dund/msdun.c index 89fa3ff0..20749760 100644 --- a/dund/msdun.c +++ b/dund/msdun.c @@ -1,25 +1,36 @@ /* - dund - Bluetooth LAN/DUN daemon for BlueZ - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/dund/sdp.c b/dund/sdp.c index 9cac4efa..c5e8015a 100644 --- a/dund/sdp.c +++ b/dund/sdp.c @@ -1,25 +1,36 @@ /* - dund - Bluetooth LAN/DUN daemon for BlueZ - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/pand/bnep.c b/pand/bnep.c index 6833f941..be0d492a 100644 --- a/pand/bnep.c +++ b/pand/bnep.c @@ -1,25 +1,36 @@ /* - pand - Bluetooth PAN daemon for BlueZ - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -62,7 +73,7 @@ static struct { int bnep_str2svc(char *svc, uint16_t *uuid) { int i; - for (i=0; __svc[i].str; i++) + for (i = 0; __svc[i].str; i++) if (!strcasecmp(svc, __svc[i].str)) { *uuid = __svc[i].uuid; return 0; @@ -73,7 +84,7 @@ int bnep_str2svc(char *svc, uint16_t *uuid) char *bnep_svc2str(uint16_t uuid) { int i; - for (i=0; __svc[i].str; i++) + for (i = 0; __svc[i].str; i++) if (__svc[i].uuid == uuid) return __svc[i].str; return NULL; @@ -258,7 +269,7 @@ int bnep_create_connection(int sk, uint16_t role, uint16_t svc, char *dev) req = (void *) pkt; req->type = BNEP_CONTROL; req->ctrl = BNEP_SETUP_CONN_REQ; - req->uuid_size = 2; //16bit UUID + req->uuid_size = 2; /* 16bit UUID */ s = (void *) req->service; s->dst = htons(svc); s->src = htons(role); diff --git a/pand/main.c b/pand/main.c index 91a9a92c..88383331 100644 --- a/pand/main.c +++ b/pand/main.c @@ -1,23 +1,30 @@ /* - pand - Bluetooth PAN daemon for BlueZ - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ #ifdef HAVE_CONFIG_H @@ -45,8 +52,8 @@ #include "pand.h" -static uint16_t role = BNEP_SVC_PANU; // Local role (ie service) -static uint16_t service = BNEP_SVC_NAP; // Remote service +static uint16_t role = BNEP_SVC_PANU; /* Local role (ie service) */ +static uint16_t service = BNEP_SVC_NAP; /* Remote service */ static int detach = 1; static int persist; @@ -106,7 +113,7 @@ static int do_listen(void) if (use_sdp) bnep_sdp_register(role); - // Create L2CAP socket and bind it to PSM BNEP + /* Create L2CAP socket and bind it to PSM BNEP */ sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (sk < 0) { syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", @@ -290,7 +297,7 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) } else cache.valid--; } - + return r; } @@ -460,17 +467,17 @@ int main(int argc, char **argv) detach = 0; dst = strdup(optarg); break; - + case 'K': mode = KILL; detach = 0; dst = NULL; break; - + case 'S': src = strdup(optarg); break; - + case 'r': bnep_str2svc(optarg, &role); break; @@ -494,7 +501,7 @@ int main(int argc, char **argv) case 'i': strcpy(netdev, optarg); break; - + case 'n': detach = 0; break; @@ -536,7 +543,7 @@ int main(int argc, char **argv) case KILL: do_kill(dst); return 0; - + case NONE: printf(main_help); return 0; @@ -589,7 +596,7 @@ int main(int argc, char **argv) str2ba(dst, &cache.bdaddr); cache.valid = 1; } - + switch (mode) { case CONNECT: do_connect(); diff --git a/pand/pand.h b/pand/pand.h index 268316de..b0052676 100644 --- a/pand/pand.h +++ b/pand/pand.h @@ -1,23 +1,30 @@ /* - pand - Bluetooth PAN daemon for BlueZ - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ /* PAN scripts & commands */ diff --git a/pand/sdp.c b/pand/sdp.c index 16f092d9..dfa4c0c7 100644 --- a/pand/sdp.c +++ b/pand/sdp.c @@ -1,25 +1,36 @@ /* - pand - Bluetooth PAN daemon for BlueZ - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2, as - published by the Free Software Foundation. - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -159,8 +170,8 @@ int bnep_sdp_register(uint16_t role) return 0; } -// Search for PAN service. -// Returns 1 if service is found and 0 otherwise. +/* Search for PAN service. + * Returns 1 if service is found and 0 otherwise. */ int bnep_sdp_search(bdaddr_t *src, bdaddr_t *dst, uint16_t service) { sdp_list_t *srch, *rsp = NULL; -- cgit From b8707600fd45e0cda31654fc7b2932f29b28d1a1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 12:44:32 +0000 Subject: Unify copyright and license information --- test/attest.c | 41 ++++++++++++++++++++++------------------- test/hstest.c | 38 +++++++++++++++++++------------------- test/l2test.c | 55 +++++++++++++++++++++++++++++++------------------------ test/rctest.c | 52 ++++++++++++++++++++++++++++++---------------------- test/scotest.c | 54 ++++++++++++++++++++++++++++++------------------------ 5 files changed, 132 insertions(+), 108 deletions(-) diff --git a/test/attest.c b/test/attest.c index 078bb886..f4732cb6 100644 --- a/test/attest.c +++ b/test/attest.c @@ -1,26 +1,35 @@ /* * - * Programm for testing AT commands over Bluetooth RFCOMM + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2001-2002 Marcel Holtmann + * Copyright (C) 2001-2004 Marcel Holtmann * * * 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. + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; * - * 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. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -35,8 +44,6 @@ #include #include - - static int at_command(int fd, char *cmd, int to) { fd_set rfds; @@ -76,7 +83,6 @@ static int at_command(int fd, char *cmd, int to) return 0; } - static int open_device(char *device) { int fd; @@ -96,7 +102,6 @@ static int open_device(char *device) return fd; } - static int open_socket(bdaddr_t *bdaddr, uint8_t channel) { struct sockaddr_rc remote_addr, local_addr; @@ -105,7 +110,7 @@ static int open_socket(bdaddr_t *bdaddr, uint8_t channel) if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { printf("Can't create socket. %s (%d)\n", strerror(errno), errno); return -1; - } + } memset(&local_addr, 0, sizeof(local_addr)); local_addr.rc_family = AF_BLUETOOTH; @@ -129,13 +134,11 @@ static int open_socket(bdaddr_t *bdaddr, uint8_t channel) return s; } - static void usage(void) { printf("Usage:\n\tattest | [channel]\n"); } - int main(int argc, char *argv[]) { int fd; diff --git a/test/hstest.c b/test/hstest.c index 23bbf089..1272cd01 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -1,25 +1,35 @@ /* * - * Bluetooth Headset Test utility + * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002 Marcel Holtmann + * Copyright (C) 2002-2004 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -38,14 +48,12 @@ #include #include - static volatile int terminate = 0; static void sig_term(int sig) { terminate = 1; } - static int rfcomm_connect(bdaddr_t *src, bdaddr_t *dst, uint8_t channel) { struct sockaddr_rc addr; @@ -124,7 +132,6 @@ static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t return s; } - static void usage(void) { printf("Usage:\n" @@ -154,7 +161,6 @@ int main(int argc, char *argv[]) int dd, rd, sd, fd; uint16_t sco_handle, sco_mtu, vs; - switch (argc) { case 4: str2ba(argv[3], &bdaddr); @@ -182,7 +188,6 @@ int main(int argc, char *argv[]) filename = argv[2]; - hci_devba(0, &local); dd = hci_open_dev(0); hci_read_voice_setting(dd, &vs, 1000); @@ -194,7 +199,6 @@ int main(int argc, char *argv[]) return -1; } - if (strcmp(filename, "-") == 0) { switch (mode) { case PLAY: @@ -213,7 +217,6 @@ int main(int argc, char *argv[]) } } - memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = sig_term; @@ -224,7 +227,6 @@ int main(int argc, char *argv[]) sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); - if ((rd = rfcomm_connect(&local, &bdaddr, channel)) < 0) { perror("Can't connect RFCOMM channel"); return -1; @@ -232,7 +234,6 @@ int main(int argc, char *argv[]) fprintf(stderr, "RFCOMM channel connected\n"); - if ((sd = sco_connect(&local, &bdaddr, &sco_handle, &sco_mtu)) < 0) { perror("Can't connect SCO audio channel"); close(rd); @@ -240,7 +241,6 @@ int main(int argc, char *argv[]) } fprintf(stderr, "SCO audio channel connected (handle %d, mtu %d)\n", sco_handle, sco_mtu); - if (mode == RECORD) write(rd, "RING\r\n", 6); diff --git a/test/l2test.c b/test/l2test.c index 4d782532..f98e5109 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -1,30 +1,37 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/test/rctest.c b/test/rctest.c index 3d50ba95..4dcd4f3c 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -1,28 +1,36 @@ -/* - RFCOMM test tool - Copyright (C) 2002 Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include diff --git a/test/scotest.c b/test/scotest.c index 0c8d8da3..d245b9c0 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -1,30 +1,36 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation; - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY CLAIM, - OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER - RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE - USE OR PERFORMANCE OF THIS SOFTWARE. - - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, COPYRIGHTS, - TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. -*/ - /* - * $Id$ + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include -- cgit From 8c6eef637625edae6104dd7ff8d9fabc8d00475f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 13:40:58 +0000 Subject: Give udev some time to create the RFCOMM device nodes --- dund/dun.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dund/dun.c b/dund/dun.c index 1486d515..6611ad86 100644 --- a/dund/dun.c +++ b/dund/dun.c @@ -182,7 +182,7 @@ static int dun_create_tty(int sk, char *tty, int size) { struct sockaddr_rc sa; struct stat st; - int id, alen; + int id, alen, try = 3; struct rfcomm_dev_req req = { flags: (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP), @@ -205,10 +205,19 @@ static int dun_create_tty(int sk, char *tty, int size) return id; snprintf(tty, size, "/dev/rfcomm%d", id); - if (stat(tty, &st) < 0) { + while (stat(tty, &st) < 0) { snprintf(tty, size, "/dev/bluetooth/rfcomm/%d", id); if (stat(tty, &st) < 0) { snprintf(tty, size, "/dev/rfcomm%d", id); + if (try--) { + sleep(1); + continue; + } + + memset(&req, 0, sizeof(req)); + req.dev_id = id; + ioctl(sk, RFCOMMRELEASEDEV, &req); + return -1; } } -- cgit From 2281c91ec70741bd49a26f4f5bd92abceca49ed5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Apr 2004 16:16:19 +0000 Subject: Add the hidd utility --- Makefile.am | 2 +- configure.in | 2 +- hidd/Makefile.am | 11 ++ hidd/hidd.h | 32 ++++++ hidd/main.c | 321 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hidd/sdp.c | 93 ++++++++++++++++ 6 files changed, 459 insertions(+), 2 deletions(-) create mode 100644 hidd/Makefile.am create mode 100644 hidd/hidd.h create mode 100644 hidd/main.c create mode 100644 hidd/sdp.c diff --git a/Makefile.am b/Makefile.am index 0d627329..d20a2110 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -SUBDIRS := hcid tools rfcomm sdpd dund pand test scripts pcmcia +SUBDIRS := hcid tools rfcomm sdpd dund pand hidd test scripts pcmcia DISTCLEANFILES = conftest.c conftest diff --git a/configure.in b/configure.in index 9a6a9630..58b20bf1 100644 --- a/configure.in +++ b/configure.in @@ -25,4 +25,4 @@ AC_PATH_BLUEZ AC_PATH_DBUS -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/hidd/Makefile.am b/hidd/Makefile.am new file mode 100644 index 00000000..dfc7b3e1 --- /dev/null +++ b/hidd/Makefile.am @@ -0,0 +1,11 @@ +# +# $Id$ +# + +noinst_PROGRAMS = hidd + +hidd_SOURCES = main.c hidd.h sdp.c + +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ diff --git a/hidd/hidd.h b/hidd/hidd.h new file mode 100644 index 00000000..cd0c102c --- /dev/null +++ b/hidd/hidd.h @@ -0,0 +1,32 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#define L2CAP_PSM_HIDP_CTRL 0x11 +#define L2CAP_PSM_HIDP_INTR 0x13 + +int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req); diff --git a/hidd/main.c b/hidd/main.c new file mode 100644 index 00000000..46b25ec4 --- /dev/null +++ b/hidd/main.c @@ -0,0 +1,321 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "hidd.h" + +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ +} + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + +static int l2cap_listen(const bdaddr_t *bdaddr, unsigned short psm, int backlog) +{ + struct sockaddr_l2 addr; + struct l2cap_options opts; + int sk, lm = L2CAP_LM_MASTER; + + if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) + return -1; + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, bdaddr); + addr.l2_psm = htobs(psm); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(sk); + return -1; + } + + setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)); + + opts.imtu = HIDP_DEFAULT_MTU; + opts.omtu = HIDP_DEFAULT_MTU; + opts.flush_to = 0xffff; + + setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)); + + if (listen(sk, backlog) < 0) { + close(sk); + return -1; + } + + return sk; +} + +static int l2cap_accept(int sk, bdaddr_t *bdaddr) +{ + struct sockaddr_l2 addr; + socklen_t addrlen; + int nsk; + + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + + if ((nsk = accept(sk, (struct sockaddr *) &addr, &addrlen)) < 0) + return -1; + + if (bdaddr) + bacpy(bdaddr, &addr.l2_bdaddr); + + return nsk; +} + +static int create(int ctl, int csk, int isk, int timeout) +{ + struct hidp_connadd_req req; + struct sockaddr_l2 addr; + socklen_t addrlen; + bdaddr_t src, dst; + char bda[18]; + int err; + + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + + if (getsockname(csk, (struct sockaddr *) &addr, &addrlen) < 0) + return -1; + + bacpy(&src, &addr.l2_bdaddr); + + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + + if (getpeername(csk, (struct sockaddr *) &addr, &addrlen) < 0) + return -1; + + bacpy(&dst, &addr.l2_bdaddr); + + ba2str(&dst, bda); + syslog(LOG_INFO, "New HID connection from %s", bda); + + memset(&req, 0, sizeof(req)); + req.ctrl_sock = csk; + req.intr_sock = isk; + req.flags = 0; + req.idle_to = timeout * 60; + + get_hid_device_info(&src, &dst, &req); + + err = ioctl(ctl, HIDPCONNADD, &req); + + if (req.rd_data) + free(req.rd_data); + + return err; +} + +static void run(int ctl, int csk, int isk, int timeout) +{ + struct pollfd p[2]; + short events; + int err, ncsk, nisk; + + p[0].fd = csk; + p[0].events = POLLIN | POLLERR | POLLHUP; + + p[1].fd = isk; + p[1].events = POLLIN | POLLERR | POLLHUP; + + while (!__io_canceled) { + p[0].revents = 0; + p[1].revents = 0; + + err = poll(p, 2, 100); + if (err <= 0) + continue; + + events = p[0].revents | p[1].revents; + + if (events & POLLIN) { + ncsk = l2cap_accept(csk, NULL); + nisk = l2cap_accept(isk, NULL); + + err = create(ctl, ncsk, nisk, timeout); + if (err < 0) + syslog(LOG_ERR, "HID create error %d (%s)", + errno, strerror(errno)); + + close(ncsk); + close(nisk); + } + } +} + +static void usage(void) +{ + printf("hidd - Bluetooth HID daemon\n\n"); + + printf("Usage:\n" + "\thidd [options]\n" + "\n"); + + printf("Options:\n" + "\t-i Local HCI device or BD Address\n" + "\t-t Set idle timeout (in minutes)\n" + "\t-n, --nodaemon Don't fork daemon to background\n" + "\t-h, --help Display help\n" + "\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "nodaemon", 0, 0, 'n' }, + { "timeout", 1, 0, 't' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct sigaction sa; + bdaddr_t bdaddr; + char addr[18]; + int log_option = LOG_NDELAY | LOG_PID; + int opt, fd, ctl, csk, isk; + int daemon = 1, timeout = 30; + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt = getopt_long(argc, argv, "+i:nt:h", main_options, NULL)) != -1) { + switch(opt) { + case 'i': + if (!strncasecmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); + break; + case 'n': + daemon = 0; + break; + case 't': + timeout = atoi(optarg); + break; + case 'h': + usage(); + exit(0); + default: + exit(0); + } + } + + ba2str(&bdaddr, addr); + + csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, 10); + if (csk < 0) { + perror("Can't listen on HID control channel"); + exit(1); + } + + isk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_INTR, 10); + if (isk < 0) { + perror("Can't listen on HID interrupt channel"); + close(csk); + exit(1); + } + + ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP); + if (ctl < 0) { + perror("Can't open HIDP control socket"); + close(csk); + close(isk); + exit(1); + } + + if (daemon) { + if (fork()) + exit(0); + + fd = open("/dev/null", O_RDWR); + dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); + close(fd); + + setsid(); + chdir("/"); + } else + log_option |= LOG_PERROR; + + openlog("hidd", log_option, LOG_DAEMON); + + if (bacmp(&bdaddr, BDADDR_ANY)) + syslog(LOG_INFO, "Bluetooth HID daemon (%s)", addr); + else + syslog(LOG_INFO, "Bluetooth HID daemon"); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + run(ctl, csk, isk, timeout); + + syslog(LOG_INFO, "Exit"); + + close(ctl); + close(csk); + close(isk); + + return 0; +} diff --git a/hidd/sdp.c b/hidd/sdp.c new file mode 100644 index 00000000..4c92aa66 --- /dev/null +++ b/hidd/sdp.c @@ -0,0 +1,93 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "hidd.h" + +int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req) +{ + sdp_session_t *s; + sdp_list_t *srch, *attrs, *rsp; + sdp_record_t *rec; + sdp_data_t *pdlist; + uuid_t svclass; + uint16_t attr; + int err; + + s = sdp_connect(src, dst, 0); + if (!s) + return -1; + + sdp_uuid16_create(&svclass, HID_SVCLASS_ID); + srch = sdp_list_append(NULL, &svclass); + + attr = 0x0206; + attrs = sdp_list_append(NULL, &attr); + + err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); + + sdp_close(s); + + if (err || !rsp) + return -1; + + rec = (sdp_record_t *) rsp->data; + + pdlist = sdp_data_get(rec, 0x0206); + pdlist = pdlist->val.dataseq; + pdlist = pdlist->val.dataseq; + pdlist = pdlist->next; + + req->rd_data = malloc(pdlist->unitSize); + if (req->rd_data) { + memcpy(req->rd_data, (unsigned char *) pdlist->val.str, pdlist->unitSize); + req->rd_size = pdlist->unitSize; + } + + return 0; +} -- cgit From 417d75ccb5aa92384fd75651b6cd8a53193439e4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Apr 2004 20:14:21 +0000 Subject: Change prefix for bluepin, add option for D-Bus PIN helper and set rswitch --- hcid/hcid.conf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hcid/hcid.conf b/hcid/hcid.conf index 89645993..37892256 100644 --- a/hcid/hcid.conf +++ b/hcid/hcid.conf @@ -23,7 +23,10 @@ options { pairing multi; # PIN helper - pin_helper /bin/bluepin; + pin_helper /usr/bin/bluepin; + + # D-Bus PIN helper + #dbus_pin_helper; } # Default settings for HCI devices @@ -61,7 +64,7 @@ device { # #lp hold,sniff; # - lp hold,sniff,park; + lp rswitch,hold,sniff,park; # Authentication and Encryption #auth enable; -- cgit From bc085054220d80e9308fe5f4c2260e7ccc06e7e3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 May 2004 03:36:18 +0000 Subject: Add Bluetooth backend for CUPS --- Makefile.am | 2 +- acinclude.m4 | 65 +++++++++--- configure.in | 4 +- cups/Makefile.am | 16 +++ cups/hcrp.c | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ cups/main.c | 188 +++++++++++++++++++++++++++++++++ cups/sdp.c | 155 +++++++++++++++++++++++++++ cups/spp.c | 103 ++++++++++++++++++ 8 files changed, 834 insertions(+), 15 deletions(-) create mode 100644 cups/Makefile.am create mode 100644 cups/hcrp.c create mode 100644 cups/main.c create mode 100644 cups/sdp.c create mode 100644 cups/spp.c diff --git a/Makefile.am b/Makefile.am index d20a2110..1171035e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -SUBDIRS := hcid tools rfcomm sdpd dund pand hidd test scripts pcmcia +SUBDIRS := hcid tools rfcomm sdpd dund pand hidd cups test scripts pcmcia DISTCLEANFILES = conftest.c conftest diff --git a/acinclude.m4 b/acinclude.m4 index dc885de8..5004e983 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -15,14 +15,18 @@ AC_DEFUN(AC_PREFIX_BLUEZ, [ if test "$mandir" = '${prefix}/man'; then AC_SUBST([mandir], ['${prefix}/share/man']) fi + + bluez_prefix="$ac_default_prefix" + else + bluez_prefix="$prefix" fi ]) AC_DEFUN(AC_PATH_BLUEZ, [ AC_ARG_WITH(bluez, [ --with-bluez=DIR BlueZ library is installed in DIR], [ if (test "$withval" = "yes"); then - bluez_includes=/usr/include - bluez_libraries=/usr/lib + bluez_includes=$bluez_prefix/include + bluez_libraries=$bluez_prefix/lib else bluez_includes=$withval/include bluez_libraries=$withval/lib @@ -62,15 +66,14 @@ AC_DEFUN(AC_PATH_BLUEZ, [ ]) AC_DEFUN(AC_PATH_DBUS, [ - AC_ARG_ENABLE(dbus, [ --enable-dbus enable D-BUS support], - dbus_enable=$enableval, - dbus_enable=no - ) + AC_ARG_ENABLE(dbus, [ --enable-dbus enable D-BUS support], [ + dbus_enable=$enableval + ]) AC_ARG_WITH(dbus, [ --with-dbus=DIR D-BUS library is installed in DIR], [ if (test "$withval" = "yes"); then - dbus_includes=/usr/include - dbus_libraries=/usr/lib + dbus_includes=$bluez_prefix/include + dbus_libraries=$bluez_prefix/lib else dbus_includes=$withval/include dbus_libraries=$withval/lib @@ -86,7 +89,7 @@ AC_DEFUN(AC_PATH_DBUS, [ if test -n "$dbus_includes"; then CFLAGS="$CFLAGS -I$dbus_includes -I$dbus_includes/dbus-1.0" else - CFLAGS="$CFLAGS -I/usr/include/dbus-1.0" + CFLAGS="$CFLAGS -I$bluez_prefix/include/dbus-1.0 -I/usr/include/dbus-1.0" fi CFLAGS="$CFLAGS -DDBUS_API_SUBJECT_TO_CHANGE" @@ -95,7 +98,7 @@ AC_DEFUN(AC_PATH_DBUS, [ CFLAGS="$CFLAGS -I$dbus_libraries/dbus-1.0/include" LDFLAGS="$LDFLAGS -L$dbus_libraries" else - CFLAGS="$CFLAGS -I/usr/lib/dbus-1.0/include" + CFLAGS="$CFLAGS -I$bluez_prefix/include/dbus-1.0 -I/usr/lib/dbus-1.0/include" fi if test "$dbus_enable" = "yes"; then @@ -111,7 +114,7 @@ AC_DEFUN(AC_PATH_DBUS, [ if test -n "$dbus_includes"; then DBUS_INCLUDES="-I$dbus_includes -I$dbus_includes/dbus-1.0" else - DBUS_INCLUDES="-I/usr/include/dbus-1.0" + DBUS_INCLUDES="-I$bluez_prefix/include/dbus-1.0 -I/usr/include/dbus-1.0" fi LDFLAGS=$ac_save_LDFLAGS @@ -120,7 +123,7 @@ AC_DEFUN(AC_PATH_DBUS, [ DBUS_LDFLAGS="-L$dbus_libraries" DBUS_LIBS="-L$dbus_libraries $DBUS_LIBS" else - DBUS_INCLUDES="$DBUS_INCLUDES -I/usr/lib/dbus-1.0/include" + DBUS_INCLUDES="$DBUS_INCLUDES -I$bluez_prefix/include/dbus-1.0 -I/usr/lib/dbus-1.0/include" fi AC_SUBST(DBUS_INCLUDES) @@ -129,3 +132,41 @@ AC_DEFUN(AC_PATH_DBUS, [ AM_CONDITIONAL(DBUS, test "$dbus_enable" = "yes") ]) + +AC_DEFUN(AC_PATH_CUPS, [ + AC_ARG_ENABLE(cups, [ --enable-cups enable CUPS support], [ + cups_enable=$enableval + cups_prefix=/usr + ]) + + AC_ARG_WITH(cups, [ --with-cups=DIR CUPS is installed in DIR], [ + if (test "$withval" = "yes"); then + cups_prefix=/usr + else + cups_prefix=$withval + fi + cups_enable=yes + ]) + + CUPS_BACKEND_DIR="" + + if test "$cups_enable" = "yes"; then + AC_MSG_CHECKING(for CUPS backend directory) + + if (test -d "$cups_prefix/lib/cups/backend"); then + CUPS_BACKEND_DIR="$cups_prefix/lib/cups/backend" + else + cups_enable=no + fi + + if test "$cups_enable" = "yes"; then + AC_MSG_RESULT($CUPS_BACKEND_DIR) + else + AC_MSG_RESULT($cups_enable) + fi + fi + + AC_SUBST(CUPS_BACKEND_DIR) + + AM_CONDITIONAL(CUPS, test "$cups_enable" = "yes") +]) diff --git a/configure.in b/configure.in index 58b20bf1..fb6db57d 100644 --- a/configure.in +++ b/configure.in @@ -22,7 +22,7 @@ AC_PROG_YACC AM_PROG_LEX AC_PATH_BLUEZ - AC_PATH_DBUS +AC_PATH_CUPS -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) diff --git a/cups/Makefile.am b/cups/Makefile.am new file mode 100644 index 00000000..2e4ba707 --- /dev/null +++ b/cups/Makefile.am @@ -0,0 +1,16 @@ +# +# $Id$ +# + +noinst_PROGRAMS = bluetooth + +bluetooth_SOURCES = main.c sdp.c spp.c hcrp.c + +LDFLAGS = @BLUEZ_LIBS@ + +INCLUDES = @BLUEZ_INCLUDES@ + +if CUPS +install-data-local: bluetooth + $(INSTALL) -D -m 755 $(srcdir)/bluetooth $(DESTDIR)@CUPS_BACKEND_DIR@/bluetooth +endif diff --git a/cups/hcrp.c b/cups/hcrp.c new file mode 100644 index 00000000..f69800a7 --- /dev/null +++ b/cups/hcrp.c @@ -0,0 +1,316 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define HCRP_PDU_CREDIT_GRANT 0x0001 +#define HCRP_PDU_CREDIT_REQUEST 0x0002 +#define HCRP_PDU_GET_LPT_STATUS 0x0005 + +#define HCRP_STATUS_FEATURE_UNSUPPORTED 0x0000 +#define HCRP_STATUS_SUCCESS 0x0001 +#define HCRP_STATUS_CREDIT_SYNC_ERROR 0x0002 +#define HCRP_STATUS_GENERIC_FAILURE 0xffff + +struct hcrp_pdu_hdr { + uint16_t pid; + uint16_t tid; + uint16_t plen; +} __attribute__ ((packed)); +#define HCRP_PDU_HDR_SIZE 6 + +struct hcrp_credit_grant_cp { + uint32_t credit; +} __attribute__ ((packed)); +#define HCRP_CREDIT_GRANT_CP_SIZE 4 + +struct hcrp_credit_grant_rp { + uint16_t status; +} __attribute__ ((packed)); +#define HCRP_CREDIT_GRANT_RP_SIZE 2 + +struct hcrp_credit_request_rp { + uint16_t status; + uint32_t credit; +} __attribute__ ((packed)); +#define HCRP_CREDIT_REQUEST_RP_SIZE 6 + +struct hcrp_get_lpt_status_rp { + uint16_t status; + uint8_t lpt_status; +} __attribute__ ((packed)); +#define HCRP_GET_LPT_STATUS_RP_SIZE 3 + +static int hcrp_credit_grant(int sk, uint16_t tid, uint32_t credit) +{ + struct hcrp_pdu_hdr hdr; + struct hcrp_credit_grant_cp cp; + struct hcrp_credit_grant_rp rp; + unsigned char buf[128]; + int len; + + hdr.pid = htons(HCRP_PDU_CREDIT_GRANT); + hdr.tid = htons(tid); + hdr.plen = htons(HCRP_CREDIT_GRANT_CP_SIZE); + cp.credit = credit; + memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE); + memcpy(buf + HCRP_PDU_HDR_SIZE, &cp, HCRP_CREDIT_GRANT_CP_SIZE); + write(sk, buf, HCRP_PDU_HDR_SIZE + HCRP_CREDIT_GRANT_CP_SIZE); + + len = read(sk, buf, sizeof(buf)); + memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE); + memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_CREDIT_GRANT_RP_SIZE); + + if (ntohs(rp.status) != HCRP_STATUS_SUCCESS) { + errno = EIO; + return -1; + } + + return 0; +} + +static int hcrp_credit_request(int sk, uint16_t tid, uint32_t *credit) +{ + struct hcrp_pdu_hdr hdr; + struct hcrp_credit_request_rp rp; + unsigned char buf[128]; + int len; + + hdr.pid = htons(HCRP_PDU_CREDIT_REQUEST); + hdr.tid = htons(tid); + hdr.plen = htons(0); + memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE); + write(sk, buf, HCRP_PDU_HDR_SIZE); + + len = read(sk, buf, sizeof(buf)); + memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE); + memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_CREDIT_REQUEST_RP_SIZE); + + if (ntohs(rp.status) != HCRP_STATUS_SUCCESS) { + errno = EIO; + return -1; + } + + if (credit) + *credit = ntohl(rp.credit); + + return 0; +} + +static int hcrp_get_lpt_status(int sk, uint16_t tid, uint8_t *lpt_status) +{ + struct hcrp_pdu_hdr hdr; + struct hcrp_get_lpt_status_rp rp; + unsigned char buf[128]; + int len; + + hdr.pid = htons(HCRP_PDU_GET_LPT_STATUS); + hdr.tid = htons(tid); + hdr.plen = htons(0); + memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE); + write(sk, buf, HCRP_PDU_HDR_SIZE); + + len = read(sk, buf, sizeof(buf)); + memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE); + memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_GET_LPT_STATUS_RP_SIZE); + + if (ntohs(rp.status) != HCRP_STATUS_SUCCESS) { + errno = EIO; + return -1; + } + + if (lpt_status) + *lpt_status = rp.lpt_status; + + return 0; +} + +static inline int hcrp_get_next_tid(int tid) +{ + if (tid > 0xf000) + return 0; + else + return tid + 1; +} + +int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies) +{ + struct sockaddr_l2 addr; + struct l2cap_options opts; + unsigned char buf[2048]; + int i, size, ctrl_sk, data_sk, mtu, count, len, timeout = 0; + uint8_t status; + uint16_t tid = 0; + uint32_t tmp, credit = 0; + + if ((ctrl_sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) { + perror("ERROR: Can't create socket"); + return 1; + } + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, src); + addr.l2_psm = 0; + + if (bind(ctrl_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("ERROR: Can't bind socket"); + close(ctrl_sk); + return 1; + } + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, dst); + addr.l2_psm = htobs(ctrl_psm); + + if (connect(ctrl_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("ERROR: Can't connect to device"); + close(ctrl_sk); + return 1; + } + + if ((data_sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) { + perror("ERROR: Can't create socket"); + close(ctrl_sk); + return 1; + } + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, src); + addr.l2_psm = 0; + + if (bind(data_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("ERROR: Can't bind socket"); + close(data_sk); + close(ctrl_sk); + return 1; + } + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, dst); + addr.l2_psm = htobs(data_psm); + + if (connect(data_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("ERROR: Can't connect to device"); + close(data_sk); + close(ctrl_sk); + return 1; + } + + size = sizeof(opts); + + if (getsockopt(data_sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) { + perror("ERROR: Can't get socket options"); + close(data_sk); + close(ctrl_sk); + return 1; + } + + mtu = opts.omtu; + + /* Ignore SIGTERM signals if printing from stdin */ + if (fd == 0) { +#ifdef HAVE_SIGSET + sigset(SIGTERM, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, SIG_IGN); +#endif /* HAVE_SIGSET */ + } + + tid = hcrp_get_next_tid(tid); + if (hcrp_credit_grant(ctrl_sk, tid, 0) < 0) { + fprintf(stderr, "ERROR: Can't grant initial credits\n"); + close(data_sk); + close(ctrl_sk); + return 1; + } + + for (i = 0; i < copies; i++) { + + if (fd != 0) { + fprintf(stderr, "PAGE: 1 1\n"); + lseek(fd, 0, SEEK_SET); + } + + while (1) { + if (credit < mtu) { + tid = hcrp_get_next_tid(tid); + if (!hcrp_credit_request(ctrl_sk, tid, &tmp)) { + credit += tmp; + timeout = 0; + } + } + + if (!credit) { + if (timeout++ > 300) { + tid = hcrp_get_next_tid(tid); + if (!hcrp_get_lpt_status(ctrl_sk, tid, &status)) + fprintf(stderr, "ERROR: LPT status 0x%02x\n", status); + break; + } + + sleep(1); + continue; + } + + count = read(fd, buf, (credit > mtu) ? mtu : credit); + if (count <= 0) + break; + + len = write(data_sk, buf, count); + if (len != count) + fprintf(stderr, "ERROR: Can't send complete data\n"); + + credit -= len; + } + + } + + close(data_sk); + close(ctrl_sk); + + return 0; +} diff --git a/cups/main.c b/cups/main.c new file mode 100644 index 00000000..352ea4ea --- /dev/null +++ b/cups/main.c @@ -0,0 +1,188 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel); +int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm); + +int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies); +int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies); + +static void list_devices(void) +{ +} + +/* + * Usage: printer-uri job-id user title copies options [file] + * + */ + +int main(int argc, char *argv[]) +{ + sdp_session_t *sdp; + bdaddr_t bdaddr; + unsigned short ctrl_psm, data_psm; + uint8_t channel, b[6]; + char *ptr, str[3], device[18], service[12]; + int i, err, fd, copies, proto; + + /* Make sure status messages are not buffered */ + setbuf(stderr, NULL); + + /* Ignore SIGPIPE signals */ +#ifdef HAVE_SIGSET + sigset(SIGPIPE, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); +#endif /* HAVE_SIGSET */ + + if (argc == 1) { + list_devices(); + return 0; + } + + if (argc < 6 || argc > 7) { + fprintf(stderr, "Usage: bluetooth job-id user title copies options [file]\n"); + return 1; + } + + if (argc == 6) { + fd = 0; + copies = 1; + } else { + if ((fd = open(argv[6], O_RDONLY)) < 0) { + perror("ERROR: Unable to open print file"); + return 1; + } + copies = atoi(argv[4]); + } + + if (strncasecmp(argv[0], "bluetooth://", 12)) { + fprintf(stderr, "ERROR: No device URI found\n"); + return 1; + } + + ptr = argv[0] + 12; + for (i = 0; i < 6; i++) { + strncpy(str, ptr, 2); + b[i] = (uint8_t) strtol(str, NULL, 16); + ptr += 2; + } + sprintf(device, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", + b[0], b[1], b[2], b[3], b[4], b[5]); + + str2ba(device, &bdaddr); + + ptr = strchr(ptr, '/'); + if (ptr) { + strncpy(service, ptr + 1, 12); + + if (!strncasecmp(ptr + 1, "spp", 3)) + proto = 1; + else if (!strncasecmp(ptr + 1, "hcrp", 4)) + proto = 2; + else + proto = 0; + } else { + strcpy(service, "auto"); + proto = 0; + } + + fprintf(stderr, "DEBUG: %s device %s service %s fd %d copies %d\n", + argv[0], device, service, fd, copies); + + sdp = sdp_connect(BDADDR_ANY, &bdaddr, 0 /*SDP_RETRY_IF_BUSY*/); + if (!sdp) { + fprintf(stderr, "ERROR: Can't open Bluetooth connection\n"); + return 1; + } + + switch (proto) { + case 1: + err = sdp_search_spp(sdp, &channel); + break; + case 2: + err = sdp_search_hcrp(sdp, &ctrl_psm, &data_psm); + break; + default: + proto = 2; + err = sdp_search_hcrp(sdp, &ctrl_psm, &data_psm); + if (err) { + proto = 1; + err = sdp_search_spp(sdp, &channel); + } + break; + } + + sdp_close(sdp); + + if (err) { + fprintf(stderr, "ERROR: Can't get service information\n"); + return 1; + } + + switch (proto) { + case 1: + err = spp_print(BDADDR_ANY, &bdaddr, channel, fd, copies); + break; + case 2: + err = hcrp_print(BDADDR_ANY, &bdaddr, ctrl_psm, data_psm, fd, copies); + break; + default: + err = 1; + fprintf(stderr, "ERROR: Unsupported protocol\n"); + break; + } + + if (fd != 0) + close(fd); + + if (!err) + fprintf(stderr, "INFO: Ready to print\n"); + + return err; +} diff --git a/cups/sdp.c b/cups/sdp.c new file mode 100644 index 00000000..7491ab1f --- /dev/null +++ b/cups/sdp.c @@ -0,0 +1,155 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define HCRP_CTRL_UUID 0x0012 +#define HCRP_DATA_UUID 0x0014 + +#define HCR_PROFILE_ID 0x1125 +#define HCR_PRINT_SVCLASS_ID 0x1126 + +#define SDP_ATTR_ADD_PROTO_DESC_LIST 0x000d + +static int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap) +{ + sdp_data_t *pdlist, *curr; + sdp_list_t *ap = 0; + + pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST); + if (pdlist == NULL) { + errno = ENODATA; + return -1; + } + + pdlist = pdlist->val.dataseq; + + for (; pdlist; pdlist = pdlist->next) { + sdp_list_t *pds = 0; + for (curr = pdlist->val.dataseq; curr; curr = curr->next) + pds = sdp_list_append(pds, curr->val.dataseq); + ap = sdp_list_append(ap, pds); + } + + *pap = ap; + + return 0; +} + +int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm) +{ + sdp_list_t *srch, *attrs, *rsp; + uuid_t svclass; + uint16_t attr1, attr2; + int err; + + if (!sdp) + return -1; + + sdp_uuid16_create(&svclass, HCR_PRINT_SVCLASS_ID); + srch = sdp_list_append(NULL, &svclass); + + attr1 = SDP_ATTR_PROTO_DESC_LIST; + attrs = sdp_list_append(NULL, &attr1); + attr2 = SDP_ATTR_ADD_PROTO_DESC_LIST; + attrs = sdp_list_append(attrs, &attr2); + + err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); + if (err) + return -1; + + for (; rsp; rsp = rsp->next) { + sdp_record_t *rec = (sdp_record_t *) rsp->data; + sdp_list_t *protos; + + if (!sdp_get_access_protos(rec, &protos)) { + unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID); + if (psm > 0) { + *ctrl_psm = psm; + } + } + + if (!sdp_get_add_access_protos(rec, &protos)) { + unsigned short psm = sdp_get_proto_port(protos, L2CAP_UUID); + if (psm > 0 && *ctrl_psm > 0) { + *data_psm = psm; + return 0; + } + } + } + + return -1; +} + +int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel) +{ + sdp_list_t *srch, *attrs, *rsp; + uuid_t svclass; + uint16_t attr; + int err; + + if (!sdp) + return -1; + + sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID); + srch = sdp_list_append(NULL, &svclass); + + attr = SDP_ATTR_PROTO_DESC_LIST; + attrs = sdp_list_append(NULL, &attr); + + err = sdp_service_search_attr_req(sdp, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); + if (err) + return -1; + + for (; rsp; rsp = rsp->next) { + sdp_record_t *rec = (sdp_record_t *) rsp->data; + sdp_list_t *protos; + + if (!sdp_get_access_protos(rec, &protos)) { + uint8_t ch = sdp_get_proto_port(protos, RFCOMM_UUID); + if (ch > 0) { + *channel = ch; + return 0; + } + } + } + + return -1; +} diff --git a/cups/spp.c b/cups/spp.c new file mode 100644 index 00000000..ec8fcdd5 --- /dev/null +++ b/cups/spp.c @@ -0,0 +1,103 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies) +{ + struct sockaddr_rc addr; + unsigned char buf[2048]; + int i, sk, len; + + if ((sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { + perror("ERROR: Can't create socket"); + return 1; + } + + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, src); + addr.rc_channel = 0; + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("ERROR: Can't bind socket"); + close(sk); + return 1; + } + + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, dst); + addr.rc_channel = channel; + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("ERROR: Can't connect to device"); + close(sk); + return 1; + } + + /* Ignore SIGTERM signals if printing from stdin */ + if (fd == 0) { +#ifdef HAVE_SIGSET + sigset(SIGTERM, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, SIG_IGN); +#endif /* HAVE_SIGSET */ + } + + for (i = 0; i < copies; i++) { + + if (fd != 0) { + fprintf(stderr, "PAGE: 1 1\n"); + lseek(fd, 0, SEEK_SET); + } + + while ((len = read(fd, buf, sizeof(buf))) > 0) { + write(sk, buf, len); + } + + } + + close(sk); + + return 0; +} -- cgit From 8566cd3b75ff3a2d453397e630f6670d7d3f02f7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 May 2004 21:45:21 +0000 Subject: Moved the sdp_get_add_access_protos() function into the Bluetooth library --- cups/sdp.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/cups/sdp.c b/cups/sdp.c index 7491ab1f..3a79d7b6 100644 --- a/cups/sdp.c +++ b/cups/sdp.c @@ -46,33 +46,6 @@ #define HCR_PROFILE_ID 0x1125 #define HCR_PRINT_SVCLASS_ID 0x1126 -#define SDP_ATTR_ADD_PROTO_DESC_LIST 0x000d - -static int sdp_get_add_access_protos(const sdp_record_t *rec, sdp_list_t **pap) -{ - sdp_data_t *pdlist, *curr; - sdp_list_t *ap = 0; - - pdlist = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST); - if (pdlist == NULL) { - errno = ENODATA; - return -1; - } - - pdlist = pdlist->val.dataseq; - - for (; pdlist; pdlist = pdlist->next) { - sdp_list_t *pds = 0; - for (curr = pdlist->val.dataseq; curr; curr = curr->next) - pds = sdp_list_append(pds, curr->val.dataseq); - ap = sdp_list_append(ap, pds); - } - - *pap = ap; - - return 0; -} - int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm) { sdp_list_t *srch, *attrs, *rsp; -- cgit From 7aebf78831f16192d979910c6d359e9f76e51a54 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 May 2004 21:55:36 +0000 Subject: Use definitions from the Bluetooth library --- cups/sdp.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cups/sdp.c b/cups/sdp.c index 3a79d7b6..c636f7d2 100644 --- a/cups/sdp.c +++ b/cups/sdp.c @@ -40,12 +40,6 @@ #include #include -#define HCRP_CTRL_UUID 0x0012 -#define HCRP_DATA_UUID 0x0014 - -#define HCR_PROFILE_ID 0x1125 -#define HCR_PRINT_SVCLASS_ID 0x1126 - int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm) { sdp_list_t *srch, *attrs, *rsp; -- cgit From 596ce96eefb0a1f7feda4ecd29a49d8bc6792cf3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 3 May 2004 13:25:14 +0000 Subject: Fix default baudrate for ST devices --- tools/hciattach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 7194ad6a..3e8be20a 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -779,7 +779,7 @@ static int st(int fd, struct uart_t *u, struct termios *ti) break; default: cmd[4] = 0x10; - u->speed = 57600; + u->speed = 115200; break; } -- cgit From 014f95443e8c29ffd6f28d7f3eac916b16f96b00 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 08:30:41 +0000 Subject: Fix section number --- tools/hciconfig.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index b8b780ee..3c6c96d8 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -1,4 +1,4 @@ -.TH HCICONFIG 1 "Nov 11 2002" BlueZ "Linux System Administration" +.TH HCICONFIG 8 "Nov 11 2002" BlueZ "Linux System Administration" .SH NAME hciconfig \- configure Bluetooth devices .SH SYNOPSIS -- cgit From 63acfaaadfcf85aaba0fb63b9a600d89819cd47b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 17:51:28 +0000 Subject: Use one init.d script --- scripts/Makefile.am | 8 ++--- scripts/bluetooth.rc.deb | 86 --------------------------------------------- scripts/bluetooth.rc.rh | 90 ------------------------------------------------ 3 files changed, 3 insertions(+), 181 deletions(-) delete mode 100755 scripts/bluetooth.rc.deb delete mode 100755 scripts/bluetooth.rc.rh diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 8e05086b..6130c842 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -4,10 +4,8 @@ bin_SCRIPTS = bluepin -EXTRA_DIST = bluepin bluetooth.rc.rh bluetooth.rc.deb create_dev +EXTRA_DIST = bluepin bluetooth.init bluetooth.default create_dev install-data-local: - [ ! -f /etc/redhat-release -o ! -f /etc/mandrake-release ] || \ - $(INSTALL) -D -m 755 $(srcdir)/bluetooth.rc.rh $(DESTDIR)$(sysconfdir)/rc.d/init.d/bluetooth - [ ! -f /etc/debian_version ] || \ - $(INSTALL) -D -m 755 $(srcdir)/bluetooth.rc.deb $(DESTDIR)$(sysconfdir)/init.d/bluetooth + $(INSTALL) -D -m 755 $(srcdir)/bluetooth.init $(DESTDIR)$(sysconfdir)/init.d/bluetooth + $(INSTALL) -D -m 644 $(srcdir)/bluetooth.default $(DESTDIR)$(sysconfdir)/default/bluetooth diff --git a/scripts/bluetooth.rc.deb b/scripts/bluetooth.rc.deb deleted file mode 100755 index 4c216c31..00000000 --- a/scripts/bluetooth.rc.deb +++ /dev/null @@ -1,86 +0,0 @@ -#! /bin/sh -# -# bluetooth Bluetooth subsystem starting and stopping -# - -NAME=bluetooth -DESC="Bluetooth subsystem" -PATH=/sbin:/bin:/usr/sbin:/usr/bin -HCID=/usr/sbin/hcid -HCID_CONF=/etc/bluetooth/hcid.conf -HCIATTACH=/usr/sbin/hciattach -UART_CONF=/etc/bluetooth/uart -SDPD=/usr/sbin/sdpd -RFCOMM=/usr/bin/rfcomm -RFCOMM_CONF=/etc/bluetooth/rfcomm.conf - -set -e - -start_uarts() -{ - [ -x $HCIATTACH -a -f $UART_CONF ] || return - grep -v '^#' $UART_CONF | while read i; do - $HCIATTACH $i - done -} - -stop_uarts() -{ - killall $HCIATTACH > /dev/null 2>&1 || true -} - -case "$1" in - start) - echo -n "Starting $DESC:" - if [ -x $HCID -a -f $HCID_CONF ] ; then - $HCID -f $HCID_CONF - echo -n " hcid" - fi - if [ -x $SDPD ] ; then - $SDPD - echo -n " sdpd" - fi - if [ -x $RFCOMM -a -f $RFCOMM_CONF ] ; then - $RFCOMM -f $RFCOMM_CONF bind all - echo -n " rfcomm" - fi - echo "." - start_uarts || true - ;; - stop) - echo -n "Stopping $DESC:" - if [ -x $RFCOMM ] ; then - echo -n " rfcomm" - $RFCOMM release all - fi - echo -n " sdpd" - killall $SDPD > /dev/null 2>&1 || true - echo -n " hcid" - killall $HCID > /dev/null 2>&1 || true - echo "." - stop_uarts - ;; - restart|force-reload) - echo -n "Restarting $DESC:" - echo -n " hcid" - killall $HCID > /dev/null 2>&1 || true - sleep 1 - if [ -x $HCID -a -f $HCID_CONF ] ; then - $HCID -f $HCID_CONF - fi - echo -n " sdpd" - killall $SDPD > /dev/null 2>&1 || true - sleep 1 - if [ -x $SDPD ] ; then - $SDPD - fi - echo "." - ;; - *) - N=/etc/init.d/bluetooth - echo "Usage: $N {start|stop|restart|force-reload}" >&2 - exit 1 - ;; -esac - -exit 0 diff --git a/scripts/bluetooth.rc.rh b/scripts/bluetooth.rc.rh deleted file mode 100755 index c8560946..00000000 --- a/scripts/bluetooth.rc.rh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/sh -# -# bluetooth Bluetooth subsystem starting and stopping -# -# chkconfig: 345 25 90 -# description: Bluetooth subsystem -# - -# Source function library. -. /etc/rc.d/init.d/functions - -# Source Bluetooth configuration. -#. /etc/sysconfig/bluetooth - -prog="Bluetooth" - -UART_CONF="/etc/bluetooth/uart" - -start_uarts() -{ - [ -f /sbin/hciattach -a -f $UART_CONF ] || return - grep -v '^#' $UART_CONF | while read i; do - /sbin/hciattach $i - done -} - -stop_uarts() -{ - killproc hciattach > /dev/null 2>&1 -} - -start() -{ - echo -n $"Starting $prog: " - daemon /sbin/hcid - - if [ -x /usr/sbin/sdpd ]; then - daemon /usr/sbin/sdpd - fi - - if [ -x /bin/rfcomm -a -f /etc/bluetooth/rfcomm.conf ]; then - /bin/rfcomm -f /etc/bluetooth/rfcomm.conf bind all - fi - - start_uarts - touch /var/lock/subsys/bluetooth - echo -} - -stop() -{ - echo -n $"Shutting down $prog: " - killproc hcid - - if [ -x /usr/sbin/sdpd ]; then - killproc sdpd - fi - - if [ -x /bin/rfcomm ]; then - /bin/rfcomm release all - fi - - stop_uarts - rm -f /var/lock/subsys/bluetooth - echo -} - -[ -f /sbin/hcid ] || exit 0 - -# See how we were called. -case "$1" in - start) - start - ;; - stop) - stop - ;; - restart|reload) - stop - start - ;; - condrestart) - [ -e /var/lock/subsys/bluetooth ] && (stop; start) - ;; - *) - echo $"Usage: $0 {start|stop|restart|reload|condrestart}" - exit 1 -esac - -exit 0 -- cgit From 46db4df8662288a5282f52fe29d522142c021444 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 17:57:42 +0000 Subject: Don't overwrite default file if it exists --- scripts/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 6130c842..f375290c 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -8,4 +8,6 @@ EXTRA_DIST = bluepin bluetooth.init bluetooth.default create_dev install-data-local: $(INSTALL) -D -m 755 $(srcdir)/bluetooth.init $(DESTDIR)$(sysconfdir)/init.d/bluetooth - $(INSTALL) -D -m 644 $(srcdir)/bluetooth.default $(DESTDIR)$(sysconfdir)/default/bluetooth + $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/default + [ -f $(DESTDIR)$(sysconfdir)/default/bluetooth ] || \ + $(INSTALL_DATA) $(srcdir)/bluetooth.default $(DESTDIR)$(sysconfdir)/default/bluetooth -- cgit From 7b058edb0e54176809bfcce6567c82cb608029ba Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 22:04:27 +0000 Subject: Allow options for hidd --- scripts/bluetooth.default | 3 +++ scripts/bluetooth.init | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/bluetooth.default b/scripts/bluetooth.default index d96342c6..4817d38c 100644 --- a/scripts/bluetooth.default +++ b/scripts/bluetooth.default @@ -12,6 +12,9 @@ SDPD_ENABLE=true # Start hidd (allowed values are "true" and "false") HIDD_ENABLE=true +# Arguments to hidd +HIDD_OPTIONS="" + # Run hid2hci (allowed values are "true" and "false") HID2HCI_ENABLE=true diff --git a/scripts/bluetooth.init b/scripts/bluetooth.init index d0b053cf..85d3a32e 100644 --- a/scripts/bluetooth.init +++ b/scripts/bluetooth.init @@ -36,6 +36,7 @@ PAND_ENABLE=false HCID_CONFIG="/etc/bluetooth/hcid.conf" RFCOMM_CONFIG="/etc/bluetooth/rfcomm.conf" +HIDD_OPTIONS="" DUND_OPTIONS="" PAND_OPTIONS="" @@ -53,11 +54,11 @@ case "$1" in echo -n " $SDPD_NAME" fi if $HIDD_ENABLE && [ -x "$HIDD_EXEC" ] ; then - $HIDD_EXEC --tohci + $HIDD_EXEC $HIDD_OPTIONS echo -n " $HIDD_NAME" fi if $HID2HCI_ENABLE && [ -x "$HID2HCI_EXEC" ] ; then - $HID2HCI_EXEC + $HID2HCI_EXEC --tohci echo -n " $HID2HCI_NAME" fi if $RFCOMM_ENABLE && [ -x "$RFCOMM_EXEC" -a -f "$RFCOMM_CONFIG" ] ; then -- cgit From e02418e9d5439bf9f74febd1a98a3769fac98c81 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 22:17:48 +0000 Subject: Add server flag to hidd --- scripts/bluetooth.init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bluetooth.init b/scripts/bluetooth.init index 85d3a32e..4a37698b 100644 --- a/scripts/bluetooth.init +++ b/scripts/bluetooth.init @@ -54,7 +54,7 @@ case "$1" in echo -n " $SDPD_NAME" fi if $HIDD_ENABLE && [ -x "$HIDD_EXEC" ] ; then - $HIDD_EXEC $HIDD_OPTIONS + $HIDD_EXEC $HIDD_OPTIONS --server echo -n " $HIDD_NAME" fi if $HID2HCI_ENABLE && [ -x "$HID2HCI_EXEC" ] ; then -- cgit From 80ada658e05a09941ce901be73b0353ac023c32c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 22:32:22 +0000 Subject: Add connect and search options to the HID daemon --- hidd/main.c | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- hidd/sdp.c | 94 +++++++++++++++++++++++----- 2 files changed, 255 insertions(+), 44 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index 46b25ec4..aa2a7b1f 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -63,6 +63,42 @@ static void sig_term(int sig) __io_canceled = 1; } +static int l2cap_connect(bdaddr_t *src, bdaddr_t *dst, unsigned short psm) +{ + struct sockaddr_l2 addr; + struct l2cap_options opts; + int sk; + + if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) + return -1; + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, src); + addr.l2_psm = 0; + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(sk); + return -1; + } + + opts.imtu = HIDP_DEFAULT_MTU; + opts.omtu = HIDP_DEFAULT_MTU; + opts.flush_to = 0xffff; + + setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)); + + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, dst); + addr.l2_psm = htobs(psm); + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(sk); + return -1; + } + + return sk; +} + static int l2cap_listen(const bdaddr_t *bdaddr, unsigned short psm, int backlog) { struct sockaddr_l2 addr; @@ -115,7 +151,7 @@ static int l2cap_accept(int sk, bdaddr_t *bdaddr) return nsk; } -static int create(int ctl, int csk, int isk, int timeout) +static int create_device(int ctl, int csk, int isk, int timeout) { struct hidp_connadd_req req; struct sockaddr_l2 addr; @@ -140,16 +176,18 @@ static int create(int ctl, int csk, int isk, int timeout) bacpy(&dst, &addr.l2_bdaddr); - ba2str(&dst, bda); - syslog(LOG_INFO, "New HID connection from %s", bda); - memset(&req, 0, sizeof(req)); req.ctrl_sock = csk; req.intr_sock = isk; req.flags = 0; req.idle_to = timeout * 60; - get_hid_device_info(&src, &dst, &req); + err = get_hid_device_info(&src, &dst, &req); + if (err < 0) + return err; + + ba2str(&dst, bda); + syslog(LOG_INFO, "New HID device %s (%s)", bda, req.name); err = ioctl(ctl, HIDPCONNADD, &req); @@ -159,7 +197,7 @@ static int create(int ctl, int csk, int isk, int timeout) return err; } -static void run(int ctl, int csk, int isk, int timeout) +static void run_server(int ctl, int csk, int isk, int timeout) { struct pollfd p[2]; short events; @@ -185,7 +223,7 @@ static void run(int ctl, int csk, int isk, int timeout) ncsk = l2cap_accept(csk, NULL); nisk = l2cap_accept(isk, NULL); - err = create(ctl, ncsk, nisk, timeout); + err = create_device(ctl, ncsk, nisk, timeout); if (err < 0) syslog(LOG_ERR, "HID create error %d (%s)", errno, strerror(errno)); @@ -196,12 +234,87 @@ static void run(int ctl, int csk, int isk, int timeout) } } +static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, int timeout) +{ + int csk, isk, err; + + csk = l2cap_connect(src, dst, L2CAP_PSM_HIDP_CTRL); + if (csk < 0) { + perror("Can't create HID control channel"); + close(ctl); + exit(1); + } + + isk = l2cap_connect(src, dst, L2CAP_PSM_HIDP_INTR); + if (isk < 0) { + perror("Can't create HID interrupt channel"); + close(csk); + close(ctl); + exit(1); + } + + err = create_device(ctl, csk, isk, timeout); + if (err < 0) { + fprintf(stderr, "HID create error %d (%s)\n", + errno, strerror(errno)); + close(isk); + sleep(1); + close(csk); + close(ctl); + exit(1); + } +} + +static void do_search(int ctl, bdaddr_t *bdaddr, int timeout) +{ + inquiry_info *info = NULL; + bdaddr_t src, dst; + int i, dev_id, num_rsp, length, flags; + char addr[18]; + uint8_t class[3]; + + ba2str(bdaddr, addr); + dev_id = hci_devid(addr); + if (dev_id < 0) { + dev_id = hci_get_route(NULL); + hci_devba(dev_id, &src); + } else + bacpy(&src, bdaddr); + + length = 8; /* ~10 seconds */ + num_rsp = 0; + flags = 0; + + printf("Searching ...\n"); + + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + + for (i = 0; i < num_rsp; i++) { + memcpy(class, (info+i)->dev_class, 3); + if (class[1] == 0x25 && class[2] == 0x00) { + bacpy(&dst, &(info+i)->bdaddr); + ba2str(&dst, addr); + + printf("\tConnecting to device %s\n", addr); + do_connect(ctl, &src, &dst, timeout); + } + } + + free(info); + + if (!num_rsp) { + fprintf(stderr, "\tNo devices in range or visible\n"); + close(ctl); + exit(1); + } +} + static void usage(void) { printf("hidd - Bluetooth HID daemon\n\n"); printf("Usage:\n" - "\thidd [options]\n" + "\thidd [options] [commands]\n" "\n"); printf("Options:\n" @@ -210,6 +323,12 @@ static void usage(void) "\t-n, --nodaemon Don't fork daemon to background\n" "\t-h, --help Display help\n" "\n"); + + printf("Commands:\n" + "\t--server Start HID server\n" + "\t--search Search for HID devices\n" + "\t--connect Connect remote HID device\n" + "\n"); } static struct option main_options[] = { @@ -217,21 +336,25 @@ static struct option main_options[] = { { "nodaemon", 0, 0, 'n' }, { "timeout", 1, 0, 't' }, { "device", 1, 0, 'i' }, + { "server", 0, 0, 'd' }, + { "listen", 0, 0, 'd' }, + { "search", 0, 0, 's' }, + { "connect", 1, 0, 'c' }, { 0, 0, 0, 0 } }; int main(int argc, char *argv[]) { struct sigaction sa; - bdaddr_t bdaddr; + bdaddr_t bdaddr, dev; char addr[18]; int log_option = LOG_NDELAY | LOG_PID; int opt, fd, ctl, csk, isk; - int daemon = 1, timeout = 30; + int mode = 0, daemon = 1, timeout = 30; bacpy(&bdaddr, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:nt:h", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+i:nt:dsc:h", main_options, NULL)) != -1) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -245,6 +368,16 @@ int main(int argc, char *argv[]) case 't': timeout = atoi(optarg); break; + case 'd': + mode = 1; + break; + case 's': + mode = 2; + break; + case 'c': + str2ba(optarg, &dev); + mode = 3; + break; case 'h': usage(); exit(0); @@ -255,24 +388,42 @@ int main(int argc, char *argv[]) ba2str(&bdaddr, addr); - csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, 10); - if (csk < 0) { - perror("Can't listen on HID control channel"); + ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP); + if (ctl < 0) { + perror("Can't open HIDP control socket"); exit(1); } - isk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_INTR, 10); - if (isk < 0) { - perror("Can't listen on HID interrupt channel"); - close(csk); - exit(1); - } + switch (mode) { + case 1: + csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, 10); + if (csk < 0) { + perror("Can't listen on HID control channel"); + close(ctl); + exit(1); + } - ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP); - if (ctl < 0) { - perror("Can't open HIDP control socket"); - close(csk); - close(isk); + isk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_INTR, 10); + if (isk < 0) { + perror("Can't listen on HID interrupt channel"); + close(ctl); + close(csk); + exit(1); + } + break; + + case 2: + do_search(ctl, &bdaddr, timeout); + close(ctl); + exit(0); + + case 3: + do_connect(ctl, &bdaddr, &dev, timeout); + close(ctl); + exit(0); + + default: + usage(); exit(1); } @@ -309,13 +460,13 @@ int main(int argc, char *argv[]) sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); - run(ctl, csk, isk, timeout); + run_server(ctl, csk, isk, timeout); syslog(LOG_INFO, "Exit"); - close(ctl); close(csk); close(isk); + close(ctl); return 0; } diff --git a/hidd/sdp.c b/hidd/sdp.c index 4c92aa66..4db9a4c8 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -51,43 +51,103 @@ int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req) { + uint32_t range = 0x0000ffff; sdp_session_t *s; - sdp_list_t *srch, *attrs, *rsp; + sdp_list_t *search, *attrid, *pnp_rsp, *hid_rsp; sdp_record_t *rec; - sdp_data_t *pdlist; + sdp_data_t *pdlist, *pdlist2; uuid_t svclass; - uint16_t attr; int err; s = sdp_connect(src, dst, 0); if (!s) return -1; + sdp_uuid16_create(&svclass, PNP_INFO_SVCLASS_ID); + search = sdp_list_append(NULL, &svclass); + attrid = sdp_list_append(NULL, &range); + + err = sdp_service_search_attr_req(s, search, SDP_ATTR_REQ_RANGE, attrid, &pnp_rsp); + + sdp_list_free(search, 0); + sdp_list_free(attrid, 0); + sdp_uuid16_create(&svclass, HID_SVCLASS_ID); - srch = sdp_list_append(NULL, &svclass); + search = sdp_list_append(NULL, &svclass); + attrid = sdp_list_append(NULL, &range); - attr = 0x0206; - attrs = sdp_list_append(NULL, &attr); + err = sdp_service_search_attr_req(s, search, SDP_ATTR_REQ_RANGE, attrid, &hid_rsp); - err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); + sdp_list_free(search, 0); + sdp_list_free(attrid, 0); sdp_close(s); - if (err || !rsp) + if (err || !hid_rsp) return -1; - rec = (sdp_record_t *) rsp->data; + if (pnp_rsp) { + rec = (sdp_record_t *) pnp_rsp->data; + + pdlist = sdp_data_get(rec, 0x0201); + if (pdlist) + req->vendor = pdlist->val.uint16; + + pdlist = sdp_data_get(rec, 0x0202); + if (pdlist) + req->product = pdlist->val.uint16; + + pdlist = sdp_data_get(rec, 0x0203); + if (pdlist) + req->version = pdlist->val.uint16; + + sdp_record_free(rec); + } + + rec = (sdp_record_t *) hid_rsp->data; + + pdlist = sdp_data_get(rec, 0x0101); + pdlist2 = sdp_data_get(rec, 0x0102); + if (pdlist) { + if (pdlist2) { + if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) { + strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1); + strcat(req->name, " "); + } + strncat(req->name, pdlist->val.str, + sizeof(req->name) - strlen(req->name)); + } else + strncpy(req->name, pdlist->val.str, sizeof(req->name)); + } else { + pdlist2 = sdp_data_get(rec, 0x0100); + if (pdlist2) + strncpy(req->name, pdlist2->val.str, sizeof(req->name)); + } + + pdlist = sdp_data_get(rec, 0x0201); + if (pdlist) + req->parser = pdlist->val.uint16; + else + req->parser = 0x0100; + + pdlist = sdp_data_get(rec, 0x0203); + if (pdlist) + req->country = pdlist->val.uint8; pdlist = sdp_data_get(rec, 0x0206); - pdlist = pdlist->val.dataseq; - pdlist = pdlist->val.dataseq; - pdlist = pdlist->next; - - req->rd_data = malloc(pdlist->unitSize); - if (req->rd_data) { - memcpy(req->rd_data, (unsigned char *) pdlist->val.str, pdlist->unitSize); - req->rd_size = pdlist->unitSize; + if (pdlist) { + pdlist = pdlist->val.dataseq; + pdlist = pdlist->val.dataseq; + pdlist = pdlist->next; + + req->rd_data = malloc(pdlist->unitSize); + if (req->rd_data) { + memcpy(req->rd_data, (unsigned char *) pdlist->val.str, pdlist->unitSize); + req->rd_size = pdlist->unitSize; + } } + sdp_record_free(rec); + return 0; } -- cgit From 42a6874350bd1e6dd2b66837c1df223422a54dfe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 22:34:29 +0000 Subject: Install the hidd program --- hidd/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hidd/Makefile.am b/hidd/Makefile.am index dfc7b3e1..e74f154d 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -noinst_PROGRAMS = hidd +bin_PROGRAMS = hidd hidd_SOURCES = main.c hidd.h sdp.c -- cgit From 64c432fe558cb3e57152a36af44885311975ce5e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 22:50:00 +0000 Subject: Better error handling --- scripts/bluetooth.init | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/bluetooth.init b/scripts/bluetooth.init index 4a37698b..11162ee9 100644 --- a/scripts/bluetooth.init +++ b/scripts/bluetooth.init @@ -20,7 +20,7 @@ DUND_NAME=dund HCID_EXEC="`which $HCID_NAME || true`" SDPD_EXEC="`which $SDPD_NAME || true`" HIDD_EXEC="`which $HIDD_NAME || true`" -HID2HCI_EXEC="`which $HIDD_NAME || true`" +HID2HCI_EXEC="`which $HID2HCI_NAME || true`" RFCOMM_EXEC="`which $RFCOMM_NAME || true`" PAND_EXEC="`which $PAND_NAME || true`" DUND_EXEC="`which $DUND_NAME || true`" @@ -54,15 +54,15 @@ case "$1" in echo -n " $SDPD_NAME" fi if $HIDD_ENABLE && [ -x "$HIDD_EXEC" ] ; then - $HIDD_EXEC $HIDD_OPTIONS --server + $HIDD_EXEC $HIDD_OPTIONS --server || true echo -n " $HIDD_NAME" fi if $HID2HCI_ENABLE && [ -x "$HID2HCI_EXEC" ] ; then - $HID2HCI_EXEC --tohci + $HID2HCI_EXEC --tohci > /dev/null 2>&1 || true echo -n " $HID2HCI_NAME" fi if $RFCOMM_ENABLE && [ -x "$RFCOMM_EXEC" -a -f "$RFCOMM_CONFIG" ] ; then - $RFCOMM_EXEC -f $RFCOMM_CONFIG bind all + $RFCOMM_EXEC -f $RFCOMM_CONFIG bind all || true echo -n " $RFCOMM_NAME" fi if $DUND_ENABLE && [ -x "$DUND_EXEC" -a -n "$DUND_OPTIONS" ] ; then @@ -77,19 +77,19 @@ case "$1" in ;; stop) echo -n "Stopping $DESC:" - killall $PAND_EXEC > /dev/null 2>&1 || true + killall $PAND_NAME > /dev/null 2>&1 || true echo -n " $PAND_NAME" - killall $DUND_EXEC > /dev/null 2>&1 || true + killall $DUND_NAME > /dev/null 2>&1 || true echo -n " $DUND_NAME" if [ -x "$RFCOMM_EXEC" ] ; then $RFCOMM_EXEC release all echo -n " $RFCOMM_NAME" fi - killall $HIDD_EXEC > /dev/null 2>&1 || true + killall $HIDD_NAME > /dev/null 2>&1 || true echo -n " $HIDD_NAME" - killall $SDPD_EXEC > /dev/null 2>&1 || true + killall $SDPD_NAME > /dev/null 2>&1 || true echo -n " $SDPD_NAME" - killall $HCID_EXEC > /dev/null 2>&1 || true + killall $HCID_NAME > /dev/null 2>&1 || true echo -n " $HCID_NAME" echo "." ;; -- cgit From e58717d76bcba3ac0ee6cc5a4e6a03d5d307c0d9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 22:57:34 +0000 Subject: One more fix --- scripts/bluetooth.init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bluetooth.init b/scripts/bluetooth.init index 11162ee9..82cd68cf 100644 --- a/scripts/bluetooth.init +++ b/scripts/bluetooth.init @@ -82,7 +82,7 @@ case "$1" in killall $DUND_NAME > /dev/null 2>&1 || true echo -n " $DUND_NAME" if [ -x "$RFCOMM_EXEC" ] ; then - $RFCOMM_EXEC release all + $RFCOMM_EXEC release all > /dev/null 2>&1 || true echo -n " $RFCOMM_NAME" fi killall $HIDD_NAME > /dev/null 2>&1 || true -- cgit From 4c65d109ee2ced4a49a511ec185da11a8b27f069 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 23:08:02 +0000 Subject: Don't forget to enable D-Bus support --- hcid/Makefile.am | 6 ++++-- hcid/dbus.c | 1 - hcid/main.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 3a5e766a..3cbdfaa2 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -7,9 +7,11 @@ sbin_PROGRAMS = hcid if DBUS dbus_hcid_sources = dbus.c dbus_hcid_ldflags = @DBUS_LIBS@ +dbus_hcid_cflags = -DENABLE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE else dbus_hcid_sources = dbus_hcid_ldflags = +dbus_hcid_cflags = endif hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) @@ -17,11 +19,11 @@ hcid_CONFIG = hcid.conf LDFLAGS = $(dbus_hcid_ldflags) @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ @DBUS_INCLUDES@ +INCLUDES = @BLUEZ_INCLUDES@ @DBUS_INCLUDES@ $(dbus_hcid_cflags) man_MANS = hcid.8 hcid.conf.5 -YFLAGS = -d +YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h diff --git a/hcid/dbus.c b/hcid/dbus.c index a1756cc6..7ef7ac73 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -40,7 +40,6 @@ #include #include -#define DBUS_API_SUBJECT_TO_CHANGE #include #include "glib-ectomy.h" diff --git a/hcid/main.c b/hcid/main.c index c679159d..be523a19 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -506,7 +506,7 @@ int main(int argc, char *argv[], char *env[]) /* Start logging to syslog and stderr */ openlog("hcid", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); - syslog(LOG_INFO, "HCI daemon ver %s started", VERSION); + syslog(LOG_INFO, "Bluetooth HCI daemon"); memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; -- cgit From 7b767cdc03c44f2626eb80129fc0b78460f882fc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 7 May 2004 23:11:23 +0000 Subject: Fix server information --- dund/main.c | 2 +- pand/main.c | 2 +- sdpd/main.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dund/main.c b/dund/main.c index e953ef28..61d3d941 100644 --- a/dund/main.c +++ b/dund/main.c @@ -533,7 +533,7 @@ int main(int argc, char **argv) } openlog("dund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); - syslog(LOG_INFO, "DUN daemon ver %s", VERSION); + syslog(LOG_INFO, "Bluetooth DUN daemon"); if (src) { src_dev = hci_devid(src); diff --git a/pand/main.c b/pand/main.c index 88383331..1bc1d9e0 100644 --- a/pand/main.c +++ b/pand/main.c @@ -578,7 +578,7 @@ int main(int argc, char **argv) } openlog("pand", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); - syslog(LOG_INFO, "PAN daemon ver %s", VERSION); + syslog(LOG_INFO, "Bluetooth PAN daemon"); if (src) { src_dev = hci_devid(src); diff --git a/sdpd/main.c b/sdpd/main.c index b2262acd..8b6089d4 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -419,7 +419,7 @@ int main(int argc, char **argv) return -1; } - SDPINF("sdpd v%s started", VERSION); + SDPINF("Bluetooth SDP daemon"); signal(SIGINT, sig_term); signal(SIGTERM, sig_term); -- cgit From 10d6e9e4f785f220fb4d95402c56035e8a4dc1d3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 8 May 2004 20:16:56 +0000 Subject: Add commands for showing and killing connections --- hidd/main.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 3 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index aa2a7b1f..878368df 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -234,6 +234,42 @@ static void run_server(int ctl, int csk, int isk, int timeout) } } +static char *hidp_state[] = { + "unknown", + "connected", + "open", + "bound", + "listening", + "connecting", + "connecting", + "config", + "disconnecting", + "closed" +}; + +static void do_show(int ctl) +{ + struct hidp_connlist_req req; + struct hidp_conninfo ci[16]; + char addr[18]; + int i; + + req.cnum = 16; + req.ci = ci; + + if (ioctl(ctl, HIDPGETCONNLIST, &req) < 0) { + perror("Can't get connection list"); + close(ctl); + exit(1); + } + + for (i = 0; i < req.cnum; i++) { + ba2str(&ci[i].bdaddr, addr); + printf("%s %s [%04x:%04x] %s\n", addr, ci[i].name, + ci[i].vendor, ci[i].product, hidp_state[ci[i].state]); + } +} + static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, int timeout) { int csk, isk, err; @@ -309,6 +345,46 @@ static void do_search(int ctl, bdaddr_t *bdaddr, int timeout) } } +static void do_kill(int ctl, bdaddr_t *bdaddr, uint32_t flags) +{ + struct hidp_conndel_req req; + struct hidp_connlist_req cl; + struct hidp_conninfo ci[16]; + int i; + + if (!bacmp(bdaddr, BDADDR_ALL)) { + cl.cnum = 16; + cl.ci = ci; + + if (ioctl(ctl, HIDPGETCONNLIST, &cl) < 0) { + perror("Can't get connection list"); + close(ctl); + exit(1); + } + + for (i = 0; i < cl.cnum; i++) { + bacpy(&req.bdaddr, &ci[i].bdaddr); + req.flags = flags; + + if (ioctl(ctl, HIDPCONNDEL, &req) < 0) { + perror("Can't release connection"); + close(ctl); + exit(1); + } + } + + } else { + bacpy(&req.bdaddr, bdaddr); + req.flags = flags; + + if (ioctl(ctl, HIDPCONNDEL, &req) < 0) { + perror("Can't release connection"); + close(ctl); + exit(1); + } + } +} + static void usage(void) { printf("hidd - Bluetooth HID daemon\n\n"); @@ -328,6 +404,9 @@ static void usage(void) "\t--server Start HID server\n" "\t--search Search for HID devices\n" "\t--connect Connect remote HID device\n" + "\t--kill Terminate HID connection\n" + "\t--killall Terminate all connections\n" + "\t--show List current HID connections\n" "\n"); } @@ -336,10 +415,18 @@ static struct option main_options[] = { { "nodaemon", 0, 0, 'n' }, { "timeout", 1, 0, 't' }, { "device", 1, 0, 'i' }, + { "show", 0, 0, 'l' }, + { "list", 0, 0, 'l' }, { "server", 0, 0, 'd' }, { "listen", 0, 0, 'd' }, { "search", 0, 0, 's' }, + { "create", 1, 0, 'c' }, { "connect", 1, 0, 'c' }, + { "disconnect", 1, 0, 'k' }, + { "terminate", 1, 0, 'k' }, + { "release", 1, 0, 'k' }, + { "kill", 1, 0, 'k' }, + { "killall", 1, 0, 'K' }, { 0, 0, 0, 0 } }; @@ -354,7 +441,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:nt:dsc:h", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+i:nt:ldsc:k:Kh", main_options, NULL)) != -1) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -368,6 +455,9 @@ int main(int argc, char *argv[]) case 't': timeout = atoi(optarg); break; + case 'l': + mode = 0; + break; case 'd': mode = 1; break; @@ -378,6 +468,14 @@ int main(int argc, char *argv[]) str2ba(optarg, &dev); mode = 3; break; + case 'k': + str2ba(optarg, &dev); + mode = 4; + break; + case 'K': + bacpy(&dev, BDADDR_ALL); + mode = 4; + break; case 'h': usage(); exit(0); @@ -422,9 +520,15 @@ int main(int argc, char *argv[]) close(ctl); exit(0); + case 4: + do_kill(ctl, &dev, 0); + close(ctl); + exit(0); + default: - usage(); - exit(1); + do_show(ctl); + close(ctl); + exit(0); } if (daemon) { -- cgit From 7a3b95b9b649df2d56db0dc963b33b2f3835d882 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 8 May 2004 20:42:53 +0000 Subject: Update RPM spec file --- utils.spec | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/utils.spec b/utils.spec index 5ec5d210..448d4681 100644 --- a/utils.spec +++ b/utils.spec @@ -29,6 +29,9 @@ Bluetooth utilities (bluez-utils): - hciconfig - hcid - sdpd + - dund + - pand + - hidd - sdptool - ciptool - l2ping @@ -60,7 +63,8 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(-, root, root) -/etc/rc.d/init.d/bluetooth +/etc/init.d/bluetooth +/etc/default/bluetooth /usr/bin/hcitool /usr/bin/l2ping /usr/bin/bluepin @@ -69,6 +73,9 @@ rm -rf $RPM_BUILD_ROOT /usr/sbin/hciconfig /usr/sbin/hcid /usr/sbin/sdpd +/usr/bin/dund +/usr/bin/pand +/usr/bin/hidd /usr/bin/sdptool /usr/bin/ciptool %{_mandir}/man8/hciattach.8.gz @@ -76,6 +83,8 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man5/hcid.conf.5.gz %{_mandir}/man8/hcid.8.gz %{_mandir}/man8/sdpd.8.gz +%{_mandir}/man1/dund.1.gz +%{_mandir}/man1/pand.1.gz %{_mandir}/man1/hcitool.1.gz %{_mandir}/man1/sdptool.1.gz %{_mandir}/man1/ciptool.1.gz -- cgit From d30e0b53fd418d8a7485d9f8a7b08a5024fde52e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 8 May 2004 20:56:50 +0000 Subject: Update changelog and bump version number --- ChangeLog | 18 ++++++++++++++++++ configure.in | 2 +- utils.spec | 6 +++--- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8dc5717..ff6c3e9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +ver 2.7: + Add support for getting the AFH channel map. + Add support for AFH mode. + Add support for inquiry mode. + Add Bluetooth backend for CUPS. + Add the hid2hci utility. + Add the hidd utility. + Add the pand utility. + Add the dund utility. + More endian bug fixes. + Give udev some time to create the RFCOMM device nodes. + Release the TTY if no device node is found. + New startup script for the Bluetooth subsystem. + Update to the autoconf stuff. + + Note: + This version needs at least bluez-libs-2.7 + ver 2.6: Change default prefix to /usr. Add manpages for hcid and hcid.conf. diff --git a/configure.in b/configure.in index fb6db57d..14dce451 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.6) +AM_INIT_AUTOMAKE(bluez-utils, 2.7) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE diff --git a/utils.spec b/utils.spec index 448d4681..ec94f080 100644 --- a/utils.spec +++ b/utils.spec @@ -1,5 +1,5 @@ # Note that this is NOT a relocatable package -%define ver 2.6 +%define ver 2.7 %define RELEASE 1 %define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} %define prefix / @@ -18,9 +18,9 @@ BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root URL: http://bluez.sourceforge.net Docdir: %{prefix}/usr/share/doc Requires: glibc >= 2.2.4 -Requires: bluez-libs >= 2.0 +Requires: bluez-libs >= 2.7 BuildRequires: glibc >= 2.2.4 -BuildRequires: bluez-libs >= 2.0 +BuildRequires: bluez-libs >= 2.7 %description Bluetooth utilities (bluez-utils): -- cgit From ae9e56a7b15b4ddd014b30229ad4e4bcafe836e3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 May 2004 00:21:31 +0000 Subject: Add missing include of sys/socket.h --- cups/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cups/main.c b/cups/main.c index 352ea4ea..d43f631b 100644 --- a/cups/main.c +++ b/cups/main.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include -- cgit From c337593d343e7320332557ba9137561eefabf22e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 May 2004 09:35:52 +0000 Subject: Fix TTY creation problem for listen command --- rfcomm/main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/rfcomm/main.c b/rfcomm/main.c index dbb74869..3a7fe0a5 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -442,14 +442,21 @@ static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv } snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); - if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev); - while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { + if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) { if (try--) { + snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev); sleep(1); continue; } perror("Can't open RFCOMM device"); + + memset(&req, 0, sizeof(req)); + req.dev_id = dev; + req.flags = (1 << RFCOMM_HANGUP_NOW); + ioctl(ctl, RFCOMMRELEASEDEV, &req); + close(sk); return; } -- cgit From 052d647c87405e41604245f2afaee1652457b508 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 May 2004 12:40:17 +0000 Subject: The option --killall don't need an argument --- hidd/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hidd/main.c b/hidd/main.c index 878368df..7270a235 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -426,7 +426,7 @@ static struct option main_options[] = { { "terminate", 1, 0, 'k' }, { "release", 1, 0, 'k' }, { "kill", 1, 0, 'k' }, - { "killall", 1, 0, 'K' }, + { "killall", 0, 0, 'K' }, { 0, 0, 0, 0 } }; -- cgit From 0a61c1514914951ff94e1228e8031737cc423e41 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 May 2004 13:47:19 +0000 Subject: Use 10 characters array in swave() routine --- tools/hciattach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 3e8be20a..50432ec3 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -640,7 +640,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) static int swave(int fd, struct uart_t *u, struct termios *ti) { struct timespec tm = {0, 500000}; - char cmd[9], rsp[100]; + char cmd[10], rsp[100]; int r; // Silicon Wave set baud rate command -- cgit From d03add1b87c56410b25b956f82833be4d00fc340 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 May 2004 21:48:08 +0000 Subject: Fix hciattach path for PCMCIA class script --- pcmcia/bluetooth | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcmcia/bluetooth b/pcmcia/bluetooth index 503484d9..7be4a31d 100755 --- a/pcmcia/bluetooth +++ b/pcmcia/bluetooth @@ -25,7 +25,7 @@ start_serial() { IRQ=`setserial /dev/$DEVICE | sed -e 's/.*IRQ: //'` setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ - /sbin/hciattach $DEVICE $MANFID > /tmp/pcmcia + /usr/sbin/hciattach $DEVICE $MANFID } stop_serial() { do_fuser -k -HUP /dev/$DEVICE > /dev/null -- cgit From 7ac6ede99ac309c7e28f3c2993fbc9bbbe28a68b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 May 2004 10:39:50 +0000 Subject: Use LIBS instead of LDFLAGS --- cups/Makefile.am | 2 +- dund/Makefile.am | 2 +- hcid/Makefile.am | 6 +++--- hidd/Makefile.am | 2 +- pand/Makefile.am | 2 +- rfcomm/Makefile.am | 2 +- sdpd/Makefile.am | 2 +- test/Makefile.am | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cups/Makefile.am b/cups/Makefile.am index 2e4ba707..837bbfa2 100644 --- a/cups/Makefile.am +++ b/cups/Makefile.am @@ -6,7 +6,7 @@ noinst_PROGRAMS = bluetooth bluetooth_SOURCES = main.c sdp.c spp.c hcrp.c -LDFLAGS = @BLUEZ_LIBS@ +LIBS = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ diff --git a/dund/Makefile.am b/dund/Makefile.am index 9c967ce0..1c8f4069 100644 --- a/dund/Makefile.am +++ b/dund/Makefile.am @@ -6,7 +6,7 @@ bin_PROGRAMS = dund dund_SOURCES = main.c dun.c dund.h sdp.c lib.h msdun.c -LDFLAGS = @BLUEZ_LIBS@ +LIBS = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 3cbdfaa2..fe04202b 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -6,18 +6,18 @@ sbin_PROGRAMS = hcid if DBUS dbus_hcid_sources = dbus.c -dbus_hcid_ldflags = @DBUS_LIBS@ +dbus_hcid_libs = @DBUS_LIBS@ dbus_hcid_cflags = -DENABLE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE else dbus_hcid_sources = -dbus_hcid_ldflags = +dbus_hcid_libs = dbus_hcid_cflags = endif hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) hcid_CONFIG = hcid.conf -LDFLAGS = $(dbus_hcid_ldflags) @BLUEZ_LIBS@ +LIBS = $(dbus_hcid_libs) @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ @DBUS_INCLUDES@ $(dbus_hcid_cflags) diff --git a/hidd/Makefile.am b/hidd/Makefile.am index e74f154d..6b5ff2dc 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -6,6 +6,6 @@ bin_PROGRAMS = hidd hidd_SOURCES = main.c hidd.h sdp.c -LDFLAGS = @BLUEZ_LIBS@ +LIBS = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ diff --git a/pand/Makefile.am b/pand/Makefile.am index 20b99270..0520dc3d 100644 --- a/pand/Makefile.am +++ b/pand/Makefile.am @@ -6,7 +6,7 @@ bin_PROGRAMS = pand pand_SOURCES = main.c pand.h bnep.c sdp.c -LDFLAGS = @BLUEZ_LIBS@ +LIBS = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index 980b0900..b1386b02 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -9,7 +9,7 @@ bin_PROGRAMS = rfcomm rfcomm_SOURCES = main.c parser.h parser.y lexer.l kword.h kword.c rfcomm_CONFIG = rfcomm.conf -LDFLAGS = @BLUEZ_LIBS@ +LIBS = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 97f9b9e1..6fb5411f 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -6,7 +6,7 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h -LDFLAGS = @BLUEZ_LIBS@ +LIBS = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ diff --git a/test/Makefile.am b/test/Makefile.am index 79386603..8c105565 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,7 +4,7 @@ noinst_PROGRAMS = l2test scotest rctest attest hstest -LDFLAGS = @BLUEZ_LIBS@ +LIBS = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ -- cgit From 2cc3c8c8b4ae24e312533f1c60abb9f70e07f2a7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 May 2004 10:41:37 +0000 Subject: Use LDADD instead of LDFLAGS --- tools/Makefile.am | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index c1eb4564..6956f9de 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -10,17 +10,17 @@ noinst_PROGRAMS = ppporc hcisecfilter hciconfig_SOURCES = hciconfig.c csr.h csr.c -hciconfig_LDFLAGS = @BLUEZ_LIBS@ +hciconfig_LDADD = @BLUEZ_LIBS@ -hcitool_LDFLAGS = @BLUEZ_LIBS@ +hcitool_LDADD = @BLUEZ_LIBS@ -l2ping_LDFLAGS = @BLUEZ_LIBS@ +l2ping_LDADD = @BLUEZ_LIBS@ -sdptool_LDFLAGS = @BLUEZ_LIBS@ +sdptool_LDADD = @BLUEZ_LIBS@ -ciptool_LDFLAGS = @BLUEZ_LIBS@ +ciptool_LDADD = @BLUEZ_LIBS@ -ppporc_LDFLAGS = @BLUEZ_LIBS@ +ppporc_LDADD = @BLUEZ_LIBS@ INCLUDES = @BLUEZ_INCLUDES@ -- cgit From 603fb9b1df0e95cbd5af23615f96f2aa16ba7407 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 May 2004 22:21:42 +0000 Subject: Add support for writing a pidfile and cleaning up the connection on exit --- pand/main.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- pand/pand.1 | 6 ++++ 2 files changed, 105 insertions(+), 5 deletions(-) diff --git a/pand/main.c b/pand/main.c index 1bc1d9e0..d4a29867 100644 --- a/pand/main.c +++ b/pand/main.c @@ -43,6 +43,8 @@ #include #include +#include +#include #include #include @@ -61,6 +63,7 @@ static int use_sdp = 1; static int use_cache; static int encrypt; static int master; +static int cleanup; static int search_duration = 10; static struct { @@ -70,12 +73,14 @@ static struct { } cache; static char netdev[16] = "bnep%d"; - +static char *pidfile = NULL; static bdaddr_t src_addr = *BDADDR_ANY; static int src_dev = -1; volatile int terminate; +static void do_kill(char *dst); + enum { NONE, SHOW, @@ -276,9 +281,15 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) run_devup(netdev, dst); - if (persist) + if (persist) { w4_hup(sk); + if (terminate && cleanup) { + syslog(LOG_INFO, "Disconnecting from %s.", dst); + do_kill(dst); + } + } + r = 0; } else { syslog(LOG_ERR, "Connect to %s failed. %s(%d)", @@ -386,6 +397,71 @@ void sig_term(int sig) terminate = 1; } +int write_pidfile(void) +{ + int fd; + FILE *f; + pid_t pid; + + do { + fd = open(pidfile, O_WRONLY|O_TRUNC|O_CREAT|O_EXCL, 0644); + if (fd == -1) { + /* Try to open the file for read. */ + fd = open(pidfile, O_RDONLY); + if(fd == -1) { + syslog(LOG_ERR, "Could not read old pidfile: %s(%d)", strerror(errno), errno); + return -1; + } + + /* We're already running; send a SIGHUP (we presume that they + * are calling ifup for a reason, so they probably want to + * rescan) and then exit cleanly and let things go on in the + * background. Muck with the filename so that we don't go + * deleting the pid file for the already-running instance. + */ + f = fdopen(fd, "r"); + if (!f) { + syslog(LOG_ERR, "Could not fdopen old pidfile: %s(%d)", strerror(errno), errno); + close(fd); + return -1; + } + + pid = 0; + fscanf(f, "%d", &pid); + fclose(f); + + if (pid) { + /* Try to kill it. */ + if (kill(pid, SIGHUP) == -1) { + /* No such pid; remove the bogus pid file. */ + syslog(LOG_INFO, "Removing stale pidfile"); + unlink(pidfile); + fd = -1; + } else { + /* Got it. Don't mess with the pid file on + * our way out. */ + syslog(LOG_INFO, "Signalling existing process %d and exiting\n", pid); + pidfile = NULL; + return -1; + } + } + } + } while(fd == -1); + + f = fdopen(fd, "w"); + if (!f) { + syslog(LOG_ERR, "Could not fdopen new pidfile: %s(%d)", strerror(errno), errno); + close(fd); + unlink(pidfile); + return -1; + } + fprintf(f, "%d\n", getpid()); + fclose(f); + return 0; +} + + + static struct option main_lopts[] = { { "help", 0, 0, 'h' }, { "listen", 0, 0, 's' }, @@ -405,10 +481,12 @@ static struct option main_lopts[] = { { "encrypt", 0, 0, 'E' }, { "master", 0, 0, 'M' }, { "cache", 0, 0, 'C' }, + { "pidfile", 1, 0, 'P' }, + { "autozap", 0, 0, 'z' }, { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:i:S:lnp::DQ::EMC::"; +static char main_sopts[] = "hsc:k:Kr:i:S:lnp::DQ::EMC::P:z"; static char main_help[] = "PAN daemon version " VERSION " \n" @@ -418,6 +496,7 @@ static char main_help[] = "\t--show --list -l Show active PAN connections\n" "\t--listen -s Listen for PAN connections\n" "\t--connect -c Create PAN connection\n" + "\t--autozap -z Disconnect automatically on exit\n" "\t--search -Q[duration] Search and connect\n" "\t--kill -k Kill PAN connection\n" "\t--killall -K Kill all PAN connections\n" @@ -430,7 +509,8 @@ static char main_help[] = "\t--master -M Become the master of a piconet\n" "\t--nodetach -n Do not become a daemon\n" "\t--persist -p[interval] Persist mode\n" - "\t--cache -C[valid] Cache addresses\n"; + "\t--cache -C[valid] Cache addresses\n" + "\t--pidfile -P Create PID file\n"; int main(int argc, char **argv) { @@ -519,7 +599,15 @@ int main(int argc, char **argv) else use_cache = 2; break; - + + case 'P': + pidfile = strdup(optarg); + break; + + case 'z': + cleanup = 1; + break; + case 'h': default: printf(main_help); @@ -588,6 +676,9 @@ int main(int argc, char **argv) } } + if (pidfile && write_pidfile()) + return -1; + if (dst) { /* Disable cache invalidation */ use_cache = 0; @@ -607,5 +698,8 @@ int main(int argc, char **argv) break; } + if (pidfile) + unlink(pidfile); + return 0; } diff --git a/pand/pand.1 b/pand/pand.1 index a11a33c0..fbcc1ddd 100644 --- a/pand/pand.1 +++ b/pand/pand.1 @@ -56,4 +56,10 @@ Persist mode .TP \fB\-\-cache\fR \fB\-C[valid]\fR Cache addresses +.TP +\fB\-\-autozap\fR \fB\-z\fR +Disconnect automatically on exit +.TP +\fB\-\-pidfile\fR \fB\-P \fR +Create PID file -- cgit From 120825fb6af4c6dd0c933c798f2fe997d84d2466 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 3 Jun 2004 09:59:40 +0000 Subject: Add build id's for HCI 18.1 and HCI 18.2 firmware --- tools/csr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 60cba66b..6d9185e1 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -242,6 +242,10 @@ static struct { { 856, "HCI 17.3.2" }, { 857, "HCI 17.3.2" }, { 858, "HCI 17.3.2" }, + { 1168, "HCI 18.1" }, + { 1169, "HCI 18.1" }, + { 1392, "HCI 18.2" }, + { 1393, "HCI 18.2" }, { 0, } }; -- cgit From 2650bf7cbc4b7e0121a9995cd056b8debf3bc424 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jun 2004 11:43:19 +0000 Subject: Add support for audio source and audio sink --- tools/sdptool.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index 1dcdf8e4..b3ccf411 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1562,6 +1562,124 @@ end: return ret; } +static int add_audio_source(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, avdtp, a2src; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + sdp_data_t *psm, *version; + uint16_t lp = 0x0019, ver = 0x0100; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID); + svclass_id = sdp_list_append(0, &a2src); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&avdtp, AVDTP_UUID); + proto[1] = sdp_list_append(0, &avdtp); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Audio Source", 0, 0); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto done; + } + + printf("Audio source service registered\n"); + +done: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_audio_sink(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, avdtp, a2snk; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + sdp_data_t *psm, *version; + uint16_t lp = 0x0019, ver = 0x0100; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&a2snk, AUDIO_SINK_SVCLASS_ID); + svclass_id = sdp_list_append(0, &a2snk); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&avdtp, AVDTP_UUID); + proto[1] = sdp_list_append(0, &avdtp); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Audio Sink", 0, 0); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto done; + } + + printf("Audio sink service registered\n"); + +done: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + struct { char *name; uint16_t class; @@ -1584,6 +1702,9 @@ struct { { "CIP", CIP_SVCLASS_ID, add_cip }, { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, + { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source }, + { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, + { 0 } }; -- cgit From f3ba72e2b071ba40bfe535a4b76193100a956462 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 12 Jun 2004 09:41:17 +0000 Subject: Change timeout for create connection --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 5cecdf7e..8f03ae86 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -660,7 +660,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 1000) < 0) + if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 25000) < 0) perror("Can't create connection"); hci_close_dev(dd); } -- cgit From dfcfad85283a8835c5b6c7fa906c4752b5e22d77 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 12 Jun 2004 14:00:04 +0000 Subject: Update minor parts of the hidd --- hidd/hidd.h | 2 +- hidd/main.c | 16 +++++++++++----- hidd/sdp.c | 24 +++++++++++------------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/hidd/hidd.h b/hidd/hidd.h index cd0c102c..451bea4e 100644 --- a/hidd/hidd.h +++ b/hidd/hidd.h @@ -29,4 +29,4 @@ #define L2CAP_PSM_HIDP_CTRL 0x11 #define L2CAP_PSM_HIDP_INTR 0x13 -int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req); +int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, uint8_t *subclass, struct hidp_connadd_req *req); diff --git a/hidd/main.c b/hidd/main.c index 7270a235..e4202643 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -156,6 +156,7 @@ static int create_device(int ctl, int csk, int isk, int timeout) struct hidp_connadd_req req; struct sockaddr_l2 addr; socklen_t addrlen; + uint8_t subclass; bdaddr_t src, dst; char bda[18]; int err; @@ -182,15 +183,19 @@ static int create_device(int ctl, int csk, int isk, int timeout) req.flags = 0; req.idle_to = timeout * 60; - err = get_hid_device_info(&src, &dst, &req); + err = get_hid_device_info(&src, &dst, &subclass, &req); if (err < 0) - return err; + goto error; ba2str(&dst, bda); syslog(LOG_INFO, "New HID device %s (%s)", bda, req.name); + if (subclass == 0x40) { + } + err = ioctl(ctl, HIDPCONNADD, &req); +error: if (req.rd_data) free(req.rd_data); @@ -228,8 +233,9 @@ static void run_server(int ctl, int csk, int isk, int timeout) syslog(LOG_ERR, "HID create error %d (%s)", errno, strerror(errno)); - close(ncsk); close(nisk); + sleep(1); + close(ncsk); } } } @@ -319,7 +325,7 @@ static void do_search(int ctl, bdaddr_t *bdaddr, int timeout) length = 8; /* ~10 seconds */ num_rsp = 0; - flags = 0; + flags = IREQ_CACHE_FLUSH; printf("Searching ...\n"); @@ -327,7 +333,7 @@ static void do_search(int ctl, bdaddr_t *bdaddr, int timeout) for (i = 0; i < num_rsp; i++) { memcpy(class, (info+i)->dev_class, 3); - if (class[1] == 0x25 && class[2] == 0x00) { + if (class[1] == 0x25 && (class[2] == 0x00 || class[2] == 0x01)) { bacpy(&dst, &(info+i)->bdaddr); ba2str(&dst, addr); diff --git a/hidd/sdp.c b/hidd/sdp.c index 4db9a4c8..467129b2 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -49,7 +49,7 @@ #include "hidd.h" -int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req) +int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, uint8_t *subclass, struct hidp_connadd_req *req) { uint32_t range = 0x0000ffff; sdp_session_t *s; @@ -90,16 +90,13 @@ int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *r rec = (sdp_record_t *) pnp_rsp->data; pdlist = sdp_data_get(rec, 0x0201); - if (pdlist) - req->vendor = pdlist->val.uint16; + req->vendor = pdlist ? pdlist->val.uint16 : 0x0000; pdlist = sdp_data_get(rec, 0x0202); - if (pdlist) - req->product = pdlist->val.uint16; + req->product = pdlist ? pdlist->val.uint16 : 0x0000; pdlist = sdp_data_get(rec, 0x0203); - if (pdlist) - req->version = pdlist->val.uint16; + req->version = pdlist ? pdlist->val.uint16 : 0x0000; sdp_record_free(rec); } @@ -125,14 +122,15 @@ int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *r } pdlist = sdp_data_get(rec, 0x0201); - if (pdlist) - req->parser = pdlist->val.uint16; - else - req->parser = 0x0100; + req->parser = pdlist ? pdlist->val.uint16 : 0x0100; + + if (subclass) { + pdlist = sdp_data_get(rec, 0x0202); + *subclass = pdlist ? pdlist->val.uint8 : 0; + } pdlist = sdp_data_get(rec, 0x0203); - if (pdlist) - req->country = pdlist->val.uint8; + req->country = pdlist ? pdlist->val.uint8 : 0; pdlist = sdp_data_get(rec, 0x0206); if (pdlist) { -- cgit From afc7d6ff6663086aa8bb745fcb8f03f4d5f1d5aa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 13 Jun 2004 15:27:30 +0000 Subject: Fix size of address array --- hcid/security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hcid/security.c b/hcid/security.c index 7ac0dc79..7e2123ca 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -236,7 +236,7 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) { pin_code_reply_cp pr; struct sigaction sa; - char addr[12], str[255], *pin, name[20]; + char addr[18], str[255], *pin, name[20]; FILE *pipe; int ret, len; -- cgit From a40e152629d99aa0d64bfd4da689b4d524b440ce Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 16 Jun 2004 09:34:35 +0000 Subject: Update README --- README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 7bfa32df..fbbda530 100644 --- a/README +++ b/README @@ -7,7 +7,7 @@ Copyright (C) 2002-2004 Marcel Holtmann Bluetooth utilities -1. Compilation and installation. +1. Compilation and installation In order to compile Bluetooth utilities you need following software packages: - Linux Bluetooth protocol stack (BlueZ) @@ -27,8 +27,8 @@ To compile and install run: 2. Information Mailing lists: - bluez-users@lists.sourceforge.net - BlueZ general questions and discussions - bluez-devel@lists.sourceforge.net - BlueZ development + bluez-users@lists.sf.net - BlueZ general questions and discussions + bluez-devel@lists.sf.net - BlueZ development For additional information about the project visit BlueZ web site: http://www.bluez.org -- cgit From 587fe743849609dd150666d84f8fa53cd403a70e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 23 Jun 2004 16:30:41 +0000 Subject: Add support for AmbiCom BT2000C card --- pcmcia/bluetooth.conf | 4 ++++ tools/hciattach.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 42f824fa..79ef717d 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -26,6 +26,10 @@ card "Brain Boxes BL-620 Bluetooth Adapter" version "Brain Boxes", "Bluetooth PC Card" bind "serial_cs" class "bluetooth" +card "AmbiCom BT2000C Bluetooth PC/CF Card" + version ""AmbiCom BT2000C", "Bluetooth PC/CF Card" + bind "serial_cs" class "bluetooth" + card "COM One Platinium Bluetooth PC Card" version "COM1 SA", "MC310 CARD" bind "serial_cs" class "bluetooth" diff --git a/tools/hciattach.c b/tools/hciattach.c index 50432ec3..2024c1de 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -833,6 +833,9 @@ struct uart_t uart[] = { /* 3Com Bluetooth Card (Version 3.0) */ { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + /* AmbiCom BT2000C Bluetooth PC/CF Card */ + { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, csr }, + { NULL, 0 } }; -- cgit From 4b2d32e1fe19c4b84d925bc1d6bb2bd0e39cb156 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 28 Jun 2004 10:57:18 +0000 Subject: Set olen before calling getsockopt() --- pand/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pand/main.c b/pand/main.c index d4a29867..9dfa18a1 100644 --- a/pand/main.c +++ b/pand/main.c @@ -136,6 +136,7 @@ static int do_listen(void) } /* Setup L2CAP options according to BNEP spec */ + olen = sizeof(l2o); if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) { syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)", strerror(errno), errno); @@ -257,6 +258,7 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) } /* Setup L2CAP options according to BNEP spec */ + olen = sizeof(l2o); getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); l2o.imtu = l2o.omtu = BNEP_MTU; setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); -- cgit From f21d9765a64fc97cf269727b7762fd1d277fedec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 29 Jun 2004 08:53:29 +0000 Subject: Restore signals for dev-up script --- pand/main.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pand/main.c b/pand/main.c index 9dfa18a1..4afc095f 100644 --- a/pand/main.c +++ b/pand/main.c @@ -89,9 +89,10 @@ enum { KILL } modes; -static void run_devup(char *dev, char *dst) +static void run_devup(char *dev, char *dst, int sk, int nsk) { char *argv[4], prog[40]; + struct sigaction sa; sprintf(prog, "%s/%s", PAND_CONFIG_DIR, PAND_DEVUP_CMD); @@ -101,6 +102,17 @@ static void run_devup(char *dev, char *dst) if (fork()) return; + if (sk >= 0) + close(sk); + + if (nsk >= 0) + close(nsk); + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + argv[0] = prog; argv[1] = dev; argv[2] = dst; @@ -190,7 +202,7 @@ static int do_listen(void) syslog(LOG_INFO, "New connection from %s %s", str, netdev); - run_devup(netdev, str); + run_devup(netdev, str, sk, nsk); } else { syslog(LOG_ERR, "Connection failed. %s(%d)", strerror(errno), errno); @@ -281,7 +293,7 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) syslog(LOG_INFO, "%s connected", netdev); - run_devup(netdev, dst); + run_devup(netdev, dst, sk, -1); if (persist) { w4_hup(sk); -- cgit From 50111729540851e01dd1471d4ce742ee44f437e7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 4 Jul 2004 15:41:53 +0000 Subject: Make use of new subclass field --- hidd/hidd.h | 2 +- hidd/main.c | 5 ++--- hidd/sdp.c | 8 +++----- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/hidd/hidd.h b/hidd/hidd.h index 451bea4e..cd0c102c 100644 --- a/hidd/hidd.h +++ b/hidd/hidd.h @@ -29,4 +29,4 @@ #define L2CAP_PSM_HIDP_CTRL 0x11 #define L2CAP_PSM_HIDP_INTR 0x13 -int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, uint8_t *subclass, struct hidp_connadd_req *req); +int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req); diff --git a/hidd/main.c b/hidd/main.c index e4202643..c265848b 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -156,7 +156,6 @@ static int create_device(int ctl, int csk, int isk, int timeout) struct hidp_connadd_req req; struct sockaddr_l2 addr; socklen_t addrlen; - uint8_t subclass; bdaddr_t src, dst; char bda[18]; int err; @@ -183,14 +182,14 @@ static int create_device(int ctl, int csk, int isk, int timeout) req.flags = 0; req.idle_to = timeout * 60; - err = get_hid_device_info(&src, &dst, &subclass, &req); + err = get_hid_device_info(&src, &dst, &req); if (err < 0) goto error; ba2str(&dst, bda); syslog(LOG_INFO, "New HID device %s (%s)", bda, req.name); - if (subclass == 0x40) { + if (req.subclass & 0x40) { } err = ioctl(ctl, HIDPCONNADD, &req); diff --git a/hidd/sdp.c b/hidd/sdp.c index 467129b2..31020130 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -49,7 +49,7 @@ #include "hidd.h" -int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, uint8_t *subclass, struct hidp_connadd_req *req) +int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req) { uint32_t range = 0x0000ffff; sdp_session_t *s; @@ -124,10 +124,8 @@ int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, uint8_t *subclass, struct pdlist = sdp_data_get(rec, 0x0201); req->parser = pdlist ? pdlist->val.uint16 : 0x0100; - if (subclass) { - pdlist = sdp_data_get(rec, 0x0202); - *subclass = pdlist ? pdlist->val.uint8 : 0; - } + pdlist = sdp_data_get(rec, 0x0202); + req->subclass = pdlist ? pdlist->val.uint8 : 0; pdlist = sdp_data_get(rec, 0x0203); req->country = pdlist ? pdlist->val.uint8 : 0; -- cgit From bfcc6ade94b279fd03a5efcbf24fe1e151584073 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 4 Jul 2004 15:44:13 +0000 Subject: Add size parameter to expand_name() --- hcid/lib.c | 7 ++++--- hcid/lib.h | 2 +- hcid/main.c | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/hcid/lib.c b/hcid/lib.c index 5fb4b5f2..7edc46a6 100644 --- a/hcid/lib.c +++ b/hcid/lib.c @@ -53,7 +53,7 @@ volatile sig_atomic_t __io_canceled; * Device name expansion * %d - device id */ -char *expand_name(char *dst, char *str, int dev_id) +char *expand_name(char *dst, int size, char *str, int dev_id) { register int sp, np, olen; char *opt, buf[10]; @@ -62,7 +62,7 @@ char *expand_name(char *dst, char *str, int dev_id) return NULL; sp = np = 0; - while (str[sp]) { + while (np < size - 1 && str[sp]) { switch (str[sp]) { case '%': opt = NULL; @@ -88,7 +88,8 @@ char *expand_name(char *dst, char *str, int dev_id) if (opt) { /* substitute */ olen = strlen(opt); - memcpy(dst + np, opt, olen); + if (np + olen < size - 1) + memcpy(dst + np, opt, olen); np += olen; } sp += 2; diff --git a/hcid/lib.h b/hcid/lib.h index 7091fb0d..8043fbc3 100644 --- a/hcid/lib.h +++ b/hcid/lib.h @@ -30,7 +30,7 @@ #include -char *expand_name(char *dst, char *str, int dev_id); +char *expand_name(char *dst, int size, char *str, int dev_id); char *get_host_name(void); diff --git a/hcid/main.c b/hcid/main.c index be523a19..5763798c 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -227,7 +227,8 @@ static void configure_device(int hdev) /* Set device name */ if (device_opts->name) { change_local_name_cp cp; - expand_name(cp.name, device_opts->name, hdev); + memset(cp.name, 0, sizeof(cp.name)); + expand_name(cp.name, sizeof(cp.name), device_opts->name, hdev); hci_send_cmd(s, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, CHANGE_LOCAL_NAME_CP_SIZE, (void *) &cp); -- cgit From 495521cf00684b398eaf69a9bb542d85404a108e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Jul 2004 16:34:47 +0000 Subject: Make use of AM_YFLAGS --- hcid/Makefile.am | 2 +- rfcomm/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index fe04202b..81840804 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -23,7 +23,7 @@ INCLUDES = @BLUEZ_INCLUDES@ @DBUS_INCLUDES@ $(dbus_hcid_cflags) man_MANS = hcid.8 hcid.conf.5 -YFLAGS = -d +AM_YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index b1386b02..a300fcbd 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -15,7 +15,7 @@ INCLUDES = @BLUEZ_INCLUDES@ man_MANS = rfcomm.1 -YFLAGS = -d +AM_YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -- cgit From 7ef1d3ac012443faf2b369aabc3dc209cf5042ea Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Jul 2004 16:41:31 +0000 Subject: Add support for virtual cable unplug --- hidd/main.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index c265848b..b05e15cd 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -409,6 +409,7 @@ static void usage(void) "\t--server Start HID server\n" "\t--search Search for HID devices\n" "\t--connect Connect remote HID device\n" + "\t--unplug Unplug the HID connection\n" "\t--kill Terminate HID connection\n" "\t--killall Terminate all connections\n" "\t--show List current HID connections\n" @@ -432,6 +433,7 @@ static struct option main_options[] = { { "release", 1, 0, 'k' }, { "kill", 1, 0, 'k' }, { "killall", 0, 0, 'K' }, + { "unplug", 1, 0, 'u' }, { 0, 0, 0, 0 } }; @@ -439,6 +441,7 @@ int main(int argc, char *argv[]) { struct sigaction sa; bdaddr_t bdaddr, dev; + uint32_t flags = 0; char addr[18]; int log_option = LOG_NDELAY | LOG_PID; int opt, fd, ctl, csk, isk; @@ -446,7 +449,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:nt:ldsc:k:Kh", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+i:nt:ldsc:k:Ku:h", main_options, NULL)) != -1) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -481,6 +484,11 @@ int main(int argc, char *argv[]) bacpy(&dev, BDADDR_ALL); mode = 4; break; + case 'u': + str2ba(optarg, &dev); + flags = (1 << HIDP_VIRTUAL_CABLE_UNPLUG); + mode = 4; + break; case 'h': usage(); exit(0); @@ -526,7 +534,7 @@ int main(int argc, char *argv[]) exit(0); case 4: - do_kill(ctl, &dev, 0); + do_kill(ctl, &dev, flags); close(ctl); exit(0); -- cgit From 3efa98dc34c7032f614f2bd03a96e24733015002 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Jul 2004 17:20:42 +0000 Subject: Update automake bootstrap process --- bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap b/bootstrap index c9042454..9fb42d22 100755 --- a/bootstrap +++ b/bootstrap @@ -1,2 +1,2 @@ #! /bin/sh -aclocal && autoheader && automake --copy --add-missing && autoconf +aclocal && autoheader && automake --add-missing --copy --force-missing --ignore-deps && autoconf -- cgit From 3eb9e7464eb97a058f692e5c22c5556bb39644ea Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Jul 2004 17:21:03 +0000 Subject: Update changelog and bump version number --- ChangeLog | 14 ++++++++++++++ configure.in | 2 +- utils.spec | 10 +++++----- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff6c3e9f..4a039d16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +ver 2.8: + Use LIBS and LDADD instead of LDFLAGS. + Use HIDP subclass field for HID boot protocol. + Set olen before calling getsockopt() in pand. + Restore signals for dev-up script. + Add PID file support for pand. + Add size parameter to expand_name() in hcid. + Add support for audio source and audio sink SDP records. + Add support for HID virtual cable unplug. + Add support for AmbiCom BT2000C card. + + Note: + This version needs at least bluez-libs-2.8 + ver 2.7: Add support for getting the AFH channel map. Add support for AFH mode. diff --git a/configure.in b/configure.in index 14dce451..4b230c4f 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.7) +AM_INIT_AUTOMAKE(bluez-utils, 2.8) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE diff --git a/utils.spec b/utils.spec index ec94f080..e4fb930b 100644 --- a/utils.spec +++ b/utils.spec @@ -1,5 +1,5 @@ # Note that this is NOT a relocatable package -%define ver 2.7 +%define ver 2.8 %define RELEASE 1 %define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} %define prefix / @@ -12,15 +12,15 @@ Copyright: GPL Group: Applications/System Vendor: Official Linux Bluetooth protocol stack Packager: Sebastian Frankfurt -Source: http://bluez.sourceforge.net/%{name}-%{ver}.tar.gz +Source: http://bluez.sf.net/download/%{name}-%{ver}.tar.gz Patch0: %{name}-%{ver}.patch BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root -URL: http://bluez.sourceforge.net +URL: http://www.bluez.org Docdir: %{prefix}/usr/share/doc Requires: glibc >= 2.2.4 -Requires: bluez-libs >= 2.7 +Requires: bluez-libs >= 2.8 BuildRequires: glibc >= 2.2.4 -BuildRequires: bluez-libs >= 2.7 +BuildRequires: bluez-libs >= 2.8 %description Bluetooth utilities (bluez-utils): -- cgit From 203a7c86997fdedfc368d9e16b3fb6f5fd02dc09 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 12 Jul 2004 17:21:48 +0000 Subject: updates --- utils.spec | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/utils.spec b/utils.spec index e4fb930b..8d8c40fb 100644 --- a/utils.spec +++ b/utils.spec @@ -2,7 +2,7 @@ %define ver 2.8 %define RELEASE 1 %define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} -%define prefix / +%define prefix /usr Summary: Bluetooth utilities Name: bluez-utils @@ -16,7 +16,7 @@ Source: http://bluez.sf.net/download/%{name}-%{ver}.tar.gz Patch0: %{name}-%{ver}.patch BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root URL: http://www.bluez.org -Docdir: %{prefix}/usr/share/doc +Docdir: %{prefix}/share/doc Requires: glibc >= 2.2.4 Requires: bluez-libs >= 2.8 BuildRequires: glibc >= 2.2.4 @@ -63,26 +63,28 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(-, root, root) -/etc/init.d/bluetooth -/etc/default/bluetooth -/usr/bin/hcitool -/usr/bin/l2ping -/usr/bin/bluepin -/usr/bin/rfcomm -/usr/sbin/hciattach -/usr/sbin/hciconfig -/usr/sbin/hcid -/usr/sbin/sdpd -/usr/bin/dund -/usr/bin/pand -/usr/bin/hidd -/usr/bin/sdptool -/usr/bin/ciptool +%{_sysconfdir}/init.d/bluetooth +%{_sysconfdir}/default/bluetooth +%{_bindir}/hcitool +%{_bindir}/l2ping +%{_bindir}/bluepin +%{_bindir}/rfcomm +%{_sbindir}/hciattach +%{_sbindir}/hciconfig +%{_sbindir}/hcid +%{_sbindir}/hid2hci +%{_sbindir}/sdpd +%{_bindir}/dund +%{_bindir}/pand +%{_bindir}/hidd +%{_bindir}/sdptool +%{_bindir}/ciptool %{_mandir}/man8/hciattach.8.gz %{_mandir}/man8/hciconfig.8.gz %{_mandir}/man5/hcid.conf.5.gz %{_mandir}/man8/hcid.8.gz %{_mandir}/man8/sdpd.8.gz +%{_mandir}/man8/hid2hci.8.gz %{_mandir}/man1/dund.1.gz %{_mandir}/man1/pand.1.gz %{_mandir}/man1/hcitool.1.gz -- cgit From ee253a9633d29120dcc2e3be4265240ae538a072 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 13 Jul 2004 03:25:36 +0000 Subject: Add Jean to the copyright statement --- tools/sdptool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index b3ccf411..4f89491d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -6,6 +6,7 @@ * Copyright (C) 2002-2003 Maxim Krasnyansky * Copyright (C) 2002-2004 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane + * Copyright (C) 2002-2003 Jean Tourrilhes * * * This program is free software; you can redistribute it and/or modify -- cgit From 46ad9bd8f518ea68118b9bc0d943d362020df767 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Jul 2004 16:52:07 +0000 Subject: Fix underquoted calls to AC_DEFUN --- acinclude.m4 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 5004e983..020fa969 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -2,7 +2,7 @@ dnl dnl $Id$ dnl -AC_DEFUN(AC_PREFIX_BLUEZ, [ +AC_DEFUN([AC_PREFIX_BLUEZ], [ AC_PREFIX_DEFAULT(/usr) if test "$prefix" = "NONE"; then @@ -22,7 +22,7 @@ AC_DEFUN(AC_PREFIX_BLUEZ, [ fi ]) -AC_DEFUN(AC_PATH_BLUEZ, [ +AC_DEFUN([AC_PATH_BLUEZ], [ AC_ARG_WITH(bluez, [ --with-bluez=DIR BlueZ library is installed in DIR], [ if (test "$withval" = "yes"); then bluez_includes=$bluez_prefix/include @@ -65,7 +65,7 @@ AC_DEFUN(AC_PATH_BLUEZ, [ AC_SUBST(BLUEZ_LIBS) ]) -AC_DEFUN(AC_PATH_DBUS, [ +AC_DEFUN([AC_PATH_DBUS], [ AC_ARG_ENABLE(dbus, [ --enable-dbus enable D-BUS support], [ dbus_enable=$enableval ]) @@ -133,7 +133,7 @@ AC_DEFUN(AC_PATH_DBUS, [ AM_CONDITIONAL(DBUS, test "$dbus_enable" = "yes") ]) -AC_DEFUN(AC_PATH_CUPS, [ +AC_DEFUN([AC_PATH_CUPS], [ AC_ARG_ENABLE(cups, [ --enable-cups enable CUPS support], [ cups_enable=$enableval cups_prefix=/usr -- cgit From 875ca634fbbd21db17a3bd557e650acc4a5ee4da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 15 Jul 2004 18:26:55 +0000 Subject: Don't use --force-missing --- bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap b/bootstrap index 9fb42d22..3426beb4 100755 --- a/bootstrap +++ b/bootstrap @@ -1,2 +1,2 @@ #! /bin/sh -aclocal && autoheader && automake --add-missing --copy --force-missing --ignore-deps && autoconf +aclocal && autoheader && automake --add-missing --copy --ignore-deps && autoconf -- cgit From 5d85c218687d0064163852631eec5daa2a97413f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 15 Jul 2004 18:29:31 +0000 Subject: Add check the for the USB library --- acinclude.m4 | 40 ++++++++++++++++++++++++++++++++++++++++ configure.in | 1 + 2 files changed, 41 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 020fa969..cf0f2447 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -65,6 +65,46 @@ AC_DEFUN([AC_PATH_BLUEZ], [ AC_SUBST(BLUEZ_LIBS) ]) +AC_DEFUN(AC_PATH_USB, [ + AC_ARG_WITH(usb, [ --with-usb=DIR USB library is installed in DIR], [ + if (test "$withval" = "yes"); then + usb_includes=/usr/include + usb_libraries=/usr/lib + else + usb_includes=$withval/include + usb_libraries=$withval/lib + fi + ]) + + USB_INCLUDES="" + USB_LDFLAGS="" + USB_LIBS="" + + ac_save_CFLAGS=$CFLAGS + test -n "$usb_includes" && CFLAGS="$CFLAGS -I$usb_includes" + + ac_save_LDFLAGS=$LDFLAGS + test -n "$usb_libraries" && LDFLAGS="$LDFLAGS -L$usb_libraries" + + AC_CHECK_HEADER(usb.h,, + AC_MSG_ERROR(USB header files not found)) + + AC_CHECK_LIB(usb, usb_open, + USB_LIBS="$USB_LIBS -lusb", + AC_MSG_ERROR(USB library not found)) + + CFLAGS=$ac_save_CFLAGS + test -n "$usb_includes" && USB_INCLUDES="-I$usb_includes" + + LDFLAGS=$ac_save_LDFLAGS + test -n "$usb_libraries" && USB_LDFLAGS="-L$usb_libraries" + test -n "$usb_libraries" && USB_LIBS="-L$usb_libraries $USB_LIBS" + + AC_SUBST(USB_INCLUDES) + AC_SUBST(USB_LDFLAGS) + AC_SUBST(USB_LIBS) +]) + AC_DEFUN([AC_PATH_DBUS], [ AC_ARG_ENABLE(dbus, [ --enable-dbus enable D-BUS support], [ dbus_enable=$enableval diff --git a/configure.in b/configure.in index 4b230c4f..c8cf06f9 100644 --- a/configure.in +++ b/configure.in @@ -22,6 +22,7 @@ AC_PROG_YACC AM_PROG_LEX AC_PATH_BLUEZ +AC_PATH_USB AC_PATH_DBUS AC_PATH_CUPS -- cgit From 20de4b95a609aea3aa6c3be3571b58682dbc95ef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 Jul 2004 09:56:19 +0000 Subject: Update COPYING and INSTALL from automake-1.7 --- COPYING | 4 +- INSTALL | 131 +++++++++++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 91 insertions(+), 44 deletions(-) diff --git a/COPYING b/COPYING index 5b6e7c66..d60c31a9 100644 --- a/COPYING +++ b/COPYING @@ -2,7 +2,7 @@ Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -313,7 +313,7 @@ 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 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. diff --git a/INSTALL b/INSTALL index b42a17ac..54caf7c1 100644 --- a/INSTALL +++ b/INSTALL @@ -1,3 +1,9 @@ +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + Basic Installation ================== @@ -8,20 +14,27 @@ various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, a file -`config.cache' that saves the results of its tests to speed up -reconfiguring, and a file `config.log' containing compiler output -(useful mainly for debugging `configure'). +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can -be considered for the next release. If at some point `config.cache' -contains results you don't want to keep, you may remove or edit it. +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. - The file `configure.in' is used to create `configure' by a program -called `autoconf'. You only need `configure.in' if you want to change -it or regenerate `configure' using a newer version of `autoconf'. + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. The simplest way to compile this package is: @@ -55,14 +68,16 @@ Compilers and Options ===================== Some systems require unusual options for compilation or linking that -the `configure' script does not know about. You can give `configure' -initial values for variables by setting them in the environment. Using -a Bourne-compatible shell, you can do that on the command line like -this: - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: -Or on systems that have the `env' program, you can do it like this: - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== @@ -75,11 +90,11 @@ directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. - If you have to use a `make' that does not supports the `VPATH' -variable, you have to compile the package for one architecture at a time -in the source code directory. After you have installed the package for -one architecture, use `make distclean' before reconfiguring for another -architecture. + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. Installation Names ================== @@ -122,22 +137,32 @@ you can use the `configure' options `--x-includes=DIR' and Specifying the System Type ========================== - There may be some features `configure' can not figure out -automatically, but needs to determine by the type of host the package -will run on. Usually `configure' can figure that out, but if it prints -a message saying it can not guess the host type, give it the -`--host=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name with three fields: + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + CPU-COMPANY-SYSTEM -See the file `config.sub' for the possible values of each field. If +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't -need to know the host type. +need to know the machine type. - If you are building compiler tools for cross-compiling, you can also + If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will -produce code for and the `--build=TYPE' option to select the type of -system on which you are compiling the package. +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. Sharing Defaults ================ @@ -150,20 +175,44 @@ default values for variables like `CC', `cache_file', and `prefix'. `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. -Operation Controls +Defining Variables ================== + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + `configure' recognizes the following options to control how it operates. -`--cache-file=FILE' - Use and save the results of the tests in FILE instead of - `./config.cache'. Set FILE to `/dev/null' to disable caching, for - debugging `configure'. - `--help' +`-h' Print a summary of the options to `configure', and exit. +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + `--quiet' `--silent' `-q' @@ -175,8 +224,6 @@ operates. Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. -`--version' - Print the version of Autoconf used to generate the `configure' - script, and exit. +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. -`configure' also accepts some other, not widely useful, options. -- cgit From 4ed911a4825f8393d920db6139f589f32959adfd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 Jul 2004 15:35:20 +0000 Subject: Fix another underquoted call to AC_DEFUN --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index cf0f2447..162bdbe6 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -65,7 +65,7 @@ AC_DEFUN([AC_PATH_BLUEZ], [ AC_SUBST(BLUEZ_LIBS) ]) -AC_DEFUN(AC_PATH_USB, [ +AC_DEFUN([AC_PATH_USB], [ AC_ARG_WITH(usb, [ --with-usb=DIR USB library is installed in DIR], [ if (test "$withval" = "yes"); then usb_includes=/usr/include -- cgit From 86ba307855dd01138427c88294d42be4b04ecff3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 Jul 2004 18:01:44 +0000 Subject: Search also $libdir for CUPS backend directory --- acinclude.m4 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 162bdbe6..eafdc2f9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -195,6 +195,8 @@ AC_DEFUN([AC_PATH_CUPS], [ if (test -d "$cups_prefix/lib/cups/backend"); then CUPS_BACKEND_DIR="$cups_prefix/lib/cups/backend" + elif (test -d "$libdir/cups/backend"); then + CUPS_BACKEND_DIR="$libdir/cups/backend" else cups_enable=no fi -- cgit From 43f017c9527dd4f64670831114f3c85f5defebbd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:05:27 +0000 Subject: Use AM_CFLAGS instead of INCLUDES --- cups/Makefile.am | 2 +- dund/Makefile.am | 2 +- hcid/Makefile.am | 2 +- hidd/Makefile.am | 2 +- pand/Makefile.am | 2 +- rfcomm/Makefile.am | 2 +- sdpd/Makefile.am | 2 +- test/Makefile.am | 2 +- tools/Makefile.am | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cups/Makefile.am b/cups/Makefile.am index 837bbfa2..9559648f 100644 --- a/cups/Makefile.am +++ b/cups/Makefile.am @@ -8,7 +8,7 @@ bluetooth_SOURCES = main.c sdp.c spp.c hcrp.c LIBS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ if CUPS install-data-local: bluetooth diff --git a/dund/Makefile.am b/dund/Makefile.am index 1c8f4069..92d08224 100644 --- a/dund/Makefile.am +++ b/dund/Makefile.am @@ -8,7 +8,7 @@ dund_SOURCES = main.c dun.c dund.h sdp.c lib.h msdun.c LIBS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = dund.1 diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 81840804..e2f4b904 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -19,7 +19,7 @@ hcid_CONFIG = hcid.conf LIBS = $(dbus_hcid_libs) @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ @DBUS_INCLUDES@ $(dbus_hcid_cflags) +AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ $(dbus_hcid_cflags) man_MANS = hcid.8 hcid.conf.5 diff --git a/hidd/Makefile.am b/hidd/Makefile.am index 6b5ff2dc..d853c8a1 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -8,4 +8,4 @@ hidd_SOURCES = main.c hidd.h sdp.c LIBS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/pand/Makefile.am b/pand/Makefile.am index 0520dc3d..c18c24e0 100644 --- a/pand/Makefile.am +++ b/pand/Makefile.am @@ -8,7 +8,7 @@ pand_SOURCES = main.c pand.h bnep.c sdp.c LIBS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = pand.1 diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index a300fcbd..ddccca30 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -11,7 +11,7 @@ rfcomm_CONFIG = rfcomm.conf LIBS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = rfcomm.1 diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 6fb5411f..0f4460b5 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -8,7 +8,7 @@ sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h LIBS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = sdpd.8 diff --git a/test/Makefile.am b/test/Makefile.am index 8c105565..761df0a5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -6,6 +6,6 @@ noinst_PROGRAMS = l2test scotest rctest attest hstest LIBS = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ EXTRA_DIST = hsplay hsmicro diff --git a/tools/Makefile.am b/tools/Makefile.am index 6956f9de..a10ad999 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -22,7 +22,7 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ -INCLUDES = @BLUEZ_INCLUDES@ +AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 -- cgit From 15c1cf1ca0d2fc45dff471d71339db49deecd1cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:20:28 +0000 Subject: Make use of MAINTAINERCLEANFILES --- cups/Makefile.am | 2 ++ dund/Makefile.am | 2 ++ hcid/Makefile.am | 2 ++ hidd/Makefile.am | 2 ++ pand/Makefile.am | 2 ++ pcmcia/Makefile.am | 2 ++ rfcomm/Makefile.am | 2 ++ scripts/Makefile.am | 2 ++ sdpd/Makefile.am | 2 ++ test/Makefile.am | 2 ++ tools/Makefile.am | 2 ++ 11 files changed, 22 insertions(+) diff --git a/cups/Makefile.am b/cups/Makefile.am index 9559648f..42f3ac2f 100644 --- a/cups/Makefile.am +++ b/cups/Makefile.am @@ -10,6 +10,8 @@ LIBS = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ +MAINTAINERCLEANFILES = Makefile.in + if CUPS install-data-local: bluetooth $(INSTALL) -D -m 755 $(srcdir)/bluetooth $(DESTDIR)@CUPS_BACKEND_DIR@/bluetooth diff --git a/dund/Makefile.am b/dund/Makefile.am index 92d08224..3ff2b36c 100644 --- a/dund/Makefile.am +++ b/dund/Makefile.am @@ -13,3 +13,5 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = dund.1 EXTRA_DIST = $(man_MANS) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/hcid/Makefile.am b/hcid/Makefile.am index e2f4b904..d8524400 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -29,6 +29,8 @@ CLEANFILES = lexer.c parser.c parser.h EXTRA_DIST = $(hcid_CONFIG) $(man_MANS) dbus.c +MAINTAINERCLEANFILES = Makefile.in + # # Install configuration files # diff --git a/hidd/Makefile.am b/hidd/Makefile.am index d853c8a1..a24f505a 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -9,3 +9,5 @@ hidd_SOURCES = main.c hidd.h sdp.c LIBS = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ + +MAINTAINERCLEANFILES = Makefile.in diff --git a/pand/Makefile.am b/pand/Makefile.am index c18c24e0..3ed77891 100644 --- a/pand/Makefile.am +++ b/pand/Makefile.am @@ -13,3 +13,5 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = pand.1 EXTRA_DIST = $(man_MANS) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/pcmcia/Makefile.am b/pcmcia/Makefile.am index 22098446..02999616 100644 --- a/pcmcia/Makefile.am +++ b/pcmcia/Makefile.am @@ -6,6 +6,8 @@ pcmciadir = $(sysconfdir)/pcmcia EXTRA_DIST = bluetooth bluetooth.conf +MAINTAINERCLEANFILES = Makefile.in + install-data-local: $(mkinstalldirs) $(DESTDIR)$(pcmciadir) [ -f $(DESTDIR)$(pcmciadir)/bluetooth ] || \ diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index ddccca30..dd7f4082 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -21,6 +21,8 @@ CLEANFILES = lexer.c parser.c parser.h EXTRA_DIST = $(man_MANS) $(rfcomm_CONFIG) +MAINTAINERCLEANFILES = Makefile.in + install-data-local: $(mkinstalldirs) $(DESTDIR)$(confdir) [ -f $(DESTDIR)$(confdir)/$(rfcomm_CONFIG) ] || \ diff --git a/scripts/Makefile.am b/scripts/Makefile.am index f375290c..677e1306 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -6,6 +6,8 @@ bin_SCRIPTS = bluepin EXTRA_DIST = bluepin bluetooth.init bluetooth.default create_dev +MAINTAINERCLEANFILES = Makefile.in + install-data-local: $(INSTALL) -D -m 755 $(srcdir)/bluetooth.init $(DESTDIR)$(sysconfdir)/init.d/bluetooth $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/default diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 0f4460b5..44d4ba8d 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -13,3 +13,5 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = sdpd.8 EXTRA_DIST = $(man_MANS) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/test/Makefile.am b/test/Makefile.am index 761df0a5..5b3f1ff3 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -9,3 +9,5 @@ LIBS = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ EXTRA_DIST = hsplay hsmicro + +MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/Makefile.am b/tools/Makefile.am index a10ad999..cdba20b4 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -27,3 +27,5 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 EXTRA_DIST = $(man_MANS) + +MAINTAINERCLEANFILES = Makefile.in -- cgit From 4df671d23077a15b6866dc6f7987da6ba06643c8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:24:22 +0000 Subject: Update autoconf routines for better lib/lib64 checks --- Makefile.am | 8 ++- acinclude.m4 | 198 +++++++++++++++++++++++------------------------------------ 2 files changed, 83 insertions(+), 123 deletions(-) diff --git a/Makefile.am b/Makefile.am index 1171035e..8f534963 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,8 +2,10 @@ # $Id$ # -SUBDIRS := hcid tools rfcomm sdpd dund pand hidd cups test scripts pcmcia - -DISTCLEANFILES = conftest.c conftest +SUBDIRS = hcid tools rfcomm sdpd dund pand hidd cups test scripts pcmcia EXTRA_DIST = ChangeLog utils.spec + +MAINTAINERCLEANFILES = Makefile.in \ + aclocal.m4 configure config.h.in \ + missing install-sh mkinstalldirs diff --git a/acinclude.m4 b/acinclude.m4 index eafdc2f9..c49a4ede 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -5,7 +5,7 @@ dnl AC_DEFUN([AC_PREFIX_BLUEZ], [ AC_PREFIX_DEFAULT(/usr) - if test "$prefix" = "NONE"; then + if test "${prefix}" = "NONE"; then dnl no prefix and no sysconfdir, so default to /etc if test "$sysconfdir" = '${prefix}/etc'; then AC_SUBST([sysconfdir], ['/etc']) @@ -16,199 +16,157 @@ AC_DEFUN([AC_PREFIX_BLUEZ], [ AC_SUBST([mandir], ['${prefix}/share/man']) fi - bluez_prefix="$ac_default_prefix" - else - bluez_prefix="$prefix" + prefix="${ac_default_prefix}" fi ]) AC_DEFUN([AC_PATH_BLUEZ], [ AC_ARG_WITH(bluez, [ --with-bluez=DIR BlueZ library is installed in DIR], [ - if (test "$withval" = "yes"); then - bluez_includes=$bluez_prefix/include - bluez_libraries=$bluez_prefix/lib + if (test "${withval}" = "yes"); then + bluez_prefix=${prefix} else - bluez_includes=$withval/include - bluez_libraries=$withval/lib + bluez_prefix=${withval} fi ]) - BLUEZ_INCLUDES="" - BLUEZ_LDFLAGS="" - BLUEZ_LIBS="" - - ac_save_CFLAGS=$CFLAGS - test -n "$bluez_includes" && CFLAGS="$CFLAGS -I$bluez_includes" - + ac_save_CPPFLAGS=$CPPFLAGS ac_save_LDFLAGS=$LDFLAGS - test -n "$bluez_libraries" && LDFLAGS="$LDFLAGS -L$bluez_libraries" - AC_CHECK_HEADER(bluetooth/bluetooth.h,, - AC_MSG_ERROR(Bluetooth header files not found)) + BLUEZ_CFLAGS="" + test -d "${bluez_prefix}/include" && BLUEZ_CFLAGS="$BLUEZ_CFLAGS -I${bluez_prefix}/include" - AC_CHECK_LIB(bluetooth, hci_open_dev, - BLUEZ_LIBS="$BLUEZ_LIBS -lbluetooth", - AC_MSG_ERROR(Bluetooth library not found)) + CPPFLAGS="$CPPFLAGS $BLUEZ_CFLAGS" + AC_CHECK_HEADER(bluetooth/bluetooth.h,, AC_MSG_ERROR(Bluetooth header files not found)) - AC_CHECK_LIB(sdp, sdp_connect, - BLUEZ_LIBS="$BLUEZ_LIBS -lsdp") + BLUEZ_LIBS="" + test -d "${bluez_prefix}/lib" && BLUEZ_LIBS="$BLUEZ_LIBS -L${bluez_prefix}/lib" + test -d "${bluez_prefix}/lib64" && BLUEZ_LIBS="$BLUEZ_LIBS -L${bluez_prefix}/lib64" + test -d "${libdir}" && BLUEZ_LIBS="$BLUEZ_LIBS -L${libdir}" - CFLAGS=$ac_save_CFLAGS - test -n "$bluez_includes" && BLUEZ_INCLUDES="-I$bluez_includes" + LDFLAGS="$LDFLAGS $BLUEZ_LIBS" + AC_CHECK_LIB(bluetooth, hci_open_dev, BLUEZ_LIBS="$BLUEZ_LIBS -lbluetooth", AC_MSG_ERROR(Bluetooth library not found)) + AC_CHECK_LIB(sdp, sdp_connect, BLUEZ_LIBS="$BLUEZ_LIBS -lsdp") + CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS - test -n "$bluez_libraries" && BLUEZ_LDFLAGS="-L$bluez_libraries" - test -n "$bluez_libraries" && BLUEZ_LIBS="-L$bluez_libraries $BLUEZ_LIBS" - AC_SUBST(BLUEZ_INCLUDES) - AC_SUBST(BLUEZ_LDFLAGS) + AC_SUBST(BLUEZ_CFLAGS) AC_SUBST(BLUEZ_LIBS) ]) AC_DEFUN([AC_PATH_USB], [ AC_ARG_WITH(usb, [ --with-usb=DIR USB library is installed in DIR], [ if (test "$withval" = "yes"); then - usb_includes=/usr/include - usb_libraries=/usr/lib + usb_prefix=${prefix} else - usb_includes=$withval/include - usb_libraries=$withval/lib + usb_prefix=${withval} fi ]) - USB_INCLUDES="" - USB_LDFLAGS="" - USB_LIBS="" - - ac_save_CFLAGS=$CFLAGS - test -n "$usb_includes" && CFLAGS="$CFLAGS -I$usb_includes" - + ac_save_CPPFLAGS=$CPPFLAGS ac_save_LDFLAGS=$LDFLAGS - test -n "$usb_libraries" && LDFLAGS="$LDFLAGS -L$usb_libraries" - AC_CHECK_HEADER(usb.h,, - AC_MSG_ERROR(USB header files not found)) + USB_CFLAGS="" + test -d "${usb_prefix}/include" && USB_CFLAGS="$USB_CFLAGS -I${usb_prefix}/include" - AC_CHECK_LIB(usb, usb_open, - USB_LIBS="$USB_LIBS -lusb", - AC_MSG_ERROR(USB library not found)) + CPPFLAGS="$CPPFLAGS $USB_CFLAGS" + AC_CHECK_HEADER(usb.h,, AC_MSG_ERROR(USB header files not found)) - CFLAGS=$ac_save_CFLAGS - test -n "$usb_includes" && USB_INCLUDES="-I$usb_includes" + USB_LIBS="" + test -d "${usb_prefix}/lib" && USB_LIBS="$USB_LIBS -L${usb_prefix}/lib" + test -d "${usb_prefix}/lib64" && USB_LIBS="$USB_LIBS -L${usb_prefix}/lib64" + test -d "${libdir}" && USB_LIBS="$USB_LIBS -L${libdir}" + + LDFLAGS="$LDFLAGS $USB_LIBS" + AC_CHECK_LIB(usb, usb_open, USB_LIBS="$USB_LIBS -lusb", AC_MSG_ERROR(USB library not found)) + CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS - test -n "$usb_libraries" && USB_LDFLAGS="-L$usb_libraries" - test -n "$usb_libraries" && USB_LIBS="-L$usb_libraries $USB_LIBS" - AC_SUBST(USB_INCLUDES) - AC_SUBST(USB_LDFLAGS) + AC_SUBST(USB_CFLAGS) AC_SUBST(USB_LIBS) ]) AC_DEFUN([AC_PATH_DBUS], [ AC_ARG_ENABLE(dbus, [ --enable-dbus enable D-BUS support], [ - dbus_enable=$enableval + dbus_enable=${enableval} + dbus_prefix=${prefix} ]) AC_ARG_WITH(dbus, [ --with-dbus=DIR D-BUS library is installed in DIR], [ - if (test "$withval" = "yes"); then - dbus_includes=$bluez_prefix/include - dbus_libraries=$bluez_prefix/lib + if (test "${withval}" = "yes"); then + dbus_prefix=${prefix} else - dbus_includes=$withval/include - dbus_libraries=$withval/lib + dbus_prefix=${withval} fi dbus_enable=yes ]) - DBUS_INCLUDES="" - DBUS_LDFLAGS="" - DBUS_LIBS="" - - ac_save_CFLAGS=$CFLAGS - if test -n "$dbus_includes"; then - CFLAGS="$CFLAGS -I$dbus_includes -I$dbus_includes/dbus-1.0" - else - CFLAGS="$CFLAGS -I$bluez_prefix/include/dbus-1.0 -I/usr/include/dbus-1.0" - fi - CFLAGS="$CFLAGS -DDBUS_API_SUBJECT_TO_CHANGE" - + ac_save_CPPFLAGS=$CPPFLAGS ac_save_LDFLAGS=$LDFLAGS - if test -n "$dbus_libraries"; then - CFLAGS="$CFLAGS -I$dbus_libraries/dbus-1.0/include" - LDFLAGS="$LDFLAGS -L$dbus_libraries" - else - CFLAGS="$CFLAGS -I$bluez_prefix/include/dbus-1.0 -I/usr/lib/dbus-1.0/include" - fi - if test "$dbus_enable" = "yes"; then - AC_CHECK_HEADER(dbus/dbus.h,, - dbus_enable=no) + DBUS_CFLAGS="-DDBUS_API_SUBJECT_TO_CHANGE" + test -d "${dbus_prefix}/include/dbus-1.0" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/include/dbus-1.0" + test -d "${dbus_prefix}/lib/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib/dbus-1.0/include" + test -d "${dbus_prefix}/lib64/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib64/dbus-1.0/include" + test -d "${libdir}/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${libdir}/dbus-1.0/include" - AC_CHECK_LIB(dbus-1, dbus_error_init, - DBUS_LIBS="$DBUS_LIBS -ldbus-1", - dbus_enable=no) - fi + CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS" + AC_CHECK_HEADER(dbus/dbus.h,, dbus_enable=no) - CFLAGS=$ac_save_CFLAGS - if test -n "$dbus_includes"; then - DBUS_INCLUDES="-I$dbus_includes -I$dbus_includes/dbus-1.0" - else - DBUS_INCLUDES="-I$bluez_prefix/include/dbus-1.0 -I/usr/include/dbus-1.0" - fi + DBUS_LIBS="" + test -d "${dbus_prefix}/lib" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib" + test -d "${dbus_prefix}/lib64" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib64" + test -d "${libdir}" && DBUS_LIBS="$DBUS_LIBS -L${libdir}" + + LDFLAGS="$LDFLAGS $DBUS_LIBS" + AC_CHECK_LIB(dbus-1, dbus_error_init, DBUS_LIBS="$DBUS_LIBS -ldbus-1", dbus_enable=no) + CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS - if test -n "$dbus_libraries"; then - DBUS_INCLUDES="$DBUS_INCLUDES -I$dbus_libraries/dbus-1.0/include" - DBUS_LDFLAGS="-L$dbus_libraries" - DBUS_LIBS="-L$dbus_libraries $DBUS_LIBS" - else - DBUS_INCLUDES="$DBUS_INCLUDES -I$bluez_prefix/include/dbus-1.0 -I/usr/lib/dbus-1.0/include" - fi - AC_SUBST(DBUS_INCLUDES) - AC_SUBST(DBUS_LDFLAGS) + AC_SUBST(DBUS_CFLAGS) AC_SUBST(DBUS_LIBS) - AM_CONDITIONAL(DBUS, test "$dbus_enable" = "yes") + AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes") ]) AC_DEFUN([AC_PATH_CUPS], [ AC_ARG_ENABLE(cups, [ --enable-cups enable CUPS support], [ - cups_enable=$enableval - cups_prefix=/usr + cups_enable=${enableval} + cups_prefix=${prefix} ]) AC_ARG_WITH(cups, [ --with-cups=DIR CUPS is installed in DIR], [ - if (test "$withval" = "yes"); then - cups_prefix=/usr + if (test "${withval}" = "yes"); then + cups_prefix=${prefix} else - cups_prefix=$withval + cups_prefix=${withval} fi cups_enable=yes ]) CUPS_BACKEND_DIR="" - if test "$cups_enable" = "yes"; then - AC_MSG_CHECKING(for CUPS backend directory) + AC_MSG_CHECKING(for CUPS backend directory) - if (test -d "$cups_prefix/lib/cups/backend"); then - CUPS_BACKEND_DIR="$cups_prefix/lib/cups/backend" - elif (test -d "$libdir/cups/backend"); then - CUPS_BACKEND_DIR="$libdir/cups/backend" - else - cups_enable=no - fi + if (test -d "${cups_prefix}/lib/cups/backend"); then + CUPS_BACKEND_DIR="${cups_prefix}/lib/cups/backend" + elif (test -d "${cups_prefix}/lib64/cups/backend"); then + CUPS_BACKEND_DIR="${cups_prefix}/lib64/cups/backend" + elif (test -d "${libdir}/cups/backend"); then + CUPS_BACKEND_DIR="${libdir}/cups/backend" + else + cups_enable=no + fi - if test "$cups_enable" = "yes"; then - AC_MSG_RESULT($CUPS_BACKEND_DIR) - else - AC_MSG_RESULT($cups_enable) - fi + if test "${cups_enable}" = "yes"; then + AC_MSG_RESULT($CUPS_BACKEND_DIR) + else + AC_MSG_RESULT($cups_enable) fi AC_SUBST(CUPS_BACKEND_DIR) - AM_CONDITIONAL(CUPS, test "$cups_enable" = "yes") + AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") ]) -- cgit From 4a754e79fdb1c5f428e47569c0b1efda9a653ff6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:31:39 +0000 Subject: No need to add ChangeLog to EXTRA_DIST --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 8f534963..c027e1c6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ SUBDIRS = hcid tools rfcomm sdpd dund pand hidd cups test scripts pcmcia -EXTRA_DIST = ChangeLog utils.spec +EXTRA_DIST = utils.spec MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in \ -- cgit From 44dd3537501540b967bb368c16279242c4bb5f14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 15:40:55 +0000 Subject: Uninstall local files --- hcid/Makefile.am | 4 ++++ pcmcia/Makefile.am | 4 ++++ scripts/Makefile.am | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index d8524400..5201855d 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -45,3 +45,7 @@ install-data-local: [ -f $(DESTDIR)$(pin_FILE) ] || \ echo "BlueZ" > $(DESTDIR)$(pin_FILE); \ chmod 600 $(DESTDIR)$(pin_FILE) + +uninstall-local: + @rm -f $(DESTDIR)$(conf_FILE) + @rm -f $(DESTDIR)$(pin_FILE) diff --git a/pcmcia/Makefile.am b/pcmcia/Makefile.am index 02999616..f46cdf04 100644 --- a/pcmcia/Makefile.am +++ b/pcmcia/Makefile.am @@ -14,3 +14,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/bluetooth $(DESTDIR)$(pcmciadir) [ -f $(DESTDIR)$(pcmciadir)/bluetooth.conf ] || \ $(INSTALL_DATA) $(srcdir)/bluetooth.conf $(DESTDIR)$(pcmciadir) + +uninstall-local: + @rm -f $(DESTDIR)$(pcmciadir)/bluetooth + @rm -f $(DESTDIR)$(pcmciadir)/bluetooth.conf diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 677e1306..741ae080 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -13,3 +13,7 @@ install-data-local: $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/default [ -f $(DESTDIR)$(sysconfdir)/default/bluetooth ] || \ $(INSTALL_DATA) $(srcdir)/bluetooth.default $(DESTDIR)$(sysconfdir)/default/bluetooth + +uninstall-local: + @rm -f $(DESTDIR)$(sysconfdir)/init.d/bluetooth + @rm -f $(DESTDIR)$(sysconfdir)/default/bluetooth -- cgit From 0d4b1d59962b26ac34648a2fb18be892571963b5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 16:19:39 +0000 Subject: Differentiate a little bit more for the library checks --- acinclude.m4 | 58 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index c49a4ede..f4a689fb 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -5,7 +5,7 @@ dnl AC_DEFUN([AC_PREFIX_BLUEZ], [ AC_PREFIX_DEFAULT(/usr) - if test "${prefix}" = "NONE"; then + if (test "${prefix}" = "NONE"); then dnl no prefix and no sysconfdir, so default to /etc if test "$sysconfdir" = '${prefix}/etc'; then AC_SUBST([sysconfdir], ['/etc']) @@ -39,9 +39,12 @@ AC_DEFUN([AC_PATH_BLUEZ], [ AC_CHECK_HEADER(bluetooth/bluetooth.h,, AC_MSG_ERROR(Bluetooth header files not found)) BLUEZ_LIBS="" - test -d "${bluez_prefix}/lib" && BLUEZ_LIBS="$BLUEZ_LIBS -L${bluez_prefix}/lib" - test -d "${bluez_prefix}/lib64" && BLUEZ_LIBS="$BLUEZ_LIBS -L${bluez_prefix}/lib64" - test -d "${libdir}" && BLUEZ_LIBS="$BLUEZ_LIBS -L${libdir}" + if (test "${prefix}" = "${bluez_prefix}"); then + test -d "${libdir}" && BLUEZ_LIBS="$BLUEZ_LIBS -L${libdir}" + else + test -d "${bluez_prefix}/lib64" && BLUEZ_LIBS="$BLUEZ_LIBS -L${bluez_prefix}/lib64" + test -d "${bluez_prefix}/lib" && BLUEZ_LIBS="$BLUEZ_LIBS -L${bluez_prefix}/lib" + fi LDFLAGS="$LDFLAGS $BLUEZ_LIBS" AC_CHECK_LIB(bluetooth, hci_open_dev, BLUEZ_LIBS="$BLUEZ_LIBS -lbluetooth", AC_MSG_ERROR(Bluetooth library not found)) @@ -73,9 +76,12 @@ AC_DEFUN([AC_PATH_USB], [ AC_CHECK_HEADER(usb.h,, AC_MSG_ERROR(USB header files not found)) USB_LIBS="" - test -d "${usb_prefix}/lib" && USB_LIBS="$USB_LIBS -L${usb_prefix}/lib" - test -d "${usb_prefix}/lib64" && USB_LIBS="$USB_LIBS -L${usb_prefix}/lib64" - test -d "${libdir}" && USB_LIBS="$USB_LIBS -L${libdir}" + if (test "${prefix}" = "${bluez_prefix}"); then + test -d "${libdir}" && USB_LIBS="$USB_LIBS -L${libdir}" + else + test -d "${usb_prefix}/lib64" && USB_LIBS="$USB_LIBS -L${usb_prefix}/lib64" + test -d "${usb_prefix}/lib" && USB_LIBS="$USB_LIBS -L${usb_prefix}/lib" + fi LDFLAGS="$LDFLAGS $USB_LIBS" AC_CHECK_LIB(usb, usb_open, USB_LIBS="$USB_LIBS -lusb", AC_MSG_ERROR(USB library not found)) @@ -107,17 +113,23 @@ AC_DEFUN([AC_PATH_DBUS], [ DBUS_CFLAGS="-DDBUS_API_SUBJECT_TO_CHANGE" test -d "${dbus_prefix}/include/dbus-1.0" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/include/dbus-1.0" - test -d "${dbus_prefix}/lib/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib/dbus-1.0/include" - test -d "${dbus_prefix}/lib64/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib64/dbus-1.0/include" - test -d "${libdir}/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${libdir}/dbus-1.0/include" + if (test "${prefix}" = "${bluez_prefix}"); then + test -d "${libdir}/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${libdir}/dbus-1.0/include" + else + test -d "${dbus_prefix}/lib64/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib64/dbus-1.0/include" + test -d "${dbus_prefix}/lib/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib/dbus-1.0/include" + fi CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS" AC_CHECK_HEADER(dbus/dbus.h,, dbus_enable=no) DBUS_LIBS="" - test -d "${dbus_prefix}/lib" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib" - test -d "${dbus_prefix}/lib64" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib64" - test -d "${libdir}" && DBUS_LIBS="$DBUS_LIBS -L${libdir}" + if (test "${prefix}" = "${bluez_prefix}"); then + test -d "${libdir}" && DBUS_LIBS="$DBUS_LIBS -L${libdir}" + else + test -d "${dbus_prefix}/lib64" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib64" + test -d "${dbus_prefix}/lib" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib" + fi LDFLAGS="$LDFLAGS $DBUS_LIBS" AC_CHECK_LIB(dbus-1, dbus_error_init, DBUS_LIBS="$DBUS_LIBS -ldbus-1", dbus_enable=no) @@ -150,14 +162,20 @@ AC_DEFUN([AC_PATH_CUPS], [ AC_MSG_CHECKING(for CUPS backend directory) - if (test -d "${cups_prefix}/lib/cups/backend"); then - CUPS_BACKEND_DIR="${cups_prefix}/lib/cups/backend" - elif (test -d "${cups_prefix}/lib64/cups/backend"); then - CUPS_BACKEND_DIR="${cups_prefix}/lib64/cups/backend" - elif (test -d "${libdir}/cups/backend"); then - CUPS_BACKEND_DIR="${libdir}/cups/backend" + if (test "${prefix}" = "${bluez_prefix}"); then + if (test -d "${libdir}/cups/backend"); then + CUPS_BACKEND_DIR="${libdir}/cups/backend" + else + cups_enable=no + fi else - cups_enable=no + if (test -d "${cups_prefix}/lib64/cups/backend"); then + CUPS_BACKEND_DIR="${cups_prefix}/lib64/cups/backend" + elif (test -d "${cups_prefix}/lib/cups/backend"); then + CUPS_BACKEND_DIR="${cups_prefix}/lib/cups/backend" + else + cups_enable=no + fi fi if test "${cups_enable}" = "yes"; then -- cgit From fe823e651e91676ddfbc0d10f00847a8aa35e5ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 22 Jul 2004 06:40:58 +0000 Subject: Use specific prefix to check against default prefix --- acinclude.m4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index f4a689fb..46447d20 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -76,7 +76,7 @@ AC_DEFUN([AC_PATH_USB], [ AC_CHECK_HEADER(usb.h,, AC_MSG_ERROR(USB header files not found)) USB_LIBS="" - if (test "${prefix}" = "${bluez_prefix}"); then + if (test "${prefix}" = "${usb_prefix}"); then test -d "${libdir}" && USB_LIBS="$USB_LIBS -L${libdir}" else test -d "${usb_prefix}/lib64" && USB_LIBS="$USB_LIBS -L${usb_prefix}/lib64" @@ -124,7 +124,7 @@ AC_DEFUN([AC_PATH_DBUS], [ AC_CHECK_HEADER(dbus/dbus.h,, dbus_enable=no) DBUS_LIBS="" - if (test "${prefix}" = "${bluez_prefix}"); then + if (test "${prefix}" = "${dbus_prefix}"); then test -d "${libdir}" && DBUS_LIBS="$DBUS_LIBS -L${libdir}" else test -d "${dbus_prefix}/lib64" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib64" @@ -162,7 +162,7 @@ AC_DEFUN([AC_PATH_CUPS], [ AC_MSG_CHECKING(for CUPS backend directory) - if (test "${prefix}" = "${bluez_prefix}"); then + if (test "${prefix}" = "${cups_prefix}"); then if (test -d "${libdir}/cups/backend"); then CUPS_BACKEND_DIR="${libdir}/cups/backend" else -- cgit From dc56ba1a604a097420843a02cc3d2f851a16b819 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 22 Jul 2004 18:10:03 +0000 Subject: Retry SDP connect if busy --- cups/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cups/main.c b/cups/main.c index d43f631b..c6e1deb8 100644 --- a/cups/main.c +++ b/cups/main.c @@ -136,7 +136,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "DEBUG: %s device %s service %s fd %d copies %d\n", argv[0], device, service, fd, copies); - sdp = sdp_connect(BDADDR_ANY, &bdaddr, 0 /*SDP_RETRY_IF_BUSY*/); + sdp = sdp_connect(BDADDR_ANY, &bdaddr, SDP_RETRY_IF_BUSY); if (!sdp) { fprintf(stderr, "ERROR: Can't open Bluetooth connection\n"); return 1; -- cgit From d92a0b2e959fa1e7c174bd877681568404c847b6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 22 Jul 2004 18:20:30 +0000 Subject: Set ${libdir} if not overwritten on command line --- acinclude.m4 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 46447d20..27a33e65 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -18,6 +18,10 @@ AC_DEFUN([AC_PREFIX_BLUEZ], [ prefix="${ac_default_prefix}" fi + + if (test "${libdir}" = "\${exec_prefix}/lib"); then + libdir="${prefix}/lib" + fi ]) AC_DEFUN([AC_PATH_BLUEZ], [ -- cgit From 01e800f18ea32d2b9d285bb245d303e3aa81fc3b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Jul 2004 07:36:18 +0000 Subject: Use packet type and allow role switch --- tools/hcitool.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 8f03ae86..df33412f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -394,6 +394,7 @@ static void cmd_info(int dev_id, int argc, char **argv) char name[248]; unsigned char features[8]; struct hci_version version; + struct hci_dev_info di; struct hci_conn_info_req *cr; int opt, dd, cc = 0; @@ -425,6 +426,11 @@ static void cmd_info(int dev_id, int argc, char **argv) exit(1); } + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + printf("Requesting information ...\n"); dd = hci_open_dev(dev_id); @@ -443,7 +449,7 @@ static void cmd_info(int dev_id, int argc, char **argv) bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &bdaddr, htobs(HCI_DM1 | HCI_DH1), 0, 0, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -618,7 +624,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) uint16_t handle; uint8_t role; - role = 0; + role = 0x01; ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; for_each_opt(opt, cc_options, NULL) { -- cgit From 9498ee036ed2fe8ade15c4973cb09976f74680dd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Jul 2004 15:13:25 +0000 Subject: Update RPM spec file --- utils.spec | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils.spec b/utils.spec index 8d8c40fb..b62cb5e0 100644 --- a/utils.spec +++ b/utils.spec @@ -23,7 +23,8 @@ BuildRequires: glibc >= 2.2.4 BuildRequires: bluez-libs >= 2.8 %description -Bluetooth utilities (bluez-utils): +Bluetooth utilities. + - hcitool - hciattach - hciconfig @@ -55,7 +56,7 @@ make %install rm -rf $RPM_BUILD_ROOT -make DESTDIR=$RPM_BUILD_ROOT prefix=%{prefix} mandir=%{_mandir} install +make DESTDIR=$RPM_BUILD_ROOT prefix=%{prefix} mandir=%{_mandir} sysconfdir=%{_sysconfdir} install %clean rm -rf $RPM_BUILD_ROOT -- cgit From 90a6c1b2e4b6f065bd2c134fa06fe93b174e094d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 26 Jul 2004 20:57:01 +0000 Subject: Use the functions from the USB library --- tools/Makefile.am | 4 +- tools/hid2hci.8 | 3 + tools/hid2hci.c | 179 +++++++++++++++++------------------------------------- 3 files changed, 63 insertions(+), 123 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index cdba20b4..ca0514ce 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -22,7 +22,9 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ -AM_CFLAGS = @BLUEZ_CFLAGS@ +hid2hci_LDADD = @USB_LIBS@ + +AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 diff --git a/tools/hid2hci.8 b/tools/hid2hci.8 index 8f7ea4fe..6aa9be29 100644 --- a/tools/hid2hci.8 +++ b/tools/hid2hci.8 @@ -32,6 +32,9 @@ mode and back. .BI -h Gives a list of possible options. .TP +.BI -q +Don't display any messages. +.TP .BI -0 Switches the device into HCI mode. .TP diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 73b7e12c..6b2aec72 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -33,49 +33,23 @@ #include #include #include -#include -#include #include -#include #include #include #include -static char usbpath[PATH_MAX + 1] = "/proc/bus/usb"; - -struct usb_device_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t bcdUSB; - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - uint8_t bMaxPacketSize0; - uint16_t idVendor; - uint16_t idProduct; - uint16_t bcdDevice; - uint8_t iManufacturer; - uint8_t iProduct; - uint8_t iSerialNumber; - uint8_t bNumConfigurations; -} __attribute__ ((packed)); - -struct usb_ctrltransfer { - uint8_t bRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; - - uint32_t timeout; /* in milliseconds */ - void *data; /* pointer to data */ -}; +#include -#define IOCTL_USB_CONTROL _IOWR('U', 0, struct usb_ctrltransfer) +#ifndef usb_get_busses +struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif -#define USB_RECIP_DEVICE 0x00 -#define USB_TYPE_VENDOR 0x40 -#define USB_DIR_OUT 0x00 +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif static char devpath[PATH_MAX + 1] = "/dev"; @@ -127,34 +101,21 @@ struct device_id { }; struct device_info { - uint16_t busnum; - uint16_t devnum; + struct usb_device *dev; struct device_id *id; }; -static int switch_hidproxy(struct device_info *dev) +static int switch_hidproxy(struct device_info *devinfo) { - struct usb_ctrltransfer ctrl; - char devname[PATH_MAX + 1]; - int fd, err; - - snprintf(devname, PATH_MAX, "%s/%03d/%03d", - usbpath, dev->busnum, dev->devnum); - - fd = open(devname, O_RDWR); - if (fd < 0) - return fd; + struct usb_dev_handle *udev; + int err; - ctrl.bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; - ctrl.bRequest = 0; - ctrl.wValue = dev->id->mode; - ctrl.wIndex = 0; - ctrl.wLength = 0; + udev = usb_open(devinfo->dev); + if (!udev) + return -errno; - ctrl.data = NULL; - ctrl.timeout = 10000; - - err = ioctl(fd, IOCTL_USB_CONTROL, &ctrl); + err = usb_control_msg(udev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, devinfo->id->mode, 0, NULL, 0, 10000); if (err == 0) { err = -1; @@ -164,7 +125,7 @@ static int switch_hidproxy(struct device_info *dev) err = 0; } - close(fd); + usb_close(udev); return err; } @@ -197,7 +158,7 @@ static int send_report(int fd, const unsigned char *buf, size_t size) return err; } -static int switch_logitech(struct device_info *dev) +static int switch_logitech(struct device_info *devinfo) { char devname[PATH_MAX + 1]; int i, fd, err = -1; @@ -223,8 +184,8 @@ static int switch_logitech(struct device_info *dev) memset(&dinfo, 0, sizeof(dinfo)); err = ioctl(fd, HIDIOCGDEVINFO, &dinfo); - if (err < 0 || dinfo.busnum != dev->busnum || - dinfo.devnum != dev->devnum) { + if (err < 0 || dinfo.busnum != atoi(devinfo->dev->bus->dirname) || + dinfo.devnum != atoi(devinfo->dev->filename)) { close(fd); continue; } @@ -281,68 +242,30 @@ static struct device_id *match_device(int mode, uint16_t vendor, uint16_t produc return NULL; } -static int find_devices(int mode, struct device_info *dev, size_t size) +static int find_devices(int mode, struct device_info *devinfo, size_t size) { - DIR *busdir, *devdir; - struct dirent *entry; - struct usb_device_descriptor desc; + struct usb_bus *bus; + struct usb_device *dev; struct device_id *id; - int fd, len, busnum, devnum, count = 0; - char buspath[PATH_MAX + 1]; - char devname[PATH_MAX + 1]; - - if (!(busdir = opendir(usbpath))) - return -1; - - while ((entry = readdir(busdir))) { - if (entry->d_name[0] == '.') - continue; - - if (!strchr("0123456789", - entry->d_name[strlen(entry->d_name) - 1])) - continue; + int count = 0; - busnum = atoi(entry->d_name); - snprintf(buspath, PATH_MAX, "%s/%s", usbpath, entry->d_name); - if (!(devdir = opendir(buspath))) - continue; + usb_find_busses(); + usb_find_devices(); - while ((entry = readdir(devdir))) { - if (entry->d_name[0] == '.') - continue; - - if (!strchr("0123456789", - entry->d_name[strlen(entry->d_name) - 1])) - continue; - - devnum = atoi(entry->d_name); - snprintf(devname, PATH_MAX, "%s/%s", - buspath, entry->d_name); - - if ((fd = open(devname, O_RDONLY)) < 0) - continue; - - len = read(fd, &desc, sizeof(desc)); - if (len < 0 || len != sizeof(desc)) - continue; - - id = match_device(mode, desc.idVendor, desc.idProduct); + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) { + id = match_device(mode, dev->descriptor.idVendor, + dev->descriptor.idProduct); if (!id) continue; if (count < size) { - dev[count].busnum = busnum; - dev[count].devnum = devnum; - dev[count].id = id; + devinfo[count].dev = dev; + devinfo[count].id = id; count++; } } - closedir(devdir); - } - - closedir(busdir); - return count; } @@ -356,6 +279,7 @@ static void usage(void) printf("Options:\n" "\t-h, --help Display help\n" + "\t-q, --quiet Don't display any messages\n" "\t-0, --tohci Switch to HCI mode (default)\n" "\t-1, --tohid Switch to HID mode\n" "\n"); @@ -363,6 +287,7 @@ static void usage(void) static struct option main_options[] = { { "help", 0, 0, 'h' }, + { "quiet", 0, 0, 'q' }, { "tohci", 0, 0, '0' }, { "tohid", 0, 0, '1' }, { 0, 0, 0, 0 } @@ -371,9 +296,9 @@ static struct option main_options[] = { int main(int argc, char *argv[]) { struct device_info dev[16]; - int i, opt, num, mode = HCI; + int i, opt, num, quiet = 0, mode = HCI; - while ((opt = getopt_long(argc, argv, "+01h", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+01qh", main_options, NULL)) != -1) { switch (opt) { case '0': mode = HCI; @@ -381,6 +306,9 @@ int main(int argc, char *argv[]) case '1': mode = HID; break; + case 'q': + quiet = 1; + break; case 'h': usage(); exit(0); @@ -393,24 +321,31 @@ int main(int argc, char *argv[]) argv += optind; optind = 0; + usb_init(); + num = find_devices(mode, dev, sizeof(dev) / sizeof(dev[0])); if (num <= 0) { - fprintf(stderr, "No devices in %s mode found\n", - mode ? "HID" : "HCI"); + if (!quiet) + fprintf(stderr, "No devices in %s mode found\n", + mode ? "HID" : "HCI"); exit(1); } for (i = 0; i < num; i++) { struct device_id *id = dev[i].id; - printf("Switching device %04x:%04x to %s mode ", - id->vendor, id->product, mode ? "HID" : "HCI"); + if (!quiet) + printf("Switching device %04x:%04x to %s mode ", + id->vendor, id->product, mode ? "HID" : "HCI"); fflush(stdout); - if (id->func(&dev[i]) < 0) - printf("failed (%s)\n", strerror(errno)); - else - printf("was successful\n"); + if (id->func(&dev[i]) < 0) { + if (!quiet) + printf("failed (%s)\n", strerror(errno)); + } else { + if (!quiet) + printf("was successful\n"); + } } return 0; -- cgit From f4951d26a8d395ac0e428aab5335a27c3308b6f5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 09:37:21 +0000 Subject: Make use of AC_HELP_STRING --- acinclude.m4 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 27a33e65..6f69c3df 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -25,7 +25,7 @@ AC_DEFUN([AC_PREFIX_BLUEZ], [ ]) AC_DEFUN([AC_PATH_BLUEZ], [ - AC_ARG_WITH(bluez, [ --with-bluez=DIR BlueZ library is installed in DIR], [ + AC_ARG_WITH(bluez, AC_HELP_STRING([--with-bluez=DIR], [BlueZ library is installed in DIR]), [ if (test "${withval}" = "yes"); then bluez_prefix=${prefix} else @@ -62,7 +62,7 @@ AC_DEFUN([AC_PATH_BLUEZ], [ ]) AC_DEFUN([AC_PATH_USB], [ - AC_ARG_WITH(usb, [ --with-usb=DIR USB library is installed in DIR], [ + AC_ARG_WITH(usb, AC_HELP_STRING([--with-usb=DIR], [USB library is installed in DIR]), [ if (test "$withval" = "yes"); then usb_prefix=${prefix} else @@ -98,12 +98,12 @@ AC_DEFUN([AC_PATH_USB], [ ]) AC_DEFUN([AC_PATH_DBUS], [ - AC_ARG_ENABLE(dbus, [ --enable-dbus enable D-BUS support], [ + AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ dbus_enable=${enableval} dbus_prefix=${prefix} ]) - AC_ARG_WITH(dbus, [ --with-dbus=DIR D-BUS library is installed in DIR], [ + AC_ARG_WITH(dbus, AC_HELP_STRING([--with-dbus=DIR], [D-BUS library is installed in DIR]), [ if (test "${withval}" = "yes"); then dbus_prefix=${prefix} else @@ -148,12 +148,12 @@ AC_DEFUN([AC_PATH_DBUS], [ ]) AC_DEFUN([AC_PATH_CUPS], [ - AC_ARG_ENABLE(cups, [ --enable-cups enable CUPS support], [ + AC_ARG_ENABLE(cups, AC_HELP_STRING([--enable-cups], [enable CUPS support]), [ cups_enable=${enableval} cups_prefix=${prefix} ]) - AC_ARG_WITH(cups, [ --with-cups=DIR CUPS is installed in DIR], [ + AC_ARG_WITH(cups, AC_HELP_STRING([--with-cups=DIR], [CUPS is installed in DIR]), [ if (test "${withval}" = "yes"); then cups_prefix=${prefix} else -- cgit From d040d4f33ef0c6388ea70b4b9f3ef3537f0ed60a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 12:35:17 +0000 Subject: Add Broadcom firmware loader --- extra/Makefile.am | 21 ++++++ extra/bcm203x.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++ extra/bcm203x.usermap | 1 + 3 files changed, 216 insertions(+) create mode 100644 extra/Makefile.am create mode 100644 extra/bcm203x.c create mode 100644 extra/bcm203x.usermap diff --git a/extra/Makefile.am b/extra/Makefile.am new file mode 100644 index 00000000..8bbaa2c8 --- /dev/null +++ b/extra/Makefile.am @@ -0,0 +1,21 @@ +# +# $Id$ +# + +datafiles = bcm203x.usermap + +if BCM203X +usbdir = $(sysconfdir)/hotplug/usb + +usb_DATA = $(datafiles) + +usb_PROGRAMS = bcm203x + +LDADD = @USB_LIBS@ + +AM_CFLAGS = @USB_CFLAGS@ +endif + +EXTRA_DIST = $(datafiles) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/extra/bcm203x.c b/extra/bcm203x.c new file mode 100644 index 00000000..b1e89179 --- /dev/null +++ b/extra/bcm203x.c @@ -0,0 +1,194 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2001-2002 Maxim Krasnyansky + * Copyright (C) 2003-2004 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +static char *fw_path = "/lib/firmware"; + +static int load_file(struct usb_dev_handle *udev, char *filename) +{ + unsigned char buf[4096]; + int fd, err, len; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + syslog(LOG_ERR, "Can't open file %s", filename); + return fd; + } + + while (1) { + len = read(fd, buf, sizeof(buf)); + if (len < 0) { + syslog(LOG_ERR, "Can't read from file %s", filename); + close(fd); + return len; + } + + if (len == 0) + break; + + err = usb_bulk_write(udev, 0x02, buf, len, 100000); + if (err < 0) { + syslog(LOG_ERR, "Can't write bulk data packet"); + close(fd); + return err; + } + + if (err != len) { + syslog(LOG_ERR, "Partial bulk packet written"); + close(fd); + return -EIO; + } + } + + close(fd); + return 0; +} + +static void load_firmware(struct usb_device *dev) +{ + struct usb_dev_handle *udev; + char filename[PATH_MAX + 1]; + unsigned char buf[16]; + + udev = usb_open(dev); + if (!udev) { + syslog(LOG_ERR, "Can't open USB device %s/%s", + dev->bus->dirname, dev->filename); + return; + } + + if (usb_claim_interface(udev, 0) < 0) { + usb_close(udev); + return; + } + + syslog(LOG_INFO, "Loading firmware to device %s/%s", + dev->bus->dirname, dev->filename); + + snprintf(filename, PATH_MAX, "%s/%s", fw_path, "BCM2033-MD.hex"); + if (load_file(udev, filename) < 0) + goto done; + + usleep(10); + + if (usb_bulk_write(udev, 0x02, "#", 1, 1000) < 0) { + syslog(LOG_ERR, "Can't write bulk transfer"); + goto done; + } + + memset(buf, 0, sizeof(buf)); + if (usb_interrupt_read(udev, 0x81, buf, 16, 1000) < 0) { + syslog(LOG_ERR, "Can't read interrupt transfer"); + goto done; + } + + if (buf[0] != '#') { + syslog(LOG_ERR, "Memory select failed with '%c'", buf[0]); + goto done; + } + + snprintf(filename, PATH_MAX, "%s/%s", fw_path, "BCM2033-FW.bin"); + if (load_file(udev, filename) < 0) + goto done; + + memset(buf, 0, sizeof(buf)); + if (usb_interrupt_read(udev, 0x81, buf, 16, 1000) < 0) { + syslog(LOG_ERR, "Can't read interrupt transfer"); + goto done; + } + + if (buf[0] == '.') { + syslog(LOG_INFO, "Firmware loaded successful to device %s/%s", + dev->bus->dirname, dev->filename); + } else { + syslog(LOG_ERR, "Firmware loading failed with '%c'", buf[0]); + goto done; + } + + usleep(500000); + +done: + sleep(1); + + usb_release_interface(udev, 0); + usb_close(udev); +} + +int main(int argc, char *argv[]) +{ + struct usb_bus *bus; + struct usb_device *dev; + char *action, *device, *busname, *devname; + + action = getenv("ACTION"); + device = getenv("DEVICE"); + + if (!action || strcmp(action, "add")) + exit(0); + + openlog("bcm203x", LOG_NDELAY | LOG_PID, LOG_DAEMON); + + if (!device || strncmp(device, "/proc/bus/usb/", 14)) { + syslog(LOG_ERR, "Unknown device path %s", device); + closelog(); + exit(1); + } + + busname = strtok(device + 14, "/"); + devname = strtok(NULL, "/"); + + usb_init(); + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) + if (!strcmp(bus->dirname, busname) && + !strcmp(dev->filename, devname)) { + load_firmware(dev); + break; + } + + closelog(); + + return 0; +} diff --git a/extra/bcm203x.usermap b/extra/bcm203x.usermap new file mode 100644 index 00000000..46bdc197 --- /dev/null +++ b/extra/bcm203x.usermap @@ -0,0 +1 @@ +bcm203x 0x0003 0x0a5c 0x2033 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 -- cgit From c37be1ab2480c43fdaec098f75ec5e25a65ceb59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 13:01:42 +0000 Subject: Make more parts optional --- Makefile.am | 2 +- acinclude.m4 | 62 +++++++++++++++++++----------------------------------- configure.in | 4 ++-- cups/Makefile.am | 13 ++++++------ hcid/Makefile.am | 26 +++++------------------ pcmcia/Makefile.am | 19 ++++++----------- rfcomm/Makefile.am | 10 +++------ test/Makefile.am | 8 +++++-- tools/Makefile.am | 21 +++++++++++++----- 9 files changed, 68 insertions(+), 97 deletions(-) diff --git a/Makefile.am b/Makefile.am index c027e1c6..82416cd8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -SUBDIRS = hcid tools rfcomm sdpd dund pand hidd cups test scripts pcmcia +SUBDIRS = hcid tools rfcomm sdpd dund pand hidd cups test scripts pcmcia extra EXTRA_DIST = utils.spec diff --git a/acinclude.m4 b/acinclude.m4 index 6f69c3df..3e9add0c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -76,8 +76,8 @@ AC_DEFUN([AC_PATH_USB], [ USB_CFLAGS="" test -d "${usb_prefix}/include" && USB_CFLAGS="$USB_CFLAGS -I${usb_prefix}/include" - CPPFLAGS="$CPPFLAGS $USB_CFLAGS" - AC_CHECK_HEADER(usb.h,, AC_MSG_ERROR(USB header files not found)) + CPPFLAGS="$CPPFLAGS $USB_CFLAGS" + AC_CHECK_HEADER(usb.h, usb_enable=yes, usb_enable=no) USB_LIBS="" if (test "${prefix}" = "${usb_prefix}"); then @@ -88,7 +88,7 @@ AC_DEFUN([AC_PATH_USB], [ fi LDFLAGS="$LDFLAGS $USB_LIBS" - AC_CHECK_LIB(usb, usb_open, USB_LIBS="$USB_LIBS -lusb", AC_MSG_ERROR(USB library not found)) + AC_CHECK_LIB(usb, usb_open, USB_LIBS="$USB_LIBS -lusb", usb_enable=no) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS @@ -147,48 +147,30 @@ AC_DEFUN([AC_PATH_DBUS], [ AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes") ]) -AC_DEFUN([AC_PATH_CUPS], [ - AC_ARG_ENABLE(cups, AC_HELP_STRING([--enable-cups], [enable CUPS support]), [ - cups_enable=${enableval} - cups_prefix=${prefix} +AC_DEFUN([AC_PATH_EXTRA], [ + AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test], [install test programs]), [ + test_enable=${enableval} ]) - AC_ARG_WITH(cups, AC_HELP_STRING([--with-cups=DIR], [CUPS is installed in DIR]), [ - if (test "${withval}" = "yes"); then - cups_prefix=${prefix} - else - cups_prefix=${withval} - fi - cups_enable=yes + AC_ARG_ENABLE(cups, AC_HELP_STRING([--enable-cups], [install CUPS backend support]), [ + cups_enable=${enableval} + ]) + + AC_ARG_ENABLE(pcmcia, AC_HELP_STRING([--enable-pcmcia], [install PCMCIA configuration files ]), [ + pcmcia_enable=${enableval} ]) - CUPS_BACKEND_DIR="" - - AC_MSG_CHECKING(for CUPS backend directory) - - if (test "${prefix}" = "${cups_prefix}"); then - if (test -d "${libdir}/cups/backend"); then - CUPS_BACKEND_DIR="${libdir}/cups/backend" - else - cups_enable=no - fi - else - if (test -d "${cups_prefix}/lib64/cups/backend"); then - CUPS_BACKEND_DIR="${cups_prefix}/lib64/cups/backend" - elif (test -d "${cups_prefix}/lib/cups/backend"); then - CUPS_BACKEND_DIR="${cups_prefix}/lib/cups/backend" - else - cups_enable=no - fi - fi - - if test "${cups_enable}" = "yes"; then - AC_MSG_RESULT($CUPS_BACKEND_DIR) - else - AC_MSG_RESULT($cups_enable) - fi + AC_ARG_ENABLE(hid2hci, AC_HELP_STRING([--enable-hid2hci], [install HID mode switching utility]), [ + hid2hci_enable=${enableval} + ]) - AC_SUBST(CUPS_BACKEND_DIR) + AC_ARG_ENABLE(bcm203x, AC_HELP_STRING([--enable-bcm203x], [install Broadcom 203x firmware loader]), [ + bcm203x_enable=${enableval} + ]) + AM_CONDITIONAL(TEST, test "${test_enable}" = "yes") AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") + AM_CONDITIONAL(PCMCIA, test "${pcmcia_enable}" = "yes") + AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_enable}" = "yes") + AM_CONDITIONAL(BCM203X, test "${bcm203x_enable}" = "yes" && test "${usb_enable}" = "yes") ]) diff --git a/configure.in b/configure.in index c8cf06f9..84db287c 100644 --- a/configure.in +++ b/configure.in @@ -24,6 +24,6 @@ AM_PROG_LEX AC_PATH_BLUEZ AC_PATH_USB AC_PATH_DBUS -AC_PATH_CUPS +AC_PATH_EXTRA -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile test/Makefile scripts/Makefile pcmcia/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) diff --git a/cups/Makefile.am b/cups/Makefile.am index 42f3ac2f..c43cac54 100644 --- a/cups/Makefile.am +++ b/cups/Makefile.am @@ -2,17 +2,16 @@ # $Id$ # -noinst_PROGRAMS = bluetooth +if CUPS +cupsdir = $(libdir)/cups/backend + +cups_PROGRAMS = bluetooth bluetooth_SOURCES = main.c sdp.c spp.c hcrp.c -LIBS = @BLUEZ_LIBS@ +LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ +endif MAINTAINERCLEANFILES = Makefile.in - -if CUPS -install-data-local: bluetooth - $(INSTALL) -D -m 755 $(srcdir)/bluetooth $(DESTDIR)@CUPS_BACKEND_DIR@/bluetooth -endif diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 5201855d..256eba76 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -2,6 +2,10 @@ # $Id$ # +confdir = $(sysconfdir)/bluetooth + +conf_DATA = hcid.conf + sbin_PROGRAMS = hcid if DBUS @@ -15,7 +19,6 @@ dbus_hcid_cflags = endif hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) -hcid_CONFIG = hcid.conf LIBS = $(dbus_hcid_libs) @BLUEZ_LIBS@ @@ -27,25 +30,6 @@ AM_YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -EXTRA_DIST = $(hcid_CONFIG) $(man_MANS) dbus.c +EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.c MAINTAINERCLEANFILES = Makefile.in - -# -# Install configuration files -# -confdir = $(sysconfdir)/bluetooth -conf_FILE = $(confdir)/$(hcid_CONFIG) -pin_FILE = $(confdir)/pin - -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(confdir) - [ -f $(DESTDIR)$(conf_FILE) ] || \ - $(INSTALL_DATA) $(srcdir)/$(hcid_CONFIG) $(DESTDIR)$(conf_FILE) - [ -f $(DESTDIR)$(pin_FILE) ] || \ - echo "BlueZ" > $(DESTDIR)$(pin_FILE); \ - chmod 600 $(DESTDIR)$(pin_FILE) - -uninstall-local: - @rm -f $(DESTDIR)$(conf_FILE) - @rm -f $(DESTDIR)$(pin_FILE) diff --git a/pcmcia/Makefile.am b/pcmcia/Makefile.am index f46cdf04..59c16334 100644 --- a/pcmcia/Makefile.am +++ b/pcmcia/Makefile.am @@ -2,19 +2,14 @@ # $Id$ # -pcmciadir = $(sysconfdir)/pcmcia +datafiles = bluetooth bluetooth.conf -EXTRA_DIST = bluetooth bluetooth.conf +if PCMCIA +pcmciadir = $(sysconfdir)/pcmcia -MAINTAINERCLEANFILES = Makefile.in +pcmcia_DATA = $(datafiles) +endif -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(pcmciadir) - [ -f $(DESTDIR)$(pcmciadir)/bluetooth ] || \ - $(INSTALL_DATA) $(srcdir)/bluetooth $(DESTDIR)$(pcmciadir) - [ -f $(DESTDIR)$(pcmciadir)/bluetooth.conf ] || \ - $(INSTALL_DATA) $(srcdir)/bluetooth.conf $(DESTDIR)$(pcmciadir) +EXTRA_DIST = $(datafiles) -uninstall-local: - @rm -f $(DESTDIR)$(pcmciadir)/bluetooth - @rm -f $(DESTDIR)$(pcmciadir)/bluetooth.conf +MAINTAINERCLEANFILES = Makefile.in diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index dd7f4082..bedb07f6 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -4,10 +4,11 @@ confdir = $(sysconfdir)/bluetooth +conf_DATA = rfcomm.conf + bin_PROGRAMS = rfcomm rfcomm_SOURCES = main.c parser.h parser.y lexer.l kword.h kword.c -rfcomm_CONFIG = rfcomm.conf LIBS = @BLUEZ_LIBS@ @@ -19,11 +20,6 @@ AM_YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -EXTRA_DIST = $(man_MANS) $(rfcomm_CONFIG) +EXTRA_DIST = $(man_MANS) $(conf_DATA) MAINTAINERCLEANFILES = Makefile.in - -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(confdir) - [ -f $(DESTDIR)$(confdir)/$(rfcomm_CONFIG) ] || \ - $(INSTALL_DATA) $(srcdir)/$(rfcomm_CONFIG) $(DESTDIR)$(confdir)/$(rfcomm_CONFIG) diff --git a/test/Makefile.am b/test/Makefile.am index 5b3f1ff3..5b05c43d 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,11 +2,15 @@ # $Id$ # -noinst_PROGRAMS = l2test scotest rctest attest hstest +if TEST +bin_PROGRAMS = l2test rctest -LIBS = @BLUEZ_LIBS@ +noinst_PROGRAMS = scotest attest hstest + +LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ +endif EXTRA_DIST = hsplay hsmicro diff --git a/tools/Makefile.am b/tools/Makefile.am index ca0514ce..79871391 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,7 +2,20 @@ # $Id$ # -sbin_PROGRAMS = hciattach hciconfig hid2hci +manfiles = hid2hci.8 + +if HID2HCI +xbindir = $(sbindir) +xmandir = $(mandir) + +xbin_PROGRAMS = hid2hci + +hid2hci_LDADD = @USB_LIBS@ + +xman_MANS = $(manfiles) +endif + +sbin_PROGRAMS = hciattach hciconfig bin_PROGRAMS = hcitool l2ping sdptool ciptool @@ -22,12 +35,10 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ -hid2hci_LDADD = @USB_LIBS@ - AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ -man_MANS = hciattach.8 hciconfig.8 hid2hci.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 -EXTRA_DIST = $(man_MANS) +EXTRA_DIST = $(man_MANS) $(manfiles) MAINTAINERCLEANFILES = Makefile.in -- cgit From 4b1de2688c4259152a4741651fb77659edcf401a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 13:19:00 +0000 Subject: Restore creation of /etc/bluetooth/pin --- hcid/Makefile.am | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 256eba76..ac56726e 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -33,3 +33,13 @@ CLEANFILES = lexer.c parser.c parser.h EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.c MAINTAINERCLEANFILES = Makefile.in + +pinfile = $(confdir)/pin + +install-data-local: + [ -f $(DESTDIR)$(pinfile) ] || \ + echo "BlueZ" > $(DESTDIR)$(pinfile); \ + chmod 600 $(DESTDIR)$(pinfile) + +uninstall-local: + @rm -f $(DESTDIR)$(pinfile) -- cgit From 8474a2bd7c42eb2a9df05797d83ed724fb5108a9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 13:58:40 +0000 Subject: Don't forget the hid2hci manpage --- tools/Makefile.am | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index 79871391..086f521e 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,17 +2,16 @@ # $Id$ # -manfiles = hid2hci.8 - if HID2HCI xbindir = $(sbindir) -xmandir = $(mandir) xbin_PROGRAMS = hid2hci hid2hci_LDADD = @USB_LIBS@ -xman_MANS = $(manfiles) +hid2hci_manfiles = hid2hci.8 +else +hid2hci_manfiles = endif sbin_PROGRAMS = hciattach hciconfig @@ -37,8 +36,8 @@ ppporc_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 $(hid2hci_manfiles) -EXTRA_DIST = $(man_MANS) $(manfiles) +EXTRA_DIST = $(man_MANS) hid2hci.8 MAINTAINERCLEANFILES = Makefile.in -- cgit From a743d1272df2dab0d1d0d508c36e8810614abf37 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 14:08:43 +0000 Subject: Add an --enable-all option --- acinclude.m4 | 20 +++++++++++++++----- configure.in | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 3e9add0c..029ef056 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -98,11 +98,6 @@ AC_DEFUN([AC_PATH_USB], [ ]) AC_DEFUN([AC_PATH_DBUS], [ - AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ - dbus_enable=${enableval} - dbus_prefix=${prefix} - ]) - AC_ARG_WITH(dbus, AC_HELP_STRING([--with-dbus=DIR], [D-BUS library is installed in DIR]), [ if (test "${withval}" = "yes"); then dbus_prefix=${prefix} @@ -148,6 +143,21 @@ AC_DEFUN([AC_PATH_DBUS], [ ]) AC_DEFUN([AC_PATH_EXTRA], [ + AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], [enable all extra options]), [ + dbus_enable=${enableval} + dbus_prefix=${prefix} + test_enable=${enableval} + cups_enable=${enableval} + pcmcia_enable=${enableval} + hid2hci_enable=${enableval} + bcm203x_enable=${enableval} + ]) + + AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ + dbus_enable=${enableval} + dbus_prefix=${prefix} + ]) + AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test], [install test programs]), [ test_enable=${enableval} ]) diff --git a/configure.in b/configure.in index 84db287c..dc549bb2 100644 --- a/configure.in +++ b/configure.in @@ -22,8 +22,8 @@ AC_PROG_YACC AM_PROG_LEX AC_PATH_BLUEZ +AC_PATH_EXTRA AC_PATH_USB AC_PATH_DBUS -AC_PATH_EXTRA AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) -- cgit From f519c73fa821fbcec9424411e8b08dc0a296f055 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 14:23:55 +0000 Subject: Make a difference between found library and enabled option --- acinclude.m4 | 36 ++++++++++++++++-------------------- configure.in | 2 +- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 029ef056..c96243d2 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -25,10 +25,10 @@ AC_DEFUN([AC_PREFIX_BLUEZ], [ ]) AC_DEFUN([AC_PATH_BLUEZ], [ + bluez_prefix=${prefix} + AC_ARG_WITH(bluez, AC_HELP_STRING([--with-bluez=DIR], [BlueZ library is installed in DIR]), [ - if (test "${withval}" = "yes"); then - bluez_prefix=${prefix} - else + if (test "${withval}" != "yes"); then bluez_prefix=${withval} fi ]) @@ -62,10 +62,10 @@ AC_DEFUN([AC_PATH_BLUEZ], [ ]) AC_DEFUN([AC_PATH_USB], [ + usb_prefix=${prefix} + AC_ARG_WITH(usb, AC_HELP_STRING([--with-usb=DIR], [USB library is installed in DIR]), [ - if (test "$withval" = "yes"); then - usb_prefix=${prefix} - else + if (test "$withval" != "yes"); then usb_prefix=${withval} fi ]) @@ -77,7 +77,7 @@ AC_DEFUN([AC_PATH_USB], [ test -d "${usb_prefix}/include" && USB_CFLAGS="$USB_CFLAGS -I${usb_prefix}/include" CPPFLAGS="$CPPFLAGS $USB_CFLAGS" - AC_CHECK_HEADER(usb.h, usb_enable=yes, usb_enable=no) + AC_CHECK_HEADER(usb.h, usb_found=yes, usb_found=no) USB_LIBS="" if (test "${prefix}" = "${usb_prefix}"); then @@ -88,7 +88,7 @@ AC_DEFUN([AC_PATH_USB], [ fi LDFLAGS="$LDFLAGS $USB_LIBS" - AC_CHECK_LIB(usb, usb_open, USB_LIBS="$USB_LIBS -lusb", usb_enable=no) + AC_CHECK_LIB(usb, usb_open, USB_LIBS="$USB_LIBS -lusb", usb_found=no) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS @@ -98,13 +98,12 @@ AC_DEFUN([AC_PATH_USB], [ ]) AC_DEFUN([AC_PATH_DBUS], [ + dbus_prefix=${prefix} + AC_ARG_WITH(dbus, AC_HELP_STRING([--with-dbus=DIR], [D-BUS library is installed in DIR]), [ - if (test "${withval}" = "yes"); then - dbus_prefix=${prefix} - else + if (test "${withval}" != "yes"); then dbus_prefix=${withval} fi - dbus_enable=yes ]) ac_save_CPPFLAGS=$CPPFLAGS @@ -120,7 +119,7 @@ AC_DEFUN([AC_PATH_DBUS], [ fi CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS" - AC_CHECK_HEADER(dbus/dbus.h,, dbus_enable=no) + AC_CHECK_HEADER(dbus/dbus.h, dbus_found=yes, dbus_found=no) DBUS_LIBS="" if (test "${prefix}" = "${dbus_prefix}"); then @@ -131,21 +130,18 @@ AC_DEFUN([AC_PATH_DBUS], [ fi LDFLAGS="$LDFLAGS $DBUS_LIBS" - AC_CHECK_LIB(dbus-1, dbus_error_init, DBUS_LIBS="$DBUS_LIBS -ldbus-1", dbus_enable=no) + AC_CHECK_LIB(dbus-1, dbus_error_init, DBUS_LIBS="$DBUS_LIBS -ldbus-1", dbus_found=no) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS AC_SUBST(DBUS_CFLAGS) AC_SUBST(DBUS_LIBS) - - AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes") ]) AC_DEFUN([AC_PATH_EXTRA], [ AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], [enable all extra options]), [ dbus_enable=${enableval} - dbus_prefix=${prefix} test_enable=${enableval} cups_enable=${enableval} pcmcia_enable=${enableval} @@ -155,7 +151,6 @@ AC_DEFUN([AC_PATH_EXTRA], [ AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ dbus_enable=${enableval} - dbus_prefix=${prefix} ]) AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test], [install test programs]), [ @@ -178,9 +173,10 @@ AC_DEFUN([AC_PATH_EXTRA], [ bcm203x_enable=${enableval} ]) + AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes" && test "${dbus_found}" = "yes") AM_CONDITIONAL(TEST, test "${test_enable}" = "yes") AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") AM_CONDITIONAL(PCMCIA, test "${pcmcia_enable}" = "yes") - AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_enable}" = "yes") - AM_CONDITIONAL(BCM203X, test "${bcm203x_enable}" = "yes" && test "${usb_enable}" = "yes") + AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes") + AM_CONDITIONAL(BCM203X, test "${bcm203x_enable}" = "yes" && test "${usb_found}" = "yes") ]) diff --git a/configure.in b/configure.in index dc549bb2..84db287c 100644 --- a/configure.in +++ b/configure.in @@ -22,8 +22,8 @@ AC_PROG_YACC AM_PROG_LEX AC_PATH_BLUEZ -AC_PATH_EXTRA AC_PATH_USB AC_PATH_DBUS +AC_PATH_EXTRA AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) -- cgit From 053eb303cb37c762b3bf2dcedef051727a4be3ed Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 14:25:28 +0000 Subject: Mention the --mandir option --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index fbbda530..34355332 100644 --- a/README +++ b/README @@ -16,7 +16,7 @@ In order to compile Bluetooth utilities you need following software packages: - YACC (yacc, bison, byacc) To configure run: - ./configure --prefix=/usr --sysconfdir=/etc + ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc Configure automatically searches for all required components and packages. -- cgit From 35b2772c879130f24c554f4740c396afbbf8c921 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 14:47:54 +0000 Subject: Enable D-BUS support if --with-dbus is used --- acinclude.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/acinclude.m4 b/acinclude.m4 index c96243d2..205c2c83 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -104,6 +104,7 @@ AC_DEFUN([AC_PATH_DBUS], [ if (test "${withval}" != "yes"); then dbus_prefix=${withval} fi + dbus_enable=yes ]) ac_save_CPPFLAGS=$CPPFLAGS -- cgit From 48c6c4bd7bef34ccac611f7f01c7d3725b40b1c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Jul 2004 16:43:40 +0000 Subject: Check for AVM BlueFRITZ! USB v2.0 --- tools/hciconfig.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index d7b7513a..78c56ce7 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1003,9 +1003,12 @@ static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) printf("\tFirmware %d.%d.%03d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); } -static void print_rev_avm(uint16_t rev) +static void print_rev_avm(uint16_t hci_rev, uint16_t lmp_subver) { - printf("\tFirmware 03.%d.%d\n", rev >> 8, rev & 0xff); + if (lmp_subver == 0x01) + printf("\tFirmware 03.%d.%d\n", hci_rev >> 8, hci_rev & 0xff); + else + printf("\tUnknown type\n"); } static void cmd_revision(int ctl, int hdev, char *opt) @@ -1038,7 +1041,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) print_rev_broadcom(ver.hci_rev, ver.lmp_subver); break; case 31: - print_rev_avm(ver.hci_rev); + print_rev_avm(ver.hci_rev, ver.lmp_subver); break; default: printf("\tUnsupported manufacturer\n"); -- cgit From e96820efc671e4e44a4b87084ca85c7efec1fbf0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Jul 2004 15:26:05 +0000 Subject: Also accept ACTION=register --- extra/bcm203x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/bcm203x.c b/extra/bcm203x.c index b1e89179..f4c48364 100644 --- a/extra/bcm203x.c +++ b/extra/bcm203x.c @@ -161,7 +161,7 @@ int main(int argc, char *argv[]) action = getenv("ACTION"); device = getenv("DEVICE"); - if (!action || strcmp(action, "add")) + if (!action || (strcmp(action, "add") && strcmp(action, "register"))) exit(0); openlog("bcm203x", LOG_NDELAY | LOG_PID, LOG_DAEMON); -- cgit From f78701c7b01c507a6913f9b22b336225648193c6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Jul 2004 16:31:26 +0000 Subject: Enable D-BUS support and hid2hci if the libraries are found --- acinclude.m4 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 205c2c83..f7691be0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -104,7 +104,6 @@ AC_DEFUN([AC_PATH_DBUS], [ if (test "${withval}" != "yes"); then dbus_prefix=${withval} fi - dbus_enable=yes ]) ac_save_CPPFLAGS=$CPPFLAGS @@ -141,6 +140,13 @@ AC_DEFUN([AC_PATH_DBUS], [ ]) AC_DEFUN([AC_PATH_EXTRA], [ + dbus_enable=${dbus_found} + test_enable=no + cups_enable=no + pcmcia_enable=no + hid2hci_enable=${usb_found} + bcm203x_enable=no + AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], [enable all extra options]), [ dbus_enable=${enableval} test_enable=${enableval} -- cgit From 8d8392b6c6b12f3aa5a1c2efa025d01a9f44a6ff Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Jul 2004 17:45:58 +0000 Subject: Rewrite the hid2hci check --- tools/Makefile.am | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index 086f521e..6470a8a9 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -3,18 +3,14 @@ # if HID2HCI -xbindir = $(sbindir) - -xbin_PROGRAMS = hid2hci - -hid2hci_LDADD = @USB_LIBS@ - +hid2hci_programs = hid2hci hid2hci_manfiles = hid2hci.8 else +hid2hci_programs = hid2hci_manfiles = endif -sbin_PROGRAMS = hciattach hciconfig +sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool @@ -34,10 +30,14 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ +if HID2HCI +hid2hci_LDADD = @USB_LIBS@ +endif + AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 $(hid2hci_manfiles) -EXTRA_DIST = $(man_MANS) hid2hci.8 +EXTRA_DIST = $(man_MANS) hid2hci.8 hid2hci.c MAINTAINERCLEANFILES = Makefile.in -- cgit From a488cafcdbd15928f43cbe3096853b894a4cc63f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Jul 2004 19:49:33 +0000 Subject: Add --subclass option for overwriting wrong subclass values --- hidd/main.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index b05e15cd..9965d30b 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -151,7 +151,7 @@ static int l2cap_accept(int sk, bdaddr_t *bdaddr) return nsk; } -static int create_device(int ctl, int csk, int isk, int timeout) +static int create_device(int ctl, int csk, int isk, uint8_t subclass, int timeout) { struct hidp_connadd_req req; struct sockaddr_l2 addr; @@ -186,6 +186,9 @@ static int create_device(int ctl, int csk, int isk, int timeout) if (err < 0) goto error; + if (subclass != 0x00) + req.subclass = subclass; + ba2str(&dst, bda); syslog(LOG_INFO, "New HID device %s (%s)", bda, req.name); @@ -201,7 +204,7 @@ error: return err; } -static void run_server(int ctl, int csk, int isk, int timeout) +static void run_server(int ctl, int csk, int isk, uint8_t subclass, int timeout) { struct pollfd p[2]; short events; @@ -227,7 +230,7 @@ static void run_server(int ctl, int csk, int isk, int timeout) ncsk = l2cap_accept(csk, NULL); nisk = l2cap_accept(isk, NULL); - err = create_device(ctl, ncsk, nisk, timeout); + err = create_device(ctl, ncsk, nisk, subclass, timeout); if (err < 0) syslog(LOG_ERR, "HID create error %d (%s)", errno, strerror(errno)); @@ -275,7 +278,7 @@ static void do_show(int ctl) } } -static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, int timeout) +static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int timeout) { int csk, isk, err; @@ -294,7 +297,7 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, int timeout) exit(1); } - err = create_device(ctl, csk, isk, timeout); + err = create_device(ctl, csk, isk, subclass, timeout); if (err < 0) { fprintf(stderr, "HID create error %d (%s)\n", errno, strerror(errno)); @@ -306,7 +309,7 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, int timeout) } } -static void do_search(int ctl, bdaddr_t *bdaddr, int timeout) +static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int timeout) { inquiry_info *info = NULL; bdaddr_t src, dst; @@ -337,7 +340,7 @@ static void do_search(int ctl, bdaddr_t *bdaddr, int timeout) ba2str(&dst, addr); printf("\tConnecting to device %s\n", addr); - do_connect(ctl, &src, &dst, timeout); + do_connect(ctl, &src, &dst, subclass, timeout); } } @@ -401,6 +404,7 @@ static void usage(void) printf("Options:\n" "\t-i Local HCI device or BD Address\n" "\t-t Set idle timeout (in minutes)\n" + "\t-b Overwrite the boot mode subclass\n" "\t-n, --nodaemon Don't fork daemon to background\n" "\t-h, --help Display help\n" "\n"); @@ -419,6 +423,7 @@ static void usage(void) static struct option main_options[] = { { "help", 0, 0, 'h' }, { "nodaemon", 0, 0, 'n' }, + { "subclass", 1, 0, 'b' }, { "timeout", 1, 0, 't' }, { "device", 1, 0, 'i' }, { "show", 0, 0, 'l' }, @@ -442,6 +447,7 @@ int main(int argc, char *argv[]) struct sigaction sa; bdaddr_t bdaddr, dev; uint32_t flags = 0; + uint8_t subclass = 0x00; char addr[18]; int log_option = LOG_NDELAY | LOG_PID; int opt, fd, ctl, csk, isk; @@ -449,7 +455,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:nt:ldsc:k:Ku:h", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+i:nt:b:ldsc:k:Ku:h", main_options, NULL)) != -1) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -463,6 +469,12 @@ int main(int argc, char *argv[]) case 't': timeout = atoi(optarg); break; + case 'b': + if (!strncasecmp(optarg, "0x", 2)) + subclass = (uint8_t) strtol(optarg, NULL, 16); + else + subclass = atoi(optarg); + break; case 'l': mode = 0; break; @@ -524,12 +536,12 @@ int main(int argc, char *argv[]) break; case 2: - do_search(ctl, &bdaddr, timeout); + do_search(ctl, &bdaddr, subclass, timeout); close(ctl); exit(0); case 3: - do_connect(ctl, &bdaddr, &dev, timeout); + do_connect(ctl, &bdaddr, &dev, subclass, timeout); close(ctl); exit(0); @@ -577,7 +589,7 @@ int main(int argc, char *argv[]) sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); - run_server(ctl, csk, isk, timeout); + run_server(ctl, csk, isk, subclass, timeout); syslog(LOG_INFO, "Exit"); -- cgit From 560a2768ee675ed0abd685f062eef1eab58a304f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Jul 2004 09:08:35 +0000 Subject: Add EPoX endian quirk for buggy keyboards --- hidd/sdp.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/hidd/sdp.c b/hidd/sdp.c index 31020130..24ed4b53 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -32,14 +32,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -49,6 +41,31 @@ #include "hidd.h" +static void epox_endian_quirk(unsigned char *data, int size) +{ + /* USAGE_PAGE (Keyboard) 05 07 + * USAGE_MINIMUM (0) 19 00 + * USAGE_MAXIMUM (65280) 2A 00 FF <= must be FF 00 + * LOGICAL_MINIMUM (0) 15 00 + * LOGICAL_MAXIMUM (65280) 26 00 FF <= must be FF 00 + */ + unsigned char pattern[] = { 0x05, 0x07, 0x19, 0x00, 0x2a, 0x00, 0xff, + 0x15, 0x00, 0x26, 0x00, 0xff }; + int i; + + if (!data) + return; + + for (i = 0; i < size - sizeof(pattern); i++) { + if (!memcmp(data + i, pattern, sizeof(pattern))) { + data[i + 5] = 0xff; + data[i + 6] = 0x00; + data[i + 10] = 0xff; + data[i + 11] = 0x00; + } + } +} + int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req) { uint32_t range = 0x0000ffff; @@ -140,6 +157,7 @@ int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *r if (req->rd_data) { memcpy(req->rd_data, (unsigned char *) pdlist->val.str, pdlist->unitSize); req->rd_size = pdlist->unitSize; + epox_endian_quirk(req->rd_data, req->rd_size); } } -- cgit From e6d6d06c733bf8055dfdc0f9b585585cc4e450a4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Jul 2004 09:16:53 +0000 Subject: Show flags of connected devices --- hidd/main.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index 9965d30b..78501fea 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -255,6 +255,20 @@ static char *hidp_state[] = { "closed" }; +static char *hidp_flagstostr(uint32_t flags) +{ + static char str[100] = ""; + + strcat(str, "["); + + if (flags & (1 << HIDP_BOOT_PROTOCOL_MODE)) + strcat(str, "boot-protocol"); + + strcat(str, "]"); + + return str; +} + static void do_show(int ctl) { struct hidp_connlist_req req; @@ -273,8 +287,9 @@ static void do_show(int ctl) for (i = 0; i < req.cnum; i++) { ba2str(&ci[i].bdaddr, addr); - printf("%s %s [%04x:%04x] %s\n", addr, ci[i].name, - ci[i].vendor, ci[i].product, hidp_state[ci[i].state]); + printf("%s %s [%04x:%04x] %s %s\n", addr, ci[i].name, + ci[i].vendor, ci[i].product, hidp_state[ci[i].state], + ci[i].flags ? hidp_flagstostr(ci[i].flags) : ""); } } -- cgit From 82c455c669afad8d25ca27aba1859013bd76c95b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Jul 2004 09:27:17 +0000 Subject: Remove RPM spec file --- Makefile.am | 2 -- utils.spec | 101 ------------------------------------------------------------ 2 files changed, 103 deletions(-) delete mode 100644 utils.spec diff --git a/Makefile.am b/Makefile.am index 82416cd8..0c4d3fe1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,8 +4,6 @@ SUBDIRS = hcid tools rfcomm sdpd dund pand hidd cups test scripts pcmcia extra -EXTRA_DIST = utils.spec - MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in \ missing install-sh mkinstalldirs diff --git a/utils.spec b/utils.spec deleted file mode 100644 index b62cb5e0..00000000 --- a/utils.spec +++ /dev/null @@ -1,101 +0,0 @@ -# Note that this is NOT a relocatable package -%define ver 2.8 -%define RELEASE 1 -%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE} -%define prefix /usr - -Summary: Bluetooth utilities -Name: bluez-utils -Version: %ver -Release: %rel -Copyright: GPL -Group: Applications/System -Vendor: Official Linux Bluetooth protocol stack -Packager: Sebastian Frankfurt -Source: http://bluez.sf.net/download/%{name}-%{ver}.tar.gz -Patch0: %{name}-%{ver}.patch -BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root -URL: http://www.bluez.org -Docdir: %{prefix}/share/doc -Requires: glibc >= 2.2.4 -Requires: bluez-libs >= 2.8 -BuildRequires: glibc >= 2.2.4 -BuildRequires: bluez-libs >= 2.8 - -%description -Bluetooth utilities. - - - hcitool - - hciattach - - hciconfig - - hcid - - sdpd - - dund - - pand - - hidd - - sdptool - - ciptool - - l2ping - - start scripts (RedHat) - - pcmcia configuration files - -The BLUETOOTH trademarks are owned by Bluetooth SIG, Inc., U.S.A. - -%changelog -* Tue Aug 13 2002 Sebastian Frankfurt -- Initial RPM - -%prep -rm -rf $RPM_BUILD_ROOT - -%setup -q - -%build -CFLAGS="$RPM_OPT_FLAGS" ./configure --enable-pcmcia --prefix=%{prefix} --mandir=%{_mandir} --sysconfdir=%{_sysconfdir} -make - -%install -rm -rf $RPM_BUILD_ROOT -make DESTDIR=$RPM_BUILD_ROOT prefix=%{prefix} mandir=%{_mandir} sysconfdir=%{_sysconfdir} install - -%clean -rm -rf $RPM_BUILD_ROOT - -%files -%defattr(-, root, root) - -%{_sysconfdir}/init.d/bluetooth -%{_sysconfdir}/default/bluetooth -%{_bindir}/hcitool -%{_bindir}/l2ping -%{_bindir}/bluepin -%{_bindir}/rfcomm -%{_sbindir}/hciattach -%{_sbindir}/hciconfig -%{_sbindir}/hcid -%{_sbindir}/hid2hci -%{_sbindir}/sdpd -%{_bindir}/dund -%{_bindir}/pand -%{_bindir}/hidd -%{_bindir}/sdptool -%{_bindir}/ciptool -%{_mandir}/man8/hciattach.8.gz -%{_mandir}/man8/hciconfig.8.gz -%{_mandir}/man5/hcid.conf.5.gz -%{_mandir}/man8/hcid.8.gz -%{_mandir}/man8/sdpd.8.gz -%{_mandir}/man8/hid2hci.8.gz -%{_mandir}/man1/dund.1.gz -%{_mandir}/man1/pand.1.gz -%{_mandir}/man1/hcitool.1.gz -%{_mandir}/man1/sdptool.1.gz -%{_mandir}/man1/ciptool.1.gz -%{_mandir}/man1/rfcomm.1.gz -%{_mandir}/man1/l2ping.1.gz -%{_sysconfdir}/bluetooth/* -%{_sysconfdir}/pcmcia/bluetooth.conf -%{_sysconfdir}/pcmcia/bluetooth - -%doc AUTHORS COPYING INSTALL ChangeLog NEWS README - -- cgit From 02be6993b4ae4442c320ef2fbb8080c01c887edf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Jul 2004 09:47:31 +0000 Subject: The USB library is needed for hid2hci and bcm203x --- README | 1 + 1 file changed, 1 insertion(+) diff --git a/README b/README index 34355332..7fc90362 100644 --- a/README +++ b/README @@ -12,6 +12,7 @@ Bluetooth utilities In order to compile Bluetooth utilities you need following software packages: - Linux Bluetooth protocol stack (BlueZ) - GCC compiler + - USB library - Lexical Analyzer (flex, lex) - YACC (yacc, bison, byacc) -- cgit From b4273fd4b7ee7c8d879903a1b1b4bde2d9b5e0fb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Jul 2004 09:49:00 +0000 Subject: Update changelog and bump version number --- ChangeLog | 11 +++++++++++ configure.in | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4a039d16..7cd161d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +ver 2.9: + Retry SDP connect if busy in the CUPS backend. + Use packet type and allow role switch in hcitool. + Use the functions from the USB library for hid2hci. + Add Broadcom firmware loader. + Add EPoX endian quirk for buggy keyboards. + Update the autoconf/automake scripts. + + Note: + This version needs at least bluez-libs-2.9 + ver 2.8: Use LIBS and LDADD instead of LDFLAGS. Use HIDP subclass field for HID boot protocol. diff --git a/configure.in b/configure.in index 84db287c..db44ef1d 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.8) +AM_INIT_AUTOMAKE(bluez-utils, 2.9) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From ddcfd576f568db8e2064ff5e69a0f708c8d0bfa4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Jul 2004 22:03:02 +0000 Subject: Fix double quotation typo --- pcmcia/bluetooth.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 79ef717d..6e059963 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -27,7 +27,7 @@ card "Brain Boxes BL-620 Bluetooth Adapter" bind "serial_cs" class "bluetooth" card "AmbiCom BT2000C Bluetooth PC/CF Card" - version ""AmbiCom BT2000C", "Bluetooth PC/CF Card" + version "AmbiCom BT2000C", "Bluetooth PC/CF Card" bind "serial_cs" class "bluetooth" card "COM One Platinium Bluetooth PC Card" -- cgit From 93f7135d5885057d17bd599a5374053f3b1020e6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Aug 2004 07:57:44 +0000 Subject: Define a value for the configuration directory --- acinclude.m4 | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index f7691be0..878cf50a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -7,21 +7,29 @@ AC_DEFUN([AC_PREFIX_BLUEZ], [ if (test "${prefix}" = "NONE"); then dnl no prefix and no sysconfdir, so default to /etc - if test "$sysconfdir" = '${prefix}/etc'; then + if (test "$sysconfdir" = '${prefix}/etc'); then AC_SUBST([sysconfdir], ['/etc']) fi dnl no prefix and no mandir, so use ${prefix}/share/man as default - if test "$mandir" = '${prefix}/man'; then + if (test "$mandir" = '${prefix}/man'); then AC_SUBST([mandir], ['${prefix}/share/man']) fi prefix="${ac_default_prefix}" fi - if (test "${libdir}" = "\${exec_prefix}/lib"); then + if (test "${libdir}" = '${exec_prefix}/lib'); then libdir="${prefix}/lib" fi + + if (test "$sysconfdir" = '${prefix}/etc'); then + configdir="${prefix}/etc/bluetooth" + else + configdir="${sysconfdir}/bluetooth" + fi + + AC_DEFINE_UNQUOTED(CONFIGDIR, "${configdir}", [Directory for the configuration files]) ]) AC_DEFUN([AC_PATH_BLUEZ], [ -- cgit From 71e6fca1e290bee72853bea6ea3768879d4510a7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 Aug 2004 08:01:36 +0000 Subject: Make use of CONFIGDIR --- hcid/hcid.h | 8 ++++---- rfcomm/parser.y | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index 41b62419..a5074ffa 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -34,10 +34,10 @@ #include "glib-ectomy.h" -#define HCID_CONFIG_FILE "/etc/bluetooth/hcid.conf" -#define HCID_PIN_FILE "/etc/bluetooth/pin" -#define HCID_KEY_FILE "/etc/bluetooth/link_key" -#define HCID_PIN_HELPER "/bin/bluepin" +#define HCID_CONFIG_FILE CONFIGDIR "/hcid.conf" +#define HCID_PIN_FILE CONFIGDIR "/pin" +#define HCID_KEY_FILE CONFIGDIR "/link_key" +#define HCID_PIN_HELPER "/usr/bin/bluepin" struct device_opts { char *name; diff --git a/rfcomm/parser.y b/rfcomm/parser.y index 58bc74c0..1d5f9024 100644 --- a/rfcomm/parser.y +++ b/rfcomm/parser.y @@ -161,7 +161,7 @@ int rfcomm_read_config(char *filename) snprintf(file, MAXPATHLEN, "%s/.bluetooth/rfcomm.conf", getenv("HOME")); if ((getuid() == 0) || (access(file, R_OK) < 0)) - snprintf(file, MAXPATHLEN, "/etc/bluetooth/rfcomm.conf"); + snprintf(file, MAXPATHLEN, "%s/rfcomm.conf", CONFIGDIR); } if (!(yyin = fopen(file, "r"))) -- cgit From 5bec11bb84e13e200a38798271a7da8924c3f6f7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 10 Aug 2004 12:59:39 +0000 Subject: Fix string init for flags to string translation --- hidd/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hidd/main.c b/hidd/main.c index 78501fea..bdbb4013 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -257,7 +257,8 @@ static char *hidp_state[] = { static char *hidp_flagstostr(uint32_t flags) { - static char str[100] = ""; + static char str[100]; + str[0] = 0; strcat(str, "["); -- cgit From da2cf82c5b073be1bc3f3185a16722a2f5d289de Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Aug 2004 12:47:37 +0000 Subject: Make the installation of the init scripts and bluepin optional --- acinclude.m4 | 14 ++++++++++++++ scripts/Makefile.am | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 878cf50a..f45c138c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -152,6 +152,8 @@ AC_DEFUN([AC_PATH_EXTRA], [ test_enable=no cups_enable=no pcmcia_enable=no + initscripts_enable=no + bluepin_enable=no hid2hci_enable=${usb_found} bcm203x_enable=no @@ -160,6 +162,8 @@ AC_DEFUN([AC_PATH_EXTRA], [ test_enable=${enableval} cups_enable=${enableval} pcmcia_enable=${enableval} + initscripts_enable=${enableval} + bluepin_enable=${enableval} hid2hci_enable=${enableval} bcm203x_enable=${enableval} ]) @@ -180,6 +184,14 @@ AC_DEFUN([AC_PATH_EXTRA], [ pcmcia_enable=${enableval} ]) + AC_ARG_ENABLE(initscripts, AC_HELP_STRING([--enable-initscripts], [install Bluetooth boot scripts]), [ + initscripts_enable=${enableval} + ]) + + AC_ARG_ENABLE(bluepin, AC_HELP_STRING([--enable-bluepin], [install Python based PIN helper utility]), [ + bluepin_enable=${enableval} + ]) + AC_ARG_ENABLE(hid2hci, AC_HELP_STRING([--enable-hid2hci], [install HID mode switching utility]), [ hid2hci_enable=${enableval} ]) @@ -192,6 +204,8 @@ AC_DEFUN([AC_PATH_EXTRA], [ AM_CONDITIONAL(TEST, test "${test_enable}" = "yes") AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") AM_CONDITIONAL(PCMCIA, test "${pcmcia_enable}" = "yes") + AM_CONDITIONAL(INITSCRIPTS, test "${initscripts_enable}" = "yes") + AM_CONDITIONAL(BLUEPIN, test "${bluepin_enable}" = "yes") AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(BCM203X, test "${bcm203x_enable}" = "yes" && test "${usb_found}" = "yes") ]) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 741ae080..e77f3f12 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -2,12 +2,15 @@ # $Id$ # +if BLUEPIN bin_SCRIPTS = bluepin +endif EXTRA_DIST = bluepin bluetooth.init bluetooth.default create_dev MAINTAINERCLEANFILES = Makefile.in +if INITSCRIPTS install-data-local: $(INSTALL) -D -m 755 $(srcdir)/bluetooth.init $(DESTDIR)$(sysconfdir)/init.d/bluetooth $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/default @@ -17,3 +20,4 @@ install-data-local: uninstall-local: @rm -f $(DESTDIR)$(sysconfdir)/init.d/bluetooth @rm -f $(DESTDIR)$(sysconfdir)/default/bluetooth +endif -- cgit From 750ac6d869c3b4bd94ecdb6dce9c16265326b954 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Aug 2004 13:17:11 +0000 Subject: Check for usb_get_busses() and usb_interrupt_read() --- acinclude.m4 | 2 ++ extra/bcm203x.c | 14 ++++++++++++++ tools/hid2hci.c | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index f45c138c..e9aa2aca 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -97,6 +97,8 @@ AC_DEFUN([AC_PATH_USB], [ LDFLAGS="$LDFLAGS $USB_LIBS" AC_CHECK_LIB(usb, usb_open, USB_LIBS="$USB_LIBS -lusb", usb_found=no) + AC_CHECK_LIB(usb, usb_get_busses, dummy=yes, AC_DEFINE(NEED_USB_GET_BUSSES, 1, [Define to 1 if you need the usb_get_busses() function.])) + AC_CHECK_LIB(usb, usb_interrupt_read, dummy=yes, AC_DEFINE(NEED_USB_INTERRUPT_READ, 1, [Define to 1 if you need the usb_interrupt_read() function.])) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS diff --git a/extra/bcm203x.c b/extra/bcm203x.c index f4c48364..1aa9257b 100644 --- a/extra/bcm203x.c +++ b/extra/bcm203x.c @@ -40,6 +40,20 @@ #include +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +#ifdef NEED_USB_INTERRUPT_READ +static inline int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) +{ + return usb_bulk_read(dev, ep, bytes, size, timeout); +} +#endif + static char *fw_path = "/lib/firmware"; static int load_file(struct usb_dev_handle *udev, char *filename) diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 6b2aec72..c800c7ee 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -40,8 +40,8 @@ #include -#ifndef usb_get_busses -struct usb_bus *usb_get_busses(void) +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) { return usb_busses; } -- cgit From de58f635303b1ad9d5c61d4e6d714638ba3b0c32 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Aug 2004 16:03:09 +0000 Subject: Add optional support for PIE and debug information --- acinclude.m4 | 39 +++++++++++++++++++++++++++++++++++++-- configure.in | 8 ++++---- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index e9aa2aca..3bf506ce 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -2,9 +2,23 @@ dnl dnl $Id$ dnl -AC_DEFUN([AC_PREFIX_BLUEZ], [ +AC_DEFUN([AC_PROG_CC_PIE], [ + AC_CACHE_CHECK([whether ${CC-cc} accepts -fPIE], ac_cv_prog_cc_pie, [ + echo 'void f(){}' > conftest.c + if test -z "`${CC-cc} -fPIE -pie -c conftest.c 2>&1`"; then + ac_cv_prog_cc_pie=yes + else + ac_cv_prog_cc_pie=no + fi + rm -rf conftest* + ]) +]) + +AC_DEFUN([AC_INIT_BLUEZ], [ AC_PREFIX_DEFAULT(/usr) + CFLAGS="-Wall -O2" + if (test "${prefix}" = "NONE"); then dnl no prefix and no sysconfdir, so default to /etc if (test "$sysconfdir" = '${prefix}/etc'); then @@ -149,7 +163,9 @@ AC_DEFUN([AC_PATH_DBUS], [ AC_SUBST(DBUS_LIBS) ]) -AC_DEFUN([AC_PATH_EXTRA], [ +AC_DEFUN([AC_ARG_BLUEZ], [ + pie_enable=no + debug_enable=no dbus_enable=${dbus_found} test_enable=no cups_enable=no @@ -160,6 +176,8 @@ AC_DEFUN([AC_PATH_EXTRA], [ bcm203x_enable=no AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], [enable all extra options]), [ + pie_enable=${enableval} + debug_enable=${enableval} dbus_enable=${enableval} test_enable=${enableval} cups_enable=${enableval} @@ -170,6 +188,14 @@ AC_DEFUN([AC_PATH_EXTRA], [ bcm203x_enable=${enableval} ]) + AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie], [enable position independent executables option]), [ + pie_enable=${enableval} + ]) + + AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable compiling with debugging information]), [ + debug_enable=${enableval} + ]) + AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ dbus_enable=${enableval} ]) @@ -202,6 +228,15 @@ AC_DEFUN([AC_PATH_EXTRA], [ bcm203x_enable=${enableval} ]) + if (test "${pie_enable}" = "yes" && test "${ac_cv_prog_cc_pie}" = "yes"); then + CFLAGS="$CFLAGS -fPIE" + LDFLAGS="$LDFLAGS -pie" + fi + + if (test "${debug_enable}" = "yes" && test "${ac_cv_prog_cc_g}" = "yes"); then + CFLAGS="$CFLAGS -g" + fi + AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes" && test "${dbus_found}" = "yes") AM_CONDITIONAL(TEST, test "${test_enable}" = "yes") AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") diff --git a/configure.in b/configure.in index db44ef1d..1cf69659 100644 --- a/configure.in +++ b/configure.in @@ -10,13 +10,12 @@ AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -AC_PREFIX_BLUEZ - -CFLAGS="-Wall -g -O2" +AC_INIT_BLUEZ AC_LANG_C AC_PROG_CC +AC_PROG_CC_PIE AC_PROG_INSTALL AC_PROG_YACC AM_PROG_LEX @@ -24,6 +23,7 @@ AM_PROG_LEX AC_PATH_BLUEZ AC_PATH_USB AC_PATH_DBUS -AC_PATH_EXTRA + +AC_ARG_BLUEZ AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) -- cgit From c9fc470995095031ac0469bad82eea94cd31468b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Aug 2004 16:04:04 +0000 Subject: Install bluepin by default --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 3bf506ce..4c23ccd1 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -171,7 +171,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ cups_enable=no pcmcia_enable=no initscripts_enable=no - bluepin_enable=no + bluepin_enable=yes hid2hci_enable=${usb_found} bcm203x_enable=no -- cgit From 6a4c20067612717286e9c85f06705ff509fcc6c8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Aug 2004 16:18:45 +0000 Subject: Don't enable PIE or debug when --enable-all is specified --- acinclude.m4 | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 4c23ccd1..f50253b7 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -175,9 +175,15 @@ AC_DEFUN([AC_ARG_BLUEZ], [ hid2hci_enable=${usb_found} bcm203x_enable=no - AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], [enable all extra options]), [ - pie_enable=${enableval} + AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable compiling with debugging information]), [ debug_enable=${enableval} + ]) + + AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie], [enable position independent executables flag]), [ + pie_enable=${enableval} + ]) + + AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], [enable all extra options below]), [ dbus_enable=${enableval} test_enable=${enableval} cups_enable=${enableval} @@ -188,14 +194,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [ bcm203x_enable=${enableval} ]) - AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie], [enable position independent executables option]), [ - pie_enable=${enableval} - ]) - - AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable compiling with debugging information]), [ - debug_enable=${enableval} - ]) - AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ dbus_enable=${enableval} ]) @@ -228,15 +226,15 @@ AC_DEFUN([AC_ARG_BLUEZ], [ bcm203x_enable=${enableval} ]) + if (test "${debug_enable}" = "yes" && test "${ac_cv_prog_cc_g}" = "yes"); then + CFLAGS="$CFLAGS -g" + fi + if (test "${pie_enable}" = "yes" && test "${ac_cv_prog_cc_pie}" = "yes"); then CFLAGS="$CFLAGS -fPIE" LDFLAGS="$LDFLAGS -pie" fi - if (test "${debug_enable}" = "yes" && test "${ac_cv_prog_cc_g}" = "yes"); then - CFLAGS="$CFLAGS -g" - fi - AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes" && test "${dbus_found}" = "yes") AM_CONDITIONAL(TEST, test "${test_enable}" = "yes") AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") -- cgit From f9cbc885a447b4d1047648b0e2d4749e923a0190 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 13 Aug 2004 12:35:22 +0000 Subject: Don't override CFLAGS --- acinclude.m4 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index f50253b7..91c61eb9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -17,7 +17,9 @@ AC_DEFUN([AC_PROG_CC_PIE], [ AC_DEFUN([AC_INIT_BLUEZ], [ AC_PREFIX_DEFAULT(/usr) - CFLAGS="-Wall -O2" + if (test "${CFLAGS}" = ""); then + CFLAGS="-Wall -O2" + fi if (test "${prefix}" = "NONE"); then dnl no prefix and no sysconfdir, so default to /etc -- cgit From beb514e9152e98bd46018966f365d0cd57e17e4f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 13 Aug 2004 14:04:04 +0000 Subject: Update changelog and bump version number --- ChangeLog | 12 ++++++++++++ configure.in | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7cd161d7..ee26544f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +ver 2.10: + Use a define for the configuration directory. + Fix string initialization for flags translation. + Check for usb_get_busses() and usb_interrupt_read(). + Add optional support for compiling with PIE. + Make installation of the init scripts optional. + Make compiling with debug information optional. + Don't override CFLAGS from configure. + + Note: + This version needs at least bluez-libs-2.10 + ver 2.9: Retry SDP connect if busy in the CUPS backend. Use packet type and allow role switch in hcitool. diff --git a/configure.in b/configure.in index 1cf69659..52ec0525 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.9) +AM_INIT_AUTOMAKE(bluez-utils, 2.10) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From 4b5556bbbb60803559de24a46a15d7533d397041 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Aug 2004 00:38:05 +0000 Subject: Display VERSION information --- hidd/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hidd/main.c b/hidd/main.c index bdbb4013..22883a58 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -411,7 +411,7 @@ static void do_kill(int ctl, bdaddr_t *bdaddr, uint32_t flags) static void usage(void) { - printf("hidd - Bluetooth HID daemon\n\n"); + printf("hidd - Bluetooth HID daemon version %s\n\n", VERSION); printf("Usage:\n" "\thidd [options] [commands]\n" -- cgit From 5c8acb2c0dabd7fe0c8397d97c140d78b7bd8cd7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Aug 2004 10:10:13 +0000 Subject: Don't include asm/types.h --- hcid/security.c | 2 +- tools/hciattach.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hcid/security.c b/hcid/security.c index 7e2123ca..f903e11c 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include diff --git a/tools/hciattach.c b/tools/hciattach.c index 2024c1de..b3f40b3a 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -47,7 +47,7 @@ #include #include #include -#include +#include #include #include -- cgit From 4a5bc48ff3c2a2f3acdacc6fc6ee2632687455e7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Aug 2004 10:11:10 +0000 Subject: Don't include asm/types.h and asm/byteorder.h --- tools/l2ping.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/l2ping.c b/tools/l2ping.c index 85d12eee..af056bc6 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -51,9 +51,6 @@ #include #include -#include -#include - #include #include @@ -134,7 +131,7 @@ static void ping(char *svr) /* Build command header */ cmd->code = L2CAP_ECHO_REQ; cmd->ident = id; - cmd->len = __cpu_to_le16(size); + cmd->len = htobs(size); gettimeofday(&tv_send, NULL); @@ -171,7 +168,7 @@ static void ping(char *svr) exit(1); } - cmd->len = __le16_to_cpu(cmd->len); + cmd->len = btohs(cmd->len); /* Check for our id */ if( cmd->ident != id ) -- cgit From e7989c831f54770196b92d24d78f80d5c5161352 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Aug 2004 11:22:22 +0000 Subject: Let the id display start with 0 even if internal it start with 200 --- tools/l2ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/l2ping.c b/tools/l2ping.c index af056bc6..1f3f3a41 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -191,7 +191,7 @@ static void ping(char *svr) gettimeofday(&tv_recv, NULL); timersub(&tv_recv, &tv_send, &tv_diff); - printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id, tv2fl(tv_diff)); + printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id - ident, tv2fl(tv_diff)); if (delay) sleep(delay); } else { -- cgit From b9817e90f1fd86d2c263ba37334744dbd8483589 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Aug 2004 16:27:55 +0000 Subject: Fix --nosdp --- dund/dund.1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dund/dund.1 b/dund/dund.1 index ad2b775c..3ac0f03d 100644 --- a/dund/dund.1 +++ b/dund/dund.1 @@ -32,8 +32,8 @@ RFCOMM channel \fB\-\-source\fR \fB\-S\fR Source bdaddr .TP -\fB\-\-sdp\fR \fB\-D\fR -Enable SDP +\fB\-\-nosdp\fR \fB\-D\fR +Disable SDP .TP \fB\-\-encrypt\fR \fB\-E\fR Enable encryption -- cgit From b2622e897b972a8a8e467f3f08ec6abd33034a25 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Aug 2004 10:38:50 +0000 Subject: Print a dummy device list when called with no arguments --- cups/main.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cups/main.c b/cups/main.c index c6e1deb8..a8a01d4c 100644 --- a/cups/main.c +++ b/cups/main.c @@ -49,10 +49,6 @@ int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies); int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies); -static void list_devices(void) -{ -} - /* * Usage: printer-uri job-id user title copies options [file] * @@ -82,7 +78,7 @@ int main(int argc, char *argv[]) #endif /* HAVE_SIGSET */ if (argc == 1) { - list_devices(); + puts("network bluetooth \"Unknown\" \"Bluetooth printer\""); return 0; } -- cgit From 885fe862f39efde91f3b5017b8c6019c8c1f6541 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 27 Aug 2004 13:40:46 +0000 Subject: Cleanup --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 91c61eb9..2890d674 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -166,8 +166,8 @@ AC_DEFUN([AC_PATH_DBUS], [ ]) AC_DEFUN([AC_ARG_BLUEZ], [ - pie_enable=no debug_enable=no + pie_enable=no dbus_enable=${dbus_found} test_enable=no cups_enable=no -- cgit From 49c565df53bf26483c097b511547c203c81f4d41 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 27 Aug 2004 14:37:54 +0000 Subject: fix memory leaks --- pand/main.c | 3 +-- pand/sdp.c | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pand/main.c b/pand/main.c index 4afc095f..e57c80be 100644 --- a/pand/main.c +++ b/pand/main.c @@ -551,7 +551,6 @@ int main(int argc, char **argv) case 'Q': mode = CONNECT; - dst = NULL; if (optarg) search_duration = atoi(optarg); break; @@ -565,7 +564,6 @@ int main(int argc, char **argv) case 'K': mode = KILL; detach = 0; - dst = NULL; break; case 'S': @@ -700,6 +698,7 @@ int main(int argc, char **argv) strncpy(cache.dst, dst, sizeof(cache.dst) - 1); str2ba(dst, &cache.bdaddr); cache.valid = 1; + free(dst); } switch (mode) { diff --git a/pand/sdp.c b/pand/sdp.c index dfa4c0c7..686b25b5 100644 --- a/pand/sdp.c +++ b/pand/sdp.c @@ -63,6 +63,7 @@ int bnep_sdp_register(uint16_t role) uuid_t root_uuid, pan, l2cap, bnep; sdp_profile_desc_t profile[1]; sdp_list_t *proto[2]; + sdp_data_t *v, *p; uint16_t psm = 15, version = 0x0100; int status; @@ -84,15 +85,18 @@ int bnep_sdp_register(uint16_t role) sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); sdp_set_browse_groups(record, root); + sdp_list_free(root, 0); sdp_uuid16_create(&l2cap, L2CAP_UUID); proto[0] = sdp_list_append(NULL, &l2cap); - proto[0] = sdp_list_append(proto[0], sdp_data_alloc(SDP_UINT16, &psm)); + p = sdp_data_alloc(SDP_UINT16, &psm); + proto[0] = sdp_list_append(proto[0], p); apseq = sdp_list_append(NULL, proto[0]); sdp_uuid16_create(&bnep, BNEP_UUID); proto[1] = sdp_list_append(NULL, &bnep); - proto[1] = sdp_list_append(proto[1], sdp_data_alloc(SDP_UINT16, &version)); + v = sdp_data_alloc(SDP_UINT16, &version); + proto[1] = sdp_list_append(proto[1], v); /* Supported protocols */ { @@ -118,6 +122,12 @@ int bnep_sdp_register(uint16_t role) aproto = sdp_list_append(NULL, apseq); sdp_set_access_protos(record, aproto); + sdp_list_free(proto[0], NULL); + sdp_list_free(proto[1], NULL); + sdp_list_free(apseq, NULL); + sdp_list_free(aproto, NULL); + sdp_data_free(p); + sdp_data_free(v); switch (role) { case BNEP_SVC_NAP: @@ -150,11 +160,13 @@ int bnep_sdp_register(uint16_t role) sdp_uuid16_create(&pan, PANU_SVCLASS_ID); svclass = sdp_list_append(NULL, &pan); sdp_set_service_classes(record, svclass); + sdp_list_free(svclass, 0); sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(NULL, &profile[0]); sdp_set_profile_descs(record, pfseq); + sdp_list_free(pfseq, 0); sdp_set_info_attr(record, "PAN User", NULL, NULL); break; -- cgit From 2525689e0e1de1da8fff4cd4b0ea5aadc0fca630 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 29 Aug 2004 11:09:56 +0000 Subject: Add checks for the OpenOBEX support --- acinclude.m4 | 44 ++++++++++++++++++++++++++++++++++++++++++++ configure.in | 1 + 2 files changed, 45 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 2890d674..49bed4ea 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -85,6 +85,43 @@ AC_DEFUN([AC_PATH_BLUEZ], [ AC_SUBST(BLUEZ_LIBS) ]) +AC_DEFUN([AC_PATH_OPENOBEX], [ + openobex_prefix=${prefix} + + AC_ARG_WITH(openobex, AC_HELP_STRING([--with-openobex=DIR], [OpenOBEX library is installed in DIR]), [ + if (test "${withval}" != "yes"); then + openobex_prefix=${withval} + fi + ]) + + ac_save_CPPFLAGS=$CPPFLAGS + ac_save_LDFLAGS=$LDFLAGS + + OPENOBEX_CFLAGS="" + test -d "${openobex_prefix}/include" && OPENOBEX_CFLAGS="$OPENOBEX_CFLAGS -I${openobex_prefix}/include" + + CPPFLAGS="$CPPFLAGS $OPENOBEX_CFLAGS" + AC_CHECK_HEADER(openobex/obex.h, openobex_found=yes, openobex_found=no) + + OPENOBEX_LIBS="" + if (test "${prefix}" = "${openobex_prefix}"); then + test -d "${libdir}" && OPENOBEX_LIBS="$OPENOBEX_LIBS -L${libdir}" + else + test -d "${openobex_prefix}/lib64" && OPENOBEX_LIBS="$OPENOBEX_LIBS -L${openobex_prefix}/lib64" + test -d "${openobex_prefix}/lib" && OPENOBEX_LIBS="$OPENOBEX_LIBS -L${openobex_prefix}/lib" + fi + + LDFLAGS="$LDFLAGS $OPENOBEX_LIBS" + AC_CHECK_LIB(openobex, OBEX_Init, OPENOBEX_LIBS="$OPENOBEX_LIBS -lopenobex", openobex_found=no) + AC_CHECK_LIB(openobex, BtOBEX_TransportConnect, AC_DEFINE(HAVE_BTOBEX_TRANSPORT_CONNECT, 1, [Define to 1 if you have the BtOBEX_TransportConnect() function.])) + + CPPFLAGS=$ac_save_CPPFLAGS + LDFLAGS=$ac_save_LDFLAGS + + AC_SUBST(OPENOBEX_CFLAGS) + AC_SUBST(OPENOBEX_LIBS) +]) + AC_DEFUN([AC_PATH_USB], [ usb_prefix=${prefix} @@ -168,6 +205,7 @@ AC_DEFUN([AC_PATH_DBUS], [ AC_DEFUN([AC_ARG_BLUEZ], [ debug_enable=no pie_enable=no + obex_enable=${openobex_found} dbus_enable=${dbus_found} test_enable=no cups_enable=no @@ -186,6 +224,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ ]) AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], [enable all extra options below]), [ + obex_enable=${enableval} dbus_enable=${enableval} test_enable=${enableval} cups_enable=${enableval} @@ -196,6 +235,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ bcm203x_enable=${enableval} ]) + AC_ARG_ENABLE(obex, AC_HELP_STRING([--enable-obex], [enable OBEX support]), [ + obex_enable=${enableval} + ]) + AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ dbus_enable=${enableval} ]) @@ -237,6 +280,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ LDFLAGS="$LDFLAGS -pie" fi + AM_CONDITIONAL(OBEX, test "${obex_enable}" = "yes" && test "${openobex_found}" = "yes") AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes" && test "${dbus_found}" = "yes") AM_CONDITIONAL(TEST, test "${test_enable}" = "yes") AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") diff --git a/configure.in b/configure.in index 52ec0525..b8d2140b 100644 --- a/configure.in +++ b/configure.in @@ -21,6 +21,7 @@ AC_PROG_YACC AM_PROG_LEX AC_PATH_BLUEZ +AC_PATH_OPENOBEX AC_PATH_USB AC_PATH_DBUS -- cgit From 67f9a013ade0649d032b9b25e694567a089237d1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 30 Aug 2004 16:04:41 +0000 Subject: Fragment SCO payload that is greater than the SCO MTU --- test/hstest.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/hstest.c b/test/hstest.c index 1272cd01..98428b68 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -148,7 +148,7 @@ int main(int argc, char *argv[]) fd_set rfds; struct timeval timeout; - unsigned char buf[2048]; + unsigned char buf[2048], *p; int maxfd, sel, rlen, wlen; bdaddr_t local; @@ -274,7 +274,15 @@ int main(int argc, char *argv[]) switch (mode) { case PLAY: rlen = read(fd, buf, rlen); - wlen = write(sd, buf, rlen); + + wlen = 0; + p = buf; + while (rlen > sco_mtu) { + wlen += write(sd, p, sco_mtu); + rlen -= sco_mtu; + p += sco_mtu; + } + wlen += write(sd, p, rlen); break; case RECORD: wlen = write(fd, buf, rlen); -- cgit From 462b9676004b39d4852d303b7c66fba7103ea39d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Sep 2004 15:55:01 +0000 Subject: Add --master option for forcing the role switch --- hidd/main.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index 22883a58..2cae2653 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -99,11 +99,11 @@ static int l2cap_connect(bdaddr_t *src, bdaddr_t *dst, unsigned short psm) return sk; } -static int l2cap_listen(const bdaddr_t *bdaddr, unsigned short psm, int backlog) +static int l2cap_listen(const bdaddr_t *bdaddr, unsigned short psm, int lm, int backlog) { struct sockaddr_l2 addr; struct l2cap_options opts; - int sk, lm = L2CAP_LM_MASTER; + int sk; if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) return -1; @@ -442,6 +442,7 @@ static struct option main_options[] = { { "subclass", 1, 0, 'b' }, { "timeout", 1, 0, 't' }, { "device", 1, 0, 'i' }, + { "master", 0, 0, 'M' }, { "show", 0, 0, 'l' }, { "list", 0, 0, 'l' }, { "server", 0, 0, 'd' }, @@ -467,11 +468,11 @@ int main(int argc, char *argv[]) char addr[18]; int log_option = LOG_NDELAY | LOG_PID; int opt, fd, ctl, csk, isk; - int mode = 0, daemon = 1, timeout = 30; + int mode = 0, daemon = 1, timeout = 30, lm = 0; bacpy(&bdaddr, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:nt:b:ldsc:k:Ku:h", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+i:nt:b:Mldsc:k:Ku:h", main_options, NULL)) != -1) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -491,6 +492,9 @@ int main(int argc, char *argv[]) else subclass = atoi(optarg); break; + case 'M': + lm |= L2CAP_LM_MASTER; + break; case 'l': mode = 0; break; @@ -535,14 +539,14 @@ int main(int argc, char *argv[]) switch (mode) { case 1: - csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, 10); + csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, lm, 10); if (csk < 0) { perror("Can't listen on HID control channel"); close(ctl); exit(1); } - isk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_INTR, 10); + isk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_INTR, lm, 10); if (isk < 0) { perror("Can't listen on HID interrupt channel"); close(ctl); -- cgit From d33a1214b4299aad065df79686b6b1ecb17c5af1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Sep 2004 20:58:15 +0000 Subject: Add entries for the IBM and TDK PCMCIA cards --- pcmcia/bluetooth.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 6e059963..bb0bb5a1 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -26,6 +26,14 @@ card "Brain Boxes BL-620 Bluetooth Adapter" version "Brain Boxes", "Bluetooth PC Card" bind "serial_cs" class "bluetooth" +card "IBM Bluetooth PC Card II" + version "IBM", "Bluetooth PC Card II" + bind "serial_cs" class "bluetooth" + +card "TDK Bluetooth PC Card" + version "TDK", "Bluetooth PC Card" + bind "serial_cs" class "bluetooth" + card "AmbiCom BT2000C Bluetooth PC/CF Card" version "AmbiCom BT2000C", "Bluetooth PC/CF Card" bind "serial_cs" class "bluetooth" -- cgit From ca8d9c9f9ac9b20b33bde4c1407ce80f44b814ec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 20 Sep 2004 15:51:15 +0000 Subject: Mention flow|noflow in help text and other speeds --- tools/hciattach.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index b3f40b3a..a22a0b1d 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -84,12 +84,18 @@ static int uart_speed(int s) return B230400; case 460800: return B460800; + case 500000: + return B500000; + case 576000: + return B576000; case 921600: return B921600; case 1000000: return B1000000; case 1152000: return B1152000; + case 1500000: + return B1500000; default: return B57600; } @@ -932,7 +938,7 @@ static void usage(void) { printf("hciattach - HCI UART driver initialization utility\n"); printf("Usage:\n"); - printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [speed] [flow]\n"); + printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [speed] [flow|noflow]\n"); printf("\thciattach -l\n"); } -- cgit From d2b015d284692e02d1d8539b82d1da13a51c7d5c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 22 Sep 2004 15:27:23 +0000 Subject: Add manual page for hidd --- hidd/Makefile.am | 4 ++++ hidd/hidd.1 | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 hidd/hidd.1 diff --git a/hidd/Makefile.am b/hidd/Makefile.am index a24f505a..5519143a 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -10,4 +10,8 @@ LIBS = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ +man_MANS = hidd.1 + +EXTRA_DIST = $(man_MANS) + MAINTAINERCLEANFILES = Makefile.in diff --git a/hidd/hidd.1 b/hidd/hidd.1 new file mode 100644 index 00000000..417457eb --- /dev/null +++ b/hidd/hidd.1 @@ -0,0 +1,41 @@ +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33. +.TH HIDD "1" "May 2004" "hidd - Bluetooth HID daemon" "User Commands" +.SH NAME +hidd \- manual page for hidd - Bluetooth HID daemon +.SH DESCRIPTION +hidd - Bluetooth HID daemon +.SS "Usage:" +.IP +hidd [options] [commands] +.SH OPTIONS +.TP +\fB\-i\fR +Local HCI device or BD Address +.TP +\fB\-t\fR +Set idle timeout (in minutes) +.TP +\fB\-n\fR, \fB\-\-nodaemon\fR +Don't fork daemon to background +.TP +\fB\-h\fR, \fB\-\-help\fR +Display help +.SS "Commands:" +.TP +\fB\-\-server\fR +Start HID server +.TP +\fB\-\-search\fR +Search for HID devices +.TP +\fB\-\-connect\fR +Connect remote HID device +.TP +\fB\-\-kill\fR +Terminate HID connection +.TP +\fB\-\-killall\fR +Terminate all connections +.TP +\fB\-\-show\fR +List current HID connections -- cgit From a82f59ecd2f6fa37d679e4430163c0189193deb5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 22 Sep 2004 17:45:17 +0000 Subject: Set service classes to "Networking, Rendering, Capturing, Object Transfer" --- hcid/hcid.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hcid/hcid.conf b/hcid/hcid.conf index 37892256..150fe06d 100644 --- a/hcid/hcid.conf +++ b/hcid/hcid.conf @@ -37,7 +37,7 @@ device { name "BlueZ (%d)"; # Local device class - class 0x100; + class 0x1e0100; # Default packet type #pkt_type DH1,DM1,HV1; -- cgit From 6153da844acccec9519301e3e15743643c096e09 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 1 Oct 2004 11:38:41 +0000 Subject: Fix class display and some compile warnings for 64 bit userland --- tools/hciconfig.c | 26 +++++++++++++------------- tools/sdptool.c | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 78c56ce7..862deeb9 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -397,10 +397,10 @@ void cmd_name(int ctl, int hdev, char *opt) */ static char *get_minor_device_name(int major, int minor) { - switch(major) { - case 0:/* misc */ + switch (major) { + case 0: /* misc */ return ""; - case 1:/* computer */ + case 1: /* computer */ switch(minor) { case 0: return "Uncategorized"; @@ -418,7 +418,7 @@ static char *get_minor_device_name(int major, int minor) return "Wearable"; } break; - case 2:/* phone */ + case 2: /* phone */ switch(minor) { case 0: return "Uncategorized"; @@ -436,7 +436,7 @@ static char *get_minor_device_name(int major, int minor) return "Sim Card Reader"; } break; - case 3:/* lan access */ + case 3: /* lan access */ if (minor == 0) return "Uncategorized"; switch(minor / 8) { @@ -458,7 +458,7 @@ static char *get_minor_device_name(int major, int minor) return "No service available"; } break; - case 4:/* audio/video */ + case 4: /* audio/video */ switch(minor) { case 0: return "Uncategorized"; @@ -498,7 +498,7 @@ static char *get_minor_device_name(int major, int minor) return "Gaming/Toy"; } break; - case 5:/* peripheral */ + case 5: /* peripheral */ switch(minor) { case 16: return "Keyboard"; @@ -508,7 +508,7 @@ static char *get_minor_device_name(int major, int minor) return "Combo keyboard/pointing device"; } break; - case 6:/* imaging */ + case 6: /* imaging */ if (minor & 4) return "Display"; if (minor & 8) @@ -518,7 +518,7 @@ static char *get_minor_device_name(int major, int minor) if (minor & 32) return "Printer"; break; - case 63:/* uncategorised */ + case 63: /* uncategorised */ return ""; } return "Unknown (reserved) minor device class"; @@ -550,14 +550,14 @@ void cmd_class(int ctl, int hdev, char *opt) } if (opt) { uint32_t cod = strtoul(opt, NULL, 16); - if (0 > hci_write_class_of_dev(s, cod, 1000)) { + if (hci_write_class_of_dev(s, cod, 1000) < 0) { printf("Can't write local class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { uint8_t cls[3]; - if (0 > hci_read_class_of_dev(s, cls, 1000)) { + if (hci_read_class_of_dev(s, cls, 1000) < 0) { printf("Can't read class of device on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); @@ -567,7 +567,7 @@ void cmd_class(int ctl, int hdev, char *opt) printf("\tService Classes: "); if (cls[2]) { int first = 1; - for(s=0; s < sizeof(services); s++) + for (s = 0; s < sizeof(*services); s++) if (cls[2] & (1 << s)) { if (!first) printf(", "); @@ -577,7 +577,7 @@ void cmd_class(int ctl, int hdev, char *opt) } else printf("Unspecified"); printf("\n\tDevice Class: "); - if ((cls[1] & 0x1f) > sizeof(major_devices)) + if ((cls[1] & 0x1f) > sizeof(*major_devices)) printf("Invalid Device Class!\n"); else printf("%s, %s\n", major_devices[cls[1] & 0x1f], diff --git a/tools/sdptool.c b/tools/sdptool.c index 4f89491d..99684d9c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -813,7 +813,7 @@ void print_lang_attr(void *value, void *user) printf(" base_offset: 0x%02x\n", lang->base_offset); } -void print_access_protos(value, userData) +void print_access_protos(void *value, void *userData) { sdp_list_t *protDescSeq = (sdp_list_t *)value; sdp_list_foreach(protDescSeq, print_service_desc, 0); -- cgit From c8c2b3ffa0c932033a5c666a49481122e58cec27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 1 Oct 2004 11:40:15 +0000 Subject: Change dynamic assignment of record handles to a more standard one --- sdpd/main.c | 5 ++++- sdpd/sdpd.h | 1 + sdpd/service.c | 5 ++++- sdpd/servicedb.c | 10 ++++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/sdpd/main.c b/sdpd/main.c index 8b6089d4..0efc7d50 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -106,7 +106,10 @@ static void register_public_browse_group(void) sdp_data_t *sdpdata; sdp_record_t *browse = sdp_record_alloc(); - browse->handle = (uint32_t)browse; + browse->handle = sdp_next_handle(); + if (browse->handle < 0x10000) + return; + sdp_record_add(browse); sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 30eb1de3..bc085c83 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -83,6 +83,7 @@ sdp_record_t *sdp_record_find(uint32_t handle); void sdp_record_add(sdp_record_t *rec); int sdp_record_remove(uint32_t handle); sdp_list_t *sdp_get_record_list(); +uint32_t sdp_next_handle(void); long sdp_get_time(); diff --git a/sdpd/service.c b/sdpd/service.c index 0834122d..a8d93994 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -141,7 +141,10 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) return -1; } - rec->handle = (uint32_t)rec; + rec->handle = sdp_next_handle(); + if (rec->handle < 0x10000) + return -1; + sdp_record_add(rec); if (!(req->flags & SDP_RECORD_PERSIST)) sdp_svcdb_set_collectable(rec, req->sock); diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 5a6469f5..9f87eca6 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -203,3 +203,13 @@ sdp_list_t *sdp_get_record_list() { return service_db; } + +uint32_t sdp_next_handle(void) +{ + uint32_t handle = 0x10000; + + while (sdp_record_find(handle)) + handle++; + + return handle; +} -- cgit From 70bc373b28975204b08974d45213e5772a07a41e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Oct 2004 09:52:09 +0000 Subject: Add support for the Zoom PCMCIA card --- pcmcia/bluetooth.conf | 4 ++++ tools/hciattach.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index bb0bb5a1..a4d03fd1 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -54,6 +54,10 @@ card "Compaq iPAQ Bluetooth Sleeve" version "CF CARD", "GENERIC" bind "serial_cs" class "bluetooth" +card "Zoom Bluetooth Card" + version "PCMCIA", "Bluetooth Card" + bind "serial_cs" class "bluetooth" + card "Nokia Bluetooth Card" version "Nokia Mobile Phones", "DTL-1" diff --git a/tools/hciattach.c b/tools/hciattach.c index a22a0b1d..d59992e1 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -842,6 +842,9 @@ struct uart_t uart[] = { /* AmbiCom BT2000C Bluetooth PC/CF Card */ { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, csr }, + /* Zoom Bluetooth PCMCIA Card */ + { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { NULL, 0 } }; -- cgit From b089fd9850e50bb0a75dacfb665ec1e85aaa30b4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Oct 2004 10:31:33 +0000 Subject: Add timeout option --- tools/l2ping.1 | 9 ++++++++- tools/l2ping.c | 27 +++++++++++++++++---------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tools/l2ping.1 b/tools/l2ping.1 index 186e5056..0c7da44b 100644 --- a/tools/l2ping.1 +++ b/tools/l2ping.1 @@ -10,6 +10,8 @@ l2ping \- Send L2CAP echo request and receive answer ] [ .I -c count ] [ +.I -t timeout +] [ .I -f ] < .I bd_addr @@ -34,6 +36,11 @@ Send .B count number of packets then exit. .TP +.I -c timeout +Wait +.B timeout +for the response. +.TP .I -f Kind of flood ping. Use with care! It reduces the delay time between packets to 0. @@ -44,6 +51,6 @@ The Bluetooth MAC address to be pinged in dotted hex notation like or .B 01:EF:cd:aB:02:03 .SH AUTHORS -Written by Maxim Krasnyansky +Written by Maxim Krasnyansky and Marcel Holtmann .PP man page by Nils Faerber diff --git a/tools/l2ping.c b/tools/l2ping.c index 1f3f3a41..45ddbe92 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -56,10 +56,11 @@ /* Defaults */ bdaddr_t bdaddr; -int size = 20; -int ident = 200; -int delay = 1; -int count = -1; +int size = 20; +int ident = 200; +int delay = 1; +int count = -1; +int timeout = 10; /* Stats */ int sent_pkt = 0, recv_pkt = 0; @@ -120,7 +121,7 @@ static void ping(char *svr) /* Initialize buffer */ for (i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) - buf[i]=(i%40)+'A'; + buf[i] = (i % 40) + 'A'; id = ident; @@ -148,7 +149,7 @@ static void ping(char *svr) register int err; pf[0].fd = s; pf[0].events = POLLIN; - if ((err = poll(pf, 1, 10*1000)) < 0) { + if ((err = poll(pf, 1, timeout * 1000)) < 0) { perror("Poll failed"); exit(1); } @@ -193,12 +194,14 @@ static void ping(char *svr) printf("%d bytes from %s id %d time %.2fms\n", cmd->len, svr, id - ident, tv2fl(tv_diff)); - if (delay) sleep(delay); + if (delay) + sleep(delay); } else { printf("no response from %s: id %d\n", svr, id); } - if (++id > 254) id = ident; + if (++id > 254) + id = ident; } stat(0); } @@ -207,7 +210,7 @@ static void usage(void) { printf("l2ping - L2CAP ping\n"); printf("Usage:\n"); - printf("\tl2ping [-S source addr] [-s size] [-c count] [-f] \n"); + printf("\tl2ping [-S source addr] [-s size] [-c count] [-t timeout] [-f] \n"); } extern int optind,opterr,optopt; @@ -220,7 +223,7 @@ int main(int argc, char *argv[]) /* Default options */ bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"s:c:fS:")) != EOF) { + while ((opt=getopt(argc,argv,"s:c:t:fS:")) != EOF) { switch(opt) { case 'f': /* Kinda flood ping */ @@ -231,6 +234,10 @@ int main(int argc, char *argv[]) count = atoi(optarg); break; + case 't': + timeout = atoi(optarg); + break; + case 's': size = atoi(optarg); break; -- cgit From 3aa6a3e9a775e1d143d3640fe7f3ced170bb71b9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Oct 2004 13:59:57 +0000 Subject: Sleep some time after sending break --- tools/hciattach.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index d59992e1..ac94c41e 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -908,8 +908,10 @@ int init_uart(char *dev, struct uart_t *u, int send_break) tcflush(fd, TCIOFLUSH); - if (send_break) + if (send_break) { tcsendbreak(fd, 0); + usleep(500000); + } if (u->init && u->init(fd, u, &ti) < 0) return -1; -- cgit From 1dd606979d87e4d725df282fdb00669fb8a76d1a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 13 Oct 2004 12:05:52 +0000 Subject: Add support for SIM Access Profile --- tools/sdptool.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 99684d9c..025ab0da 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -254,6 +254,7 @@ static struct uuid_def uuid16_names[] = { { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, + { 0x112d, "SIM Access (SAP)", NULL, 0 }, /* ... */ { 0x1200, "PnPInformation", NULL, 0 }, { 0x1201, "GenericNetworking", NULL, 0 }, @@ -1154,7 +1155,7 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); - sdp_set_info_attr(&record, "", 0, 0); + sdp_set_info_attr(&record, "Handsfree", 0, 0); if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { printf("Service Record registration failed\n"); @@ -1171,6 +1172,67 @@ end: return ret; } +static int add_simaccess(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 3; + uint16_t u16 = 0x31; + sdp_data_t *channel, *features; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, SAP_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_uuid16_create(&ga_svclass_uuid, GENERIC_TELEPHONY_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, SAP_PROFILE_ID); + profile.version = 0x0101; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + features = sdp_data_alloc(SDP_UINT16, &u16); + sdp_attr_add(&record, SDP_SUPPORTED_FEATURES, features); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "SIM Access", 0, 0); + + if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Handsfree service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} static int add_fax(sdp_session_t *session, svc_info_t *si) { @@ -1695,6 +1757,7 @@ struct { { "HS", HEADSET_SVCLASS_ID, add_headset }, { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, + { "SAP", SAP_SVCLASS_ID, add_simaccess }, { "NAP", NAP_SVCLASS_ID, add_nap }, { "GN", GN_SVCLASS_ID, add_gn }, -- cgit From b3f9653837d74d6866c90114e52d9d4c024d6423 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Oct 2004 05:51:25 +0000 Subject: Wait some time before calling disconnect --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index df33412f..089ca103 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -477,8 +477,10 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 63)); } - if (cc) + if (cc) { + usleep(10000); hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } close(dd); } -- cgit From e0a9a33079d4ae64c6553e02f5da4f5a039c372f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 05:44:23 +0000 Subject: Display revision information for Digianswer devices --- tools/hciconfig.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 862deeb9..9405de08 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -959,7 +959,7 @@ static void print_rev_ericsson(int dd) unsigned char buf[102]; memset(&rq, 0, sizeof(rq)); - rq.ogf = 0x3f; + rq.ogf = OGF_VENDOR_CMD; rq.ocf = 0x000f; rq.cparam = NULL; rq.clen = 0; @@ -967,7 +967,7 @@ static void print_rev_ericsson(int dd) rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\n Can't read revision info. %s(%d)\n", strerror(errno), errno); + printf("\nCan't read revision info. %s(%d)\n", strerror(errno), errno); return; } @@ -998,6 +998,28 @@ static void print_rev_csr(int dd, uint16_t rev) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); } +static void print_rev_digianswer(int dd) +{ + struct hci_request rq; + unsigned char req[] = { 0x07 }; + unsigned char buf[102]; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x000e; + rq.cparam = req; + rq.clen = sizeof(req); + rq.rparam = &buf; + rq.rlen = sizeof(buf); + + if (hci_send_req(dd, &rq, 1000) < 0) { + printf("\nCan't read revision info. %s(%d)\n", strerror(errno), errno); + return; + } + + printf("\t%s\n", buf + 1); +} + static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) { printf("\tFirmware %d.%d.%03d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); @@ -1037,6 +1059,9 @@ static void cmd_revision(int ctl, int hdev, char *opt) case 10: print_rev_csr(dd, ver.hci_rev); break; + case 12: + print_rev_digianswer(dd); + break; case 15: print_rev_broadcom(ver.hci_rev, ver.lmp_subver); break; -- cgit From 7e08a09c87660616b173f338aff9baf3f7b61f5d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 07:20:17 +0000 Subject: Use Bluetooth library functions --- tools/hcitool.c | 67 +++++++++++---------------------------------------------- 1 file changed, 13 insertions(+), 54 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 089ca103..7cb807ec 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -732,7 +732,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 100) < 0) + if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) perror("Disconnect failed"); close(dd); @@ -752,9 +752,8 @@ static char *sr_help = static void cmd_sr(int dev_id, int argc, char **argv) { - struct hci_request rq; - switch_role_cp cp; - evt_role_change rp; + bdaddr_t bdaddr; + uint8_t role; int opt, dd; for_each_opt(opt, sr_options, NULL) { @@ -772,21 +771,21 @@ static void cmd_sr(int dev_id, int argc, char **argv) return; } - str2ba(argv[0], &cp.bdaddr); + str2ba(argv[0], &bdaddr); switch (argv[1][0]) { case 'm': - cp.role = 0; + role = 0; break; case 's': - cp.role = 1; + role = 1; break; default: - cp.role = atoi(argv[1]); + role = atoi(argv[1]); break; } if (dev_id < 0) { - dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &cp.bdaddr); + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { fprintf(stderr, "Not connected.\n"); exit(1); @@ -799,25 +798,11 @@ static void cmd_sr(int dev_id, int argc, char **argv) exit(1); } - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_POLICY; - rq.ocf = OCF_SWITCH_ROLE; - rq.cparam = &cp; - rq.clen = SWITCH_ROLE_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_ROLE_CHANGE_SIZE; - rq.event = EVT_ROLE_CHANGE; - - if (hci_send_req(dd, &rq, 300) < 0) { + if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) { perror("Switch role request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "Switch role cmd failed (0x%2.2X)\n", rp.status); - exit(1); - } - close(dd); } @@ -1388,9 +1373,6 @@ static char *auth_help = static void cmd_auth(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - auth_requested_cp cp; - evt_auth_complete rp; bdaddr_t bdaddr; int opt, dd; @@ -1436,18 +1418,7 @@ static void cmd_auth(int dev_id, int argc, char **argv) exit(1); } - cp.handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_AUTH_REQUESTED; - rq.cparam = &cp; - rq.clen = AUTH_REQUESTED_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_AUTH_COMPLETE_SIZE; - rq.event = EVT_AUTH_COMPLETE; - - if (hci_send_req(dd, &rq, 25000) < 0) { + if (hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000) < 0) { perror("HCI authentication request failed"); exit(1); } @@ -1470,10 +1441,8 @@ static char *enc_help = static void cmd_enc(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - set_conn_encrypt_cp cp; - evt_encrypt_change rp; bdaddr_t bdaddr; + uint8_t encrypt; int opt, dd; for_each_opt(opt, enc_options, NULL) { @@ -1518,19 +1487,9 @@ static void cmd_enc(int dev_id, int argc, char **argv) exit(1); } - cp.handle = htobs(cr->conn_info->handle); - cp.encrypt = (argc > 1) ? atoi(argv[1]) : 1; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_ENCRYPT; - rq.cparam = &cp; - rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; - rq.event = EVT_ENCRYPT_CHANGE; + encrypt = (argc > 1) ? atoi(argv[1]) : 1; - if (hci_send_req(dd, &rq, 25000) < 0) { + if (hci_encrypt_link(dd, htobs(cr->conn_info->handle), encrypt, 25000) < 0) { perror("HCI set encryption request failed"); exit(1); } -- cgit From 4e37d72b4562ffbfc3e73ef5d9bf0b722e841ab1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 07:37:55 +0000 Subject: Use the library functions for reading and writing the inquiry mode --- tools/hciconfig.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 9405de08..797cb775 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -666,42 +666,25 @@ void cmd_inq_mode(int ctl, int hdev, char *opt) memset(&rq, 0, sizeof(rq)); if (opt) { - write_inquiry_mode_cp cp; + uint8_t mode = atoi(opt); - cp.mode = atoi(opt); - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_INQUIRY_MODE; - rq.cparam = &cp; - rq.clen = WRITE_INQUIRY_MODE_RP_SIZE; - - if (hci_send_req(dd, &rq, 1000) < 0) { + if (hci_write_inquiry_mode(dd, mode, 1000) < 0) { printf("Can't set inquiry mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { - read_inquiry_mode_rp rp; - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_INQUIRY_MODE; - rq.rparam = &rp; - rq.rlen = READ_INQUIRY_MODE_RP_SIZE; + uint8_t mode; - if (hci_send_req(dd, &rq, 1000) < 0) { + if (hci_read_inquiry_mode(dd, &mode, 1000) < 0) { printf("Can't read inquiry mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - if (rp.status) { - printf("Read inquiry mode on hci%d returned status %d\n", - hdev, rp.status); - exit(1); - } print_dev_hdr(&di); printf("\tInquiry mode: %s\n", - rp.mode == 1 ? "Inquiry with RSSI" : "Standard Inquiry"); + mode == 1 ? "Inquiry with RSSI" : "Standard Inquiry"); } } -- cgit From 2f2181a94c8be0d4a97df83c15b17e1ea7b19624 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 08:16:45 +0000 Subject: Don't do anything if the kernel security manager is active --- hcid/security.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hcid/security.c b/hcid/security.c index f903e11c..fecafb93 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -414,6 +414,11 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) dev = g_io_channel_unix_get_fd(chan); + ioctl(dev, HCIGETDEVINFO, (void *) di); + + if (hci_test_bit(HCI_SECMGR, &di->flags)) + return TRUE; + switch (eh->evt) { case EVT_PIN_CODE_REQ: pin_code_request(dev, &di->bdaddr, (bdaddr_t *) ptr); -- cgit From 853ed92c6a6a97a202ca5a4dcb495197b3c3cc9e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 08:17:41 +0000 Subject: Add support for requesting encryption on keyboards --- hidd/main.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 13 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index 2cae2653..2aee55a1 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -151,7 +151,79 @@ static int l2cap_accept(int sk, bdaddr_t *bdaddr) return nsk; } -static int create_device(int ctl, int csk, int isk, uint8_t subclass, int timeout) +static int request_authentication(bdaddr_t *src, bdaddr_t *dst) +{ + struct hci_conn_info_req *cr; + char addr[18]; + int err, dd, dev_id; + + ba2str(src, addr); + dev_id = hci_devid(addr); + if (dev_id < 0) + return dev_id; + + dd = hci_open_dev(dev_id); + if (dd < 0) + return dd; + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return -ENOMEM; + + bacpy(&cr->bdaddr, dst); + cr->type = ACL_LINK; + err = ioctl(dd, HCIGETCONNINFO, (unsigned long) cr); + if (err < 0) { + free(cr); + hci_close_dev(dd); + return err; + } + + err = hci_authenticate_link(dd, htobs(cr->conn_info->handle), 25000); + + free(cr); + hci_close_dev(dd); + + return err; +} + +static int request_encryption(bdaddr_t *src, bdaddr_t *dst) +{ + struct hci_conn_info_req *cr; + char addr[18]; + int err, dd, dev_id; + + ba2str(src, addr); + dev_id = hci_devid(addr); + if (dev_id < 0) + return dev_id; + + dd = hci_open_dev(dev_id); + if (dd < 0) + return dd; + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return -ENOMEM; + + bacpy(&cr->bdaddr, dst); + cr->type = ACL_LINK; + err = ioctl(dd, HCIGETCONNINFO, (unsigned long) cr); + if (err < 0) { + free(cr); + hci_close_dev(dd); + return err; + } + + err = hci_encrypt_link(dd, htobs(cr->conn_info->handle), 1, 25000); + + free(cr); + hci_close_dev(dd); + + return err; +} + +static int create_device(int ctl, int csk, int isk, uint8_t subclass, int encrypt, int timeout) { struct hidp_connadd_req req; struct sockaddr_l2 addr; @@ -192,7 +264,16 @@ static int create_device(int ctl, int csk, int isk, uint8_t subclass, int timeou ba2str(&dst, bda); syslog(LOG_INFO, "New HID device %s (%s)", bda, req.name); - if (req.subclass & 0x40) { + if (encrypt && (req.subclass & 0x40)) { + err = request_authentication(&src, &dst); + if (err < 0) { + syslog(LOG_ERR, "Authentication for %s failed", bda); + goto error; + } + + err = request_encryption(&src, &dst); + if (err < 0) + syslog(LOG_ERR, "Encryption for %s failed", bda); } err = ioctl(ctl, HIDPCONNADD, &req); @@ -204,7 +285,7 @@ error: return err; } -static void run_server(int ctl, int csk, int isk, uint8_t subclass, int timeout) +static void run_server(int ctl, int csk, int isk, uint8_t subclass, int encrypt, int timeout) { struct pollfd p[2]; short events; @@ -230,7 +311,7 @@ static void run_server(int ctl, int csk, int isk, uint8_t subclass, int timeout) ncsk = l2cap_accept(csk, NULL); nisk = l2cap_accept(isk, NULL); - err = create_device(ctl, ncsk, nisk, subclass, timeout); + err = create_device(ctl, ncsk, nisk, subclass, encrypt, timeout); if (err < 0) syslog(LOG_ERR, "HID create error %d (%s)", errno, strerror(errno)); @@ -294,7 +375,7 @@ static void do_show(int ctl) } } -static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int timeout) +static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int encrypt, int timeout) { int csk, isk, err; @@ -313,7 +394,7 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, exit(1); } - err = create_device(ctl, csk, isk, subclass, timeout); + err = create_device(ctl, csk, isk, subclass, encrypt, timeout); if (err < 0) { fprintf(stderr, "HID create error %d (%s)\n", errno, strerror(errno)); @@ -325,7 +406,7 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, } } -static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int timeout) +static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int encrypt, int timeout) { inquiry_info *info = NULL; bdaddr_t src, dst; @@ -356,7 +437,7 @@ static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int timeout) ba2str(&dst, addr); printf("\tConnecting to device %s\n", addr); - do_connect(ctl, &src, &dst, subclass, timeout); + do_connect(ctl, &src, &dst, subclass, encrypt, timeout); } } @@ -443,6 +524,7 @@ static struct option main_options[] = { { "timeout", 1, 0, 't' }, { "device", 1, 0, 'i' }, { "master", 0, 0, 'M' }, + { "encrypt", 0, 0, 'E' }, { "show", 0, 0, 'l' }, { "list", 0, 0, 'l' }, { "server", 0, 0, 'd' }, @@ -468,11 +550,11 @@ int main(int argc, char *argv[]) char addr[18]; int log_option = LOG_NDELAY | LOG_PID; int opt, fd, ctl, csk, isk; - int mode = 0, daemon = 1, timeout = 30, lm = 0; + int mode = 0, daemon = 1, encrypt = 0, timeout = 30, lm = 0; bacpy(&bdaddr, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:nt:b:Mldsc:k:Ku:h", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+i:nt:b:MEldsc:k:Ku:h", main_options, NULL)) != -1) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -495,6 +577,9 @@ int main(int argc, char *argv[]) case 'M': lm |= L2CAP_LM_MASTER; break; + case 'E': + encrypt = 1; + break; case 'l': mode = 0; break; @@ -556,12 +641,12 @@ int main(int argc, char *argv[]) break; case 2: - do_search(ctl, &bdaddr, subclass, timeout); + do_search(ctl, &bdaddr, subclass, encrypt, timeout); close(ctl); exit(0); case 3: - do_connect(ctl, &bdaddr, &dev, subclass, timeout); + do_connect(ctl, &bdaddr, &dev, subclass, encrypt, timeout); close(ctl); exit(0); @@ -609,7 +694,7 @@ int main(int argc, char *argv[]) sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); - run_server(ctl, csk, isk, subclass, timeout); + run_server(ctl, csk, isk, subclass, encrypt, timeout); syslog(LOG_INFO, "Exit"); -- cgit From 8e6ac465d6f3504f60d6e81e0c6f5dc6a653717c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 08:19:07 +0000 Subject: Display version number on start --- pand/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pand/main.c b/pand/main.c index e57c80be..9165bf92 100644 --- a/pand/main.c +++ b/pand/main.c @@ -503,7 +503,7 @@ static struct option main_lopts[] = { static char main_sopts[] = "hsc:k:Kr:i:S:lnp::DQ::EMC::P:z"; static char main_help[] = - "PAN daemon version " VERSION " \n" + "Bluetooth PAN daemon version " VERSION " \n" "Usage:\n" "\tpand \n" "Options:\n" @@ -678,7 +678,7 @@ int main(int argc, char **argv) } openlog("pand", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); - syslog(LOG_INFO, "Bluetooth PAN daemon"); + syslog(LOG_INFO, "Bluetooth PAN daemon version %s", VERSION); if (src) { src_dev = hci_devid(src); -- cgit From 8831229d721edddb91548d86420a013f5b44b57f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 08:34:08 +0000 Subject: Support for enabling the kernel security manager --- tools/hciconfig.8 | 42 ++++++++++++++++++++++++------------------ tools/hciconfig.c | 28 +++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 3c6c96d8..5340978d 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -25,7 +25,7 @@ encryption enabled). .SH OPTIONS .TP .BI -h -Gives a list of possible commands +Gives a list of possible commands. .TP .BI -a Other than the basic info, print features, packet type, link policy, link mode, @@ -33,40 +33,46 @@ name, class, version. .SH COMMANDS .TP .BI up -Open and initialize HCI device +Open and initialize HCI device. .TP .BI down -Close HCI device +Close HCI device. .TP .BI reset -Reset HCI device +Reset HCI device. .TP .BI rstat -Reset statistic counters +Reset statistic counters. .TP .BI auth -Enable authentication +Enable authentication (sets device to security mode 3). .TP .BI noauth -Disable authentication +Disable authentication. .TP .BI encrypt -Enable encryption +Enable encryption (sets device to security mode 3). .TP .BI noencrypt -Disable encryption +Disable encryption. +.TP +.BI secmgr +Enable security manager (current kernel support is limited). +.TP +.BI nosecmgr +Disable security manager. .TP .BI piscan -Enable page and inquiry scan +Enable page and inquiry scan. .TP .BI noscan -Disable page and inquiry scan +Disable page and inquiry scan. .TP .BI iscan -Enable inquiry scan, disable page scan +Enable inquiry scan, disable page scan. .TP .BI pscan -Enable page scan, disable inquiry scan +Enable page scan, disable inquiry scan. .TP .BI ptype " [type]" With no @@ -182,13 +188,13 @@ bytes and SCO buffer size to packets. .TP .BI features -Display device features +Display device features. .TP .BI version -Display version information +Display version information. .TP .BI revision -Display revision information +Display revision information. .TP .BI lm " [mode]" With no @@ -232,8 +238,8 @@ ACCEPT is present, the device will accept baseband connections even when there are no listening .I AF_BLUETOOTH -sockets +sockets. .SH AUTHORS -Written by Maxim Krasnyansky +Written by Maxim Krasnyansky and Marcel Holtmann .PP man page by Fabrizio Gennari diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 797cb775..0e591e8d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -198,12 +198,12 @@ void cmd_auth(int ctl, int hdev, char *opt) struct hci_dev_req dr; dr.dev_id = hdev; - if( !strcmp(opt, "auth") ) + if (!strcmp(opt, "auth")) dr.dev_opt = AUTH_ENABLED; else dr.dev_opt = AUTH_DISABLED; - if( ioctl(ctl, HCISETAUTH, (unsigned long)&dr) < 0 ) { + if (ioctl(ctl, HCISETAUTH, (unsigned long) &dr) < 0) { printf("Can't set auth on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -214,17 +214,33 @@ void cmd_encrypt(int ctl, int hdev, char *opt) struct hci_dev_req dr; dr.dev_id = hdev; - if( !strcmp(opt, "encrypt") ) + if (!strcmp(opt, "encrypt")) dr.dev_opt = ENCRYPT_P2P; else dr.dev_opt = ENCRYPT_DISABLED; - if( ioctl(ctl, HCISETENCRYPT, (unsigned long)&dr) < 0 ) { + if (ioctl(ctl, HCISETENCRYPT, (unsigned long) &dr) < 0) { printf("Can't set encrypt on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } +void cmd_secmgr(int ctl, int hdev, char *opt) +{ + int val, s = hci_open_dev(hdev); + + if (!strcmp(opt, "secmgr")) + val = 1; + else + val = 0; + + if (ioctl(s, HCISETSECMGR, val) < 0) { + printf("Can't set security manager on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + exit(1); + } + close(s); +} + void cmd_up(int ctl, int hdev, char *opt) { int ret; @@ -236,7 +252,7 @@ void cmd_up(int ctl, int hdev, char *opt) printf("Can't init device hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - cmd_scan(ctl, hdev, "piscan"); + cmd_scan(ctl, hdev, "piscan"); } void cmd_down(int ctl, int hdev, char *opt) @@ -1119,6 +1135,8 @@ struct { { "noauth", cmd_auth, 0, "Disable Authentication" }, { "encrypt", cmd_encrypt, 0, "Enable Encryption" }, { "noencrypt", cmd_encrypt, 0, "Disable Encryption" }, + { "secmgr", cmd_secmgr, 0, "Enable Security Manager" }, + { "nosecmgr", cmd_secmgr, 0, "Disable Security Manager" }, { "piscan", cmd_scan, 0, "Enable Page and Inquiry scan" }, { "noscan", cmd_scan, 0, "Disable scan" }, { "iscan", cmd_scan, 0, "Enable Inquiry scan" }, -- cgit From 9e05169423054722af54ca7e93261c2c8c694e3d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 26 Oct 2004 02:21:16 +0000 Subject: Add more audio/video profile translations --- tools/sdptool.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 025ab0da..c63750c4 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -226,8 +226,12 @@ static struct uuid_def uuid16_names[] = { { 0x1108, "Headset", audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, { 0x1109, "CordlessTelephony", NULL, 0 }, - /* ... */ - { 0x110F, "VideoConferencing", NULL, 0 }, + { 0x110a, "AudioSource", NULL, 0 }, + { 0x110b, "AudioSink", NULL, 0 }, + { 0x110c, "RemoteControlTarget", NULL, 0 }, + { 0x110d, "AdvancedAudio", NULL, 0 }, + { 0x110e, "RemoteControl", NULL, 0 }, + { 0x110f, "VideoConferencing", NULL, 0 }, { 0x1110, "Intercom", NULL, 0 }, { 0x1111, "Fax", NULL, 0 }, { 0x1112, "HeadsetAudioGateway", NULL, 0 }, -- cgit From c29ecd6c660249eeaba7919f99eb79cf380e9fa6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 26 Oct 2004 02:31:22 +0000 Subject: Add audio to the service class value --- hcid/hcid.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hcid/hcid.conf b/hcid/hcid.conf index 150fe06d..78ca06e2 100644 --- a/hcid/hcid.conf +++ b/hcid/hcid.conf @@ -37,7 +37,7 @@ device { name "BlueZ (%d)"; # Local device class - class 0x1e0100; + class 0x3e0100; # Default packet type #pkt_type DH1,DM1,HV1; -- cgit From e4f0eb0611d76862fecf7053ce55d423409d2ef3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Oct 2004 02:49:27 +0000 Subject: Add support for setting link mode --- test/rctest.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/rctest.c b/test/rctest.c index 4dcd4f3c..5fb5075c 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -150,23 +150,21 @@ void do_listen( void (*handler)(int sk) ) exit(1); } -#if 0 /* Set link mode */ opt = 0; if (master) - opt |= L2CAP_LM_MASTER; + opt |= RFCOMM_LM_MASTER; if (auth) - opt |= L2CAP_LM_AUTH; + opt |= RFCOMM_LM_AUTH; if (encrypt) - opt |= L2CAP_LM_ENCRYPT; + opt |= RFCOMM_LM_ENCRYPT; - if (setsockopt(s, SOL_RFCOMM, L2CAP_LM, &opt, sizeof(opt)) < 0) { + if (setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); exit(1); } -#endif if( listen(s, 10) ) { syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); -- cgit From b80620ee96d7ed8c13fdd1331af16856f4e4e135 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Oct 2004 04:01:48 +0000 Subject: Correct typo in help information --- test/rctest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rctest.c b/test/rctest.c index 5fb5075c..31ecae57 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -347,7 +347,7 @@ void usage(void) "\t[-I imtu] [-O omtu]\n" "\t[-L seconds] enabled SO_LINGER option\n" "\t[-N num] number of frames to send\n" - "\t[-E] request encryption\n" + "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-M] become master\n"); } -- cgit From 1c111444bad2e4f0d66874a9032e43f91cb6cc3f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Nov 2004 11:18:50 +0000 Subject: Some whitespace cleanup --- tools/hcitool.c | 102 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 7cb807ec..6c41483b 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -65,7 +65,7 @@ static int dev_info(int s, int dev_id, long arg) struct hci_dev_info di = {dev_id: dev_id}; char addr[18]; - if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void *) &di)) return 0; ba2str(&di.bdaddr, addr); @@ -91,12 +91,12 @@ static int conn_list(int s, int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { perror("Can't get connection list"); exit(1); } - for (i=0; i < cl->conn_num; i++, ci++) { + for (i = 0; i < cl->conn_num; i++, ci++) { char addr[18]; ba2str(&ci->bdaddr, addr); printf("\t%s %s %s handle %d state %d lm %s\n", @@ -105,6 +105,7 @@ static int conn_list(int s, int dev_id, long arg) addr, ci->handle, ci->state, hci_lmtostr(ci->link_mode)); } + return 0; } @@ -122,14 +123,15 @@ static int find_conn(int s, int dev_id, long arg) cl->conn_num = 10; ci = cl->conn_info; - if (ioctl(s, HCIGETCONNLIST, (void*)cl)) { + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { perror("Can't get connection list"); exit(1); } - for (i=0; i < cl->conn_num; i++, ci++) - if (!bacmp((bdaddr_t *)arg, &ci->bdaddr)) + for (i = 0; i < cl->conn_num; i++, ci++) + if (!bacmp((bdaddr_t *) arg, &ci->bdaddr)) return 1; + return 0; } @@ -137,7 +139,7 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) { register int i,n; - for (i=0, n=1; ibdaddr, &bdaddr); cr->type = ACL_LINK; if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &bdaddr, htobs(di.pkt_type & ACL_PTYPE_MASK), 0, 0x01, &handle, 25000) < 0) { + if (hci_create_connection(dd, &bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + 0, 0x01, &handle, 25000) < 0) { perror("Can't create connection"); close(dd); exit(1); @@ -466,15 +469,18 @@ static void cmd_info(int dev_id, int argc, char **argv) if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" "\tManufacturer: %s (%d)\n", - lmp_vertostr(version.lmp_ver), version.lmp_ver, version.lmp_subver, - bt_compidtostr(version.manufacturer), version.manufacturer); + lmp_vertostr(version.lmp_ver), + version.lmp_ver, + version.lmp_subver, + bt_compidtostr(version.manufacturer), + version.manufacturer); } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", - features[0], features[1], features[2], features[3], - features[4], features[5], features[6], features[7], - lmp_featurestostr(features, "\t\t", 63)); + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7], + lmp_featurestostr(features, "\t\t", 63)); } if (cc) { @@ -508,7 +514,7 @@ static void cmd_cmd(int dev_id, int argc, char **argv) uint8_t ogf; for_each_opt(opt, cmd_options, NULL) { - switch(opt) { + switch (opt) { default: printf(cmd_help); return; @@ -573,7 +579,6 @@ static void cmd_cmd(int dev_id, int argc, char **argv) hex_dump(" ", 20, ptr, len); fflush(stdout); hci_close_dev(dd); - return; } /* Display active connections */ @@ -592,7 +597,7 @@ static void cmd_con(int dev_id, int argc, char **argv) int opt; for_each_opt(opt, con_options, NULL) { - switch(opt) { + switch (opt) { default: printf(con_help); return; @@ -630,7 +635,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; for_each_opt(opt, cc_options, NULL) { - switch(opt) { + switch (opt) { case 'p': hci_strtoptype(optarg, &ptype); break; @@ -668,7 +673,8 @@ static void cmd_cc(int dev_id, int argc, char **argv) exit(1); } - if (hci_create_connection(dd, &bdaddr, htobs(ptype), 0, role, &handle, 25000) < 0) + if (hci_create_connection(dd, &bdaddr, htobs(ptype), + 0, role, &handle, 25000) < 0) perror("Can't create connection"); hci_close_dev(dd); } @@ -691,7 +697,7 @@ static void cmd_dc(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, dc_options, NULL) { - switch(opt) { + switch (opt) { default: printf(dc_help); return; @@ -732,7 +738,8 @@ static void cmd_dc(int dev_id, int argc, char **argv) exit(1); } - if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) + if (hci_disconnect(dd, htobs(cr->conn_info->handle), + HCI_OE_USER_ENDED_CONNECTION, 10000) < 0) perror("Disconnect failed"); close(dd); @@ -757,7 +764,7 @@ static void cmd_sr(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, sr_options, NULL) { - switch(opt) { + switch (opt) { default: printf(sr_help); return; @@ -827,7 +834,7 @@ static void cmd_rssi(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, rssi_options, NULL) { - switch(opt) { + switch (opt) { default: printf(rssi_help); return; @@ -884,7 +891,8 @@ static void cmd_rssi(int dev_id, int argc, char **argv) } if (rp.status) { - printf("Read RSSI returned (error) status 0x%2.2X\n", rp.status); + printf("Read RSSI returned (error) status 0x%2.2X\n", + rp.status); exit(1); } printf("RSSI return value: %d\n", rp.rssi); @@ -914,7 +922,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, lq_options, NULL) { - switch(opt) { + switch (opt) { default: printf(lq_help); return; @@ -971,7 +979,7 @@ static void cmd_lq(int dev_id, int argc, char **argv) } if (rp.status) { - fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", + fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", rp.status); exit(1); } @@ -1002,7 +1010,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, tpl_options, NULL) { - switch(opt) { + switch (opt) { default: printf(tpl_help); return; @@ -1091,7 +1099,7 @@ static void cmd_afh(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, afh_options, NULL) { - switch(opt) { + switch (opt) { default: printf(afh_help); return; @@ -1148,7 +1156,7 @@ static void cmd_afh(int dev_id, int argc, char **argv) } if (rp.status) { - fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", + fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", rp.status); exit(1); } @@ -1187,7 +1195,7 @@ static void cmd_cpt(int dev_id, int argc, char **argv) int opt, dd, ptype; for_each_opt(opt, cpt_options, NULL) { - switch(opt) { + switch (opt) { default: printf(cpt_help); return; @@ -1272,7 +1280,7 @@ static void cmd_lst(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, lst_options, NULL) { - switch(opt) { + switch (opt) { default: printf(lst_help); return; @@ -1377,7 +1385,7 @@ static void cmd_auth(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, auth_options, NULL) { - switch(opt) { + switch (opt) { default: printf(auth_help); return; @@ -1446,7 +1454,7 @@ static void cmd_enc(int dev_id, int argc, char **argv) int opt, dd; for_each_opt(opt, enc_options, NULL) { - switch(opt) { + switch (opt) { default: printf(enc_help); return; @@ -1535,7 +1543,7 @@ static void usage(void) "\t--help\tDisplay help\n" "\t-i dev\tHCI device\n"); printf("Commands:\n"); - for (i=0; command[i].cmd; i++) + for (i = 0; command[i].cmd; i++) printf("\t%-4s\t%s\n", command[i].cmd, command[i].doc); printf("\n" @@ -1544,8 +1552,8 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"device", 1,0, 'i'}, + {"help", 0,0, 'h'}, + {"device", 1,0, 'i'}, {0, 0, 0, 0} }; @@ -1555,7 +1563,7 @@ int main(int argc, char **argv) bdaddr_t ba; while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { - switch(opt) { + switch (opt) { case 'i': dev_id = hci_devid(optarg); if (dev_id < 0) { @@ -1585,7 +1593,7 @@ int main(int argc, char **argv) exit(1); } - for (i=0; command[i].cmd; i++) { + for (i = 0; command[i].cmd; i++) { if (strncmp(command[i].cmd, argv[0], 3)) continue; command[i].func(dev_id, argc, argv); -- cgit From 5327e84a4c0f07e44d8c3b23410c355465b094e5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Nov 2004 11:23:01 +0000 Subject: Add support for changing the link key of a connection --- tools/hcitool.1 | 6 ++++- tools/hcitool.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/tools/hcitool.1 b/tools/hcitool.1 index 1d87b9a0..c4c69b87 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -166,7 +166,11 @@ Request authentication for the device with Bluetooth address .BI enc " [encrypt enable]" Enable or disable the encryption for the device with Bluetooth address .IR bdaddr . +.TP +.BI key " " +Change the connection link key for the device with Bluetooth address +.IR bdaddr . .SH AUTHORS -Written by Maxim Krasnyansky +Written by Maxim Krasnyansky and Marcel Holtmann .PP man page by Fabrizio Gennari diff --git a/tools/hcitool.c b/tools/hcitool.c index 6c41483b..4ecead2f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1506,6 +1506,74 @@ static void cmd_enc(int dev_id, int argc, char **argv) free(cr); } +/* Change connection link key */ + +static struct option key_options[] = { + {"help", 0,0, 'h'}, + {0, 0, 0, 0} +}; + +static char *key_help = + "Usage:\n" + "\tkey \n"; + +static void cmd_key(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + int opt, dd; + + for_each_opt(opt, key_options, NULL) { + switch (opt) { + default: + printf(key_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(key_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_change_link_key(dd, htobs(cr->conn_info->handle), 25000) < 0) { + perror("Changing link key failed"); + exit(1); + } + + close(dd); + free(cr); +} + static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -1529,6 +1597,7 @@ static struct { { "lst", cmd_lst, "Set/display link supervision timeout" }, { "auth", cmd_auth, "Request authentication" }, { "enc", cmd_enc, "Set connection encryption" }, + { "key", cmd_key, "Change connection link key" }, { NULL, NULL, 0 } }; -- cgit From 1fc62ff85f185eae7f2297648fc9a2846fcb284d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 22:55:42 +0000 Subject: Use the new AFH functions --- tools/hciconfig.c | 33 +++++---------------------------- tools/hcitool.c | 23 ++++------------------- 2 files changed, 9 insertions(+), 47 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 0e591e8d..854c8715 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -670,7 +670,6 @@ void cmd_version(int ctl, int hdev, char *opt) void cmd_inq_mode(int ctl, int hdev, char *opt) { - struct hci_request rq; int dd; dd = hci_open_dev(hdev); @@ -679,8 +678,6 @@ void cmd_inq_mode(int ctl, int hdev, char *opt) exit(1); } - memset(&rq, 0, sizeof(rq)); - if (opt) { uint8_t mode = atoi(opt); @@ -902,7 +899,6 @@ void cmd_page_to(int ctl, int hdev, char *opt) void cmd_afh_mode(int ctl, int hdev, char *opt) { - struct hci_request rq; int dd; dd = hci_open_dev(hdev); @@ -911,44 +907,25 @@ void cmd_afh_mode(int ctl, int hdev, char *opt) exit(1); } - memset(&rq, 0, sizeof(rq)); - if (opt) { - write_afh_mode_cp cp; - - cp.mode = atoi(opt); - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_AFH_MODE; - rq.cparam = &cp; - rq.clen = WRITE_AFH_MODE_RP_SIZE; + uint8_t mode = atoi(opt); - if (hci_send_req(dd, &rq, 1000) < 0) { + if (hci_write_afh_mode(dd, mode, 1000) < 0) { printf("Can't set AFH mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } } else { - read_afh_mode_rp rp; - - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_AFH_MODE; - rq.rparam = &rp; - rq.rlen = READ_AFH_MODE_RP_SIZE; + uint8_t mode; - if (hci_send_req(dd, &rq, 1000) < 0) { + if (hci_read_afh_mode(dd, &mode, 1000) < 0) { printf("Can't read AFH mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); exit(1); } - if (rp.status) { - printf("Read AFH mode on hci%d returned status %d\n", - hdev, rp.status); - exit(1); - } print_dev_hdr(&di); - printf("\tAFH mode: %s\n", rp.mode == 1 ? "Enabled" : "Disabled"); + printf("\tAFH mode: %s\n", mode == 1 ? "Enabled" : "Disabled"); } } diff --git a/tools/hcitool.c b/tools/hcitool.c index 4ecead2f..8bb68427 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1092,10 +1092,9 @@ static char *afh_help = static void cmd_afh(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_afh_map_rp rp; bdaddr_t bdaddr; uint16_t handle; + uint8_t mode, map[10]; int opt, dd; for_each_opt(opt, afh_options, NULL) { @@ -1142,30 +1141,16 @@ static void cmd_afh(int dev_id, int argc, char **argv) handle = htobs(cr->conn_info->handle); - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_AFH_MAP; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = READ_AFH_MAP_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_afh_map(dd, handle, &mode, map, 1000) < 0) { perror("HCI read AFH map request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI read_afh_map cmd failed (0x%2.2X)\n", - rp.status); - exit(1); - } - - if (rp.mode == 0x01) { + if (mode == 0x01) { int i; printf("AFH map: 0x"); for (i = 0; i < 10; i++) - printf("%02x", rp.map[i]); + printf("%02x", map[i]); printf("\n"); } else printf("AFH disabled\n"); -- cgit From 472036c7d265f73ae8d1beddbcf7a0762f6b1386 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 11 Nov 2004 18:22:27 +0000 Subject: Add checks for the ALSA library --- acinclude.m4 | 47 +++++++++++++++++++++++++++++++++++++++++++++-- configure.in | 1 + 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 49bed4ea..8b25acf8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -122,6 +122,42 @@ AC_DEFUN([AC_PATH_OPENOBEX], [ AC_SUBST(OPENOBEX_LIBS) ]) +AC_DEFUN([AC_PATH_ALSA], [ + alsa_prefix=${prefix} + + AC_ARG_WITH(alsa, AC_HELP_STRING([--with-alsa=DIR], [ALSA library is installed in DIR]), [ + if (test "${withval}" != "yes"); then + alsa_prefix=${withval} + fi + ]) + + ac_save_CPPFLAGS=$CPPFLAGS + ac_save_LDFLAGS=$LDFLAGS + + ALSA_CFLAGS="" + test -d "${alsa_prefix}/include" && ALSA_CFLAGS="$ALSA_CFLAGS -I${alsa_prefix}/include" + + CPPFLAGS="$CPPFLAGS $ALSA_CFLAGS" + AC_CHECK_HEADER(alsa/version.h, alsa_found=yes, alsa_found=no) + + ALSA_LIBS="" + if (test "${prefix}" = "${alsa_prefix}"); then + test -d "${libdir}" && ALSA_LIBS="$ALSA_LIBS -L${libdir}" + else + test -d "${alsa_prefix}/lib64" && ALSA_LIBS="$ALSA_LIBS -L${alsa_prefix}/lib64" + test -d "${alsa_prefix}/lib" && ALSA_LIBS="$ALSA_LIBS -L${alsa_prefix}/lib" + fi + + LDFLAGS="$LDFLAGS $ALSA_LIBS" + AC_CHECK_LIB(asound, snd_ctl_open, ALSA_LIBS="$ALSA_LIBS -lasound", alsa_found=no) + + CPPFLAGS=$ac_save_CPPFLAGS + LDFLAGS=$ac_save_LDFLAGS + + AC_SUBST(ALSA_CFLAGS) + AC_SUBST(ALSA_LIBS) +]) + AC_DEFUN([AC_PATH_USB], [ usb_prefix=${prefix} @@ -206,6 +242,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ debug_enable=no pie_enable=no obex_enable=${openobex_found} + alsa_enable=no dbus_enable=${dbus_found} test_enable=no cups_enable=no @@ -225,6 +262,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], [enable all extra options below]), [ obex_enable=${enableval} + alsa_enable=${enableval} dbus_enable=${enableval} test_enable=${enableval} cups_enable=${enableval} @@ -239,10 +277,14 @@ AC_DEFUN([AC_ARG_BLUEZ], [ obex_enable=${enableval} ]) + AC_ARG_ENABLE(alsa, AC_HELP_STRING([--enable-alsa], [enable ALSA support]), [ + alsa_enable=${enableval} + ]) + AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ dbus_enable=${enableval} ]) - + AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test], [install test programs]), [ test_enable=${enableval} ]) @@ -250,7 +292,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ AC_ARG_ENABLE(cups, AC_HELP_STRING([--enable-cups], [install CUPS backend support]), [ cups_enable=${enableval} ]) - + AC_ARG_ENABLE(pcmcia, AC_HELP_STRING([--enable-pcmcia], [install PCMCIA configuration files ]), [ pcmcia_enable=${enableval} ]) @@ -281,6 +323,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ fi AM_CONDITIONAL(OBEX, test "${obex_enable}" = "yes" && test "${openobex_found}" = "yes") + AM_CONDITIONAL(ALSA, test "${alsa_enable}" = "yes" && test "${alsa_found}" = "yes") AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes" && test "${dbus_found}" = "yes") AM_CONDITIONAL(TEST, test "${test_enable}" = "yes") AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") diff --git a/configure.in b/configure.in index b8d2140b..15e95198 100644 --- a/configure.in +++ b/configure.in @@ -22,6 +22,7 @@ AM_PROG_LEX AC_PATH_BLUEZ AC_PATH_OPENOBEX +AC_PATH_ALSA AC_PATH_USB AC_PATH_DBUS -- cgit From 4f20f27924bd0ad6fcb02b22df6dd1128fcccd78 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 11 Nov 2004 18:25:46 +0000 Subject: Add experimental mRouter support --- dund/dund.h | 5 ++--- dund/main.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++--------- dund/sdp.c | 12 ++++++------ 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/dund/dund.h b/dund/dund.h index 4a8af59b..92626310 100644 --- a/dund/dund.h +++ b/dund/dund.h @@ -45,7 +45,6 @@ int dun_kill_all_connections(void); int dun_open_connection(int sk, char *pppd, char **pppd_opts, int wait); /* SDP functions */ -int dun_sdp_register(uint8_t channel); +int dun_sdp_register(uint8_t channel, int mrouter); void dun_sdp_unregister(void); -int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel); - +int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int mrouter); diff --git a/dund/main.c b/dund/main.c index 61d3d941..51ad1db3 100644 --- a/dund/main.c +++ b/dund/main.c @@ -72,6 +72,7 @@ static int persist; static int use_sdp = 1; static int encrypt; static int master; +static int mrouter; static int search_duration = 10; static uint use_cache; @@ -97,16 +98,32 @@ enum { KILL } modes; +static int create_connection(char *dst, bdaddr_t *bdaddr, int mrouter); + static int do_listen(void) { struct sockaddr_rc sa; int sk; + if (mrouter) { + if (!cache.valid) + return -1; + + if (create_connection(cache.dst, &cache.bdaddr, mrouter) < 0) { + syslog(LOG_ERR, "Cannot connect to mRouter device. %s(%d)", + strerror(errno), errno); + return -1; + } + } + if (!channel) channel = DUN_DEFAULT_CHANNEL; if (use_sdp) - dun_sdp_register(channel); + dun_sdp_register(channel, mrouter); + + if (mrouter) + syslog(LOG_INFO, "Waiting for mRouter callback on channel %d", channel); /* Create RFCOMM socket */ sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); @@ -145,9 +162,15 @@ static int do_listen(void) syslog(LOG_ERR, "Fork failed. %s(%d)", strerror(errno), errno); default: close(nsk); + if (mrouter) { + close(sk); + terminate = 1; + } continue; } + close(sk); + if (msdun && ms_dun(nsk, 1, msdun) < 0) { syslog(LOG_ERR, "MSDUN failed. %s(%d)", strerror(errno), errno); exit(0); @@ -178,7 +201,7 @@ static int do_listen(void) * 1 - non critical error * 0 - success */ -static int create_connection(char *dst, bdaddr_t *bdaddr) +static int create_connection(char *dst, bdaddr_t *bdaddr, int mrouter) { struct sockaddr_rc sa; int sk, err = 0, ch; @@ -188,13 +211,13 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) ch = cache.channel; } else if (!channel) { - syslog(LOG_INFO, "Searching for %s on %s", "LAP", dst); + syslog(LOG_INFO, "Searching for %s on %s", mrouter ? "SP" : "LAP", dst); - if (dun_sdp_search(&src_addr, bdaddr, &ch) <= 0) + if (dun_sdp_search(&src_addr, bdaddr, &ch, mrouter) <= 0) return 0; } else ch = channel; - + syslog(LOG_INFO, "Connecting to %s channel %d", dst, ch); sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); @@ -216,6 +239,12 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) sa.rc_bdaddr = *bdaddr; if (!connect(sk, (struct sockaddr *) &sa, sizeof(sa)) ) { + if (mrouter) { + sleep(1); + close(sk); + return 0; + } + syslog(LOG_INFO, "Connection established"); if (msdun && ms_dun(sk, 0, msdun) < 0) { @@ -271,7 +300,7 @@ static int do_connect(void) if (cache.valid) { /* Use cached bdaddr */ - r = create_connection(cache.dst, &cache.bdaddr); + r = create_connection(cache.dst, &cache.bdaddr, 0); if (r < 0) { terminate = 1; break; @@ -294,7 +323,7 @@ static int do_connect(void) char dst[40]; ba2str(&ii[i].bdaddr, dst); - r = create_connection(dst, &ii[i].bdaddr); + r = create_connection(dst, &ii[i].bdaddr, 0); if (r < 0) { terminate = 1; break; @@ -351,19 +380,21 @@ static struct option main_lopts[] = { { "cache", 0, 0, 'C' }, { "pppd", 1, 0, 'd' }, { "msdun", 2, 0, 'X' }, + { "mrouter", 1, 0, 'm' }, { 0, 0, 0, 0 } }; static char main_sopts[] = "hsc:k:Kr:S:lnp::DQ::EMP:C::P:X"; static char main_help[] = - "LAP (LAN Access over PPP) daemon version " VERSION " \n" + "Bluetooth LAP (LAN Access over PPP) daemon version " VERSION " \n" "Usage:\n" "\tdund [pppd options]\n" "Options:\n" "\t--show --list -l Show active LAP connections\n" "\t--listen -s Listen for LAP connections\n" "\t--connect -c Create LAP connection\n" + "\t--mrouter -m Create mRouter connection\n" "\t--search -Q[duration] Search and connect\n" "\t--kill -k Kill LAP connection\n" "\t--killall -K Kill all LAP connections\n" @@ -467,6 +498,12 @@ int main(int argc, char **argv) msdun = 10; break; + case 'm': + mode = LISTEN; + dst = strdup(optarg); + mrouter = 1; + break; + case 'h': default: printf(main_help); @@ -533,7 +570,7 @@ int main(int argc, char **argv) } openlog("dund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); - syslog(LOG_INFO, "Bluetooth DUN daemon"); + syslog(LOG_INFO, "Bluetooth DUN daemon version %s", VERSION); if (src) { src_dev = hci_devid(src); diff --git a/dund/sdp.c b/dund/sdp.c index c5e8015a..939c361c 100644 --- a/dund/sdp.c +++ b/dund/sdp.c @@ -55,7 +55,7 @@ void dun_sdp_unregister(void) sdp_close(session); } -int dun_sdp_register(uint8_t channel) +int dun_sdp_register(uint8_t channel, int mrouter) { sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; uuid_t root_uuid, l2cap, rfcomm, dun; @@ -92,16 +92,16 @@ int dun_sdp_register(uint8_t channel) aproto = sdp_list_append(NULL, apseq); sdp_set_access_protos(record, aproto); - sdp_uuid16_create(&dun, LAN_ACCESS_SVCLASS_ID); + sdp_uuid16_create(&dun, mrouter ? SERIAL_PORT_SVCLASS_ID : LAN_ACCESS_SVCLASS_ID); svclass = sdp_list_append(NULL, &dun); sdp_set_service_classes(record, svclass); - sdp_uuid16_create(&profile[0].uuid, LAN_ACCESS_PROFILE_ID); + sdp_uuid16_create(&profile[0].uuid, mrouter ? SERIAL_PORT_PROFILE_ID : LAN_ACCESS_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(NULL, &profile[0]); sdp_set_profile_descs(record, pfseq); - sdp_set_info_attr(record, "LAN Access Point", NULL, NULL); + sdp_set_info_attr(record, mrouter ? "mRouter" : "LAN Access Point", NULL, NULL); status = sdp_record_register(session, record, 0); if (status) { @@ -112,7 +112,7 @@ int dun_sdp_register(uint8_t channel) return 0; } -int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel) +int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int mrouter) { sdp_session_t *s; sdp_list_t *srch, *attrs, *rsp; @@ -127,7 +127,7 @@ int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel) return -1; } - sdp_uuid16_create(&svclass, LAN_ACCESS_SVCLASS_ID); + sdp_uuid16_create(&svclass, mrouter ? SERIAL_PORT_SVCLASS_ID : LAN_ACCESS_SVCLASS_ID); srch = sdp_list_append(NULL, &svclass); attr = SDP_ATTR_PROTO_DESC_LIST; -- cgit From 895c3c7805f472daacca50e08014b4eeae6dce1a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 11 Nov 2004 18:36:43 +0000 Subject: Update changelog and bump version number --- ChangeLog | 17 +++++++++++++++++ configure.in | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ee26544f..e6461088 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +ver 2.11: + Various cleanups to avoid inclusion of kernel headers. + Fix output when the CUPS backend is called without arguments. + Fix problems with a 64 bit userland. + Use Bluetooth library functions if available. + Use standard numbering scheme of SDP record handles. + Add a master option to the hidd. + Add support for changing the link key of a connection. + Add support for requesting encryption on keyboards. + Add support for revision information of Digianswer devices. + Add support for the Zoom, IBM and TDK PCMCIA cards. + Add checks for the OpenOBEX and the ALSA libraries. + Add experimental mRouter support. + + Note: + This version needs at least bluez-libs-2.11 + ver 2.10: Use a define for the configuration directory. Fix string initialization for flags translation. diff --git a/configure.in b/configure.in index 15e95198..1eab0ecd 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.10) +AM_INIT_AUTOMAKE(bluez-utils, 2.11) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From e0cbfd7cc76db2b084c1218408e71838d3c4e3b0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Nov 2004 14:43:56 +0000 Subject: Add HCI 18.3 firmware build ids --- tools/csr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 6d9185e1..d5737fd9 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -246,6 +246,10 @@ static struct { { 1169, "HCI 18.1" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, + { 1733, "HCI 18.3" }, + { 1734, "HCI 18.3" }, + { 1735, "HCI 18.3" }, + { 1737, "HCI 18.3" }, { 0, } }; -- cgit From 5ac3c1ef76b8d1640bad9a21b74b197a82111874 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 14 Nov 2004 02:17:58 +0000 Subject: Inherit the device specific options from the default --- hcid/hcid.h | 2 +- hcid/main.c | 4 +++- hcid/parser.y | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index a5074ffa..87875beb 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -97,7 +97,7 @@ extern struct hcid_opts hcid; int read_config(char *file); -struct device_opts *alloc_device_opts(char *addr); +struct device_opts *alloc_device_opts(char *ref); gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data); gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data); diff --git a/hcid/main.c b/hcid/main.c index 5763798c..fbc85a5c 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -78,6 +78,7 @@ static inline void init_device_defaults(struct device_opts *device_opts) { memset(device_opts, 0, sizeof(*device_opts)); device_opts->scan = SCAN_PAGE | SCAN_INQUIRY; + device_opts->name = strdup("BlueZ"); } struct device_opts *alloc_device_opts(char *ref) @@ -95,7 +96,8 @@ struct device_opts *alloc_device_opts(char *ref) device->next = device_list; device_list = device; - init_device_defaults(&device->opts); + memcpy(&device->opts, &default_device, sizeof(struct device_opts)); + device->opts.name = strdup(default_device.name); return &device->opts; } diff --git a/hcid/parser.y b/hcid/parser.y index eb81ab22..7c33278e 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -183,7 +183,7 @@ device_opt: | K_NAME dev_name { if (parser_device->name) free(parser_device->name); - parser_device->name = $2; + parser_device->name = strdup($2); } | K_CLASS NUM { -- cgit From 23b788ad7e8009445323f65b3fb94bb6b11717d0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 15 Nov 2004 17:34:40 +0000 Subject: Add --nosdp option for devices with resource limitation --- hidd/main.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index 2aee55a1..1ad39e0f 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -223,7 +223,7 @@ static int request_encryption(bdaddr_t *src, bdaddr_t *dst) return err; } -static int create_device(int ctl, int csk, int isk, uint8_t subclass, int encrypt, int timeout) +static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int encrypt, int timeout) { struct hidp_connadd_req req; struct sockaddr_l2 addr; @@ -254,9 +254,12 @@ static int create_device(int ctl, int csk, int isk, uint8_t subclass, int encryp req.flags = 0; req.idle_to = timeout * 60; - err = get_hid_device_info(&src, &dst, &req); - if (err < 0) - goto error; + if (!nosdp) { + err = get_hid_device_info(&src, &dst, &req); + if (err < 0) + goto error; + } else + req.subclass = 0xc0; if (subclass != 0x00) req.subclass = subclass; @@ -285,7 +288,7 @@ error: return err; } -static void run_server(int ctl, int csk, int isk, uint8_t subclass, int encrypt, int timeout) +static void run_server(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int encrypt, int timeout) { struct pollfd p[2]; short events; @@ -311,7 +314,7 @@ static void run_server(int ctl, int csk, int isk, uint8_t subclass, int encrypt, ncsk = l2cap_accept(csk, NULL); nisk = l2cap_accept(isk, NULL); - err = create_device(ctl, ncsk, nisk, subclass, encrypt, timeout); + err = create_device(ctl, ncsk, nisk, subclass, nosdp, encrypt, timeout); if (err < 0) syslog(LOG_ERR, "HID create error %d (%s)", errno, strerror(errno)); @@ -375,7 +378,7 @@ static void do_show(int ctl) } } -static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int encrypt, int timeout) +static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int nosdp, int encrypt, int timeout) { int csk, isk, err; @@ -394,7 +397,7 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, exit(1); } - err = create_device(ctl, csk, isk, subclass, encrypt, timeout); + err = create_device(ctl, csk, isk, subclass, nosdp, encrypt, timeout); if (err < 0) { fprintf(stderr, "HID create error %d (%s)\n", errno, strerror(errno)); @@ -406,7 +409,7 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, } } -static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int encrypt, int timeout) +static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int nosdp, int encrypt, int timeout) { inquiry_info *info = NULL; bdaddr_t src, dst; @@ -437,7 +440,7 @@ static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int encrypt, ba2str(&dst, addr); printf("\tConnecting to device %s\n", addr); - do_connect(ctl, &src, &dst, subclass, encrypt, timeout); + do_connect(ctl, &src, &dst, subclass, nosdp, encrypt, timeout); } } @@ -525,6 +528,7 @@ static struct option main_options[] = { { "device", 1, 0, 'i' }, { "master", 0, 0, 'M' }, { "encrypt", 0, 0, 'E' }, + { "nosdp", 0, 0, 'D' }, { "show", 0, 0, 'l' }, { "list", 0, 0, 'l' }, { "server", 0, 0, 'd' }, @@ -550,11 +554,11 @@ int main(int argc, char *argv[]) char addr[18]; int log_option = LOG_NDELAY | LOG_PID; int opt, fd, ctl, csk, isk; - int mode = 0, daemon = 1, encrypt = 0, timeout = 30, lm = 0; + int mode = 0, daemon = 1, nosdp = 0, encrypt = 0, timeout = 30, lm = 0; bacpy(&bdaddr, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:nt:b:MEldsc:k:Ku:h", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+i:nt:b:MEDldsc:k:Ku:h", main_options, NULL)) != -1) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -580,6 +584,9 @@ int main(int argc, char *argv[]) case 'E': encrypt = 1; break; + case 'D': + nosdp = 1; + break; case 'l': mode = 0; break; @@ -641,12 +648,12 @@ int main(int argc, char *argv[]) break; case 2: - do_search(ctl, &bdaddr, subclass, encrypt, timeout); + do_search(ctl, &bdaddr, subclass, nosdp, encrypt, timeout); close(ctl); exit(0); case 3: - do_connect(ctl, &bdaddr, &dev, subclass, encrypt, timeout); + do_connect(ctl, &bdaddr, &dev, subclass, nosdp, encrypt, timeout); close(ctl); exit(0); @@ -694,7 +701,7 @@ int main(int argc, char *argv[]) sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); - run_server(ctl, csk, isk, subclass, encrypt, timeout); + run_server(ctl, csk, isk, subclass, nosdp, encrypt, timeout); syslog(LOG_INFO, "Exit"); -- cgit From 52d36be0bf2610739f04786d18df80db23e9cf6b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 17 Nov 2004 08:28:52 +0000 Subject: Add parameter for activating secure mode --- test/l2test.c | 34 +++++++++++++++++++++++----------- test/rctest.c | 45 ++++++++++++++++++++++----------------------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index f98e5109..eedf4b70 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -51,6 +51,8 @@ #include #include +#include +#include #include #define NIBBLE_TO_ASCII(c) ((c) < 0x0a ? (c) + 0x30 : (c) + 0x57) @@ -88,6 +90,7 @@ int num_frames = -1; // Infinite int master = 0; int auth = 0; int encrypt = 0; +int secure = 0; int socktype = SOCK_SEQPACKET; int linger = 0; int reliable = 0; @@ -270,15 +273,14 @@ void do_listen(void (*handler)(int sk)) opt = 0; if (reliable) opt |= L2CAP_LM_RELIABLE; - if (master) - opt |= L2CAP_LM_MASTER; - + opt |= L2CAP_LM_MASTER; if (auth) - opt |= L2CAP_LM_AUTH; - + opt |= L2CAP_LM_AUTH; if (encrypt) - opt |= L2CAP_LM_ENCRYPT; + opt |= L2CAP_LM_ENCRYPT; + if (secure) + opt |= L2CAP_LM_SECURE; if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); @@ -570,7 +572,7 @@ void usage(void) "\t-m multiple connects\n"); printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P psm]\n" + "\t[-b bytes] [-i device] [-P psm]\n" "\t[-I imtu] [-O omtu]\n" "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" @@ -578,6 +580,7 @@ void usage(void) "\t[-D] use connectionless channel (datagram)\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" + "\t[-S] secure connection\n" "\t[-M] become master\n"); } @@ -590,8 +593,10 @@ int main(int argc ,char *argv[]) struct sigaction sa; mode = RECV; need_addr = 0; - - while ((opt=getopt(argc,argv,"rdscuwmnxyb:P:I:O:S:N:RMAEDL:")) != EOF) { + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:RMAESL:D")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -642,8 +647,11 @@ int main(int argc ,char *argv[]) mode = SENDDUMP; break; - case 'S': - baswap(&bdaddr, strtoba(optarg)); + case 'i': + if (!strncasecmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); break; case 'P': @@ -678,6 +686,10 @@ int main(int argc ,char *argv[]) encrypt = 1; break; + case 'S': + secure = 1; + break; + case 'D': socktype = SOCK_DGRAM; break; diff --git a/test/rctest.c b/test/rctest.c index 31ecae57..6e5fba27 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -49,6 +49,8 @@ #include #include +#include +#include #include /* Test modes */ @@ -65,10 +67,6 @@ enum { unsigned char *buf; -/* Default mtu */ -int imtu = 672; -int omtu = 0; - /* Default data size */ long data_size = 127; long num_frames = -1; @@ -80,6 +78,7 @@ uint8_t channel = 10; int master = 0; int auth = 0; int encrypt = 0; +int secure = 0; int socktype = SOCK_STREAM; int linger = 0; @@ -153,13 +152,13 @@ void do_listen( void (*handler)(int sk) ) /* Set link mode */ opt = 0; if (master) - opt |= RFCOMM_LM_MASTER; - + opt |= RFCOMM_LM_MASTER; if (auth) - opt |= RFCOMM_LM_AUTH; - + opt |= RFCOMM_LM_AUTH; if (encrypt) - opt |= RFCOMM_LM_ENCRYPT; + opt |= RFCOMM_LM_ENCRYPT; + if (secure) + opt |= RFCOMM_LM_SECURE; if (setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); @@ -343,8 +342,7 @@ void usage(void) "\t-m multiple connects\n"); printf("Options:\n" - "\t[-b bytes] [-S bdaddr] [-P channel]\n" - "\t[-I imtu] [-O omtu]\n" + "\t[-b bytes] [-i device] [-P channel]\n" "\t[-L seconds] enabled SO_LINGER option\n" "\t[-N num] number of frames to send\n" "\t[-A] request authentication\n" @@ -361,8 +359,10 @@ int main(int argc ,char *argv[]) struct sigaction sa; mode = RECV; need_addr = 0; - - while ((opt=getopt(argc,argv,"rdscuwmnb:P:I:O:S:MAEL:N:")) != EOF) { + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:N:MAESL:")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -405,22 +405,17 @@ int main(int argc ,char *argv[]) data_size = atoi(optarg); break; - case 'S': - baswap(&bdaddr, strtoba(optarg)); + case 'i': + if (!strncasecmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); break; case 'P': channel = atoi(optarg); break; - case 'I': - imtu = atoi(optarg); - break; - - case 'O': - omtu = atoi(optarg); - break; - case 'M': master = 1; break; @@ -433,6 +428,10 @@ int main(int argc ,char *argv[]) encrypt = 1; break; + case 'S': + secure = 1; + break; + case 'L': linger = atoi(optarg); break; -- cgit From 16a857ba91612b9350062f233fcfb007bcd3f7c2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 18 Nov 2004 07:46:44 +0000 Subject: More build ids for HCI 18.2 and the BlueCore3-Multimedia --- tools/csr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index d5737fd9..b085b869 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -246,6 +246,14 @@ static struct { { 1169, "HCI 18.1" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, + { 1501, "HCI 18.2" }, + { 1503, "HCI 18.2" }, + { 1504, "HCI 18.2" }, + { 1505, "HCI 18.2" }, + { 1506, "HCI 18.2" }, + { 1520, "HCI 18.2" }, + { 1591, "HCI 18.2" }, + { 1592, "HCI 18.2" }, { 1733, "HCI 18.3" }, { 1734, "HCI 18.3" }, { 1735, "HCI 18.3" }, -- cgit From 27bcb4ea2983a5ee437704dece36067653b7c22e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 18 Nov 2004 07:53:06 +0000 Subject: Add build ids for BlueCore3-ROM --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index b085b869..143fcca0 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -242,8 +242,10 @@ static struct { { 856, "HCI 17.3.2" }, { 857, "HCI 17.3.2" }, { 858, "HCI 17.3.2" }, + { 1120, "HCI 17.11" }, { 1168, "HCI 18.1" }, { 1169, "HCI 18.1" }, + { 1298, "HCI 18.2" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, { 1501, "HCI 18.2" }, -- cgit From e3c755f8a89c8dab5f902d1c6f332c2c03348291 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 18 Nov 2004 08:17:50 +0000 Subject: Use --device for selecting the source device --- pand/main.c | 14 +++++++------- pand/pand.1 | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pand/main.c b/pand/main.c index 9165bf92..725ee553 100644 --- a/pand/main.c +++ b/pand/main.c @@ -47,9 +47,9 @@ #include #include -#include #include #include +#include #include #include "pand.h" @@ -485,8 +485,8 @@ static struct option main_lopts[] = { { "killall", 0, 0, 'K' }, { "role", 1, 0, 'r' }, { "service", 1, 0, 'd' }, + { "ethernet", 1, 0, 'e' }, { "device", 1, 0, 'i' }, - { "source", 1, 0, 'S' }, { "nosdp", 0, 0, 'D' }, { "list", 0, 0, 'l' }, { "show", 0, 0, 'l' }, @@ -500,7 +500,7 @@ static struct option main_lopts[] = { { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:i:S:lnp::DQ::EMC::P:z"; +static char main_sopts[] = "hsc:k:Kr:e:i:lnp::DQ::EMC::P:z"; static char main_help[] = "Bluetooth PAN daemon version " VERSION " \n" @@ -516,8 +516,8 @@ static char main_help[] = "\t--killall -K Kill all PAN connections\n" "\t--role -r Local PAN role (PANU, NAP, GN)\n" "\t--service -d Remote PAN service (PANU, NAP, GN)\n" - "\t--device -i Network interface name\n" - "\t--source -S Source bdaddr\n" + "\t--ethernet -e Network interface name\n" + "\t--device -i Source bdaddr\n" "\t--nosdp -D Disable SDP\n" "\t--encrypt -E Enable encryption\n" "\t--master -M Become the master of a piconet\n" @@ -566,7 +566,7 @@ int main(int argc, char **argv) detach = 0; break; - case 'S': + case 'i': src = strdup(optarg); break; @@ -590,7 +590,7 @@ int main(int argc, char **argv) master = 1; break; - case 'i': + case 'e': strcpy(netdev, optarg); break; diff --git a/pand/pand.1 b/pand/pand.1 index fbcc1ddd..c6c32dfc 100644 --- a/pand/pand.1 +++ b/pand/pand.1 @@ -33,10 +33,10 @@ Local PAN role (PANU, NAP, GN) \fB\-\-service\fR \fB\-d\fR Remote PAN service (PANU, NAP, GN) .TP -\fB\-\-device\fR \fB\-i\fR +\fB\-\-ethernet\fR \fB\-e\fR Network interface name .TP -\fB\-\-source\fR \fB\-S\fR +\fB\-\-device\fR \fB\-i\fR Source bdaddr .TP \fB\-\-nosdp\fR \fB\-D\fR -- cgit From 6f6c722d1fc37d94f45c438f1b611c2d885e62f3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 18 Nov 2004 08:23:23 +0000 Subject: Add support for secure mode --- pand/main.c | 12 ++++++++++-- pand/pand.1 | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pand/main.c b/pand/main.c index 725ee553..e7fcb875 100644 --- a/pand/main.c +++ b/pand/main.c @@ -62,6 +62,7 @@ static int persist; static int use_sdp = 1; static int use_cache; static int encrypt; +static int secure; static int master; static int cleanup; static int search_duration = 10; @@ -166,9 +167,10 @@ static int do_listen(void) lm = 0; if (master) lm |= L2CAP_LM_MASTER; - if (encrypt) lm |= L2CAP_LM_ENCRYPT; + if (secure) + lm |= L2CAP_LM_SECURE; if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { syslog(LOG_ERR, "Failed to set link mode. %s(%d)", strerror(errno), errno); @@ -493,6 +495,7 @@ static struct option main_lopts[] = { { "nodetach", 0, 0, 'n' }, { "persist", 2, 0, 'p' }, { "encrypt", 0, 0, 'E' }, + { "secure", 0, 0, 'S' }, { "master", 0, 0, 'M' }, { "cache", 0, 0, 'C' }, { "pidfile", 1, 0, 'P' }, @@ -500,7 +503,7 @@ static struct option main_lopts[] = { { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:e:i:lnp::DQ::EMC::P:z"; +static char main_sopts[] = "hsc:k:Kr:e:i:lnp::DQ::ESMC::P:z"; static char main_help[] = "Bluetooth PAN daemon version " VERSION " \n" @@ -520,6 +523,7 @@ static char main_help[] = "\t--device -i Source bdaddr\n" "\t--nosdp -D Disable SDP\n" "\t--encrypt -E Enable encryption\n" + "\t--secure -S Secure connection\n" "\t--master -M Become the master of a piconet\n" "\t--nodetach -n Do not become a daemon\n" "\t--persist -p[interval] Persist mode\n" @@ -586,6 +590,10 @@ int main(int argc, char **argv) encrypt = 1; break; + case 'S': + secure = 1; + break; + case 'M': master = 1; break; diff --git a/pand/pand.1 b/pand/pand.1 index c6c32dfc..4e18ad4a 100644 --- a/pand/pand.1 +++ b/pand/pand.1 @@ -45,6 +45,9 @@ Disable SDP \fB\-\-encrypt\fR \fB\-E\fR Enable encryption .TP +\fB\-\-secure\fR \fB\-S\fR +Secure connection +.TP \fB\-\-master\fR \fB\-M\fR Become the master of a piconet .TP -- cgit From 1b876422a5d3464c3a7ddad14956542adb2c1e53 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 18 Nov 2004 08:26:06 +0000 Subject: Use --device for selecting the source device --- dund/dund.1 | 2 +- dund/main.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dund/dund.1 b/dund/dund.1 index 3ac0f03d..7b4e7cd9 100644 --- a/dund/dund.1 +++ b/dund/dund.1 @@ -29,7 +29,7 @@ Kill all DUN connections \fB\-\-channel\fR \fB\-C\fR RFCOMM channel .TP -\fB\-\-source\fR \fB\-S\fR +\fB\-\-device\fR \fB\-i\fR Source bdaddr .TP \fB\-\-nosdp\fR \fB\-D\fR diff --git a/dund/main.c b/dund/main.c index 51ad1db3..b7d2b356 100644 --- a/dund/main.c +++ b/dund/main.c @@ -45,9 +45,9 @@ #include #include -#include #include #include +#include #include "dund.h" #include "lib.h" @@ -369,7 +369,7 @@ static struct option main_lopts[] = { { "kill", 1, 0, 'k' }, { "killall", 0, 0, 'K' }, { "channel", 1, 0, 'P' }, - { "source", 1, 0, 'S' }, + { "device", 1, 0, 'i' }, { "nosdp", 0, 0, 'D' }, { "list", 0, 0, 'l' }, { "show", 0, 0, 'l' }, @@ -384,7 +384,7 @@ static struct option main_lopts[] = { { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:S:lnp::DQ::EMP:C::P:X"; +static char main_sopts[] = "hsc:k:Kr:i:lnp::DQ::EMP:C::P:X"; static char main_help[] = "Bluetooth LAP (LAN Access over PPP) daemon version " VERSION " \n" @@ -399,7 +399,7 @@ static char main_help[] = "\t--kill -k Kill LAP connection\n" "\t--killall -K Kill all LAP connections\n" "\t--channel -P RFCOMM channel\n" - "\t--source -S Source bdaddr\n" + "\t--device -i Source bdaddr\n" "\t--nosdp -D Disable SDP\n" "\t--nodetach -n Do not become a daemon\n" "\t--persist -p[interval] Persist mode\n" @@ -453,7 +453,7 @@ int main(int argc, char **argv) channel = atoi(optarg); break; - case 'S': + case 'i': src = strdup(optarg); break; -- cgit From d500612b723b88342b46c18e57730cec4b1d96af Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Nov 2004 20:22:32 +0000 Subject: Add more build ids and chip versions --- tools/csr.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 143fcca0..54acc260 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -45,6 +45,9 @@ static struct { uint16_t id; char *str; } csr_map[] = { + { 66, "HCI 9.8" }, + { 97, "HCI 10.3" }, + { 101, "HCI 10.5" }, { 111, "HCI 11.0" }, { 112, "HCI 11.1" }, { 114, "HCI 11.2" }, @@ -245,6 +248,7 @@ static struct { { 1120, "HCI 17.11" }, { 1168, "HCI 18.1" }, { 1169, "HCI 18.1" }, + { 1241, "HCI 18.x" }, { 1298, "HCI 18.2" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, @@ -287,10 +291,31 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) else return "BlueCore01b"; case 0x02: - if (rev == 0x89) - return "BlueCore02 (ES2)"; - else + switch (rev) { + case 0x89: + return "BlueCore02-External (ES2)"; + case 0x8a: + return "BlueCore02-External"; + case 0x28: + return "BlueCore02-ROM/Audio/Flash"; + default: return "BlueCore02"; + } + case 0x03: + switch (rev) { + case 0x43: + return "BlueCore3-MM"; + case 0x15: + return "BlueCore3-ROM"; + case 0xe2: + return "BlueCore3-Flash"; + case 0x26: + return "BlueCore4-External"; + case 0x30: + return "BlueCore4-ROM"; + default: + return "BlueCore3 or BlueCore4"; + } default: return "Unknown"; } -- cgit From 338653545090b72df3e97610ce8dc9b6f1a4e6d4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Nov 2004 16:56:03 +0000 Subject: Fix a bug when connected to a device from the config file --- rfcomm/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rfcomm/main.c b/rfcomm/main.c index 3a7fe0a5..86331b9d 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -275,7 +275,7 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg bacpy(&raddr.rc_bdaddr, &rfcomm_opts[dev].bdaddr); raddr.rc_channel = rfcomm_opts[dev].channel; - if (bacmp(&req.dst, BDADDR_ANY) == 0) { + if (bacmp(&raddr.rc_bdaddr, BDADDR_ANY) == 0) { fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev); return; } -- cgit From 2ec32295cb3b5f8b1cf140a8913d1e75dd8a6db5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 03:49:36 +0000 Subject: Update UUID translation for WAP --- tools/sdptool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index c63750c4..3257159a 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -236,7 +236,7 @@ static struct uuid_def uuid16_names[] = { { 0x1111, "Fax", NULL, 0 }, { 0x1112, "HeadsetAudioGateway", NULL, 0 }, { 0x1113, "WAP", NULL, 0 }, - { 0x1114, "WAP_CLIENT", NULL, 0 }, + { 0x1114, "WAP Client", NULL, 0 }, { 0x1115, "PANU (PAN/BNEP)", pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, { 0x1116, "NAP (PAN/BNEP)", -- cgit From 2b6e37e7f5891fcdfa163bc4f7b988f4287f05bb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 12:35:17 +0000 Subject: Add build id of the Apple firmware update 1.2 --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/csr.c b/tools/csr.c index 54acc260..6861c4ab 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -258,6 +258,7 @@ static struct { { 1505, "HCI 18.2" }, { 1506, "HCI 18.2" }, { 1520, "HCI 18.2" }, + { 1586, "HCI 18.2" }, { 1591, "HCI 18.2" }, { 1592, "HCI 18.2" }, { 1733, "HCI 18.3" }, -- cgit From 6b24ea1e4fdfba1d9f189d2575d1f9695daca7e9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 15:02:25 +0000 Subject: Add support for KYE/Genius adapter --- tools/hid2hci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/hid2hci.c b/tools/hid2hci.c index c800c7ee..115e0ef5 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -219,6 +219,8 @@ static int switch_logitech(struct device_info *devinfo) static struct device_id device_list[] = { { HCI, 0x0a12, 0x1000, switch_hidproxy }, { HID, 0x0a12, 0x0001, switch_hidproxy }, + { HCI, 0x0458, 0x1000, switch_hidproxy }, + { HID, 0x0458, 0x003f, switch_hidproxy }, { HCI, 0x05ac, 0x1000, switch_hidproxy }, { HID, 0x05ac, 0x8203, switch_hidproxy }, { HCI, 0x046d, 0xc703, switch_logitech }, -- cgit From 20ab71f23fe08b749b43dbd3c7a96e0313a6471e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 18:55:17 +0000 Subject: Add build id for the KYE/Genius Bluetooth adapter --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/csr.c b/tools/csr.c index 6861c4ab..5f6f4b27 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -250,6 +250,7 @@ static struct { { 1169, "HCI 18.1" }, { 1241, "HCI 18.x" }, { 1298, "HCI 18.2" }, + { 1354, "HCI 18.2" } { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, { 1501, "HCI 18.2" }, -- cgit From feb6bed4073bfb6eef1e636d9c055dcb8f320637 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 18:55:53 +0000 Subject: Typo --- tools/csr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/csr.c b/tools/csr.c index 5f6f4b27..ca28ef2f 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -250,7 +250,7 @@ static struct { { 1169, "HCI 18.1" }, { 1241, "HCI 18.x" }, { 1298, "HCI 18.2" }, - { 1354, "HCI 18.2" } + { 1354, "HCI 18.2" }, { 1392, "HCI 18.2" }, { 1393, "HCI 18.2" }, { 1501, "HCI 18.2" }, -- cgit From d9e14bfc034177b2a805d368a79c999a401216a9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 2 Dec 2004 08:48:59 +0000 Subject: Update changelog and bump version number --- ChangeLog | 11 +++++++++++ configure.in | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e6461088..35325162 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +ver 2.12: + Inherit the device specific options from the default. + Use --device for selecting the source device. + Add --nosdp option for devices with resource limitation. + Add support and parameter option for secure mode. + Add a lot of build ids and hardware revisions. + Update UUID translation tables. + + Note: + This version needs at least bluez-libs-2.12 + ver 2.11: Various cleanups to avoid inclusion of kernel headers. Fix output when the CUPS backend is called without arguments. diff --git a/configure.in b/configure.in index 1eab0ecd..1a94d114 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.11) +AM_INIT_AUTOMAKE(bluez-utils, 2.12) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From c75b3f2fae502b565565bcb94a4fab9dd889646a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 4 Dec 2004 04:53:46 +0000 Subject: Use --device and make more functions static --- tools/sdptool.c | 161 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 87 insertions(+), 74 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 3257159a..8d212c4e 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -34,12 +34,15 @@ #include #endif -#include #include -#include #include +#include +#include #include +#include +#include +#include #include #include @@ -48,7 +51,7 @@ /* * Convert a string to a BDADDR, with a few "enhancements" - Jean II */ -int estr2ba(char *str, bdaddr_t *ba) +static int estr2ba(char *str, bdaddr_t *ba) { /* Only trap "local", "any" is already dealt with */ if(!strcmp(str, "local")) { @@ -268,16 +271,16 @@ static struct uuid_def uuid16_names[] = { { 0x1204, "GenericTelephony", NULL, 0 }, }; -const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); +static const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); -void sdp_data_printf(sdp_data_t *, struct attrib_context *, int); +static void sdp_data_printf(sdp_data_t *, struct attrib_context *, int); /* * Parse a UUID. * The BT assigned numbers only list UUID16, so I'm not sure the * other types will ever get used... */ -void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int indent) +static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int indent) { if (uuid) { if (uuid->type == SDP_UUID16) { @@ -360,7 +363,7 @@ static void printf_dataseq(sdp_data_t * pData, * Parse a single data element (either in the attribute or in a data * sequence). */ -void sdp_data_printf(sdp_data_t *sdpdata, +static void sdp_data_printf(sdp_data_t *sdpdata, struct attrib_context *context, int indent) { @@ -443,7 +446,7 @@ void sdp_data_printf(sdp_data_t *sdpdata, /* * Parse a single attribute. */ -void sdp_attr_printf_func(void *value, void *userData) +static void sdp_attr_printf_func(void *value, void *userData) { sdp_data_t *sdpdata = NULL; uint16_t attrId; @@ -496,7 +499,7 @@ void sdp_attr_printf_func(void *value, void *userData) * We assume the record has already been read, parsed and cached * locally. Jean II */ -void sdp_printf_service_attr(sdp_record_t *rec) +static void sdp_printf_service_attr(sdp_record_t *rec) { if (rec && rec->attrlist) { struct service_context service = { NULL }; @@ -508,7 +511,7 @@ void sdp_printf_service_attr(sdp_record_t *rec) * Set attributes with single values in SDP record * Jean II */ -int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *value) +static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *value) { sdp_list_t *attrid_list; uint32_t range = 0x0000ffff; @@ -560,8 +563,8 @@ int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, char *valu } static struct option set_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { 0, 0, 0, 0 } }; static char *set_help = @@ -571,7 +574,7 @@ static char *set_help = /* * Add an attribute to an existing SDP record on the local SDP server */ -int cmd_setattr(int argc, char **argv) +static int cmd_setattr(int argc, char **argv) { int opt, status; uint32_t handle; @@ -610,7 +613,7 @@ int cmd_setattr(int argc, char **argv) * We do only simple data sequences. Sequence of sequences is a pain ;-) * Jean II */ -int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attrib, int argc, char **argv) +static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attrib, int argc, char **argv) { sdp_list_t *attrid_list; uint32_t range = 0x0000ffff; @@ -695,8 +698,8 @@ int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attrib, int } static struct option seq_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { 0, 0, 0, 0 } }; static char *seq_help = @@ -707,7 +710,7 @@ static char *seq_help = * Add an attribute sequence to an existing SDP record * on the local SDP server */ -int cmd_setseq(int argc, char **argv) +static int cmd_setseq(int argc, char **argv) { int opt, status; uint32_t handle; @@ -810,7 +813,7 @@ static void print_service_desc(void *value, void *user) } } -void print_lang_attr(void *value, void *user) +static void print_lang_attr(void *value, void *user) { sdp_lang_attr_t *lang = (sdp_lang_attr_t *)value; printf(" code_ISO639: 0x%02x\n", lang->code_ISO639); @@ -818,13 +821,13 @@ void print_lang_attr(void *value, void *user) printf(" base_offset: 0x%02x\n", lang->base_offset); } -void print_access_protos(void *value, void *userData) +static void print_access_protos(void *value, void *userData) { sdp_list_t *protDescSeq = (sdp_list_t *)value; sdp_list_foreach(protDescSeq, print_service_desc, 0); } -void print_profile_desc(void *value, void *userData) +static void print_profile_desc(void *value, void *userData) { sdp_profile_desc_t *desc = (sdp_profile_desc_t *)value; char str[MAX_LEN_PROFILEDESCRIPTOR_UUID_STR]; @@ -840,7 +843,7 @@ void print_profile_desc(void *value, void *userData) /* * Parse a SDP record in user friendly form. */ -void print_service_attr(sdp_record_t *rec) +static void print_service_attr(sdp_record_t *rec) { sdp_list_t *list = 0, *proto = 0; @@ -926,7 +929,7 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Serial Port", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -984,7 +987,7 @@ static int add_dun(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Dial-Up Networking", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1040,7 +1043,7 @@ static int add_lan(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "LAN Access over PPP", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1099,7 +1102,7 @@ static int add_headset(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Headset", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1161,7 +1164,7 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Handsfree", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1223,7 +1226,7 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "SIM Access", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1281,7 +1284,7 @@ static int add_fax(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Fax", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1354,7 +1357,7 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "OBEX Object Push", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1415,7 +1418,7 @@ static int add_file_trans(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "OBEX File Transfer", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1488,7 +1491,7 @@ static int add_nap(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Network Access Point Service", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1547,7 +1550,7 @@ static int add_gn(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Group Network Service", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1614,7 +1617,7 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Cordless Telephony", 0, 0); - if (0 > sdp_record_register(session, &record, SDP_RECORD_PERSIST)) { + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1777,7 +1780,7 @@ struct { }; /* Add local service */ -int add_service(bdaddr_t *bdaddr, svc_info_t *si) +static int add_service(bdaddr_t *bdaddr, svc_info_t *si) { int i; sdp_session_t *sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); @@ -1799,16 +1802,16 @@ int add_service(bdaddr_t *bdaddr, svc_info_t *si) } static struct option add_options[] = { - {"help", 0,0, 'h'}, - {"channel", 1,0, 'c'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { "channel", 1,0, 'c' }, + { 0, 0, 0, 0} }; static char *add_help = "Usage:\n" "\tadd [--channel=CHAN] service\n"; -int cmd_add(int argc, char **argv) +static int cmd_add(int argc, char **argv) { svc_info_t si; int opt; @@ -1837,7 +1840,7 @@ int cmd_add(int argc, char **argv) } /* Delete local service */ -int del_service(bdaddr_t *bdaddr, void *arg) +static int del_service(bdaddr_t *bdaddr, void *arg) { uint32_t handle, range = 0x0000ffff; sdp_list_t *attr; @@ -1873,15 +1876,15 @@ int del_service(bdaddr_t *bdaddr, void *arg) } static struct option del_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { 0, 0, 0, 0 } }; static char *del_help = "Usage:\n" "\tdel record_handle\n"; -int cmd_del(int argc, char **argv) +static int cmd_del(int argc, char **argv) { int opt; @@ -1923,7 +1926,7 @@ static void inquiry(handler_t handler, void *arg) /* * Search for a specific SDP service */ -int do_search(bdaddr_t *bdaddr, struct search_context *context) +static int do_search(bdaddr_t *bdaddr, struct search_context *context) { sdp_list_t *attrid, *search, *seq, *next; uint32_t range = 0x0000ffff; @@ -1984,9 +1987,9 @@ int do_search(bdaddr_t *bdaddr, struct search_context *context) } static struct option browse_options[] = { - {"help", 0,0, 'h'}, - {"tree", 0,0, 't'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { "tree", 0,0, 't' }, + { 0, 0, 0, 0 } }; static char *browse_help = @@ -1997,7 +2000,7 @@ static char *browse_help = * Browse the full SDP database (i.e. list all services starting from the * root/top-level). */ -int cmd_browse(int argc, char **argv) +static int cmd_browse(int argc, char **argv) { struct search_context context; int opt; @@ -2029,10 +2032,10 @@ int cmd_browse(int argc, char **argv) } static struct option search_options[] = { - {"help", 0,0, 'h'}, - {"bdaddr", 1,0, 'b'}, - {"tree", 0,0, 't'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { "bdaddr", 1,0, 'b' }, + { "tree", 0,0, 't' }, + { 0, 0, 0, 0} }; static char *search_help = @@ -2048,7 +2051,7 @@ static char *search_help = * (this would search a service supporting both L2CAP and BNEP directly in * the top level browse group) */ -int cmd_search(int argc, char **argv) +static int cmd_search(int argc, char **argv) { struct search_context context; uint16_t class = 0; @@ -2116,7 +2119,7 @@ int cmd_search(int argc, char **argv) * Not really useful to the user, just show how it can be done... * Jean II */ -int get_service(bdaddr_t *bdaddr, struct search_context *context) +static int get_service(bdaddr_t *bdaddr, struct search_context *context) { sdp_list_t *attrid; uint32_t range = 0x0000ffff; @@ -2150,10 +2153,10 @@ int get_service(bdaddr_t *bdaddr, struct search_context *context) } static struct option get_options[] = { - {"help", 0,0, 'h'}, - {"bdaddr", 1,0, 'b'}, - {"tree", 0,0, 't'}, - {0, 0, 0, 0} + { "help", 0,0, 'h' }, + { "bdaddr", 1,0, 'b' }, + { "tree", 0,0, 't' }, + { 0, 0, 0, 0 } }; static char *get_help = @@ -2163,7 +2166,7 @@ static char *get_help = /* * Get a specific SDP record on the local SDP server */ -int cmd_get(int argc, char **argv) +static int cmd_get(int argc, char **argv) { struct search_context context; bdaddr_t bdaddr; @@ -2200,7 +2203,7 @@ int cmd_get(int argc, char **argv) return get_service(has_addr? &bdaddr: BDADDR_LOCAL, &context); } -struct { +static struct { char *cmd; int (*func)(int argc, char **argv); char *doc; @@ -2212,14 +2215,14 @@ struct { { "get", cmd_get, "Get local service" }, { "setattr", cmd_setattr, "Set/Add attribute to a SDP record" }, { "setseq", cmd_setseq, "Set/Add attribute sequence to a SDP record" }, - { 0, 0, 0} + { 0, 0, 0 } }; static void usage(void) { int i; - printf("sdptool - SDP Tool v%s\n", VERSION); + printf("sdptool - SDP tool v%s\n", VERSION); printf("Usage:\n" "\tsdptool [options] [command parameters]\n"); printf("Options:\n" @@ -2227,47 +2230,57 @@ static void usage(void) "\t--source\tSpecify source interface\n"); printf("Commands:\n"); - for (i=0; command[i].cmd; i++) + for (i = 0; command[i].cmd; i++) printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc); printf("\nServices:\n\t"); - for (i=0; service[i].name; i++) + for (i = 0; service[i].name; i++) printf("%s ", service[i].name); printf("\n"); } static struct option main_options[] = { - {"help", 0, 0, 'h'}, - {"source", 1, 0, 'S'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } }; int main(int argc, char **argv) { - int opt, i; + int i, opt; bacpy(&interface, BDADDR_ANY); - while ((opt=getopt_long(argc, argv, "+hS:", main_options, 0)) != -1) { + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch(opt) { - case 'S': - str2ba(optarg, &interface); + case 'i': + if (!strncmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &interface); + else + str2ba(optarg, &interface); break; + case 'h': - default: usage(); - return -1; + exit(0); + + default: + exit(1); } } + argc -= optind; argv += optind; optind = 0; if (argc < 1) { usage(); - return -1; + exit(1); } - for (i=0; command[i].cmd; i++) + + for (i = 0; command[i].cmd; i++) if (strncmp(command[i].cmd, argv[0], 4) == 0) return command[i].func(argc, argv); + return -1; } -- cgit From ba3d640d8a665d61973172b2a0e9531b735f5f91 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 4 Dec 2004 18:17:59 +0000 Subject: Remove one whitespace --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 854c8715..22aaeda7 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1063,7 +1063,7 @@ void print_dev_hdr(struct hci_dev_info *di) ba2str(&di->bdaddr, addr); printf("%s:\tType: %s\n", di->name, hci_dtypetostr(di->type) ); - printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", + printf("\tBD Address: %s ACL MTU: %d:%d SCO MTU: %d:%d\n", addr, di->acl_mtu, di->acl_pkts, di->sco_mtu, di->sco_pkts); } -- cgit From b85cf3e041b3972ed220af85c0152efdc9fe19f3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Dec 2004 11:48:52 +0000 Subject: Whitespace cleanup --- tools/sdptool.c | 374 ++++++++++++++++++++++++++------------------------------ 1 file changed, 176 insertions(+), 198 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 8d212c4e..fb657a3d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -63,7 +63,7 @@ static int estr2ba(char *str, bdaddr_t *ba) /* Pass args to the inquiry/search handler */ struct search_context { - char *svc; /* Service */ + char *svc; /* Service */ uuid_t group; /* Browse group */ int tree; /* Display full attribute tree */ uint32_t handle; /* Service record handle */ @@ -76,35 +76,35 @@ static bdaddr_t interface; /* Definition of attribute members */ struct member_def { - char *name; + char *name; }; /* Definition of an attribute */ struct attrib_def { - int num; /* Numeric ID - 16 bits */ - char * name; /* User readable name */ - struct member_def * members; /* Definition of attribute args */ - int member_max; /* Max of attribute arg definitions */ + int num; /* Numeric ID - 16 bits */ + char *name; /* User readable name */ + struct member_def *members; /* Definition of attribute args */ + int member_max; /* Max of attribute arg definitions */ }; /* Definition of a service or protocol */ struct uuid_def { - int num; /* Numeric ID - 16 bits */ - char * name; /* User readable name */ - struct attrib_def * attribs; /* Specific attribute definitions */ - int attrib_max; /* Max of attribute definitions */ + int num; /* Numeric ID - 16 bits */ + char *name; /* User readable name */ + struct attrib_def *attribs; /* Specific attribute definitions */ + int attrib_max; /* Max of attribute definitions */ }; /* Context information about current attribute */ struct attrib_context { - struct uuid_def * service; /* Service UUID, if known */ - struct attrib_def * attrib; /* Description of the attribute */ - int member_index; /* Index of current attribute member */ + struct uuid_def *service; /* Service UUID, if known */ + struct attrib_def *attrib; /* Description of the attribute */ + int member_index; /* Index of current attribute member */ }; /* Context information about the whole service */ struct service_context { - struct uuid_def * service; /* Service UUID, if known */ + struct uuid_def *service; /* Service UUID, if known */ }; /* Allow us to do nice formatting of the lists */ @@ -117,158 +117,157 @@ static char *indent_spaces = " "; /* Definition of the optional arguments in protocol list */ static struct member_def protocol_members[] = { - { "Protocol" }, - { "Channel/Port" }, - { "Version" }, + { "Protocol" }, + { "Channel/Port" }, + { "Version" }, }; /* Definition of the optional arguments in profile list */ static struct member_def profile_members[] = { - { "Profile" }, - { "Version" }, + { "Profile" }, + { "Version" }, }; /* Definition of the optional arguments in Language list */ static struct member_def language_members[] = { - { "Code ISO639" }, - { "Encoding" }, - { "Base Offset" }, + { "Code ISO639" }, + { "Encoding" }, + { "Base Offset" }, }; /* Name of the various common attributes. See BT assigned numbers */ static struct attrib_def attrib_names[] = { - { 0x0, "ServiceRecordHandle", NULL, 0 }, - { 0x1, "ServiceClassIDList", NULL, 0 }, - { 0x2, "ServiceRecordState", NULL, 0 }, - { 0x3, "ServiceID", NULL, 0 }, - { 0x4, "ProtocolDescriptorList", - protocol_members, sizeof(protocol_members)/sizeof(struct member_def) }, - { 0x5, "BrowseGroupList", NULL, 0 }, - { 0x6, "LanguageBaseAttributeIDList", - language_members, sizeof(language_members)/sizeof(struct member_def) }, - { 0x7, "ServiceInfoTimeToLive", NULL, 0 }, - { 0x8, "ServiceAvailability", NULL, 0 }, - { 0x9, "BluetoothProfileDescriptorList", - profile_members, sizeof(profile_members)/sizeof(struct member_def) }, - { 0xA, "DocumentationURL", NULL, 0 }, - { 0xB, "ClientExecutableURL", NULL, 0 }, - { 0xC, "IconURL", NULL, 0 }, - { 0xD, "AdditionalProtocolDescriptorLists", NULL, 0 }, - /* Definitions after that are tricky (per profile or offset) */ + { 0x0, "ServiceRecordHandle", NULL, 0 }, + { 0x1, "ServiceClassIDList", NULL, 0 }, + { 0x2, "ServiceRecordState", NULL, 0 }, + { 0x3, "ServiceID", NULL, 0 }, + { 0x4, "ProtocolDescriptorList", + protocol_members, sizeof(protocol_members)/sizeof(struct member_def) }, + { 0x5, "BrowseGroupList", NULL, 0 }, + { 0x6, "LanguageBaseAttributeIDList", + language_members, sizeof(language_members)/sizeof(struct member_def) }, + { 0x7, "ServiceInfoTimeToLive", NULL, 0 }, + { 0x8, "ServiceAvailability", NULL, 0 }, + { 0x9, "BluetoothProfileDescriptorList", + profile_members, sizeof(profile_members)/sizeof(struct member_def) }, + { 0xA, "DocumentationURL", NULL, 0 }, + { 0xB, "ClientExecutableURL", NULL, 0 }, + { 0xC, "IconURL", NULL, 0 }, + { 0xD, "AdditionalProtocolDescriptorLists", NULL, 0 }, + /* Definitions after that are tricky (per profile or offset) */ }; const int attrib_max = sizeof(attrib_names)/sizeof(struct attrib_def); /* Name of the various SPD attributes. See BT assigned numbers */ static struct attrib_def sdp_attrib_names[] = { - { 0x200, "VersionNumberList", NULL, 0 }, - { 0x201, "ServiceDatabaseState", NULL, 0 }, + { 0x200, "VersionNumberList", NULL, 0 }, + { 0x201, "ServiceDatabaseState", NULL, 0 }, }; /* Name of the various SPD attributes. See BT assigned numbers */ static struct attrib_def browse_attrib_names[] = { - { 0x200, "GroupID", NULL, 0 }, + { 0x200, "GroupID", NULL, 0 }, }; /* Name of the various PAN attributes. See BT assigned numbers */ /* Note : those need to be double checked - Jean II */ static struct attrib_def pan_attrib_names[] = { - { 0x200, "IpSubnet", NULL, 0 }, /* Obsolete ??? */ - { 0x30A, "SecurityDescription", NULL, 0 }, - { 0x30B, "NetAccessType", NULL, 0 }, - { 0x30C, "MaxNetAccessrate", NULL, 0 }, - { 0x30D, "IPv4Subnet", NULL, 0 }, - { 0x30E, "IPv6Subnet", NULL, 0 }, + { 0x200, "IpSubnet", NULL, 0 }, /* Obsolete ??? */ + { 0x30A, "SecurityDescription", NULL, 0 }, + { 0x30B, "NetAccessType", NULL, 0 }, + { 0x30C, "MaxNetAccessrate", NULL, 0 }, + { 0x30D, "IPv4Subnet", NULL, 0 }, + { 0x30E, "IPv6Subnet", NULL, 0 }, }; /* Name of the various Generic-Audio attributes. See BT assigned numbers */ /* Note : totally untested - Jean II */ static struct attrib_def audio_attrib_names[] = { - { 0x302, "Remote audio volume control", NULL, 0 }, + { 0x302, "Remote audio volume control", NULL, 0 }, }; /* Same for the UUIDs. See BT assigned numbers */ static struct uuid_def uuid16_names[] = { - /* -- Protocols -- */ - { 0x1, "SDP (Service Discovery Protocol)", NULL, 0 }, - { 0x2, "UDP", NULL, 0 }, - { 0x3, "RFCOMM", NULL, 0 }, - { 0x4, "TCP", NULL, 0 }, - { 0x5, "TCS-BIN", NULL, 0 }, - { 0x6, "TCS-AT", NULL, 0 }, - { 0x8, "OBEX", NULL, 0 }, - { 0x9, "IP", NULL, 0 }, - { 0xA, "FTP", NULL, 0 }, - { 0xC, "HTTP", NULL, 0 }, - { 0xE, "WSP", NULL, 0 }, - { 0xF, "BNEP (PAN/BNEP)", NULL, 0 }, - { 0x10, "UPnP/ESDP", NULL, 0 }, - { 0x11, "HIDP", NULL, 0 }, - { 0x12, "HardcopyControlChannel", NULL, 0 }, - { 0x14, "HardcopyDataChannel", NULL, 0 }, - { 0x16, "HardcopyNotification", NULL, 0 }, - { 0x17, "AVCTP", NULL, 0 }, - { 0x19, "AVDTP", NULL, 0 }, - { 0x1B, "CMTP", NULL, 0 }, - { 0x1D, "UDI_C-Plane", NULL, 0 }, - { 0x100, "L2CAP", NULL, 0 }, - /* -- Services -- */ - { 0x1000, "ServiceDiscoveryServerServiceClassID (SDP)", - sdp_attrib_names, sizeof(sdp_attrib_names)/sizeof(struct attrib_def) }, - { 0x1001, "BrowseGroupDescriptorServiceClassID (SDP)", - browse_attrib_names, - sizeof(browse_attrib_names)/sizeof(struct attrib_def) }, - { 0x1002, "PublicBrowseGroup (SDP)", NULL, 0 }, - { 0x1101, "SerialPort", NULL, 0 }, - { 0x1102, "LANAccessUsingPPP", NULL, 0 }, - { 0x1103, "DialupNetworking (DUN)", NULL, 0 }, - { 0x1104, "IrMCSync", NULL, 0 }, - { 0x1105, "OBEXObjectPush", NULL, 0 }, - { 0x1106, "OBEXFileTransfer", NULL, 0 }, - { 0x1107, "IrMCSyncCommand", NULL, 0 }, - { 0x1108, "Headset", - audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, - { 0x1109, "CordlessTelephony", NULL, 0 }, - { 0x110a, "AudioSource", NULL, 0 }, - { 0x110b, "AudioSink", NULL, 0 }, - { 0x110c, "RemoteControlTarget", NULL, 0 }, - { 0x110d, "AdvancedAudio", NULL, 0 }, - { 0x110e, "RemoteControl", NULL, 0 }, - { 0x110f, "VideoConferencing", NULL, 0 }, - { 0x1110, "Intercom", NULL, 0 }, - { 0x1111, "Fax", NULL, 0 }, - { 0x1112, "HeadsetAudioGateway", NULL, 0 }, - { 0x1113, "WAP", NULL, 0 }, - { 0x1114, "WAP Client", NULL, 0 }, - { 0x1115, "PANU (PAN/BNEP)", - pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, - { 0x1116, "NAP (PAN/BNEP)", - pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, - { 0x1117, "GN (PAN/BNEP)", - pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, - { 0x1118, "DirectPrinting (BPP)", NULL, 0 }, - { 0x1119, "ReferencePrinting (BPP)", NULL, 0 }, - /* ... */ - { 0x111e, "Handsfree", NULL, 0 }, - { 0x111f, "HandsfreeAudioGateway", NULL, 0 }, - { 0x1120, "DirectPrintingReferenceObjectsService (BPP)", NULL, 0 }, - { 0x1121, "ReflectedUI (BPP)", NULL, 0 }, - { 0x1122, "BasicPrinting (BPP)", NULL, 0 }, - { 0x1123, "PrintingStatus (BPP)", NULL, 0 }, - { 0x1124, "HumanInterfaceDeviceService (HID)", NULL, 0 }, - { 0x1125, "HardcopyCableReplacement (HCR)", NULL, 0 }, - { 0x1126, "HCR_Print (HCR)", NULL, 0 }, - { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, - { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, - { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, - { 0x112d, "SIM Access (SAP)", NULL, 0 }, - /* ... */ - { 0x1200, "PnPInformation", NULL, 0 }, - { 0x1201, "GenericNetworking", NULL, 0 }, - { 0x1202, "GenericFileTransfer", NULL, 0 }, - { 0x1203, "GenericAudio", - audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, - { 0x1204, "GenericTelephony", NULL, 0 }, + /* -- Protocols -- */ + { 0x0001, "SDP (Service Discovery Protocol)", NULL, 0 }, + { 0x0002, "UDP", NULL, 0 }, + { 0x0003, "RFCOMM", NULL, 0 }, + { 0x0004, "TCP", NULL, 0 }, + { 0x0005, "TCS-BIN", NULL, 0 }, + { 0x0006, "TCS-AT", NULL, 0 }, + { 0x0008, "OBEX", NULL, 0 }, + { 0x0009, "IP", NULL, 0 }, + { 0x000a, "FTP", NULL, 0 }, + { 0x000c, "HTTP", NULL, 0 }, + { 0x000e, "WSP", NULL, 0 }, + { 0x000f, "BNEP (PAN/BNEP)", NULL, 0 }, + { 0x0010, "UPnP/ESDP", NULL, 0 }, + { 0x0011, "HIDP", NULL, 0 }, + { 0x0012, "HardcopyControlChannel", NULL, 0 }, + { 0x0014, "HardcopyDataChannel", NULL, 0 }, + { 0x0016, "HardcopyNotification", NULL, 0 }, + { 0x0017, "AVCTP", NULL, 0 }, + { 0x0019, "AVDTP", NULL, 0 }, + { 0x001b, "CMTP", NULL, 0 }, + { 0x001d, "UDI_C-Plane", NULL, 0 }, + { 0x0100, "L2CAP", NULL, 0 }, + /* -- Services -- */ + { 0x1000, "ServiceDiscoveryServerServiceClassID (SDP)", + sdp_attrib_names, sizeof(sdp_attrib_names)/sizeof(struct attrib_def) }, + { 0x1001, "BrowseGroupDescriptorServiceClassID (SDP)", + browse_attrib_names, sizeof(browse_attrib_names)/sizeof(struct attrib_def) }, + { 0x1002, "PublicBrowseGroup (SDP)", NULL, 0 }, + { 0x1101, "SerialPort", NULL, 0 }, + { 0x1102, "LANAccessUsingPPP", NULL, 0 }, + { 0x1103, "DialupNetworking (DUN)", NULL, 0 }, + { 0x1104, "IrMCSync", NULL, 0 }, + { 0x1105, "OBEXObjectPush", NULL, 0 }, + { 0x1106, "OBEXFileTransfer", NULL, 0 }, + { 0x1107, "IrMCSyncCommand", NULL, 0 }, + { 0x1108, "Headset", + audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, + { 0x1109, "CordlessTelephony", NULL, 0 }, + { 0x110a, "AudioSource", NULL, 0 }, + { 0x110b, "AudioSink", NULL, 0 }, + { 0x110c, "RemoteControlTarget", NULL, 0 }, + { 0x110d, "AdvancedAudio", NULL, 0 }, + { 0x110e, "RemoteControl", NULL, 0 }, + { 0x110f, "VideoConferencing", NULL, 0 }, + { 0x1110, "Intercom", NULL, 0 }, + { 0x1111, "Fax", NULL, 0 }, + { 0x1112, "HeadsetAudioGateway", NULL, 0 }, + { 0x1113, "WAP", NULL, 0 }, + { 0x1114, "WAP Client", NULL, 0 }, + { 0x1115, "PANU (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1116, "NAP (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1117, "GN (PAN/BNEP)", + pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, + { 0x1118, "DirectPrinting (BPP)", NULL, 0 }, + { 0x1119, "ReferencePrinting (BPP)", NULL, 0 }, + /* ... */ + { 0x111e, "Handsfree", NULL, 0 }, + { 0x111f, "HandsfreeAudioGateway", NULL, 0 }, + { 0x1120, "DirectPrintingReferenceObjectsService (BPP)", NULL, 0 }, + { 0x1121, "ReflectedUI (BPP)", NULL, 0 }, + { 0x1122, "BasicPrinting (BPP)", NULL, 0 }, + { 0x1123, "PrintingStatus (BPP)", NULL, 0 }, + { 0x1124, "HumanInterfaceDeviceService (HID)", NULL, 0 }, + { 0x1125, "HardcopyCableReplacement (HCR)", NULL, 0 }, + { 0x1126, "HCR_Print (HCR)", NULL, 0 }, + { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, + { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, + { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, + { 0x112d, "SIM Access (SAP)", NULL, 0 }, + /* ... */ + { 0x1200, "PnPInformation", NULL, 0 }, + { 0x1201, "GenericNetworking", NULL, 0 }, + { 0x1202, "GenericFileTransfer", NULL, 0 }, + { 0x1203, "GenericAudio", + audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, + { 0x1204, "GenericTelephony", NULL, 0 }, }; static const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); @@ -302,14 +301,13 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in if(uuidDef) printf("%.*sUUID16 : 0x%.4x - %s\n", - indent, indent_spaces, - uuidNum, uuidDef->name); + indent, indent_spaces, uuidNum, uuidDef->name); else printf("%.*sUUID16 : 0x%.4x\n", - indent, indent_spaces, uuidNum); + indent, indent_spaces, uuidNum); } else if (uuid->type == SDP_UUID32) { printf("%.*sUUID32 : 0x%.8x\n", - indent, indent_spaces, uuid->value.uuid32); + indent, indent_spaces, uuid->value.uuid32); } else if (uuid->type == SDP_UUID128) { unsigned int data0; unsigned short data1; @@ -326,23 +324,21 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in memcpy(&data5, &uuid->value.uuid128.data[14], 2); printf("%.*sUUID128 : 0x%.8x-%.4x-%.4x-%.4x-%.8x-%.4x\n", - indent, indent_spaces, - ntohl(data0), ntohs(data1), ntohs(data2), - ntohs(data3), ntohl(data4), ntohs(data5)); + indent, indent_spaces, + ntohl(data0), ntohs(data1), ntohs(data2), + ntohs(data3), ntohl(data4), ntohs(data5)); } else printf("%.*sEnum type of UUID not set\n", - indent, indent_spaces); + indent, indent_spaces); } else printf("%.*sNull passed to print UUID\n", - indent, indent_spaces); + indent, indent_spaces); } /* * Parse a sequence of data elements (i.e. a list) */ -static void printf_dataseq(sdp_data_t * pData, - struct attrib_context *context, - int indent) +static void printf_dataseq(sdp_data_t * pData, struct attrib_context *context, int indent) { sdp_data_t *sdpdata = NULL; @@ -363,9 +359,7 @@ static void printf_dataseq(sdp_data_t * pData, * Parse a single data element (either in the attribute or in a data * sequence). */ -static void sdp_data_printf(sdp_data_t *sdpdata, - struct attrib_context *context, - int indent) +static void sdp_data_printf(sdp_data_t *sdpdata, struct attrib_context *context, int indent) { char *member_name = NULL; @@ -392,11 +386,10 @@ static void sdp_data_printf(sdp_data_t *sdpdata, case SDP_INT128: if (member_name) { printf("%.*s%s (Integer) : 0x%x\n", - indent, indent_spaces, - member_name, sdpdata->val.uint32); + indent, indent_spaces, member_name, sdpdata->val.uint32); } else { printf("%.*sInteger : 0x%x\n", indent, indent_spaces, - sdpdata->val.uint32); + sdpdata->val.uint32); } break; @@ -417,14 +410,12 @@ static void sdp_data_printf(sdp_data_t *sdpdata, printf(" %02x", (unsigned char) sdpdata->val.str[i]); printf("\n"); } else - printf("%.*sText : \"%s\"\n", indent, indent_spaces, - sdpdata->val.str); + printf("%.*sText : \"%s\"\n", indent, indent_spaces, sdpdata->val.str); break; case SDP_URL_STR8: case SDP_URL_STR16: case SDP_URL_STR32: - printf("%.*sURL : %s\n", indent, indent_spaces, - sdpdata->val.str); + printf("%.*sURL : %s\n", indent, indent_spaces, sdpdata->val.str); break; case SDP_SEQ8: @@ -464,9 +455,8 @@ static void sdp_attr_printf_func(void *value, void *userData) break; } /* Search amongst the specific attributes of this service */ - if ((attrDef == NULL) && - (service->service != NULL) && - (service->service->attribs != NULL)) { + if ((attrDef == NULL) && (service->service != NULL) && + (service->service->attribs != NULL)) { struct attrib_def *svc_attribs = service->service->attribs; int svc_attrib_max = service->service->attrib_max; for (i = 0; i < svc_attrib_max; i++) @@ -477,8 +467,7 @@ static void sdp_attr_printf_func(void *value, void *userData) } if (attrDef) - printf("Attribute Identifier : 0x%x - %s\n", - attrId, attrDef->name); + printf("Attribute Identifier : 0x%x - %s\n", attrId, attrDef->name); else printf("Attribute Identifier : 0x%x\n", attrId); /* Build context */ @@ -534,7 +523,7 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha value_int = strtoul(value + 3, NULL, 16); sdp_uuid16_create(&value_uuid, value_int); printf("Adding attrib 0x%X uuid16 0x%X to record 0x%X\n", - attrib, value_int, handle); + attrib, value_int, handle); sdp_attr_add_new(rec, attrib, SDP_UUID16, &value_uuid.value.uuid16); } else if (!strncasecmp(value, "0x", 2)) { @@ -542,13 +531,13 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha uint32_t value_int; value_int = strtoul(value + 2, NULL, 16); printf("Adding attrib 0x%X int 0x%X to record 0x%X\n", - attrib, value_int, handle); + attrib, value_int, handle); sdp_attr_add_new(rec, attrib, SDP_UINT32, &value_int); } else { /* String */ printf("Adding attrib 0x%X string \"%s\" to record 0x%X\n", - attrib, value, handle); + attrib, value, handle); /* Add/Update our attribute to the record */ sdp_attr_add_new(rec, attrib, SDP_TEXT_STR8, value); @@ -651,8 +640,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri allocArray[i] = value_uuid; sdp_uuid16_create(value_uuid, value_int); - printf("Adding uuid16 0x%X to record 0x%X\n", - value_int, handle); + printf("Adding uuid16 0x%X to record 0x%X\n", value_int, handle); dtdArray[i] = &uuid16; valueArray[i] = &value_uuid->value.uuid16; } else if (!strncasecmp(argv[i], "0x", 2)) { @@ -661,14 +649,12 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri allocArray[i] = value_int; *value_int = strtoul((argv[i]) + 2, NULL, 16); - printf("Adding int 0x%X to record 0x%X\n", - *value_int, handle); + printf("Adding int 0x%X to record 0x%X\n", *value_int, handle); dtdArray[i] = &uint32; valueArray[i] = value_int; } else { /* String */ - printf("Adding string \"%s\" to record 0x%X\n", - argv[i], handle); + printf("Adding string \"%s\" to record 0x%X\n", argv[i], handle); dtdArray[i] = &str8; valueArray[i] = argv[i]; } @@ -1566,16 +1552,6 @@ end: return ret; } -static int add_hid(sdp_session_t *sess, svc_info_t *si) -{ - return -1; -} - -static int add_cip(sdp_session_t *sess, svc_info_t *si) -{ - return -1; -} - static int add_ctp(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -1751,30 +1727,30 @@ done: } struct { - char *name; - uint16_t class; - int (*add)(sdp_session_t *sess, svc_info_t *si); + char *name; + uint16_t class; + int (*add)(sdp_session_t *sess, svc_info_t *si); } service[] = { - { "SP", SERIAL_PORT_SVCLASS_ID, add_sp }, - { "DUN", DIALUP_NET_SVCLASS_ID, add_dun }, - { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, - { "FAX", FAX_SVCLASS_ID, add_fax }, - { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, - { "FTRN", OBEX_FILETRANS_SVCLASS_ID, add_file_trans }, + { "SP", SERIAL_PORT_SVCLASS_ID, add_sp }, + { "DUN", DIALUP_NET_SVCLASS_ID, add_dun }, + { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, + { "FAX", FAX_SVCLASS_ID, add_fax }, + { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, + { "FTRN", OBEX_FILETRANS_SVCLASS_ID, add_file_trans }, - { "HS", HEADSET_SVCLASS_ID, add_headset }, - { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, - { "SAP", SAP_SVCLASS_ID, add_simaccess }, + { "HS", HEADSET_SVCLASS_ID, add_headset }, + { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, + { "SAP", SAP_SVCLASS_ID, add_simaccess }, - { "NAP", NAP_SVCLASS_ID, add_nap }, - { "GN", GN_SVCLASS_ID, add_gn }, + { "NAP", NAP_SVCLASS_ID, add_nap }, + { "GN", GN_SVCLASS_ID, add_gn }, - { "HID", HID_SVCLASS_ID, add_hid }, - { "CIP", CIP_SVCLASS_ID, add_cip }, - { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, + { "HID", HID_SVCLASS_ID, NULL }, + { "CIP", CIP_SVCLASS_ID, NULL }, + { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, - { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source }, - { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, + { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source}, + { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, { 0 } }; @@ -1788,9 +1764,11 @@ static int add_service(bdaddr_t *bdaddr, svc_info_t *si) if (!sess) return -1; if (si->name) - for (i=0; service[i].name; i++) + for (i = 0; service[i].name; i++) if (!strcasecmp(service[i].name, si->name)) { - int ret = service[i].add(sess, si); + int ret = -1; + if (service[i].add) + ret = service[i].add(sess, si); free(si->name); sdp_close(sess); return ret; @@ -1919,7 +1897,7 @@ static void inquiry(handler_t handler, void *arg) printf("Inquiry failed\n"); return; } - for (i=0; i Date: Tue, 7 Dec 2004 12:31:26 +0000 Subject: Add support for Device ID --- tools/sdptool.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index fb657a3d..358fbb42 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -170,6 +170,16 @@ static struct attrib_def browse_attrib_names[] = { { 0x200, "GroupID", NULL, 0 }, }; +/* Name of the various Device ID attributes. See Device Id spec. */ +static struct attrib_def did_attrib_names[] = { + { 0x200, "SpecificationID", NULL, 0 }, + { 0x201, "VendorID", NULL, 0 }, + { 0x202, "ProductID", NULL, 0 }, + { 0x203, "Version", NULL, 0 }, + { 0x204, "PrimaryRecord", NULL, 0 }, + { 0x205, "VendorIDSource", NULL, 0 }, +}; + /* Name of the various PAN attributes. See BT assigned numbers */ /* Note : those need to be double checked - Jean II */ static struct attrib_def pan_attrib_names[] = { @@ -262,7 +272,8 @@ static struct uuid_def uuid16_names[] = { { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, { 0x112d, "SIM Access (SAP)", NULL, 0 }, /* ... */ - { 0x1200, "PnPInformation", NULL, 0 }, + { 0x1200, "PnPInformation", + did_attrib_names, sizeof(did_attrib_names)/sizeof(struct attrib_def) }, { 0x1201, "GenericNetworking", NULL, 0 }, { 0x1202, "GenericFileTransfer", NULL, 0 }, { 0x1203, "GenericAudio", @@ -1143,7 +1154,7 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) apseq = sdp_list_append(apseq, proto[1]); features = sdp_data_alloc(SDP_UINT16, &u16); - sdp_attr_add(&record, SDP_SUPPORTED_FEATURES, features); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); @@ -1205,7 +1216,7 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) apseq = sdp_list_append(apseq, proto[1]); features = sdp_data_alloc(SDP_UINT16, &u16); - sdp_attr_add(&record, SDP_SUPPORTED_FEATURES, features); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); @@ -1589,7 +1600,7 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); - sdp_attr_add(&record, SDP_EXTERNAL_NETWORK, network); + sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network); sdp_set_info_attr(&record, "Cordless Telephony", 0, 0); @@ -1731,6 +1742,8 @@ struct { uint16_t class; int (*add)(sdp_session_t *sess, svc_info_t *si); } service[] = { + { "DID", PNP_INFO_SVCLASS_ID, NULL, }, + { "SP", SERIAL_PORT_SVCLASS_ID, add_sp }, { "DUN", DIALUP_NET_SVCLASS_ID, add_dun }, { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, @@ -2074,7 +2087,7 @@ static int cmd_search(int argc, char **argv) } else { /* Convert class name to an UUID */ - for (i=0; service[i].name; i++) + for (i = 0; service[i].name; i++) if (strcasecmp(context.svc, service[i].name) == 0) { class = service[i].class; break; -- cgit From a4a063c607c0d2693f253af261b6d8a0bf221f9c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Dec 2004 12:50:50 +0000 Subject: Add support for HID attribute descriptions --- tools/sdptool.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 358fbb42..6ceb0bd9 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -180,6 +180,25 @@ static struct attrib_def did_attrib_names[] = { { 0x205, "VendorIDSource", NULL, 0 }, }; +/* Name of the various HID attributes. See HID spec. */ +static struct attrib_def hid_attrib_names[] = { + { 0x200, "DeviceReleaseNum", NULL, 0 }, + { 0x201, "ParserVersion", NULL, 0 }, + { 0x202, "DeviceSubclass", NULL, 0 }, + { 0x203, "CountryCode", NULL, 0 }, + { 0x204, "VirtualCable", NULL, 0 }, + { 0x205, "ReconnectInitiate", NULL, 0 }, + { 0x206, "DescriptorList", NULL, 0 }, + { 0x207, "LangIDBaseList", NULL, 0 }, + { 0x208, "SDPDisable", NULL, 0 }, + { 0x209, "BatteryPower", NULL, 0 }, + { 0x20a, "RemoteWakeup", NULL, 0 }, + { 0x20b, "ProfileVersion", NULL, 0 }, + { 0x20c, "SupervisionTimeout", NULL, 0 }, + { 0x20d, "NormallyConnectable", NULL, 0 }, + { 0x20e, "BootDevice", NULL, 0 }, +}; + /* Name of the various PAN attributes. See BT assigned numbers */ /* Note : those need to be double checked - Jean II */ static struct attrib_def pan_attrib_names[] = { @@ -264,7 +283,8 @@ static struct uuid_def uuid16_names[] = { { 0x1121, "ReflectedUI (BPP)", NULL, 0 }, { 0x1122, "BasicPrinting (BPP)", NULL, 0 }, { 0x1123, "PrintingStatus (BPP)", NULL, 0 }, - { 0x1124, "HumanInterfaceDeviceService (HID)", NULL, 0 }, + { 0x1124, "HumanInterfaceDeviceService (HID)", + hid_attrib_names, sizeof(hid_attrib_names)/sizeof(struct attrib_def) }, { 0x1125, "HardcopyCableReplacement (HCR)", NULL, 0 }, { 0x1126, "HCR_Print (HCR)", NULL, 0 }, { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, -- cgit From f90e45fa8fb3edc954ccb9e537d2d8082a3d8070 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 8 Dec 2004 12:03:47 +0000 Subject: Check for sdp_connect() in -lbluetooth first --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 8b25acf8..94f665c8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -76,7 +76,7 @@ AC_DEFUN([AC_PATH_BLUEZ], [ LDFLAGS="$LDFLAGS $BLUEZ_LIBS" AC_CHECK_LIB(bluetooth, hci_open_dev, BLUEZ_LIBS="$BLUEZ_LIBS -lbluetooth", AC_MSG_ERROR(Bluetooth library not found)) - AC_CHECK_LIB(sdp, sdp_connect, BLUEZ_LIBS="$BLUEZ_LIBS -lsdp") + AC_CHECK_LIB(bluetooth, sdp_connect,, AC_CHECK_LIB(sdp, sdp_connect, BLUEZ_LIBS="$BLUEZ_LIBS -lsdp")) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS -- cgit From 19812023eacc4a912db4adb92c040a02a50cdff7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 10 Dec 2004 09:06:36 +0000 Subject: Also translate UUID-32 to string --- tools/sdptool.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 6ceb0bd9..cfbe2bba 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -318,8 +318,8 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in struct uuid_def *uuidDef = NULL; int i; - for(i = 0; i < uuid16_max; i++) - if(uuid16_names[i].num == uuidNum) { + for (i = 0; i < uuid16_max; i++) + if (uuid16_names[i].num == uuidNum) { uuidDef = &uuid16_names[i]; break; } @@ -330,15 +330,31 @@ static void sdp_uuid_printf(uuid_t *uuid, struct attrib_context *context, int in context->service = uuidDef; } - if(uuidDef) + if (uuidDef) printf("%.*sUUID16 : 0x%.4x - %s\n", indent, indent_spaces, uuidNum, uuidDef->name); else printf("%.*sUUID16 : 0x%.4x\n", indent, indent_spaces, uuidNum); } else if (uuid->type == SDP_UUID32) { - printf("%.*sUUID32 : 0x%.8x\n", - indent, indent_spaces, uuid->value.uuid32); + struct uuid_def *uuidDef = NULL; + int i; + + if (!(uuid->value.uuid32 & 0xffff0000)) { + uint16_t uuidNum = uuid->value.uuid32; + for (i = 0; i < uuid16_max; i++) + if (uuid16_names[i].num == uuidNum) { + uuidDef = &uuid16_names[i]; + break; + } + } + + if (uuidDef) + printf("%.*sUUID32 : 0x%.8x - %s\n", + indent, indent_spaces, uuid->value.uuid32, uuidDef->name); + else + printf("%.*sUUID32 : 0x%.8x\n", + indent, indent_spaces, uuid->value.uuid32); } else if (uuid->type == SDP_UUID128) { unsigned int data0; unsigned short data1; -- cgit From 6aa87b34ea5135cfb8dd403f1bfca8fe10172fd1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Dec 2004 13:58:56 +0000 Subject: The big whitespace cleanup for hcid --- hcid/dbus.c | 5 +- hcid/glib-ectomy.c | 153 +++++++++++++++++++++++++++-------------------------- hcid/glib-ectomy.h | 120 ++++++++++++++++++----------------------- hcid/kword.h | 2 +- hcid/lexer.l | 10 ++-- hcid/lib.c | 14 ++--- hcid/lib.h | 4 +- hcid/main.c | 23 ++++---- hcid/security.c | 29 +++++----- 9 files changed, 172 insertions(+), 188 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 7ef7ac73..04e7c757 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -48,7 +48,7 @@ static DBusConnection *connection; -#define TIMEOUT (30 * 1000) // 30 seconds +#define TIMEOUT (30 * 1000) /* 30 seconds */ #define SERVICE_NAME "org.bluez.PinAgent" #define INTERFACE_NAME SERVICE_NAME @@ -57,8 +57,7 @@ static DBusConnection *connection; #define WRONG_ARGS_ERROR "org.bluez.Error.WrongArgs" -struct pin_request -{ +struct pin_request { int dev; bdaddr_t bda; }; diff --git a/hcid/glib-ectomy.c b/hcid/glib-ectomy.c index 8489cd73..bea7f47c 100644 --- a/hcid/glib-ectomy.c +++ b/hcid/glib-ectomy.c @@ -1,75 +1,81 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + #include -#include -#include -#include #include #include +#include +#include +#include +#include #include #include "glib-ectomy.h" -GIOError g_io_channel_read (GIOChannel *channel, - gchar *buf, - gsize count, - gsize *bytes_read) +GIOError g_io_channel_read(GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read) { int fd = channel->fd; gssize result; - - if (count > SSIZE_MAX) /* At least according to the Debian manpage for read */ - count = SSIZE_MAX; - - retry: - result = read (fd, buf, count); - - if (result < 0) - { - *bytes_read = 0; - - switch (errno) - { + + /* At least according to the Debian manpage for read */ + if (count > SSIZE_MAX) + count = SSIZE_MAX; + +retry: + result = read (fd, buf, count); + + if (result < 0) { + *bytes_read = 0; + + switch (errno) { #ifdef EINTR - case EINTR: - goto retry; + case EINTR: + goto retry; #endif #ifdef EAGAIN - case EAGAIN: - return G_IO_STATUS_AGAIN; + case EAGAIN: + return G_IO_STATUS_AGAIN; #endif - default: - return G_IO_STATUS_ERROR; - } - } + default: + return G_IO_STATUS_ERROR; + } + } - *bytes_read = result; + *bytes_read = result; - return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; + return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; } -void g_io_channel_close (GIOChannel *channel) +void g_io_channel_close(GIOChannel *channel) { - int fd = channel->fd; + if (!channel) + return; - close(fd); + close(channel->fd); memset(channel, 0, sizeof(channel)); free(channel); } -GIOChannel* g_io_channel_unix_new (int fd) +GIOChannel *g_io_channel_unix_new(int fd) { - GIOChannel *channel = malloc(sizeof(GIOChannel)); + GIOChannel *channel; + + channel = malloc(sizeof(GIOChannel)); + if (!channel) + return NULL; + channel->fd = fd; + return channel; } -gint g_io_channel_unix_get_fd (GIOChannel *channel) +gint g_io_channel_unix_get_fd(GIOChannel *channel) { return channel->fd; } - - struct watch { guint id; GIOChannel *channel; @@ -82,25 +88,19 @@ struct watch { static struct watch watch_head = { .id = 0, .next = 0 }; -void g_io_remove_watch (guint id) +void g_io_remove_watch(guint id) { - struct watch *w, *p; - - for (p = &watch_head, w = watch_head.next; w; w = w->next) - { - if (w->id == id) - { - p->next = w->next; - free (w); - return; - } - } + struct watch *w, *p; + + for (p = &watch_head, w = watch_head.next; w; w = w->next) + if (w->id == id) { + p->next = w->next; + free (w); + return; + } } -guint g_io_add_watch (GIOChannel *channel, - GIOCondition condition, - GIOFunc func, - gpointer user_data) +guint g_io_add_watch(GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data) { struct watch *watch = malloc(sizeof(struct watch)); @@ -116,20 +116,27 @@ guint g_io_add_watch (GIOChannel *channel, return watch->id; } -GMainLoop *g_main_loop_new (GMainContext *context, - gboolean is_running) +GMainLoop *g_main_loop_new(GMainContext *context, gboolean is_running) { - GMainLoop *ml = malloc(sizeof(GMainLoop)); + GMainLoop *ml; + + ml = malloc(sizeof(GMainLoop)); + if (!ml) + return NULL; ml->bail = 0; return ml; } -void g_main_loop_run (GMainLoop *loop) +void g_main_loop_run(GMainLoop *loop) { int open_max = sysconf(_SC_OPEN_MAX); - struct pollfd *ufds = malloc(open_max * sizeof(struct pollfd)); + struct pollfd *ufds; + + ufds = malloc(open_max * sizeof(struct pollfd)); + if (!ufds) + return; while (!loop->bail) { int nfds, rc, i; @@ -142,43 +149,37 @@ void g_main_loop_run (GMainLoop *loop) ufds[nfds].revents = 0; nfds++; } - - rc = poll(ufds, nfds, -1); - if (rc < 0 && (errno == EINTR)) + rc = poll(ufds, nfds, -1); + if (rc < 0) continue; - if (rc < 0) { - perror("poll"); - continue; - } - p = &watch_head; w = watch_head.next; i = 0; + while (w) { if (ufds[i].revents) { gboolean keep = w->func(w->channel, ufds[i].revents, w->user_data); if (!keep) { - p->next = w->next; - memset(w, 0, sizeof(*w)); - w = p->next; - i++; - continue; + p->next = w->next; + memset(w, 0, sizeof(*w)); + w = p->next; + i++; + continue; } - } - + } + p = w; w = w->next; i++; } - } free(ufds); } -void g_main_loop_quit (GMainLoop *loop) +void g_main_loop_quit(GMainLoop *loop) { loop->bail = 1; } diff --git a/hcid/glib-ectomy.h b/hcid/glib-ectomy.h index 703ae54b..c507e3c7 100644 --- a/hcid/glib-ectomy.h +++ b/hcid/glib-ectomy.h @@ -1,34 +1,33 @@ -#ifndef _GLIB_ECTOMY_H_ -#define _GLIB_ECTOMY_H_ +#ifndef __GLIB_ECTOMY_H +#define __GLIB_ECTOMY_H #include #include -typedef char gchar; -typedef short gshort; -typedef long glong; -typedef int gint; -typedef gint gboolean; +typedef char gchar; +typedef short gshort; +typedef long glong; +typedef int gint; +typedef gint gboolean; -typedef unsigned char guchar; -typedef unsigned short gushort; -typedef unsigned long gulong; -typedef unsigned int guint; +typedef unsigned char guchar; +typedef unsigned short gushort; +typedef unsigned long gulong; +typedef unsigned int guint; -typedef float gfloat; -typedef double gdouble; +typedef float gfloat; +typedef double gdouble; -typedef void* gpointer; -typedef const void *gconstpointer; +typedef void * gpointer; +typedef const void * gconstpointer; -typedef size_t gsize; -typedef ssize_t gssize; +typedef size_t gsize; +typedef ssize_t gssize; #ifndef SSIZE_MAX #define SSIZE_MAX INT_MAX #endif - typedef struct _GIOChannel { int fd; } GIOChannel; @@ -41,68 +40,53 @@ typedef struct _GMainLoop { int bail; } GMainLoop; -typedef enum -{ - G_IO_ERROR_NONE, - G_IO_ERROR_AGAIN, - G_IO_ERROR_INVAL, - G_IO_ERROR_UNKNOWN +typedef enum { + G_IO_ERROR_NONE, + G_IO_ERROR_AGAIN, + G_IO_ERROR_INVAL, + G_IO_ERROR_UNKNOWN } GIOError; -typedef enum -{ - G_IO_STATUS_ERROR = -1, - G_IO_STATUS_NORMAL = 0, - G_IO_STATUS_EOF = 1, - G_IO_STATUS_AGAIN = 2 +typedef enum { + G_IO_STATUS_ERROR = -1, + G_IO_STATUS_NORMAL = 0, + G_IO_STATUS_EOF = 1, + G_IO_STATUS_AGAIN = 2 } GIOStatus; -#ifndef FALSE -#define FALSE (0) +#ifndef FALSE +#define FALSE (0) #endif -#ifndef TRUE -#define TRUE (!FALSE) +#ifndef TRUE +#define TRUE (!FALSE) #endif - -typedef enum -{ - G_IO_IN = POLLIN, - G_IO_OUT = POLLOUT, - G_IO_PRI = POLLPRI, - G_IO_ERR = POLLERR, - G_IO_HUP = POLLHUP, - G_IO_NVAL = POLLNVAL +typedef enum { + G_IO_IN = POLLIN, + G_IO_OUT = POLLOUT, + G_IO_PRI = POLLPRI, + G_IO_ERR = POLLERR, + G_IO_HUP = POLLHUP, + G_IO_NVAL = POLLNVAL } GIOCondition; -typedef gboolean (*GIOFunc) (GIOChannel *source, - GIOCondition condition, - gpointer data); - -GIOError g_io_channel_read (GIOChannel *channel, - gchar *buf, - gsize count, - gsize *bytes_read); -void g_io_channel_close (GIOChannel *channel); +typedef gboolean (*GIOFunc) (GIOChannel *source, GIOCondition condition, gpointer data); -GIOChannel* g_io_channel_unix_new (int fd); -gint g_io_channel_unix_get_fd (GIOChannel *channel); -guint g_io_add_watch (GIOChannel *channel, - GIOCondition condition, - GIOFunc func, - gpointer user_data); -void g_io_remove_watch (guint id); +GIOError g_io_channel_read(GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read); +void g_io_channel_close(GIOChannel *channel); +GIOChannel *g_io_channel_unix_new(int fd); +gint g_io_channel_unix_get_fd(GIOChannel *channel); +guint g_io_add_watch(GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data); +void g_io_remove_watch(guint id); +GMainLoop *g_main_loop_new(GMainContext *context, gboolean is_running); +void g_main_loop_run(GMainLoop *loop); +void g_main_loop_quit(GMainLoop *loop); -GMainLoop *g_main_loop_new (GMainContext *context, - gboolean is_running); -void g_main_loop_run (GMainLoop *loop); -void g_main_loop_quit (GMainLoop *loop); +#define g_main_new(is_running) g_main_loop_new(NULL, is_running); +#define g_main_run(loop) g_main_loop_run(loop) +#define g_main_quit(loop) g_main_loop_quit(loop) -#define g_main_new(is_running) g_main_loop_new (NULL, is_running); -#define g_main_run(loop) g_main_loop_run(loop) -#define g_main_quit(loop) g_main_loop_quit(loop) - -#endif +#endif /* __GLIB_ECTOMY_H */ diff --git a/hcid/kword.h b/hcid/kword.h index 88ceb8d1..2f6cae4a 100644 --- a/hcid/kword.h +++ b/hcid/kword.h @@ -34,7 +34,7 @@ struct kword { }; extern int lineno; -extern struct kword cfg_keyword[]; +extern struct kword cfg_keyword[]; extern struct kword sec_param[]; extern struct kword pair_param[]; diff --git a/hcid/lexer.l b/hcid/lexer.l index 7f10ffda..1031ea51 100644 --- a/hcid/lexer.l +++ b/hcid/lexer.l @@ -107,7 +107,7 @@ bdaddr {hextuple}:{hextuple}:{hextuple}:{hextuple}:{hextuple}:{hextuple} {kword} { int kw = find_keyword(cfg_keyword, yytext); - if( kw != -1 ) + if( kw != -1 ) return kw; yylval.str = yytext; @@ -120,13 +120,13 @@ bdaddr {hextuple}:{hextuple}:{hextuple}:{hextuple}:{hextuple}:{hextuple} } {string} { - if(yyleng > sizeof(str_buf)-1){ + if(yyleng > sizeof(str_buf) - 1){ yyerror("string too long"); return 0; } - strncpy(str_buf, yytext+1, yyleng-2); - str_buf[yyleng-2] = '\0'; + strncpy(str_buf, yytext + 1, yyleng - 2); + str_buf[yyleng - 2] = '\0'; yylval.str = str_buf; return STRING; @@ -148,7 +148,7 @@ bdaddr {hextuple}:{hextuple}:{hextuple}:{hextuple}:{hextuple}:{hextuple} %% -int yywrap(void) +int yywrap(void) { return 1; } diff --git a/hcid/lib.c b/hcid/lib.c index 7edc46a6..bbc78950 100644 --- a/hcid/lib.c +++ b/hcid/lib.c @@ -51,7 +51,7 @@ volatile sig_atomic_t __io_canceled; /* * Device name expansion - * %d - device id + * %d - device id */ char *expand_name(char *dst, int size, char *str, int dev_id) { @@ -76,7 +76,7 @@ char *expand_name(char *dst, int size, char *str, int dev_id) case 'h': opt = hcid.host_name; break; - + case '%': dst[np++] = str[sp++]; /* fall through */ @@ -115,14 +115,14 @@ char *get_host_name(void) if (!gethostname(name, sizeof(name)-1)) { name[sizeof(name)-1] = 0; return strdup(name); - } + } return strdup("noname"); } /* Functions to manipulate program title */ extern char **environ; char *title_start; /* start of the proc title space */ -char *title_end; /* end of the proc title space */ +char *title_end; /* end of the proc title space */ int title_size; void init_title(int argc, char *argv[], char *envp[], const char *name) @@ -152,11 +152,11 @@ void init_title(int argc, char *argv[], char *envp[], const char *name) * Determine how much space we can use for set_title. * Use all contiguous argv and envp pointers starting at argv[0] */ - for (i=0; i 0) { if ((w = read(fd, buf, len)) < 0) { @@ -74,7 +74,7 @@ static inline int read_n(int fd, void *buf, int len) /* Write exactly len bytes (Signal safe)*/ static inline int write_n(int fd, void *buf, int len) { - register int t = 0, w; + register int w, t = 0; while (!__io_canceled && len > 0) { if ((w = write(fd, buf, len)) < 0) { diff --git a/hcid/main.c b/hcid/main.c index fbc85a5c..abd7f14c 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -87,7 +87,7 @@ struct device_opts *alloc_device_opts(char *ref) device = malloc(sizeof(struct device_list)); if (!device) { - syslog(LOG_INFO, "Can't allocate devlist opts buffer. %s(%d)", + syslog(LOG_INFO, "Can't allocate devlist opts buffer. %s(%d)", strerror(errno), errno); exit(1); } @@ -190,7 +190,7 @@ static void configure_device(int hdev) /* Set scan mode */ dr.dev_opt = device_opts->scan; if (ioctl(s, HCISETSCAN, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set scan mode on hci%d. %s(%d)\n", + syslog(LOG_ERR, "Can't set scan mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } @@ -201,7 +201,7 @@ static void configure_device(int hdev) dr.dev_opt = AUTH_DISABLED; if (ioctl(s, HCISETAUTH, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set auth on hci%d. %s(%d)\n", + syslog(LOG_ERR, "Can't set auth on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } @@ -212,7 +212,7 @@ static void configure_device(int hdev) dr.dev_opt = ENCRYPT_DISABLED; if (ioctl(s, HCISETENCRYPT, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set encrypt on hci%d. %s(%d)\n", + syslog(LOG_ERR, "Can't set encrypt on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } @@ -250,7 +250,7 @@ static void init_device(int hdev) case 0: break; case -1: - syslog(LOG_ERR, "Fork failed. Can't init device hci%d. %s(%d)\n", + syslog(LOG_ERR, "Fork failed. Can't init device hci%d. %s(%d)\n", hdev, strerror(errno), errno); default: return; @@ -259,7 +259,8 @@ static void init_device(int hdev) set_title("hci%d init", hdev); if ((s = hci_open_dev(hdev)) < 0) { - syslog(LOG_ERR, "Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't open device hci%d. %s(%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -277,7 +278,7 @@ static void init_device(int hdev) if (device_opts->pkt_type) { dr.dev_opt = device_opts->pkt_type; if (ioctl(s, HCISETPTYPE, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set packet type on hci%d. %s(%d)\n", + syslog(LOG_ERR, "Can't set packet type on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } } @@ -286,7 +287,7 @@ static void init_device(int hdev) if (device_opts->link_mode) { dr.dev_opt = device_opts->link_mode; if (ioctl(s, HCISETLINKMODE, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set link mode on hci%d. %s(%d)\n", + syslog(LOG_ERR, "Can't set link mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } } @@ -295,7 +296,7 @@ static void init_device(int hdev) if (device_opts->link_policy) { dr.dev_opt = device_opts->link_policy; if (ioctl(s, HCISETLINKPOL, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set link policy on hci%d. %s(%d)\n", + syslog(LOG_ERR, "Can't set link policy on hci%d. %s(%d)\n", hdev, strerror(errno), errno); } } @@ -420,7 +421,7 @@ gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data) if (err == G_IO_ERROR_AGAIN) return TRUE; - syslog(LOG_ERR, "Read from control socket failed. %s(%d)", + syslog(LOG_ERR, "Read from control socket failed. %s(%d)", strerror(errno), errno); g_main_quit(event_loop); return FALSE; @@ -471,7 +472,7 @@ int main(int argc, char *argv[], char *env[]) hcid.key_file = strdup(HCID_KEY_FILE); init_defaults(); - + while ((opt = getopt(argc, argv, "f:n")) != EOF) { switch (opt) { case 'n': diff --git a/hcid/security.c b/hcid/security.c index fecafb93..7eb26258 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -81,7 +81,7 @@ static struct link_key *__get_link_key(int f, bdaddr_t *sba, bdaddr_t *dba) static struct link_key k; struct link_key *key = NULL; int r; - + while ((r = read_n(f, &k, sizeof(k)))) { if (r < 0) { syslog(LOG_ERR, "Link key database read failed. %s(%d)", @@ -191,7 +191,7 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) bacpy(&key.dba, dba); key.type = evt->key_type; key.time = time(0); - + save_link_key(&key); } @@ -245,7 +245,7 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) case 0: break; case -1: - syslog(LOG_ERR, "Can't fork PIN helper. %s(%d)", + syslog(LOG_ERR, "Can't fork PIN helper. %s(%d)", strerror(errno), errno); default: return; @@ -261,9 +261,8 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) //hci_remote_name(dev, &ci->bdaddr, sizeof(name), name, 0); ba2str(&ci->bdaddr, addr); - sprintf(str, "%s %s %s \'%s\'", hcid.pin_helper, - ci->out ? "out" : "in", - addr, name); + sprintf(str, "%s %s %s \'%s\'", hcid.pin_helper, + ci->out ? "out" : "in", addr, name); setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1); @@ -276,7 +275,7 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) if (!pipe) { syslog(LOG_ERR, "Can't exec PIN helper. %s(%d)", strerror(errno), errno); goto reject; - } + } pin = fgets(str, sizeof(str), pipe); ret = pclose(pipe); @@ -291,7 +290,7 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) pin += 4; len = strlen(pin); - + memset(&pr, 0, sizeof(pr)); bacpy(&pr.bdaddr, &ci->bdaddr); memcpy(pr.pin_code, pin, len); @@ -364,14 +363,14 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) PIN_CODE_REPLY_CP_SIZE, &pr); } else { /* Outgoing connection */ - + /* Let PIN helper handle that */ request_pin(dev, ci); } } else { /* Let PIN helper handle that */ request_pin(dev, ci); - } + } free(cr); return; @@ -395,7 +394,7 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) free(data); return FALSE; } - + if ((err = g_io_channel_read(chan, buf, sizeof(buf), &len))) { if (err == G_IO_ERROR_AGAIN) return TRUE; @@ -469,20 +468,20 @@ void start_security_manager(int hdev) di = malloc(sizeof(*di)); if (!di) { - syslog(LOG_ERR, "Can't allocate device info buffer. %s(%d)", + syslog(LOG_ERR, "Can't allocate device info buffer. %s(%d)", strerror(errno), errno); close(dev); return; } - + di->dev_id = hdev; if (ioctl(dev, HCIGETDEVINFO, (void *)di)) { - syslog(LOG_ERR, "Can't get device info. %s(%d)", + syslog(LOG_ERR, "Can't get device info. %s(%d)", strerror(errno), errno); close(dev); return; } - + chan = g_io_channel_unix_new(dev); g_io_add_watch(chan, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, io_security_event, (void *) di); -- cgit From 229f278865d075b36ea6c901d133c13939807630 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Dec 2004 14:16:03 +0000 Subject: Add comments about security mode 3 --- hcid/hcid.conf | 8 +------- hcid/hcid.conf.5 | 2 ++ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/hcid/hcid.conf b/hcid/hcid.conf index 78ca06e2..d2740b74 100644 --- a/hcid/hcid.conf +++ b/hcid/hcid.conf @@ -50,9 +50,6 @@ device { # accept - always accept incoming connections # master - become master on incoming connections, # deny role switch on outgoing connections - # - #lm accept,master; - # lm accept; # Default link policy @@ -61,12 +58,9 @@ device { # hold - allow hold mode # sniff - allow sniff mode # park - allow park mode - # - #lp hold,sniff; - # lp rswitch,hold,sniff,park; - # Authentication and Encryption + # Authentication and Encryption (Security Mode 3) #auth enable; #encrypt enable; } diff --git a/hcid/hcid.conf.5 b/hcid/hcid.conf.5 index 4bac6de1..d110e2a7 100644 --- a/hcid/hcid.conf.5 +++ b/hcid/hcid.conf.5 @@ -105,6 +105,8 @@ Enables or disables authentication between local and remote devices when they co Authentication is done following a challenge\-response mechanism described in the Bluetooth Specification 1.2 volume 2 part C section 4.2, and uses the link key generated during pairing as the shared secret. +Activating this option sets the local device into Bluetooth security mode 3. + .TP \fBencrypt\fP enable|disable Enable or disable link encryption. Should be set to enable in most cases, unless one of the devices does not support encryption for some reason. -- cgit From ff0836d7d011d979a78b16fa947aef3d24cee71b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Dec 2004 16:59:04 +0000 Subject: Typo --- hcid/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hcid/parser.y b/hcid/parser.y index 7c33278e..c5bb80a4 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -318,7 +318,7 @@ int read_config(char *file) { extern FILE *yyin; - if( !(yyin = fopen(file,"r")) ){ + if (!(yyin = fopen(file, "r"))) { syslog(LOG_ERR,"Can not open %s", file); return -1; } -- cgit From c12ea67bb3cc692fd9367ae5672b6270bf491c28 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 13 Dec 2004 16:59:26 +0000 Subject: Use file permission 0600 for the link key file --- hcid/security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hcid/security.c b/hcid/security.c index 7eb26258..1cb07da4 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -140,7 +140,7 @@ static void save_link_key(struct link_key *key) char sa[18], da[18]; int f, err; - f = open(hcid.key_file, O_RDWR | O_CREAT, 0); + f = open(hcid.key_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (f < 0) { syslog(LOG_ERR, "Link key database open failed. %s(%d)", strerror(errno), errno); -- cgit From ac243219976dab3363bcd3215f963eb0026af788 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Dec 2004 10:27:49 +0000 Subject: Add Nokia DTL-4 card --- pcmcia/bluetooth.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index a4d03fd1..6a93d6ff 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -63,6 +63,10 @@ card "Nokia Bluetooth Card" version "Nokia Mobile Phones", "DTL-1" bind "dtl1_cs" +card "Nokia Bluetooth Card" + version "Nokia Mobile Phones", "DTL-4" + bind "dtl1_cs" + card "Socket Bluetooth Card" version "Socket", "CF+ Personal Network Card" bind "dtl1_cs" -- cgit From bbda499067067aefc8e642a2784d247ac0331eae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 25 Dec 2004 17:43:16 +0000 Subject: Add memset() to different places to initialize the structures --- cups/hcrp.c | 7 +++++-- hidd/main.c | 25 ++++++++++++++++++++++--- pand/main.c | 17 ++++++++++------- sdpd/main.c | 1 + test/hstest.c | 6 ++++++ test/l2test.c | 2 ++ tools/ciptool.c | 5 ++++- 7 files changed, 50 insertions(+), 13 deletions(-) diff --git a/cups/hcrp.c b/cups/hcrp.c index f69800a7..75171524 100644 --- a/cups/hcrp.c +++ b/cups/hcrp.c @@ -187,9 +187,9 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s return 1; } + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, src); - addr.l2_psm = 0; if (bind(ctrl_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("ERROR: Can't bind socket"); @@ -197,6 +197,7 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s return 1; } + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, dst); addr.l2_psm = htobs(ctrl_psm); @@ -213,9 +214,9 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s return 1; } + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, src); - addr.l2_psm = 0; if (bind(data_sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("ERROR: Can't bind socket"); @@ -224,6 +225,7 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s return 1; } + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, dst); addr.l2_psm = htobs(data_psm); @@ -235,6 +237,7 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s return 1; } + memset(&opts, 0, sizeof(opts)); size = sizeof(opts); if (getsockopt(data_sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) { diff --git a/hidd/main.c b/hidd/main.c index 1ad39e0f..84d94b78 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -72,21 +72,23 @@ static int l2cap_connect(bdaddr_t *src, bdaddr_t *dst, unsigned short psm) if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) return -1; + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, src); - addr.l2_psm = 0; if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { close(sk); return -1; } + memset(&opts, 0, sizeof(opts)); opts.imtu = HIDP_DEFAULT_MTU; opts.omtu = HIDP_DEFAULT_MTU; opts.flush_to = 0xffff; setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)); + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, dst); addr.l2_psm = htobs(psm); @@ -108,6 +110,7 @@ static int l2cap_listen(const bdaddr_t *bdaddr, unsigned short psm, int lm, int if ((sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) return -1; + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, bdaddr); addr.l2_psm = htobs(psm); @@ -119,6 +122,7 @@ static int l2cap_listen(const bdaddr_t *bdaddr, unsigned short psm, int lm, int setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)); + memset(&opts, 0, sizeof(opts)); opts.imtu = HIDP_DEFAULT_MTU; opts.omtu = HIDP_DEFAULT_MTU; opts.flush_to = 0xffff; @@ -258,8 +262,23 @@ static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, err = get_hid_device_info(&src, &dst, &req); if (err < 0) goto error; - } else - req.subclass = 0xc0; + } else { + struct l2cap_conninfo conn; + socklen_t size; + uint8_t class[3]; + + memset(&conn, 0, sizeof(conn)); + size = sizeof(conn); + if (getsockopt(csk, SOL_L2CAP, L2CAP_CONNINFO, &conn, &size) < 0) + memset(class, 0, 3); + else + memcpy(class, conn.dev_class, 3); + + if (class[1] == 0x25 && (class[2] == 0x00 || class[2] == 0x01)) + req.subclass = class[0]; + else + req.subclass = 0xc0; + } if (subclass != 0x00) req.subclass = subclass; diff --git a/pand/main.c b/pand/main.c index e7fcb875..2090f9f8 100644 --- a/pand/main.c +++ b/pand/main.c @@ -139,9 +139,10 @@ static int do_listen(void) return -1; } + memset(&l2a, 0, sizeof(l2a)); l2a.l2_family = AF_BLUETOOTH; - l2a.l2_psm = htobs(BNEP_PSM); - l2a.l2_bdaddr = src_addr; + bacpy(&l2a.l2_bdaddr, &src_addr); + l2a.l2_psm = htobs(BNEP_PSM); if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno); @@ -149,6 +150,7 @@ static int do_listen(void) } /* Setup L2CAP options according to BNEP spec */ + memset(&l2o, 0, sizeof(l2o)); olen = sizeof(l2o); if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) { syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)", @@ -272,23 +274,24 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) } /* Setup L2CAP options according to BNEP spec */ + memset(&l2o, 0, sizeof(l2o)); olen = sizeof(l2o); getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); l2o.imtu = l2o.omtu = BNEP_MTU; setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); + memset(&l2a, 0, sizeof(l2a)); l2a.l2_family = AF_BLUETOOTH; - - /* Set local address */ - l2a.l2_psm = 0; - l2a.l2_bdaddr = src_addr; + bacpy(&l2a.l2_bdaddr, &src_addr); if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno); + memset(&l2a, 0, sizeof(l2a)); + l2a.l2_family = AF_BLUETOOTH; + bacpy(&l2a.l2_bdaddr, bdaddr); l2a.l2_psm = htobs(BNEP_PSM); - l2a.l2_bdaddr = *bdaddr; if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) && !bnep_create_connection(sk, role, service, netdev)) { diff --git a/sdpd/main.c b/sdpd/main.c index 0efc7d50..eb59a6fa 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -318,6 +318,7 @@ static inline void handle_request(int sk, char *data, int len) if (sa.l2_family == AF_BLUETOOTH) { struct l2cap_options lo; + memset(&lo, 0, sizeof(lo)); size = sizeof(lo); getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size); req.bdaddr = sa.l2_bdaddr; diff --git a/test/hstest.c b/test/hstest.c index 98428b68..f269621c 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -98,6 +98,7 @@ static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t memset(&addr, 0, sizeof(addr)); addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, src); + if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { close(s); return -1; @@ -106,18 +107,23 @@ static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t memset(&addr, 0, sizeof(addr)); addr.sco_family = AF_BLUETOOTH; bacpy(&addr.sco_bdaddr, dst); + if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){ close(s); return -1; } + memset(&conn, 0, sizeof(conn)); size = sizeof(conn); + if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &size) < 0) { close(s); return -1; } + memset(&opts, 0, sizeof(opts)); size = sizeof(opts); + if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &opts, &size) < 0) { close(s); return -1; diff --git a/test/l2test.c b/test/l2test.c index eedf4b70..627d37f1 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -192,6 +192,7 @@ int do_connect(char *svr) } /* Get default options */ + memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); @@ -236,6 +237,7 @@ int do_connect(char *svr) return -1; } + memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); diff --git a/tools/ciptool.c b/tools/ciptool.c index d0b6625d..7c952cf4 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -146,9 +146,9 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne exit(1); } + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, src); - addr.l2_psm = 0; if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("Can't bind L2CAP socket"); @@ -156,7 +156,9 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne exit(1); } + memset(&opts, 0, sizeof(opts)); size = sizeof(opts); + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &size) < 0) { perror("Can't get L2CAP options"); close(sk); @@ -173,6 +175,7 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne exit(1); } + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, dst); addr.l2_psm = htobs(psm); -- cgit From 84a66abab8579ab01c8715d8564155ad918235a2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 25 Dec 2004 17:47:52 +0000 Subject: Update changelog and bump version number --- ChangeLog | 9 +++++++++ configure.in | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 35325162..688c2577 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +ver 2.13: + Use file permission 0600 for the link key file. + Add support for HID attribute descriptions. + Add support for Device ID attributes. + Various whitespace cleanups. + + Note: + This version needs at least bluez-libs-2.13 + ver 2.12: Inherit the device specific options from the default. Use --device for selecting the source device. diff --git a/configure.in b/configure.in index 1a94d114..f7104ca9 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.12) +AM_INIT_AUTOMAKE(bluez-utils, 2.13) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From 9e6e37723b8d8798ed9ba58734fd3022fdf49dc2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 26 Dec 2004 14:10:24 +0000 Subject: Update for connection information --- test/l2test.c | 14 +++++++++++-- test/rctest.c | 15 +++++++++++-- test/scotest.c | 66 ++++++++++++++++++++++++++++++++++------------------------ 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index 627d37f1..c36cc3b7 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -176,6 +176,7 @@ int do_connect(char *svr) { struct sockaddr_l2 rem_addr, loc_addr; struct l2cap_options opts; + struct l2cap_conninfo conn; int s, opt; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { @@ -245,8 +246,17 @@ int do_connect(char *svr) return -1; } - syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d]\n", - opts.imtu, opts.omtu, opts.flush_to); + memset(&conn, 0, sizeof(conn)); + opt = sizeof(conn); + if (getsockopt(s, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { + syslog(LOG_ERR, "Can't get L2CAP connection information. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d, mode %d, handle %d, class 0x%02x%02x%02x]", + opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); return s; } diff --git a/test/rctest.c b/test/rctest.c index 6e5fba27..2ffb47dd 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -90,7 +90,8 @@ float tv2fl(struct timeval tv) int do_connect(char *svr) { struct sockaddr_rc rem_addr, loc_addr; - int s; + struct rfcomm_conninfo conn; + int s, opt; if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); @@ -125,7 +126,17 @@ int do_connect(char *svr) return -1; } - syslog(LOG_INFO, "Connected"); + memset(&conn, 0, sizeof(conn)); + opt = sizeof(conn); + if (getsockopt(s, SOL_L2CAP, RFCOMM_CONNINFO, &conn, &opt) < 0) { + syslog(LOG_ERR, "Can't get RFCOMM connection information. %s(%d)", strerror(errno), errno); + close(s); + //return -1; + } + + syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]", + conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); return s; } diff --git a/test/scotest.c b/test/scotest.c index d245b9c0..0c1ec130 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -60,22 +60,23 @@ enum { DUMP }; -unsigned char *buf; +static unsigned char *buf; /* Default data size */ -long data_size = 672; +static long data_size = 672; -bdaddr_t bdaddr; +static bdaddr_t bdaddr; -float tv2fl(struct timeval tv) +static float tv2fl(struct timeval tv) { return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); } -int do_connect(char *svr) +static int do_connect(char *svr) { struct sockaddr_sco rem_addr, loc_addr; - int s; + struct sco_conninfo conn; + int s, opt; if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); @@ -98,43 +99,53 @@ int do_connect(char *svr) return -1; } - syslog(LOG_INFO, "Connected\n"); + memset(&conn, 0, sizeof(conn)); + opt = sizeof(conn); + if (getsockopt(s, SOL_L2CAP, SCO_CONNINFO, &conn, &opt) < 0) { + syslog(LOG_ERR, "Can't get SCO connection information. %s(%d)", strerror(errno), errno); + close(s); + return -1; + } + + syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]", + conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); return s; } -void do_listen( void (*handler)(int sk) ) +static void do_listen(void (*handler)(int sk)) { struct sockaddr_sco loc_addr, rem_addr; int s, s1, opt; bdaddr_t ba; - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); exit(1); } loc_addr.sco_family = AF_BLUETOOTH; loc_addr.sco_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); } - if( listen(s, 10) ) { + if (listen(s, 10)) { syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); exit(1); } syslog(LOG_INFO,"Waiting for connection ..."); - while(1) { + while (1) { opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + if ((s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0) { syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); exit(1); } - if( fork() ) { + if (fork()) { /* Parent */ close(s1); continue; @@ -153,7 +164,7 @@ void do_listen( void (*handler)(int sk) ) } } -void dump_mode(int s) +static void dump_mode(int s) { int len; @@ -162,7 +173,7 @@ void dump_mode(int s) syslog(LOG_INFO, "Recevied %d bytes\n", len); } -void recv_mode(int s) +static void recv_mode(int s) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -194,7 +205,7 @@ void recv_mode(int s) } } -void send_mode(char *svr) +static void send_mode(char *svr) { struct sco_options so; uint32_t seq; @@ -216,7 +227,7 @@ void send_mode(char *svr) syslog(LOG_INFO,"Sending ..."); - for (i=6; i < so.mtu; i++) + for (i = 6; i < so.mtu; i++) buf[i]=0x7f; seq = 0; @@ -234,11 +245,11 @@ void send_mode(char *svr) } } -void reconnect_mode(char *svr) +static void reconnect_mode(char *svr) { - while(1){ + while (1) { int s; - if( (s = do_connect(svr)) < 0 ){ + if ((s = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); exit(1); } @@ -248,15 +259,16 @@ void reconnect_mode(char *svr) } } -void multy_connect_mode(char *svr) +static void multy_connect_mode(char *svr) { - while(1){ + while (1) { int i, s; - for(i=0; i<10; i++){ - if( fork() ) continue; + for (i = 0; i < 10; i++){ + if (fork()) + continue; /* Child */ - if( (s = do_connect(svr)) < 0 ){ + if ((s = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); } close(s); @@ -266,7 +278,7 @@ void multy_connect_mode(char *svr) } } -void usage(void) +static void usage(void) { printf("scotest - SCO testing\n" "Usage:\n"); -- cgit From 95cd931b918a07fcf12e48dce9665f3c90ab4130 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 29 Dec 2004 19:32:16 +0000 Subject: Fix typos --- test/rctest.c | 4 ++-- test/scotest.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/rctest.c b/test/rctest.c index 2ffb47dd..31d2be0f 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -128,7 +128,7 @@ int do_connect(char *svr) memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); - if (getsockopt(s, SOL_L2CAP, RFCOMM_CONNINFO, &conn, &opt) < 0) { + if (getsockopt(s, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &opt) < 0) { syslog(LOG_ERR, "Can't get RFCOMM connection information. %s(%d)", strerror(errno), errno); close(s); //return -1; @@ -172,7 +172,7 @@ void do_listen( void (*handler)(int sk) ) opt |= RFCOMM_LM_SECURE; if (setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set RFCOMM link mode. %s(%d)", strerror(errno), errno); exit(1); } diff --git a/test/scotest.c b/test/scotest.c index 0c1ec130..eddd79af 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -101,7 +101,7 @@ static int do_connect(char *svr) memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); - if (getsockopt(s, SOL_L2CAP, SCO_CONNINFO, &conn, &opt) < 0) { + if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &opt) < 0) { syslog(LOG_ERR, "Can't get SCO connection information. %s(%d)", strerror(errno), errno); close(s); return -1; -- cgit From 3c967ce42aee827ff36622c7b70cbd65ef6dd900 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 10:10:34 +0000 Subject: Fix memory leaks and make more functions static --- test/l2test.c | 112 ++++++++++++++++++++++++++++------------------------------ test/rctest.c | 94 ++++++++++++++++++++++++------------------------ 2 files changed, 100 insertions(+), 106 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index c36cc3b7..fccea39b 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -71,36 +71,36 @@ enum { LSENDDUMP }; -unsigned char *buf; +static unsigned char *buf; /* Default mtu */ -int imtu = 672; -int omtu = 0; +static int imtu = 672; +static int omtu = 0; /* Default data size */ -long data_size = 672; +static long data_size = 672; /* Default addr and psm */ -bdaddr_t bdaddr; -unsigned short psm = 10; +static bdaddr_t bdaddr; +static unsigned short psm = 10; /* Default number of frames to send */ -int num_frames = -1; // Infinite +static int num_frames = -1; // Infinite -int master = 0; -int auth = 0; -int encrypt = 0; -int secure = 0; -int socktype = SOCK_SEQPACKET; -int linger = 0; -int reliable = 0; +static int master = 0; +static int auth = 0; +static int encrypt = 0; +static int secure = 0; +static int socktype = SOCK_SEQPACKET; +static int linger = 0; +static int reliable = 0; -float tv2fl(struct timeval tv) +static float tv2fl(struct timeval tv) { return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); } -char *ltoh(unsigned long c, char* s) +static char *ltoh(unsigned long c, char* s) { int c1; @@ -124,7 +124,7 @@ char *ltoh(unsigned long c, char* s) return (s); } -char *ctoh(char c, char* s) +static char *ctoh(char c, char* s) { char c1; @@ -136,15 +136,15 @@ char *ctoh(char c, char* s) return (s); } -void hexdump(char *s, unsigned long l) +static void hexdump(char *s, unsigned long l) { char bfr[80]; char *pb; unsigned long i, n = 0; - + if (l == 0) return; - + while (n < l) { pb = bfr; pb = ltoh (n, pb); @@ -165,14 +165,14 @@ void hexdump(char *s, unsigned long l) else *(pb++) = (isprint (*(s + i)) ? *(s + i) : '.'); } - *pb = 0; + *pb = 0; n += 16; s += 16; puts(bfr); } } -int do_connect(char *svr) +static int do_connect(char *svr) { struct sockaddr_l2 rem_addr, loc_addr; struct l2cap_options opts; @@ -186,7 +186,7 @@ int do_connect(char *svr) memset(&loc_addr, 0, sizeof(loc_addr)); loc_addr.l2_family = AF_BLUETOOTH; - loc_addr.l2_bdaddr = bdaddr; + bacpy(&loc_addr.l2_bdaddr, &bdaddr); if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); @@ -232,7 +232,7 @@ int do_connect(char *svr) rem_addr.l2_family = AF_BLUETOOTH; baswap(&rem_addr.l2_bdaddr, strtoba(svr)); rem_addr.l2_psm = htobs(psm); - if (connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ) { + if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0 ) { syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); close(s); return -1; @@ -261,12 +261,12 @@ int do_connect(char *svr) return s; } -void do_listen(void (*handler)(int sk)) +static void do_listen(void (*handler)(int sk)) { struct sockaddr_l2 loc_addr, rem_addr; struct l2cap_options opts; - int s, s1, opt; - bdaddr_t ba; + int s, s1, opt; + char ba[18]; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); @@ -274,7 +274,7 @@ void do_listen(void (*handler)(int sk)) } loc_addr.l2_family = AF_BLUETOOTH; - loc_addr.l2_bdaddr = bdaddr; + bacpy(&loc_addr.l2_bdaddr, &bdaddr); loc_addr.l2_psm = htobs(psm); if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); @@ -327,7 +327,7 @@ void do_listen(void (*handler)(int sk)) while(1) { opt = sizeof(rem_addr); - if ((s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0) { + if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); exit(1); } @@ -346,9 +346,9 @@ void do_listen(void (*handler)(int sk)) exit(1); } - baswap(&ba, &rem_addr.l2_bdaddr); + ba2str(&rem_addr.l2_bdaddr, ba); syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", - batostr(&ba), opts.imtu, opts.omtu, opts.flush_to); + ba, opts.imtu, opts.omtu, opts.flush_to); /* Enable SO_LINGER */ if (linger) { @@ -362,12 +362,12 @@ void do_listen(void (*handler)(int sk)) handler(s1); - syslog(LOG_INFO, "Disconnect. %m\n"); + syslog(LOG_INFO, "Disconnect. %m"); exit(0); } } -void dump_mode(int s) +static void dump_mode(int s) { int len; int opt, optl; @@ -375,7 +375,7 @@ void dump_mode(int s) syslog(LOG_INFO, "Receiving ..."); while (1) { fd_set rset; - + FD_ZERO(&rset); FD_SET(s, &rset); @@ -393,7 +393,7 @@ void dump_mode(int s) optl = sizeof(opt); if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", - strerror(errno), errno); + strerror(errno), errno); return; } continue; @@ -409,7 +409,7 @@ void dump_mode(int s) } } -void recv_mode(int s) +static void recv_mode(int s) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -440,7 +440,7 @@ void recv_mode(int s) continue; } else { syslog(LOG_ERR, "Read failed. %s(%d)", - strerror(errno), errno); + strerror(errno), errno); } } return; @@ -453,15 +453,15 @@ void recv_mode(int s) seq = sq; } seq++; - + /* Check length */ l = btohs(*(uint16_t *)(buf+4)); if (r != l) { syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); continue; } - - /* Verify data */ + + /* Verify data */ for (i=6; i < r; i++) { if (buf[i] != 0x7f) syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); @@ -474,11 +474,11 @@ void recv_mode(int s) timersub(&tv_end,&tv_beg,&tv_diff); syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, - tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); } } -void send_mode(int s) +static void send_mode(int s) { uint32_t seq; int i; @@ -493,7 +493,7 @@ void send_mode(int s) *(uint32_t *) buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); seq++; - + if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); exit(1); @@ -507,7 +507,7 @@ void send_mode(int s) syslog(LOG_INFO, "Done"); } -void senddump_mode(int s) +static void senddump_mode(int s) { uint32_t seq; int i; @@ -522,7 +522,7 @@ void senddump_mode(int s) *(uint32_t *) buf = htobl(seq); *(uint16_t *)(buf+4) = htobs(data_size); seq++; - + if (send(s, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); exit(1); @@ -530,10 +530,9 @@ void senddump_mode(int s) } dump_mode(s); - } -void reconnect_mode(char *svr) +static void reconnect_mode(char *svr) { while(1) { int s = do_connect(svr); @@ -541,7 +540,7 @@ void reconnect_mode(char *svr) } } -void connect_mode(char *svr) +static void connect_mode(char *svr) { int s; if ((s = do_connect(svr)) < 0) @@ -549,7 +548,7 @@ void connect_mode(char *svr) sleep(99999999); } -void multi_connect_mode(char *svr) +static void multi_connect_mode(char *svr) { while (1) { int i, s; @@ -566,7 +565,7 @@ void multi_connect_mode(char *svr) } } -void usage(void) +static void usage(void) { printf("l2test - L2CAP testing\n" "Usage:\n"); @@ -585,7 +584,7 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-i device] [-P psm]\n" - "\t[-I imtu] [-O omtu]\n" + "\t[-I imtu] [-O omtu]\n" "\t[-N num] send num frames (default = infinite)\n" "\t[-L seconds] enable SO_LINGER\n" "\t[-R] reliable mode\n" @@ -593,12 +592,9 @@ void usage(void) "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-S] secure connection\n" - "\t[-M] become master\n"); + "\t[-M] become master\n"); } -extern int optind,opterr,optopt; -extern char *optarg; - int main(int argc ,char *argv[]) { int opt, mode, s, need_addr; @@ -613,7 +609,7 @@ int main(int argc ,char *argv[]) case 'r': mode = RECV; break; - + case 's': mode = SEND; need_addr = 1; @@ -733,7 +729,7 @@ int main(int argc ,char *argv[]) openlog("l2test", LOG_PERROR | LOG_PID, LOG_LOCAL0); - switch( mode ){ + switch (mode) { case RECV: do_listen(recv_mode); break; @@ -782,8 +778,8 @@ int main(int argc ,char *argv[]) case LSENDDUMP: do_listen(senddump_mode); break; - } + syslog(LOG_INFO, "Exit"); closelog(); diff --git a/test/rctest.c b/test/rctest.c index 31d2be0f..041e36b3 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -65,35 +65,35 @@ enum { LSEND }; -unsigned char *buf; +static unsigned char *buf; /* Default data size */ -long data_size = 127; -long num_frames = -1; +static long data_size = 127; +static long num_frames = -1; /* Default addr and channel */ -bdaddr_t bdaddr; -uint8_t channel = 10; +static bdaddr_t bdaddr; +static uint8_t channel = 10; -int master = 0; -int auth = 0; -int encrypt = 0; -int secure = 0; -int socktype = SOCK_STREAM; -int linger = 0; +static int master = 0; +static int auth = 0; +static int encrypt = 0; +static int secure = 0; +static int socktype = SOCK_STREAM; +static int linger = 0; -float tv2fl(struct timeval tv) +static float tv2fl(struct timeval tv) { return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); } -int do_connect(char *svr) +static int do_connect(char *svr) { struct sockaddr_rc rem_addr, loc_addr; struct rfcomm_conninfo conn; int s, opt; - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); return -1; } @@ -110,17 +110,17 @@ int do_connect(char *svr) memset(&loc_addr, 0, sizeof(loc_addr)); loc_addr.rc_family = AF_BLUETOOTH; - loc_addr.rc_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + bacpy(&loc_addr.rc_bdaddr, &bdaddr); + if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); } memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.rc_family = AF_BLUETOOTH; - baswap(&rem_addr.rc_bdaddr, strtoba(svr)); + str2ba(svr, &rem_addr.rc_bdaddr); rem_addr.rc_channel = channel; - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ + if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0) { syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); close(s); return -1; @@ -141,21 +141,21 @@ int do_connect(char *svr) return s; } -void do_listen( void (*handler)(int sk) ) +static void do_listen(void (*handler)(int sk)) { struct sockaddr_rc loc_addr, rem_addr; - int s, s1, opt; - bdaddr_t ba; + int s, s1, opt; + char ba[18]; - if( (s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0 ) { + if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); exit(1); } loc_addr.rc_family = AF_BLUETOOTH; - loc_addr.rc_bdaddr = bdaddr; + bacpy(&loc_addr.rc_bdaddr, &bdaddr); loc_addr.rc_channel = channel; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { + if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -176,7 +176,7 @@ void do_listen( void (*handler)(int sk) ) exit(1); } - if( listen(s, 10) ) { + if (listen(s, 10)) { syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); exit(1); } @@ -185,11 +185,11 @@ void do_listen( void (*handler)(int sk) ) while(1) { opt = sizeof(rem_addr); - if( (s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0 ) { + if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); exit(1); } - if( fork() ) { + if (fork()) { /* Parent */ close(s1); continue; @@ -198,8 +198,8 @@ void do_listen( void (*handler)(int sk) ) close(s); - baswap(&ba, &rem_addr.rc_bdaddr); - syslog(LOG_INFO, "Connect from %s \n", batostr(&ba)); + ba2str(&rem_addr.rc_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s", ba); /* Enable SO_LINGER */ if (linger) { @@ -213,21 +213,21 @@ void do_listen( void (*handler)(int sk) ) handler(s1); - syslog(LOG_INFO, "Disconnect\n"); + syslog(LOG_INFO, "Disconnect"); exit(0); } } -void dump_mode(int s) +static void dump_mode(int s) { int len; syslog(LOG_INFO, "Receiving ..."); while ((len = read(s, buf, data_size)) > 0) - syslog(LOG_INFO, "Recevied %d bytes\n", len); + syslog(LOG_INFO, "Recevied %d bytes", len); } -void recv_mode(int s) +static void recv_mode(int s) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -279,11 +279,11 @@ void recv_mode(int s) timersub(&tv_end,&tv_beg,&tv_diff); syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, - tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); + tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); } } -void send_mode(int s) +static void send_mode(int s) { uint32_t seq; int i; @@ -312,7 +312,7 @@ void send_mode(int s) syslog(LOG_INFO, "Done"); } -void reconnect_mode(char *svr) +static void reconnect_mode(char *svr) { while(1) { int s = do_connect(svr); @@ -320,11 +320,11 @@ void reconnect_mode(char *svr) } } -void multi_connect_mode(char *svr) +static void multi_connect_mode(char *svr) { while (1) { int i, s; - for (i=0; i<10; i++) { + for (i = 0; i < 10; i++) { if (fork()) continue; /* Child */ @@ -337,7 +337,7 @@ void multi_connect_mode(char *svr) } } -void usage(void) +static void usage(void) { printf("rctest - RFCOMM testing\n" "Usage:\n"); @@ -354,16 +354,13 @@ void usage(void) printf("Options:\n" "\t[-b bytes] [-i device] [-P channel]\n" - "\t[-L seconds] enabled SO_LINGER option\n" - "\t[-N num] number of frames to send\n" + "\t[-L seconds] enabled SO_LINGER option\n" + "\t[-N num] number of frames to send\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" - "\t[-M] become master\n"); + "\t[-M] become master\n"); } -extern int optind,opterr,optopt; -extern char *optarg; - int main(int argc ,char *argv[]) { int opt, mode, s, need_addr; @@ -374,11 +371,11 @@ int main(int argc ,char *argv[]) bacpy(&bdaddr, BDADDR_ANY); while ((opt=getopt(argc,argv,"rdscuwmnb:i:P:N:MAESL:")) != EOF) { - switch(opt) { + switch (opt) { case 'r': mode = RECV; break; - + case 's': mode = SEND; need_addr = 1; @@ -474,7 +471,7 @@ int main(int argc ,char *argv[]) openlog("rctest", LOG_PERROR | LOG_PID, LOG_LOCAL0); - switch( mode ){ + switch (mode) { case RECV: do_listen(recv_mode); break; @@ -516,6 +513,7 @@ int main(int argc ,char *argv[]) dump_mode(s); break; } + syslog(LOG_INFO, "Exit"); closelog(); -- cgit From 018d2a9255e4015860825bd4957d5bd41ba7cecc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 13:21:30 +0000 Subject: Whitespace cleanup and make more code static --- tools/hciconfig.c | 293 ++++++++++++++++++++++++++++-------------------------- tools/hcitool.c | 154 +++++++++++++--------------- 2 files changed, 225 insertions(+), 222 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 22aaeda7..11590b97 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,17 +33,11 @@ #endif #include -#include -#include -#include -#include -#include #include #include +#include +#include #include - -#include -#include #include #include @@ -53,56 +47,54 @@ #include "csr.h" -extern int optind,opterr,optopt; -extern char *optarg; - static struct hci_dev_info di; static int all; -void print_dev_hdr(struct hci_dev_info *di); -void print_dev_info(int ctl, struct hci_dev_info *di); +static void print_dev_hdr(struct hci_dev_info *di); +static void print_dev_info(int ctl, struct hci_dev_info *di); -void print_dev_list(int ctl, int flags) +static void print_dev_list(int ctl, int flags) { struct hci_dev_list_req *dl; struct hci_dev_req *dr; int i; - if( !(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t))) ) { + if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) { perror("Can't allocate memory"); exit(1); } dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if( ioctl(ctl, HCIGETDEVLIST, (void*)dl) ) { + if (ioctl(ctl, HCIGETDEVLIST, (void *) dl)) { perror("Can't get device list"); exit(1); } - for(i=0; i< dl->dev_num; i++) { + + for (i = 0; i< dl->dev_num; i++) { di.dev_id = (dr+i)->dev_id; - if( ioctl(ctl, HCIGETDEVINFO, (void*)&di) ) + if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) continue; print_dev_info(ctl, &di); } } -void print_pkt_type(struct hci_dev_info *di) +static void print_pkt_type(struct hci_dev_info *di) { printf("\tPacket type: %s\n", hci_ptypetostr(di->pkt_type)); } -void print_link_policy(struct hci_dev_info *di) +static void print_link_policy(struct hci_dev_info *di) { printf("\tLink policy: %s\n", hci_lptostr(di->link_policy)); } -void print_link_mode(struct hci_dev_info *di) +static void print_link_mode(struct hci_dev_info *di) { printf("\tLink mode: %s\n", hci_lmtostr(di->link_mode)); } -void print_dev_features(struct hci_dev_info *di, int format) +static void print_dev_features(struct hci_dev_info *di, int format) { if (!format) { printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", @@ -120,17 +112,17 @@ void print_dev_features(struct hci_dev_info *di, int format) } } -void cmd_rstat(int ctl, int hdev, char *opt) +static void cmd_rstat(int ctl, int hdev, char *opt) { /* Reset HCI device stat counters */ - if( ioctl(ctl, HCIDEVRESTAT, hdev) < 0 ) { - printf("Can't reset stats counters hci%d. %s(%d)\n", hdev, - strerror(errno), errno); + if (ioctl(ctl, HCIDEVRESTAT, hdev) < 0) { + fprintf(stderr, "Can't reset stats counters hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_scan(int ctl, int hdev, char *opt) +static void cmd_scan(int ctl, int hdev, char *opt) { struct hci_dev_req dr; @@ -143,18 +135,20 @@ void cmd_scan(int ctl, int hdev, char *opt) else if( !strcmp(opt, "piscan") ) dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; - if( ioctl(ctl, HCISETSCAN, (unsigned long)&dr) < 0 ) { - printf("Can't set scan mode on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set scan mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_iac(int ctl, int hdev, char *opt) +static void cmd_iac(int ctl, int hdev, char *opt) { int s = hci_open_dev(hdev); if (s < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { @@ -193,7 +187,7 @@ void cmd_iac(int ctl, int hdev, char *opt) close(s); } -void cmd_auth(int ctl, int hdev, char *opt) +static void cmd_auth(int ctl, int hdev, char *opt) { struct hci_dev_req dr; @@ -204,12 +198,13 @@ void cmd_auth(int ctl, int hdev, char *opt) dr.dev_opt = AUTH_DISABLED; if (ioctl(ctl, HCISETAUTH, (unsigned long) &dr) < 0) { - printf("Can't set auth on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't set auth on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_encrypt(int ctl, int hdev, char *opt) +static void cmd_encrypt(int ctl, int hdev, char *opt) { struct hci_dev_req dr; @@ -220,12 +215,13 @@ void cmd_encrypt(int ctl, int hdev, char *opt) dr.dev_opt = ENCRYPT_DISABLED; if (ioctl(ctl, HCISETENCRYPT, (unsigned long) &dr) < 0) { - printf("Can't set encrypt on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't set encrypt on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_secmgr(int ctl, int hdev, char *opt) +static void cmd_secmgr(int ctl, int hdev, char *opt) { int val, s = hci_open_dev(hdev); @@ -235,13 +231,14 @@ void cmd_secmgr(int ctl, int hdev, char *opt) val = 0; if (ioctl(s, HCISETSECMGR, val) < 0) { - printf("Can't set security manager on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't set security manager on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } close(s); } -void cmd_up(int ctl, int hdev, char *opt) +static void cmd_up(int ctl, int hdev, char *opt) { int ret; @@ -249,42 +246,47 @@ void cmd_up(int ctl, int hdev, char *opt) if( (ret = ioctl(ctl, HCIDEVUP, hdev)) < 0 ) { if( errno == EALREADY ) return; - printf("Can't init device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't init device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } cmd_scan(ctl, hdev, "piscan"); } -void cmd_down(int ctl, int hdev, char *opt) +static void cmd_down(int ctl, int hdev, char *opt) { /* Stop HCI device */ if (ioctl(ctl, HCIDEVDOWN, hdev) < 0) { - printf("Can't down device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't down device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_reset(int ctl, int hdev, char *opt) +static void cmd_reset(int ctl, int hdev, char *opt) { - /* Reset HCI device - if( ioctl(ctl, HCIDEVRESET, hdev) < 0 ){ - printf("Reset failed hci%d. %s(%d)\n", hdev, strerror(errno), errno); - exit(1); + /* Reset HCI device */ +#if 0 + if (ioctl(ctl, HCIDEVRESET, hdev) < 0 ){ + fprintf(stderr, "Reset failed for device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); } - */ +#endif cmd_down(ctl, hdev, "down"); cmd_up(ctl, hdev, "up"); } -void cmd_ptype(int ctl, int hdev, char *opt) +static void cmd_ptype(int ctl, int hdev, char *opt) { struct hci_dev_req dr; dr.dev_id = hdev; if (hci_strtoptype(opt, &dr.dev_opt)) { - if (ioctl(ctl, HCISETPTYPE, (unsigned long)&dr) < 0) { - printf("Can't set pkttype on hci%d. %s(%d)\n", hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETPTYPE, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set pkttype on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { @@ -293,16 +295,16 @@ void cmd_ptype(int ctl, int hdev, char *opt) } } -void cmd_lp(int ctl, int hdev, char *opt) +static void cmd_lp(int ctl, int hdev, char *opt) { struct hci_dev_req dr; dr.dev_id = hdev; if (hci_strtolp(opt, &dr.dev_opt)) { - if (ioctl(ctl, HCISETLINKPOL, (unsigned long)&dr) < 0) { - printf("Can't set link policy on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETLINKPOL, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set link policy on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { @@ -311,16 +313,16 @@ void cmd_lp(int ctl, int hdev, char *opt) } } -void cmd_lm(int ctl, int hdev, char *opt) +static void cmd_lm(int ctl, int hdev, char *opt) { struct hci_dev_req dr; dr.dev_id = hdev; if (hci_strtolm(opt, &dr.dev_opt)) { - if (ioctl(ctl, HCISETLINKMODE, (unsigned long)&dr) < 0) { - printf("Can't set default link mode on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETLINKMODE, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set default link mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { @@ -329,7 +331,7 @@ void cmd_lm(int ctl, int hdev, char *opt) } } -void cmd_aclmtu(int ctl, int hdev, char *opt) +static void cmd_aclmtu(int ctl, int hdev, char *opt) { struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; @@ -343,14 +345,14 @@ void cmd_aclmtu(int ctl, int hdev, char *opt) *((uint16_t *)&dr.dev_opt + 1) = mtu; *((uint16_t *)&dr.dev_opt + 0) = mpkt; - if (ioctl(ctl, HCISETACLMTU, (unsigned long)&dr) < 0) { - printf("Can't set ACL mtu on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) { + fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_scomtu(int ctl, int hdev, char *opt) +static void cmd_scomtu(int ctl, int hdev, char *opt) { struct hci_dev_req dr = { dev_id: hdev }; uint16_t mtu, mpkt; @@ -365,38 +367,39 @@ void cmd_scomtu(int ctl, int hdev, char *opt) *((uint16_t *)&dr.dev_opt + 0) = mpkt; if (ioctl(ctl, HCISETSCOMTU, (unsigned long)&dr) < 0) { - printf("Can't set SCO mtu on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } -void cmd_features(int ctl, int hdev, char *opt) +static void cmd_features(int ctl, int hdev, char *opt) { print_dev_hdr(&di); print_dev_features(&di, 1); } -void cmd_name(int ctl, int hdev, char *opt) +static void cmd_name(int ctl, int hdev, char *opt) { int s = hci_open_dev(hdev); if (s < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { - if (hci_write_local_name(s, opt, 1000) < 0) { - printf("Can't change local name on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (hci_write_local_name(s, opt, 2000) < 0) { + fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { char name[248]; int i; if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { - printf("Can't read local name on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } for (i = 0; i < 248 && name[i]; i++) @@ -540,7 +543,7 @@ static char *get_minor_device_name(int major, int minor) return "Unknown (reserved) minor device class"; } -void cmd_class(int ctl, int hdev, char *opt) +static void cmd_class(int ctl, int hdev, char *opt) { static char *services[] = { "Positioning", "Networking", @@ -561,21 +564,22 @@ void cmd_class(int ctl, int hdev, char *opt) int s = hci_open_dev(hdev); if (s < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { uint32_t cod = strtoul(opt, NULL, 16); - if (hci_write_class_of_dev(s, cod, 1000) < 0) { - printf("Can't write local class of device on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (hci_write_class_of_dev(s, cod, 2000) < 0) { + fprintf(stderr, "Can't write local class of device on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { uint8_t cls[3]; if (hci_read_class_of_dev(s, cls, 1000) < 0) { - printf("Can't read class of device on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read class of device on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } print_dev_hdr(&di); @@ -601,7 +605,7 @@ void cmd_class(int ctl, int hdev, char *opt) } } -void cmd_voice(int ctl, int hdev, char *opt) +static void cmd_voice(int ctl, int hdev, char *opt) { static char *icf[] = { "Linear", "u-Law", "A-Law", "Reserved" }; static char *idf[] = { "1's complement", "2's complement", "Sign-Magnitude", "Reserved" }; @@ -610,22 +614,23 @@ void cmd_voice(int ctl, int hdev, char *opt) int s = hci_open_dev(hdev); if (s < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { uint16_t vs = htobs(strtoul(opt, NULL, 16)); - if (0 > hci_write_voice_setting(s, vs, 1000)) { - printf("Can't write voice setting on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (hci_write_voice_setting(s, vs, 2000) < 0) { + fprintf(stderr, "Can't write voice setting on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } } else { uint16_t vs; uint8_t ic; - if (0 > hci_read_voice_setting(s, &vs, 1000)) { - printf("Can't read voice setting on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + if (hci_read_voice_setting(s, &vs, 1000) < 0) { + fprintf(stderr, "Can't read voice setting on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } vs = htobs(vs); @@ -643,46 +648,48 @@ void cmd_voice(int ctl, int hdev, char *opt) } } -void cmd_version(int ctl, int hdev, char *opt) +static void cmd_version(int ctl, int hdev, char *opt) { struct hci_version ver; int dd; dd = hci_open_dev(hdev); if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (hci_read_local_version(dd, &ver, 1000) < 0) { - printf("Can't read version info hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read version info hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } print_dev_hdr(&di); - printf( "\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n" + printf("\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n" "\tManufacturer: %s (%d)\n", - hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, - lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, + hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, + lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, bt_compidtostr(ver.manufacturer), ver.manufacturer); } -void cmd_inq_mode(int ctl, int hdev, char *opt) +static void cmd_inq_mode(int ctl, int hdev, char *opt) { int dd; dd = hci_open_dev(hdev); if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { uint8_t mode = atoi(opt); - if (hci_write_inquiry_mode(dd, mode, 1000) < 0) { - printf("Can't set inquiry mode on hci%d. %s(%d)\n", + if (hci_write_inquiry_mode(dd, mode, 2000) < 0) { + fprintf(stderr, "Can't set inquiry mode on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -690,8 +697,8 @@ void cmd_inq_mode(int ctl, int hdev, char *opt) uint8_t mode; if (hci_read_inquiry_mode(dd, &mode, 1000) < 0) { - printf("Can't read inquiry mode on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read inquiry mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -701,12 +708,14 @@ void cmd_inq_mode(int ctl, int hdev, char *opt) } } -void cmd_inq_parms(int ctl, int hdev, char *opt) +static void cmd_inq_parms(int ctl, int hdev, char *opt) { struct hci_request rq; int s; + if ((s = hci_open_dev(hdev)) < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -735,8 +744,8 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) if (interval < 0x12 || interval > 0x1000) printf("Warning: inquiry interval out of range!\n"); - if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't set inquiry parameters name on hci%d. %s(%d)\n", + if (hci_send_req(s, &rq, 2000) < 0) { + fprintf(stderr, "Can't set inquiry parameters name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -750,12 +759,12 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) rq.rlen = READ_INQ_ACTIVITY_RP_SIZE; if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't read inquiry parameters on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read inquiry parameters on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (rp.status) { - printf("Read inquiry parameters on hci%d returned status %d\n", + printf("Read inquiry parameters on hci%d returned status %d\n", hdev, rp.status); exit(1); } @@ -768,12 +777,14 @@ void cmd_inq_parms(int ctl, int hdev, char *opt) } } -void cmd_page_parms(int ctl, int hdev, char *opt) +static void cmd_page_parms(int ctl, int hdev, char *opt) { struct hci_request rq; int s; + if ((s = hci_open_dev(hdev)) < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -802,8 +813,8 @@ void cmd_page_parms(int ctl, int hdev, char *opt) if (interval < 0x12 || interval > 0x1000) printf("Warning: page interval out of range!\n"); - if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't set page parameters name on hci%d. %s(%d)\n", + if (hci_send_req(s, &rq, 2000) < 0) { + fprintf(stderr, "Can't set page parameters name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -817,12 +828,12 @@ void cmd_page_parms(int ctl, int hdev, char *opt) rq.rlen = READ_PAGE_ACTIVITY_RP_SIZE; if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't read page parameters on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read page parameters on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (rp.status) { - printf("Read page parameters on hci%d returned status %d\n", + printf("Read page parameters on hci%d returned status %d\n", hdev, rp.status); exit(1); } @@ -835,12 +846,14 @@ void cmd_page_parms(int ctl, int hdev, char *opt) } } -void cmd_page_to(int ctl, int hdev, char *opt) +static void cmd_page_to(int ctl, int hdev, char *opt) { struct hci_request rq; int s; + if ((s = hci_open_dev(hdev)) < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -865,8 +878,8 @@ void cmd_page_to(int ctl, int hdev, char *opt) if (timeout < 0x01 || timeout > 0xFFFF) printf("Warning: page timeout out of range!\n"); - if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't set page timeout on hci%d. %s(%d)\n", + if (hci_send_req(s, &rq, 2000) < 0) { + fprintf(stderr, "Can't set page timeout on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -880,12 +893,12 @@ void cmd_page_to(int ctl, int hdev, char *opt) rq.rlen = READ_PAGE_TIMEOUT_RP_SIZE; if (hci_send_req(s, &rq, 1000) < 0) { - printf("Can't read page timeout on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read page timeout on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (rp.status) { - printf("Read page timeout on hci%d returned status %d\n", + printf("Read page timeout on hci%d returned status %d\n", hdev, rp.status); exit(1); } @@ -897,21 +910,22 @@ void cmd_page_to(int ctl, int hdev, char *opt) } } -void cmd_afh_mode(int ctl, int hdev, char *opt) +static void cmd_afh_mode(int ctl, int hdev, char *opt) { int dd; dd = hci_open_dev(hdev); if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } if (opt) { uint8_t mode = atoi(opt); - if (hci_write_afh_mode(dd, mode, 1000) < 0) { - printf("Can't set AFH mode on hci%d. %s(%d)\n", + if (hci_write_afh_mode(dd, mode, 2000) < 0) { + fprintf(stderr, "Can't set AFH mode on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -919,8 +933,8 @@ void cmd_afh_mode(int ctl, int hdev, char *opt) uint8_t mode; if (hci_read_afh_mode(dd, &mode, 1000) < 0) { - printf("Can't read AFH mode on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read AFH mode on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); exit(1); } @@ -943,7 +957,7 @@ static void print_rev_ericsson(int dd) rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\nCan't read revision info. %s(%d)\n", strerror(errno), errno); + printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno); return; } @@ -989,7 +1003,7 @@ static void print_rev_digianswer(int dd) rq.rlen = sizeof(buf); if (hci_send_req(dd, &rq, 1000) < 0) { - printf("\nCan't read revision info. %s(%d)\n", strerror(errno), errno); + printf("\nCan't read revision info: %s (%d)\n", strerror(errno), errno); return; } @@ -1016,13 +1030,14 @@ static void cmd_revision(int ctl, int hdev, char *opt) dd = hci_open_dev(hdev); if (dd < 0) { - printf("Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); return; } if (hci_read_local_version(dd, &ver, 1000) < 0) { - printf("Can't read version info hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + hdev, strerror(errno), errno); return; } @@ -1051,7 +1066,7 @@ static void cmd_revision(int ctl, int hdev, char *opt) return; } -void print_dev_hdr(struct hci_dev_info *di) +static void print_dev_hdr(struct hci_dev_info *di) { static int hdr = -1; char addr[18]; @@ -1068,7 +1083,7 @@ void print_dev_hdr(struct hci_dev_info *di) di->sco_mtu, di->sco_pkts); } -void print_dev_info(int ctl, struct hci_dev_info *di) +static void print_dev_info(int ctl, struct hci_dev_info *di) { struct hci_dev_stats *st = &di->stat; @@ -1098,7 +1113,7 @@ void print_dev_info(int ctl, struct hci_dev_info *di) printf("\n"); } -struct { +static struct { char *cmd; void (*func)(int ctl, int hdev, char *opt); char *opt; @@ -1138,7 +1153,7 @@ struct { { NULL, NULL, 0 } }; -void usage(void) +static void usage(void) { int i; @@ -1194,7 +1209,7 @@ int main(int argc, char **argv, char **env) di.dev_id = atoi(argv[0] + 3); argc--; argv++; - if (ioctl(ctl, HCIGETDEVINFO, (void*)&di)) { + if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) { perror("Can't get device info"); exit(1); } diff --git a/tools/hcitool.c b/tools/hcitool.c index 8bb68427..99262f41 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,36 +33,24 @@ #endif #include -#include -#include -#include -#include -#include #include -#include - -#include -#include +#include +#include #include -#include #include #include -#include #include #include #include -extern int optind,opterr,optopt; -extern char *optarg; - #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) static void usage(void); static int dev_info(int s, int dev_id, long arg) { - struct hci_dev_info di = {dev_id: dev_id}; + struct hci_dev_info di = { dev_id: dev_id }; char addr[18]; if (ioctl(s, HCIGETDEVINFO, (void *) &di)) @@ -155,11 +143,11 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) /* Display local devices */ static struct option dev_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + {0, 0, 0, 0 } }; -static char *dev_help = +static char *dev_help = "Usage:\n" "\tdev\n"; @@ -181,14 +169,14 @@ static void cmd_dev(int dev_id, int argc, char **argv) /* Inquiry */ static struct option inq_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } }; -static char *inq_help = +static char *inq_help = "Usage:\n" "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" "\t [--numrsp=N] specify maximum number of inquiry responses\n" @@ -246,14 +234,14 @@ static void cmd_inq(int dev_id, int argc, char **argv) /* Device scanning */ static struct option scan_options[] = { - {"help", 0,0, 'h'}, - {"length", 1,0, 'l'}, - {"numrsp", 1,0, 'n'}, - {"flush", 0,0, 'f'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } }; -static char *scan_help = +static char *scan_help = "Usage:\n" "\tscan [--length=N] [--numrsp=N] [--flush]\n"; @@ -326,8 +314,8 @@ static void cmd_scan(int dev_id, int argc, char **argv) /* Remote name */ static struct option name_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; static char *name_help = @@ -380,11 +368,11 @@ static void cmd_name(int dev_id, int argc, char **argv) /* Info about remote device */ static struct option info_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *info_help = +static char *info_help = "Usage:\n" "\tinfo \n"; @@ -494,11 +482,11 @@ static void cmd_info(int dev_id, int argc, char **argv) /* Send arbitrary HCI commands */ static struct option cmd_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *cmd_help = +static char *cmd_help = "Usage:\n" "\tcmd [parameters]\n" "Example:\n" @@ -584,11 +572,11 @@ static void cmd_cmd(int dev_id, int argc, char **argv) /* Display active connections */ static struct option con_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *con_help = +static char *con_help = "Usage:\n" "\tcon\n"; @@ -611,13 +599,13 @@ static void cmd_con(int dev_id, int argc, char **argv) /* Create connection */ static struct option cc_options[] = { - {"help", 0,0, 'h'}, - {"role", 1,0, 'r'}, - {"ptype", 1,0, 'p'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "role", 1, 0, 'r' }, + { "ptype", 1, 0, 'p' }, + { 0, 0, 0, 0 } }; -static char *cc_help = +static char *cc_help = "Usage:\n" "\tcc [--role=m|s] [--ptype=pkt_types] \n" "Example:\n" @@ -682,11 +670,11 @@ static void cmd_cc(int dev_id, int argc, char **argv) /* Close connection */ static struct option dc_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *dc_help = +static char *dc_help = "Usage:\n" "\tdc \n"; @@ -749,11 +737,11 @@ static void cmd_dc(int dev_id, int argc, char **argv) /* Role switch */ static struct option sr_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *sr_help = +static char *sr_help = "Usage:\n" "\tsr \n"; @@ -816,11 +804,11 @@ static void cmd_sr(int dev_id, int argc, char **argv) /* Read RSSI */ static struct option rssi_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *rssi_help = +static char *rssi_help = "Usage:\n" "\trssi \n"; @@ -904,11 +892,11 @@ static void cmd_rssi(int dev_id, int argc, char **argv) /* Get link quality */ static struct option lq_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *lq_help = +static char *lq_help = "Usage:\n" "\tlq \n"; @@ -992,11 +980,11 @@ static void cmd_lq(int dev_id, int argc, char **argv) /* Get transmit power level */ static struct option tpl_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *tpl_help = +static char *tpl_help = "Usage:\n" "\ttpl [type]\n"; @@ -1081,11 +1069,11 @@ static void cmd_tpl(int dev_id, int argc, char **argv) /* Get AFH channel map */ static struct option afh_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *afh_help = +static char *afh_help = "Usage:\n" "\tafh \n"; @@ -1162,11 +1150,11 @@ static void cmd_afh(int dev_id, int argc, char **argv) /* Set connection packet type */ static struct option cpt_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *cpt_help = +static char *cpt_help = "Usage:\n" "\tcpt \n"; @@ -1246,11 +1234,11 @@ static void cmd_cpt(int dev_id, int argc, char **argv) /* Get/Set link supervision timeout */ static struct option lst_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *lst_help = +static char *lst_help = "Usage:\n" "\tlst [new value in slots]\n"; @@ -1355,11 +1343,11 @@ static void cmd_lst(int dev_id, int argc, char **argv) /* Request authentication */ static struct option auth_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *auth_help = +static char *auth_help = "Usage:\n" "\tauth \n"; @@ -1423,11 +1411,11 @@ static void cmd_auth(int dev_id, int argc, char **argv) /* Activate encryption */ static struct option enc_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *enc_help = +static char *enc_help = "Usage:\n" "\tenc [encrypt enable]\n"; @@ -1494,11 +1482,11 @@ static void cmd_enc(int dev_id, int argc, char **argv) /* Change connection link key */ static struct option key_options[] = { - {"help", 0,0, 'h'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } }; -static char *key_help = +static char *key_help = "Usage:\n" "\tkey \n"; @@ -1606,9 +1594,9 @@ static void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"device", 1,0, 'i'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } }; int main(int argc, char **argv) -- cgit From 9a25e71b182ed141be638d5ccf618ecbf6d1d836 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 13:33:14 +0000 Subject: More cleanups --- tools/hciconfig.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 11590b97..1a8f35d8 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -66,14 +66,14 @@ static void print_dev_list(int ctl, int flags) dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(ctl, HCIGETDEVLIST, (void *) dl)) { + if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) { perror("Can't get device list"); exit(1); } for (i = 0; i< dl->dev_num; i++) { di.dev_id = (dr+i)->dev_id; - if (ioctl(ctl, HCIGETDEVINFO, (void *) &di)) + if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0) continue; print_dev_info(ctl, &di); } @@ -128,11 +128,11 @@ static void cmd_scan(int ctl, int hdev, char *opt) dr.dev_id = hdev; dr.dev_opt = SCAN_DISABLED; - if( !strcmp(opt, "iscan") ) + if (!strcmp(opt, "iscan")) dr.dev_opt = SCAN_INQUIRY; - else if( !strcmp(opt, "pscan") ) + else if (!strcmp(opt, "pscan")) dr.dev_opt = SCAN_PAGE; - else if( !strcmp(opt, "piscan") ) + else if (!strcmp(opt, "piscan")) dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; if (ioctl(ctl, HCISETSCAN, (unsigned long) &dr) < 0) { @@ -240,11 +240,9 @@ static void cmd_secmgr(int ctl, int hdev, char *opt) static void cmd_up(int ctl, int hdev, char *opt) { - int ret; - /* Start HCI device */ - if( (ret = ioctl(ctl, HCIDEVUP, hdev)) < 0 ) { - if( errno == EALREADY ) + if (ioctl(ctl, HCIDEVUP, hdev) < 0) { + if (errno == EALREADY) return; fprintf(stderr, "Can't init device hci%d: %s (%d)\n", hdev, strerror(errno), errno); @@ -366,7 +364,7 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) *((uint16_t *)&dr.dev_opt + 1) = mtu; *((uint16_t *)&dr.dev_opt + 0) = mpkt; - if (ioctl(ctl, HCISETSCOMTU, (unsigned long)&dr) < 0) { + if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); @@ -1215,7 +1213,7 @@ int main(int argc, char **argv, char **env) } while (argc > 0) { - for (i=0; command[i].cmd; i++) { + for (i = 0; command[i].cmd; i++) { if (strncmp(command[i].cmd, *argv, 5)) continue; -- cgit From 7477c4f629682f6d1815a8e79250615533bad9ca Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 13:46:40 +0000 Subject: Add tool for changing the device address --- test/Makefile.am | 2 +- test/bdaddr.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 test/bdaddr.c diff --git a/test/Makefile.am b/test/Makefile.am index 5b05c43d..7bfb74c3 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -5,7 +5,7 @@ if TEST bin_PROGRAMS = l2test rctest -noinst_PROGRAMS = scotest attest hstest +noinst_PROGRAMS = scotest attest hstest bdaddr LDADD = @BLUEZ_LIBS@ diff --git a/test/bdaddr.c b/test/bdaddr.c new file mode 100644 index 00000000..d674c3de --- /dev/null +++ b/test/bdaddr.c @@ -0,0 +1,254 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define OCF_ERICSSON_WRITE_BD_ADDR 0x000d +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) ericsson_write_bd_addr_cp; +#define ERICSSON_WRITE_BD_ADDR_CP_SIZE 6 + +static int ericsson_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + struct hci_request rq; + ericsson_write_bd_addr_cp cp; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ERICSSON_WRITE_BD_ADDR; + rq.cparam = &cp; + rq.clen = ERICSSON_WRITE_BD_ADDR_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} + +#if 0 +#define OCF_ERICSSON_STORE_IN_FLASH 0x0022 +typedef struct { + uint8_t user_id; + uint8_t flash_length; + uint8_t flash_data[253]; +} __attribute__ ((packed)) ericsson_store_in_flash_cp; +#define ERICSSON_STORE_IN_FLASH_CP_SIZE 255 + +static int ericsson_store_in_flash(int dd, uint8_t user_id, uint8_t flash_length, uint8_t *flash_data) +{ + struct hci_request rq; + ericsson_store_in_flash_cp cp; + + memset(&cp, 0, sizeof(cp)); + cp.user_id = user_id; + cp.flash_length = flash_length; + if (flash_length > 0) + memcpy(cp.flash_data, flash_data, flash_length); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ERICSSON_STORE_IN_FLASH; + rq.cparam = &cp; + rq.clen = ERICSSON_STORE_IN_FLASH_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} +#endif + +#define OCF_ZEEVO_WRITE_BD_ADDR 0x0001 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) zeevo_write_bd_addr_cp; +#define ZEEVO_WRITE_BD_ADDR_CP_SIZE 6 + +static int zeevo_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + struct hci_request rq; + zeevo_write_bd_addr_cp cp; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ZEEVO_WRITE_BD_ADDR; + rq.cparam = &cp; + rq.clen = ZEEVO_WRITE_BD_ADDR_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} + +static struct { + uint16_t compid; + int (*func)(int dd, bdaddr_t *bdaddr); +} vendor[] = { + { 0, ericsson_write_bd_addr }, + { 18, zeevo_write_bd_addr }, + { 65535, NULL }, +}; + +static void usage(void) +{ + printf("bdaddr - Utility for changing the Bluetooth device address\n\n"); + printf("Usage:\n" + "\tbdaddr [-i ] [new bdaddr]\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0} +}; + +int main(int argc, char *argv[]) +{ + struct hci_dev_info di; + struct hci_version ver; + bdaddr_t bdaddr; + char addr[18]; + int i, dd, opt, dev = 0; + + bacpy(&bdaddr, BDADDR_ANY); + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + exit(1); + } + + di.dev_id = dev; + if (ioctl(dd, HCIGETDEVINFO, (void *) &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + printf("Manufacturer: %s (%d)\n", + bt_compidtostr(ver.manufacturer), ver.manufacturer); + + ba2str(&di.bdaddr, addr); + printf("Device address: %s\n", addr); + + if (argc < 1) { + hci_close_dev(dd); + exit(0); + } + + str2ba(argv[0], &bdaddr); + if (!bacmp(&bdaddr, BDADDR_ANY)) { + hci_close_dev(dd); + exit(0); + } + + for (i = 0; vendor[i].compid != 65535; i++) + if (ver.manufacturer == vendor[i].compid) { + ba2str(&bdaddr, addr); + printf("New BD address: %s\n\n", addr); + + if (vendor[i].func(dd, &bdaddr) < 0) { + fprintf(stderr, "Can't write new address"); + hci_close_dev(dd); + exit(1); + } + + printf("Address changed - Reset device now\n"); + + //ioctl(dd, HCIDEVRESET, dev); + //ioctl(dd, HCIDEVDOWN, dev); + //ioctl(dd, HCIDEVUP, dev); + + hci_close_dev(dd); + exit(0); + } + + hci_close_dev(dd); + + printf("\n"); + fprintf(stderr, "Unsupported manufacturer\n"); + + exit(1); +} -- cgit From f0e34fdbb90a899cca2ae6b1d75549d2050f9855 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 18:46:46 +0000 Subject: Add Sitecom CN-504 Bluetooth PCMCIA card --- pcmcia/bluetooth.conf | 4 ++++ tools/hciattach.c | 17 ++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 6a93d6ff..9f3edc61 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -58,6 +58,10 @@ card "Zoom Bluetooth Card" version "PCMCIA", "Bluetooth Card" bind "serial_cs" class "bluetooth" +card "Sitecom CN-504 Card" + version "PCMCIA", "Bluetooth Card" + bind "serial_cs" class "bluetooth" + card "Nokia Bluetooth Card" version "Nokia Mobile Phones", "DTL-1" diff --git a/tools/hciattach.c b/tools/hciattach.c index ac94c41e..e730ab7d 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,21 +33,18 @@ #endif #include -#include +#include +#include #include +#include #include #include -#include #include -#include -#include #include -#include - +#include +#include #include #include -#include -#include #include #include @@ -845,6 +842,8 @@ struct uart_t uart[] = { /* Zoom Bluetooth PCMCIA Card */ { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + /* Sitecom CN-504 PCMCIA Card */ + { "sitecom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, { NULL, 0 } }; -- cgit From 14be8b04824df3f5a9bd7b713646a9120e2b2454 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Jan 2005 21:42:38 +0000 Subject: More cleanups --- test/l2test.c | 106 +++++++++++++++++++++++++++------------------------------- test/rctest.c | 59 ++++++++++++++------------------ 2 files changed, 75 insertions(+), 90 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index fccea39b..e9a7d50d 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,21 +33,13 @@ #endif #include -#include -#include -#include -#include -#include #include #include +#include +#include +#include #include #include -#include - -#include -#include -#include -#include #include #include @@ -55,7 +47,7 @@ #include #include -#define NIBBLE_TO_ASCII(c) ((c) < 0x0a ? (c) + 0x30 : (c) + 0x57) +#define NIBBLE_TO_ASCII(c) ((c) < 0x0a ? (c) + 0x30 : (c) + 0x57) /* Test modes */ enum { @@ -121,7 +113,7 @@ static char *ltoh(unsigned long c, char* s) c1 = c & 0x0f; *(s++) = NIBBLE_TO_ASCII (c1); *s = 0; - return (s); + return s; } static char *ctoh(char c, char* s) @@ -133,7 +125,7 @@ static char *ctoh(char c, char* s) c1 = c & 0x0f; *(s++) = NIBBLE_TO_ASCII (c1); *s = 0; - return (s); + return s; } static void hexdump(char *s, unsigned long l) @@ -180,7 +172,7 @@ static int do_connect(char *svr) int s, opt; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); return -1; } @@ -188,7 +180,7 @@ static int do_connect(char *svr) loc_addr.l2_family = AF_BLUETOOTH; bacpy(&loc_addr.l2_bdaddr, &bdaddr); if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -196,7 +188,7 @@ static int do_connect(char *svr) memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", strerror(errno), errno); return -1; } @@ -204,7 +196,7 @@ static int do_connect(char *svr) opts.omtu = omtu; opts.imtu = imtu; if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", strerror(errno), errno); return -1; } @@ -212,7 +204,7 @@ static int do_connect(char *svr) if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { - syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", strerror(errno), errno); return -1; } @@ -221,19 +213,19 @@ static int do_connect(char *svr) /* Set link mode */ opt = 0; if (reliable) - opt |= L2CAP_LM_RELIABLE; + opt |= L2CAP_LM_RELIABLE; if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); exit(1); } memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.l2_family = AF_BLUETOOTH; - baswap(&rem_addr.l2_bdaddr, strtoba(svr)); + str2ba(svr, &rem_addr.l2_bdaddr); rem_addr.l2_psm = htobs(psm); if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0 ) { - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); close(s); return -1; } @@ -241,7 +233,7 @@ static int do_connect(char *svr) memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); close(s); return -1; } @@ -249,7 +241,7 @@ static int do_connect(char *svr) memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); if (getsockopt(s, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP connection information. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", strerror(errno), errno); close(s); return -1; } @@ -269,15 +261,15 @@ static void do_listen(void (*handler)(int sk)) char ba[18]; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); exit(1); } loc_addr.l2_family = AF_BLUETOOTH; bacpy(&loc_addr.l2_bdaddr, &bdaddr); - loc_addr.l2_psm = htobs(psm); + loc_addr.l2_psm = htobs(psm); if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -295,21 +287,21 @@ static void do_listen(void (*handler)(int sk)) opt |= L2CAP_LM_SECURE; if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); exit(1); } /* Get default options */ opt = sizeof(opts); if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", strerror(errno), errno); exit(1); } /* Set new options */ opts.imtu = imtu; if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", strerror(errno), errno); exit(1); } @@ -319,7 +311,7 @@ static void do_listen(void (*handler)(int sk)) } if (listen(s, 10)) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -328,10 +320,10 @@ static void do_listen(void (*handler)(int sk)) while(1) { opt = sizeof(rem_addr); if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR,"Accept failed: %s (%d)", strerror(errno), errno); exit(1); } - if( fork() ) { + if (fork()) { /* Parent */ close(s1); continue; @@ -342,7 +334,7 @@ static void do_listen(void (*handler)(int sk)) opt = sizeof(opts); if (getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP options. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); exit(1); } @@ -354,7 +346,7 @@ static void do_listen(void (*handler)(int sk)) if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { - syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", strerror(errno), errno); exit(1); } @@ -362,7 +354,7 @@ static void do_listen(void (*handler)(int sk)) handler(s1); - syslog(LOG_INFO, "Disconnect. %m"); + syslog(LOG_INFO, "Disconnect: %m"); exit(0); } } @@ -378,7 +370,7 @@ static void dump_mode(int s) FD_ZERO(&rset); FD_SET(s, &rset); - + if (select(s + 1, &rset, NULL, NULL, NULL) < 0) return; @@ -392,7 +384,7 @@ static void dump_mode(int s) syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); optl = sizeof(opt); if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)\n", strerror(errno), errno); return; } @@ -420,12 +412,12 @@ static void recv_mode(int s) seq = 0; while (1) { - gettimeofday(&tv_beg,NULL); + gettimeofday(&tv_beg, NULL); total = 0; while (total < data_size) { uint32_t sq; uint16_t l; - int i,r; + int i, r; if ((r = recv(s, buf, data_size, 0)) <= 0) { if (r < 0) { @@ -433,8 +425,8 @@ static void recv_mode(int s) syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); optl = sizeof(opt); if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s(%d)\n", - strerror(errno), errno); + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)\n", + strerror(errno), errno); return; } continue; @@ -447,7 +439,7 @@ static void recv_mode(int s) } /* Check sequence */ - sq = btohl(*(uint32_t *)buf); + sq = btohl(*(uint32_t *) buf); if (seq != sq) { syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); seq = sq; @@ -455,25 +447,25 @@ static void recv_mode(int s) seq++; /* Check length */ - l = btohs(*(uint16_t *)(buf+4)); + l = btohs(*(uint16_t *) (buf + 4)); if (r != l) { syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); continue; } /* Verify data */ - for (i=6; i < r; i++) { + for (i = 6; i < r; i++) { if (buf[i] != 0x7f) syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); } total += r; } - gettimeofday(&tv_end,NULL); + gettimeofday(&tv_end, NULL); - timersub(&tv_end,&tv_beg,&tv_diff); + timersub(&tv_end, &tv_beg, &tv_diff); - syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s", total, tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); } } @@ -485,24 +477,24 @@ static void send_mode(int s) syslog(LOG_INFO, "Sending ..."); - for(i = 6; i < data_size; i++) + for (i = 6; i < data_size; i++) buf[i] = 0x7f; seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { *(uint32_t *) buf = htobl(seq); - *(uint16_t *)(buf+4) = htobs(data_size); + *(uint16_t *) (buf + 4) = htobs(data_size); seq++; if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } } syslog(LOG_INFO, "Closing channel ..."); if (shutdown(s, SHUT_RDWR) < 0) - syslog(LOG_INFO, "Close failed. %m."); + syslog(LOG_INFO, "Close failed: %m"); else syslog(LOG_INFO, "Done"); } @@ -514,17 +506,17 @@ static void senddump_mode(int s) syslog(LOG_INFO, "Sending ..."); - for(i = 6; i < data_size; i++) + for (i = 6; i < data_size; i++) buf[i] = 0x7f; seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { *(uint32_t *) buf = htobl(seq); - *(uint16_t *)(buf+4) = htobs(data_size); + *(uint16_t *) (buf + 4) = htobs(data_size); seq++; if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } } diff --git a/test/rctest.c b/test/rctest.c index 041e36b3..d3995335 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -32,20 +32,13 @@ #endif #include -#include -#include -#include -#include +#include +#include #include +#include #include -#include -#include #include - -#include -#include -#include -#include +#include #include #include @@ -94,7 +87,7 @@ static int do_connect(char *svr) int s, opt; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); return -1; } @@ -102,7 +95,7 @@ static int do_connect(char *svr) if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { - syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", strerror(errno), errno); return -1; } @@ -112,7 +105,7 @@ static int do_connect(char *svr) loc_addr.rc_family = AF_BLUETOOTH; bacpy(&loc_addr.rc_bdaddr, &bdaddr); if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -121,7 +114,7 @@ static int do_connect(char *svr) str2ba(svr, &rem_addr.rc_bdaddr); rem_addr.rc_channel = channel; if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0) { - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); close(s); return -1; } @@ -129,7 +122,7 @@ static int do_connect(char *svr) memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); if (getsockopt(s, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get RFCOMM connection information. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", strerror(errno), errno); close(s); //return -1; } @@ -148,7 +141,7 @@ static void do_listen(void (*handler)(int sk)) char ba[18]; if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -156,7 +149,7 @@ static void do_listen(void (*handler)(int sk)) bacpy(&loc_addr.rc_bdaddr, &bdaddr); loc_addr.rc_channel = channel; if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -172,12 +165,12 @@ static void do_listen(void (*handler)(int sk)) opt |= RFCOMM_LM_SECURE; if (setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set RFCOMM link mode. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", strerror(errno), errno); exit(1); } if (listen(s, 10)) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -186,7 +179,7 @@ static void do_listen(void (*handler)(int sk)) while(1) { opt = sizeof(rem_addr); if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR,"Accept failed: %s (%d)", strerror(errno), errno); exit(1); } if (fork()) { @@ -205,7 +198,7 @@ static void do_listen(void (*handler)(int sk)) if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { - syslog(LOG_ERR, "Can't enable SO_LINGER. %s(%d)", + syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", strerror(errno), errno); exit(1); } @@ -213,7 +206,7 @@ static void do_listen(void (*handler)(int sk)) handler(s1); - syslog(LOG_INFO, "Disconnect"); + syslog(LOG_INFO, "Disconnect: %m"); exit(0); } } @@ -246,13 +239,13 @@ static void recv_mode(int s) if ((r = recv(s, buf, data_size, 0)) <= 0) { if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", + syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); return; } #if 0 /* Check sequence */ - sq = btohl(*(uint32_t *)buf); + sq = btohl(*(uint32_t *) buf); if (seq != sq) { syslog(LOG_INFO, "seq missmatch: %d -> %d", seq, sq); seq = sq; @@ -260,14 +253,14 @@ static void recv_mode(int s) seq++; /* Check length */ - l = btohs(*(uint16_t *)(buf+4)); + l = btohs(*(uint16_t *) (buf + 4)); if (r != l) { syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); continue; } /* Verify data */ - for (i=6; i < r; i++) { + for (i = 6; i < r; i++) { if (buf[i] != 0x7f) syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); } @@ -290,24 +283,24 @@ static void send_mode(int s) syslog(LOG_INFO,"Sending ..."); - for(i=6; i < data_size; i++) - buf[i]=0x7f; + for (i = 6; i < data_size; i++) + buf[i] = 0x7f; seq = 0; while ((num_frames == -1) || (num_frames-- > 0)) { *(uint32_t *) buf = htobl(seq); - *(uint16_t *)(buf+4) = htobs(data_size); + *(uint16_t *) (buf + 4) = htobs(data_size); seq++; if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } } syslog(LOG_INFO, "Closing channel ..."); if (shutdown(s, SHUT_RDWR) < 0) - syslog(LOG_INFO, "Close failed. %m."); + syslog(LOG_INFO, "Close failed: %m"); else syslog(LOG_INFO, "Done"); } -- cgit From 0197e2d62cac9323387d52b5711d3c564303d949 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 Jan 2005 20:26:52 +0000 Subject: Whitespace cleanups --- test/scotest.c | 102 ++++++++++++++++++++++++++------------------------------- 1 file changed, 47 insertions(+), 55 deletions(-) diff --git a/test/scotest.c b/test/scotest.c index eddd79af..583310a0 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -32,20 +32,13 @@ #endif #include -#include -#include -#include -#include +#include +#include #include +#include #include -#include -#include #include - -#include -#include -#include -#include +#include #include #include @@ -78,31 +71,31 @@ static int do_connect(char *svr) struct sco_conninfo conn; int s, opt; - if( (s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0 ) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); return -1; } memset(&loc_addr, 0, sizeof(loc_addr)); loc_addr.sco_family = AF_BLUETOOTH; - loc_addr.sco_bdaddr = bdaddr; - if( bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0 ) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + bacpy(&loc_addr.sco_bdaddr, &bdaddr); + if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); exit(1); } memset(&rem_addr, 0, sizeof(rem_addr)); rem_addr.sco_family = AF_BLUETOOTH; - baswap(&rem_addr.sco_bdaddr, strtoba(svr)); - if( connect(s, (struct sockaddr *)&rem_addr, sizeof(rem_addr)) < 0 ){ - syslog(LOG_ERR, "Can't connect. %s(%d)", strerror(errno), errno); + str2ba(svr, &rem_addr.sco_bdaddr); + if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0) { + syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); return -1; } memset(&conn, 0, sizeof(conn)); opt = sizeof(conn); if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get SCO connection information. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)", strerror(errno), errno); close(s); return -1; } @@ -118,22 +111,22 @@ static void do_listen(void (*handler)(int sk)) { struct sockaddr_sco loc_addr, rem_addr; int s, s1, opt; - bdaddr_t ba; + char ba[18]; if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { - syslog(LOG_ERR, "Can't create socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); exit(1); } loc_addr.sco_family = AF_BLUETOOTH; loc_addr.sco_bdaddr = bdaddr; if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); exit(1); } if (listen(s, 10)) { - syslog(LOG_ERR,"Can not listen on the socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", strerror(errno), errno); exit(1); } @@ -141,8 +134,8 @@ static void do_listen(void (*handler)(int sk)) while (1) { opt = sizeof(rem_addr); - if ((s1 = accept(s, (struct sockaddr *)&rem_addr, &opt)) < 0) { - syslog(LOG_ERR,"Accept failed. %s(%d)", strerror(errno), errno); + if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { + syslog(LOG_ERR,"Accept failed: %s (%d)", strerror(errno), errno); exit(1); } if (fork()) { @@ -154,12 +147,12 @@ static void do_listen(void (*handler)(int sk)) close(s); - baswap(&ba, &rem_addr.sco_bdaddr); - syslog(LOG_INFO, "Connect from %s\n", batostr(&ba)); + ba2str(&rem_addr.sco_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s", ba); handler(s1); - syslog(LOG_INFO, "Disconnect\n"); + syslog(LOG_INFO, "Disconnect"); exit(0); } } @@ -183,25 +176,25 @@ static void recv_mode(int s) seq = 0; while (1) { - gettimeofday(&tv_beg,NULL); + gettimeofday(&tv_beg, NULL); total = 0; while (total < data_size) { int r; if ((r = recv(s, buf, data_size, 0)) <= 0) { if (r < 0) - syslog(LOG_ERR, "Read failed. %s(%d)", + syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); return; } total += r; } - gettimeofday(&tv_end,NULL); + gettimeofday(&tv_end, NULL); - timersub(&tv_end,&tv_beg,&tv_diff); + timersub(&tv_end, &tv_beg, &tv_diff); - syslog(LOG_INFO,"%ld bytes in %.2fm speed %.2f kb",total, - tv2fl(tv_diff) / 60.0, - (float)( total / tv2fl(tv_diff) ) / 1024.0 ); + syslog(LOG_INFO,"%ld bytes in %.2fm speed %.2f kb", total, + tv2fl(tv_diff) / 60.0, + (float)( total / tv2fl(tv_diff) ) / 1024.0 ); } } @@ -212,33 +205,32 @@ static void send_mode(char *svr) int s, i, opt; if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Can't connect to the server: %s (%d)", + strerror(errno), errno); exit(1); } opt = sizeof(so); if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { - syslog(LOG_ERR, "Can't get SCO options. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Can't get SCO options: %s (%d)", + strerror(errno), errno); exit(1); } - syslog(LOG_INFO,"Sending ..."); for (i = 6; i < so.mtu; i++) - buf[i]=0x7f; + buf[i] = 0x7f; seq = 0; while (1) { - *(uint32_t *)buf = htobl(seq); - *(uint16_t *)(buf+4) = htobs(data_size); + *(uint32_t *) buf = htobl(seq); + *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - + if (send(s, buf, so.mtu, 0) <= 0) { - syslog(LOG_ERR, "Send failed. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Send failed: %s (%d)", + strerror(errno), errno); exit(1); } usleep(1); @@ -250,7 +242,8 @@ static void reconnect_mode(char *svr) while (1) { int s; if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't connect to the server: %s (%d)", + strerror(errno), errno); exit(1); } close(s); @@ -269,7 +262,8 @@ static void multy_connect_mode(char *svr) /* Child */ if ((s = do_connect(svr)) < 0) { - syslog(LOG_ERR, "Can't connect to the server. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't connect to the server: %s (%d)", + strerror(errno), errno); } close(s); exit(0); @@ -291,9 +285,6 @@ static void usage(void) "\t-s send (client)\n"); } -extern int optind,opterr,optopt; -extern char *optarg; - int main(int argc ,char *argv[]) { struct sigaction sa; @@ -304,7 +295,7 @@ int main(int argc ,char *argv[]) case 'r': mode = RECV; break; - + case 's': mode = SEND; break; @@ -331,7 +322,7 @@ int main(int argc ,char *argv[]) } } - if (!(argc - optind) && (mode!=RECV && mode !=DUMP)) { + if (!(argc - optind) && (mode != RECV && mode != DUMP)) { usage(); exit(1); } @@ -369,6 +360,7 @@ int main(int argc ,char *argv[]) multy_connect_mode(argv[optind]); break; } + syslog(LOG_INFO, "Exit"); closelog(); -- cgit From 818f37527b66b1bd8c177759a8c7710882030093 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 20:21:51 +0000 Subject: Use library functions for RSSI and link quality --- tools/hcitool.c | 48 +++++++----------------------------------------- 1 file changed, 7 insertions(+), 41 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 99262f41..ffa98536 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -815,10 +815,8 @@ static char *rssi_help = static void cmd_rssi(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_rssi_rp rp; bdaddr_t bdaddr; - uint16_t handle; + int8_t rssi; int opt, dd; for_each_opt(opt, rssi_options, NULL) { @@ -863,27 +861,12 @@ static void cmd_rssi(int dev_id, int argc, char **argv) exit(1); } - handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = READ_RSSI_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_rssi(dd, htobs(cr->conn_info->handle), &rssi, 1000) < 0) { perror("Read RSSI failed"); exit(1); } - if (rp.status) { - printf("Read RSSI returned (error) status 0x%2.2X\n", - rp.status); - exit(1); - } - printf("RSSI return value: %d\n", rp.rssi); + printf("RSSI return value: %d\n", rssi); close(dd); free(cr); @@ -903,10 +886,8 @@ static char *lq_help = static void cmd_lq(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - get_link_quality_rp rp; bdaddr_t bdaddr; - uint16_t handle; + uint8_t lq; int opt, dd; for_each_opt(opt, lq_options, NULL) { @@ -951,27 +932,12 @@ static void cmd_lq(int dev_id, int argc, char **argv) exit(1); } - handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_GET_LINK_QUALITY; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = GET_LINK_QUALITY_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { - perror("HCI get_link_quality request failed"); + if (hci_read_link_quality(dd, htobs(cr->conn_info->handle), &lq, 1000) < 0) { + perror("HCI read_link_quality request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI get_link_quality cmd failed (0x%2.2X)\n", - rp.status); - exit(1); - } - printf("Link quality: %d\n", rp.link_quality); + printf("Link quality: %d\n", lq); close(dd); free(cr); -- cgit From 1b71ff969ad17bd4e1265b6cc1d06ca38afc6c27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:48:24 +0000 Subject: Use library function for link supervision timeout --- tools/hcitool.c | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index ffa98536..8aef142b 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1211,11 +1211,8 @@ static char *lst_help = static void cmd_lst(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_link_supervision_timeout_rp rp; - write_link_supervision_timeout_cp cp; bdaddr_t bdaddr; - uint16_t handle; + uint16_t timeout; int opt, dd; for_each_opt(opt, lst_options, NULL) { @@ -1260,43 +1257,23 @@ static void cmd_lst(int dev_id, int argc, char **argv) exit(1); } - handle = htobs(cr->conn_info->handle); - if (argc == 1) { - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; - rq.cparam = &handle; - rq.clen = 2; - rq.rparam = &rp; - rq.rlen = READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE; - - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_link_supervision_timeout(dd, htobs(cr->conn_info->handle), &timeout, 1000) < 0) { perror("HCI read_link_supervision_timeout request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI read_link_supervision_timeout failed (0x%2.2X)\n", - rp.status); - exit(1); - } - if (rp.link_sup_to) + timeout = btohs(timeout); + + if (timeout) printf("Link supervision timeout: %u slots (%.2f msec)\n", - rp.link_sup_to, (float)rp.link_sup_to * 0.625); + timeout, (float) timeout * 0.625); else printf("Link supervision timeout never expires\n"); } else { - cp.handle = htobs(cr->conn_info->handle); - cp.link_sup_to = strtol(argv[1], NULL, 10); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; - rq.cparam = &cp; - rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + timeout = btohs(strtol(argv[1], NULL, 10)); - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_write_link_supervision_timeout(dd, htobs(cr->conn_info->handle), timeout, 1000) < 0) { perror("HCI write_link_supervision_timeout request failed"); exit(1); } -- cgit From cbbc9f09bb9b41caa5ee9fa751a80d16d34a4bda Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:58:13 +0000 Subject: Use library function for reading the transmit power level --- tools/hcitool.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 8aef142b..7d965dd6 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -957,10 +957,8 @@ static char *tpl_help = static void cmd_tpl(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; - struct hci_request rq; - read_transmit_power_level_cp cp; - read_transmit_power_level_rp rp; bdaddr_t bdaddr; + uint8_t type, level; int opt, dd; for_each_opt(opt, tpl_options, NULL) { @@ -979,7 +977,7 @@ static void cmd_tpl(int dev_id, int argc, char **argv) } str2ba(argv[0], &bdaddr); - cp.type = (argc > 1) ? atoi(argv[1]) : 0; + type = (argc > 1) ? atoi(argv[1]) : 0; if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); @@ -1005,28 +1003,14 @@ static void cmd_tpl(int dev_id, int argc, char **argv) perror("Get connection info failed"); exit(1); } - cp.handle = htobs(cr->conn_info->handle); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; - rq.cparam = &cp; - rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; - rq.rparam = &rp; - rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; - if (hci_send_req(dd, &rq, 100) < 0) { + if (hci_read_transmit_power_level(dd, htobs(cr->conn_info->handle), type, &level, 1000) < 0) { perror("HCI read transmit power level request failed"); exit(1); } - if (rp.status) { - fprintf(stderr, "HCI read_transmit_power_level cmd failed (0x%2.2X)\n", - rp.status); - exit(1); - } printf("%s transmit power level: %d\n", - (cp.type == 0) ? "Current" : "Maximum", rp.level); + (type == 0) ? "Current" : "Maximum", level); close(dd); free(cr); -- cgit From 76b0ca8e1c813892561ddae4593e024659783068 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 14 Jan 2005 00:14:50 +0000 Subject: Fix security filter definitions --- tools/hcisecfilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index fd296afd..d3c658c8 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -116,7 +116,7 @@ int main(void) memset((void *) ocf_mask, 0, sizeof(ocf_mask)); hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); hci_set_bit(OCF_RESET_FAILED_CONTACT_COUNTER, ocf_mask); - hci_set_bit(OCF_GET_LINK_QUALITY, ocf_mask); + hci_set_bit(OCF_READ_LINK_QUALITY, ocf_mask); hci_set_bit(OCF_READ_RSSI, ocf_mask); printf("OGF_STATUS_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", -- cgit From fde359c64aea7bd0729839c8ad469f7654f4f64d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 14 Jan 2005 00:16:54 +0000 Subject: Update changelog and bump version number --- ChangeLog | 11 +++++++++++ configure.in | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 688c2577..4c331181 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +ver 2.14: + Make use of additional connection information. + Use library function for reading the RSSI. + Use library function for reading the link quality. + Use library function for reading the transmit power level. + Use library functions for the link supervision timeout. + Add tool for changing the device address. + + Note: + This version needs at least bluez-libs-2.14 + ver 2.13: Use file permission 0600 for the link key file. Add support for HID attribute descriptions. diff --git a/configure.in b/configure.in index f7104ca9..1f84efc4 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.13) +AM_INIT_AUTOMAKE(bluez-utils, 2.14) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From 12e3734dea2e9e44d3bd829b35a13cf02dd54668 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 14 Jan 2005 08:32:38 +0000 Subject: Fix garbled name section --- hidd/hidd.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hidd/hidd.1 b/hidd/hidd.1 index 417457eb..b186ac24 100644 --- a/hidd/hidd.1 +++ b/hidd/hidd.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33. .TH HIDD "1" "May 2004" "hidd - Bluetooth HID daemon" "User Commands" .SH NAME -hidd \- manual page for hidd - Bluetooth HID daemon +hidd \- Bluetooth HID daemon .SH DESCRIPTION hidd - Bluetooth HID daemon .SS "Usage:" -- cgit From 9f859424c471dc8e52a1fa3873ab627966d80316 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Jan 2005 04:11:29 +0000 Subject: Update usage information --- test/rctest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/rctest.c b/test/rctest.c index d3995335..b7916a34 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -351,6 +351,7 @@ static void usage(void) "\t[-N num] number of frames to send\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" + "\t[-S] secure connection\n" "\t[-M] become master\n"); } -- cgit From ba53bc4c8888a3dee5214b25a1f8f846ea8b5bc4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Jan 2005 19:44:12 +0000 Subject: Enable the RFCOMM service level security --- dund/dund.1 | 3 +++ dund/main.c | 27 +++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/dund/dund.1 b/dund/dund.1 index 7b4e7cd9..41354774 100644 --- a/dund/dund.1 +++ b/dund/dund.1 @@ -38,6 +38,9 @@ Disable SDP \fB\-\-encrypt\fR \fB\-E\fR Enable encryption .TP +\fB\-\-secure\fR \fB\-S\fR +Secure connection +.TP \fB\-\-master\fR \fB\-M\fR Become the master of a piconet .TP diff --git a/dund/main.c b/dund/main.c index b7d2b356..3eb4eb7f 100644 --- a/dund/main.c +++ b/dund/main.c @@ -71,6 +71,7 @@ static int detach = 1; static int persist; static int use_sdp = 1; static int encrypt; +static int secure; static int master; static int mrouter; static int search_duration = 10; @@ -103,7 +104,7 @@ static int create_connection(char *dst, bdaddr_t *bdaddr, int mrouter); static int do_listen(void) { struct sockaddr_rc sa; - int sk; + int sk, lm; if (mrouter) { if (!cache.valid) @@ -142,6 +143,20 @@ static int do_listen(void) return -1; } + /* Set link mode */ + lm = 0; + if (master) + lm |= RFCOMM_LM_MASTER; + if (encrypt) + lm |= RFCOMM_LM_ENCRYPT; + if (secure) + lm |= RFCOMM_LM_SECURE; + + if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) { + syslog(LOG_ERR, "Failed to set link mode. %s(%d)", strerror(errno), errno); + return -1; + } + listen(sk, 10); while (!terminate) { @@ -376,6 +391,7 @@ static struct option main_lopts[] = { { "nodetach", 0, 0, 'n' }, { "persist", 2, 0, 'p' }, { "encrypt", 0, 0, 'E' }, + { "secure", 0, 0, 'S' }, { "master", 0, 0, 'M' }, { "cache", 0, 0, 'C' }, { "pppd", 1, 0, 'd' }, @@ -384,7 +400,7 @@ static struct option main_lopts[] = { { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:i:lnp::DQ::EMP:C::P:X"; +static char main_sopts[] = "hsc:k:Kr:i:lnp::DQ::ESMP:C::P:X"; static char main_help[] = "Bluetooth LAP (LAN Access over PPP) daemon version " VERSION " \n" @@ -401,6 +417,9 @@ static char main_help[] = "\t--channel -P RFCOMM channel\n" "\t--device -i Source bdaddr\n" "\t--nosdp -D Disable SDP\n" + "\t--encrypt -E Enable encryption\n" + "\t--secure -S Secure connection\n" + "\t--master -M Become the master of a piconet\n" "\t--nodetach -n Do not become a daemon\n" "\t--persist -p[interval] Persist mode\n" "\t--pppd -d Location of the PPP daemon (pppd)\n" @@ -465,6 +484,10 @@ int main(int argc, char **argv) encrypt = 1; break; + case 'S': + secure = 1; + break; + case 'M': master = 1; break; -- cgit From 3524d98e35685875e95daee7fa86a9c2178264a4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Jan 2005 19:46:10 +0000 Subject: Only set link mode when needed --- test/l2test.c | 2 +- test/rctest.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index e9a7d50d..06233d3f 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -286,7 +286,7 @@ static void do_listen(void (*handler)(int sk)) if (secure) opt |= L2CAP_LM_SECURE; - if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + if (opt && setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); exit(1); } diff --git a/test/rctest.c b/test/rctest.c index b7916a34..8298ab07 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -164,7 +164,7 @@ static void do_listen(void (*handler)(int sk)) if (secure) opt |= RFCOMM_LM_SECURE; - if (setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { + if (opt && setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", strerror(errno), errno); exit(1); } -- cgit From a5fcb1982de75e464c1c41a660975c5d8ab4b47b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Jan 2005 18:26:54 +0000 Subject: Adopt data size from the MTU --- test/l2test.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/l2test.c b/test/l2test.c index 06233d3f..859ce079 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -70,7 +70,7 @@ static int imtu = 672; static int omtu = 0; /* Default data size */ -static long data_size = 672; +static long data_size = 0; /* Default addr and psm */ static bdaddr_t bdaddr; @@ -709,6 +709,13 @@ int main(int argc ,char *argv[]) exit(1); } + if (!data_size) { + if (imtu > data_size) + data_size = imtu; + if (omtu > data_size) + data_size = omtu; + } + if (!(buf = malloc(data_size))) { perror("Can't allocate data buffer"); exit(1); -- cgit From d198227a6d76b6fb6bff050e6fda9f2e4ffc4544 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Jan 2005 18:33:49 +0000 Subject: Show connection information --- test/l2test.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index 859ce079..272f40f6 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -257,6 +257,7 @@ static void do_listen(void (*handler)(int sk)) { struct sockaddr_l2 loc_addr, rem_addr; struct l2cap_options opts; + struct l2cap_conninfo conn; int s, s1, opt; char ba[18]; @@ -332,15 +333,26 @@ static void do_listen(void (*handler)(int sk)) close(s); + memset(&opts, 0, sizeof(opts)); opt = sizeof(opts); if (getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); + close(s1); + exit(1); + } + + memset(&conn, 0, sizeof(conn)); + opt = sizeof(conn); + if (getsockopt(s1, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { + syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", strerror(errno), errno); + close(s1); exit(1); } ba2str(&rem_addr.l2_bdaddr, ba); - syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d]\n", - ba, opts.imtu, opts.omtu, opts.flush_to); + syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d, mode %d, handle %d, class 0x%02x%02x%02x]\n", + ba, opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); /* Enable SO_LINGER */ if (linger) { -- cgit From fefb12aae57e186c00a50a87a3725f8657fd95e2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Jan 2005 02:46:59 +0000 Subject: Add command for reading the clock offset --- tools/hcitool.1 | 4 +++ tools/hcitool.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 95 insertions(+), 19 deletions(-) diff --git a/tools/hcitool.1 b/tools/hcitool.1 index c4c69b87..07f41421 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -170,6 +170,10 @@ Enable or disable the encryption for the device with Bluetooth address .BI key " " Change the connection link key for the device with Bluetooth address .IR bdaddr . +.TP +.BI clkoff " " +Read the clock offset for the device with Bluetooth address +.IR bdaddr . .SH AUTHORS Written by Maxim Krasnyansky and Marcel Holtmann .PP diff --git a/tools/hcitool.c b/tools/hcitool.c index 7d965dd6..9f69ed01 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1474,30 +1474,102 @@ static void cmd_key(int dev_id, int argc, char **argv) free(cr); } +/* Read clock offset */ + +static struct option clkoff_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *clkoff_help = + "Usage:\n" + "\tclkoff \n"; + +static void cmd_clkoff(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint16_t offset; + int opt, dd; + + for_each_opt(opt, clkoff_options, NULL) { + switch (opt) { + default: + printf(clkoff_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(clkoff_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + if (hci_read_clock_offset(dd, htobs(cr->conn_info->handle), &offset, 1000) < 0) { + perror("Reading clock offset failed"); + exit(1); + } + + printf("Clock offset: 0x%4.4x\n", btohs(offset)); + + close(dd); + free(cr); +} + static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); char *doc; } command[] = { - { "dev", cmd_dev, "Display local devices" }, - { "inq", cmd_inq, "Inquire remote devices" }, - { "scan", cmd_scan, "Scan for remote devices" }, - { "name", cmd_name, "Get name from remote device" }, - { "info", cmd_info, "Get information from remote device" }, - { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, - { "con", cmd_con, "Display active connections" }, - { "cc", cmd_cc, "Create connection to remote device" }, - { "dc", cmd_dc, "Disconnect from remote device" }, - { "sr", cmd_sr, "Switch master/slave role" }, - { "cpt", cmd_cpt, "Change connection packet type" }, - { "rssi", cmd_rssi, "Display connection RSSI" }, - { "lq", cmd_lq, "Display link quality" }, - { "tpl", cmd_tpl, "Display transmit power level" }, - { "afh", cmd_afh, "Display AFH channel map" }, - { "lst", cmd_lst, "Set/display link supervision timeout" }, - { "auth", cmd_auth, "Request authentication" }, - { "enc", cmd_enc, "Set connection encryption" }, - { "key", cmd_key, "Change connection link key" }, + { "dev", cmd_dev, "Display local devices" }, + { "inq", cmd_inq, "Inquire remote devices" }, + { "scan", cmd_scan, "Scan for remote devices" }, + { "name", cmd_name, "Get name from remote device" }, + { "info", cmd_info, "Get information from remote device" }, + { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, + { "con", cmd_con, "Display active connections" }, + { "cc", cmd_cc, "Create connection to remote device" }, + { "dc", cmd_dc, "Disconnect from remote device" }, + { "sr", cmd_sr, "Switch master/slave role" }, + { "cpt", cmd_cpt, "Change connection packet type" }, + { "rssi", cmd_rssi, "Display connection RSSI" }, + { "lq", cmd_lq, "Display link quality" }, + { "tpl", cmd_tpl, "Display transmit power level" }, + { "afh", cmd_afh, "Display AFH channel map" }, + { "lst", cmd_lst, "Set/display link supervision timeout" }, + { "auth", cmd_auth, "Request authentication" }, + { "enc", cmd_enc, "Set connection encryption" }, + { "key", cmd_key, "Change connection link key" }, + { "clkoff", cmd_clkoff, "Read clock offset" }, { NULL, NULL, 0 } }; -- cgit From 30fa99ad8cc79b6e4cb4620a31510d5a6cd31acd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Jan 2005 21:41:40 +0000 Subject: Add command for reading the clock --- tools/hcitool.1 | 9 +++++++ tools/hcitool.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/tools/hcitool.1 b/tools/hcitool.1 index 07f41421..d863e7d1 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -174,6 +174,15 @@ Change the connection link key for the device with Bluetooth address .BI clkoff " " Read the clock offset for the device with Bluetooth address .IR bdaddr . +.TP +.BI clock " [which clock]" +Read the clock for the device with Bluetooth address +.IR bdaddr . +The clock can be +.BR 0 +for the local clock or +.BR 1 +for the piconet clock (which is default). .SH AUTHORS Written by Maxim Krasnyansky and Marcel Holtmann .PP diff --git a/tools/hcitool.c b/tools/hcitool.c index 9f69ed01..8b7131a0 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1545,6 +1545,84 @@ static void cmd_clkoff(int dev_id, int argc, char **argv) free(cr); } +/* Read clock */ + +static struct option clock_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static char *clock_help = + "Usage:\n" + "\tclock [which clock]\n"; + +static void cmd_clock(int dev_id, int argc, char **argv) +{ + struct hci_conn_info_req *cr; + bdaddr_t bdaddr; + uint8_t which; + uint32_t clock; + uint16_t accuracy; + int opt, dd; + + for_each_opt(opt, clock_options, NULL) { + switch (opt) { + default: + printf(clock_help); + return; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(clock_help); + return; + } + + str2ba(argv[0], &bdaddr); + + if (dev_id < 0) { + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + if (dev_id < 0) { + fprintf(stderr, "Not connected.\n"); + exit(1); + } + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + exit(1); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) + return; + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + exit(1); + } + + which = (argc > 1) ? atoi(argv[1]) : 0x01; + + if (hci_read_clock(dd, htobs(cr->conn_info->handle), which, &clock, &accuracy, 1000) < 0) { + perror("Reading clock failed"); + exit(1); + } + + accuracy = btohs(accuracy); + + printf("Clock: 0x%4.4x\n", btohl(clock)); + printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); + + close(dd); + free(cr); +} + static struct { char *cmd; void (*func)(int dev_id, int argc, char **argv); @@ -1570,6 +1648,7 @@ static struct { { "enc", cmd_enc, "Set connection encryption" }, { "key", cmd_key, "Change connection link key" }, { "clkoff", cmd_clkoff, "Read clock offset" }, + { "clock", cmd_clock, "Read local or remote clock" }, { NULL, NULL, 0 } }; -- cgit From 1798ef015acd1da838f3a265bb0003efe94757ad Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Jan 2005 02:08:01 +0000 Subject: Update for different storage methods --- hcid/Makefile.am | 2 +- hcid/dbus.c | 2 +- hcid/hcid.h | 8 ++++---- hcid/kword.c | 2 +- hcid/kword.h | 2 +- hcid/lexer.l | 2 +- hcid/lib.c | 2 +- hcid/lib.h | 2 +- hcid/main.c | 7 ++----- hcid/parser.y | 2 +- hcid/security.c | 22 ++++++++++++++++++++-- hcid/storage.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 hcid/storage.c diff --git a/hcid/Makefile.am b/hcid/Makefile.am index ac56726e..32b02005 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -18,7 +18,7 @@ dbus_hcid_libs = dbus_hcid_cflags = endif -hcid_SOURCES = main.c security.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) +hcid_SOURCES = main.c security.c storage.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) LIBS = $(dbus_hcid_libs) @BLUEZ_LIBS@ diff --git a/hcid/dbus.c b/hcid/dbus.c index 04e7c757..4d12bf11 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/hcid.h b/hcid/hcid.h index 87875beb..845e3889 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -31,6 +31,7 @@ #include #include +#include #include "glib-ectomy.h" @@ -99,9 +100,6 @@ int read_config(char *file); struct device_opts *alloc_device_opts(char *ref); -gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data); -gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data); - void init_security_data(void); void start_security_manager(int hdev); void stop_security_manager(int hdev); @@ -111,3 +109,5 @@ void toggle_pairing(int enable); void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); gboolean hcid_dbus_init(void); #endif + +int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); diff --git a/hcid/kword.c b/hcid/kword.c index 13adfcc2..895b2410 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/kword.h b/hcid/kword.h index 2f6cae4a..735e119d 100644 --- a/hcid/kword.h +++ b/hcid/kword.h @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/lexer.l b/hcid/lexer.l index 1031ea51..ce34af12 100644 --- a/hcid/lexer.l +++ b/hcid/lexer.l @@ -5,7 +5,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/lib.c b/hcid/lib.c index bbc78950..9b09ca2a 100644 --- a/hcid/lib.c +++ b/hcid/lib.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/lib.h b/hcid/lib.h index 4ff07e66..49ddfb14 100644 --- a/hcid/lib.h +++ b/hcid/lib.h @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/main.c b/hcid/main.c index abd7f14c..95f21656 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -64,9 +64,6 @@ static struct device_list *device_list = NULL; static GMainLoop *event_loop; -gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data); -gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data); - static void usage(void) { printf("hcid - HCI daemon ver %s\n", VERSION); @@ -406,7 +403,7 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si) } } -gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data) +static gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; evt_stack_internal *si; diff --git a/hcid/parser.y b/hcid/parser.y index c5bb80a4..b56bd588 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -5,7 +5,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/security.c b/hcid/security.c index 1cb07da4..eaa791b7 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -380,7 +380,18 @@ reject: return; } -gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) +static void remote_name_information(int dev, bdaddr_t *sba, void *ptr) +{ + evt_remote_name_req_complete *evt = ptr; + bdaddr_t *dba = &evt->bdaddr; + + if (!evt->status) + return; + + write_device_name(sba, dba, evt->name); +} + +static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_dev_info *di = (void *) data; @@ -415,6 +426,12 @@ gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) ioctl(dev, HCIGETDEVINFO, (void *) di); + switch (eh->evt) { + case EVT_REMOTE_NAME_REQ_COMPLETE: + remote_name_information(dev, &di->bdaddr, ptr); + break; + } + if (hci_test_bit(HCI_SECMGR, &di->flags)) return TRUE; @@ -459,6 +476,7 @@ void start_security_manager(int hdev) hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); + hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { syslog(LOG_ERR, "Can't set filter on hci%d. %s(%d)", hdev, strerror(errno), errno); diff --git a/hcid/storage.c b/hcid/storage.c new file mode 100644 index 00000000..cd04b254 --- /dev/null +++ b/hcid/storage.c @@ -0,0 +1,48 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "hcid.h" + +#define DEVPATH "/etc/bluetooth/devices" + +int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) +{ + return -EIO; +} -- cgit From d06620c3403ca50e6d8f9f0cba4e6e8c0486438e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Jan 2005 03:15:10 +0000 Subject: Add the build ids for the sniffer firmwares --- tools/csr.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/tools/csr.c b/tools/csr.c index ca28ef2f..d7bb65ae 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -266,6 +266,47 @@ static struct { { 1734, "HCI 18.3" }, { 1735, "HCI 18.3" }, { 1737, "HCI 18.3" }, + { 195, "Sniff 1 (2001-11-27)" }, + { 220, "Sniff 2 (2002-01-03)" }, + { 269, "Sniff 3 (2002-02-22)" }, + { 270, "Sniff 4 (2002-02-26)" }, + { 284, "Sniff 5 (2002-03-12)" }, + { 292, "Sniff 6 (2002-03-20)" }, + { 305, "Sniff 7 (2002-04-12)" }, + { 306, "Sniff 8 (2002-04-12)" }, + { 343, "Sniff 9 (2002-05-02)" }, + { 346, "Sniff 10 (2002-05-03)" }, + { 355, "Sniff 11 (2002-05-16)" }, + { 256, "Sniff 11 (2002-05-16)" }, + { 390, "Sniff 12 (2002-06-26)" }, + { 450, "Sniff 13 (2002-08-16)" }, + { 451, "Sniff 13 (2002-08-16)" }, + { 533, "Sniff 14 (2002-10-11)" }, + { 580, "Sniff 15 (2002-11-14)" }, + { 623, "Sniff 16 (2002-12-12)" }, + { 678, "Sniff 17 (2003-01-29)" }, + { 847, "Sniff 18 (2003-04-17)" }, + { 876, "Sniff 19 (2003-06-10)" }, + { 997, "Sniff 22 (2003-09-05)" }, + { 1027, "Sniff 23 (2003-10-03)" }, + { 1029, "Sniff 24 (2003-10-03)" }, + { 1112, "Sniff 25 (2003-12-03)" }, + { 1113, "Sniff 25 (2003-12-03)" }, + { 1133, "Sniff 26 (2003-12-18)" }, + { 1134, "Sniff 26 (2003-12-18)" }, + { 1223, "Sniff 27 (2004-03-08)" }, + { 1224, "Sniff 27 (2004-03-08)" }, + { 1319, "Sniff 31 (2004-04-22)" }, + { 1320, "Sniff 31 (2004-04-22)" }, + { 1427, "Sniff 34 (2004-06-16)" }, + { 1508, "Sniff 35 (2004-07-19)" }, + { 1509, "Sniff 35 (2004-07-19)" }, + { 1587, "Sniff 36 (2004-08-18)" }, + { 1588, "Sniff 36 (2004-08-18)" }, + { 1641, "Sniff 37 (2004-09-16)" }, + { 1642, "Sniff 37 (2004-09-16)" }, + { 1699, "Sniff 38 (2004-10-07)" }, + { 1700, "Sniff 38 (2004-10-07)" }, { 0, } }; -- cgit From 0dab40dad416805e31cb5312956880609dc21443 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 17:47:33 +0000 Subject: Cleanup the syslog messages --- hcid/main.c | 74 +++++++++++++++++++++++++++++++-------------------------- hcid/parser.y | 2 +- hcid/security.c | 65 +++++++++++++++++++++++++------------------------- 3 files changed, 74 insertions(+), 67 deletions(-) diff --git a/hcid/main.c b/hcid/main.c index 95f21656..21da79ad 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -84,8 +84,8 @@ struct device_opts *alloc_device_opts(char *ref) device = malloc(sizeof(struct device_list)); if (!device) { - syslog(LOG_INFO, "Can't allocate devlist opts buffer. %s(%d)", - strerror(errno), errno); + syslog(LOG_INFO, "Can't allocate devlist opts buffer: %s (%d)", + strerror(errno), errno); exit(1); } @@ -168,8 +168,8 @@ static void configure_device(int hdev) case 0: break; case -1: - syslog(LOG_ERR, "Fork failed. Can't init device hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Fork failed. Can't init device hci%d: %s (%d)", + hdev, strerror(errno), errno); default: return; } @@ -177,7 +177,8 @@ static void configure_device(int hdev) set_title("hci%d config", hdev); if ((s = hci_open_dev(hdev)) < 0) { - syslog(LOG_ERR, "Can't open device hci%d. %s(%d)\n", hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't open device hci%d: %s (%d)", + hdev, strerror(errno), errno); exit(1); } @@ -187,8 +188,8 @@ static void configure_device(int hdev) /* Set scan mode */ dr.dev_opt = device_opts->scan; if (ioctl(s, HCISETSCAN, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set scan mode on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't set scan mode on hci%d: %s (%d)", + hdev, strerror(errno), errno); } /* Set authentication */ @@ -198,8 +199,8 @@ static void configure_device(int hdev) dr.dev_opt = AUTH_DISABLED; if (ioctl(s, HCISETAUTH, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set auth on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't set auth on hci%d: %s (%d)", + hdev, strerror(errno), errno); } /* Set encryption */ @@ -209,8 +210,8 @@ static void configure_device(int hdev) dr.dev_opt = ENCRYPT_DISABLED; if (ioctl(s, HCISETENCRYPT, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set encrypt on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't set encrypt on hci%d: %s (%d)", + hdev, strerror(errno), errno); } /* Set device class */ @@ -247,8 +248,8 @@ static void init_device(int hdev) case 0: break; case -1: - syslog(LOG_ERR, "Fork failed. Can't init device hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Fork failed. Can't init device hci%d: %s (%d)", + hdev, strerror(errno), errno); default: return; } @@ -256,15 +257,15 @@ static void init_device(int hdev) set_title("hci%d init", hdev); if ((s = hci_open_dev(hdev)) < 0) { - syslog(LOG_ERR, "Can't open device hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't open device hci%d: %s (%d)", + hdev, strerror(errno), errno); exit(1); } /* Start HCI device */ if (ioctl(s, HCIDEVUP, hdev) < 0 && errno != EALREADY) { - syslog(LOG_ERR, "Can't init device hci%d. %s(%d)\n", hdev, - strerror(errno), errno); + syslog(LOG_ERR, "Can't init device hci%d: %s (%d)", + hdev, strerror(errno), errno); exit(1); } @@ -275,8 +276,8 @@ static void init_device(int hdev) if (device_opts->pkt_type) { dr.dev_opt = device_opts->pkt_type; if (ioctl(s, HCISETPTYPE, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set packet type on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't set packet type on hci%d: %s (%d)", + hdev, strerror(errno), errno); } } @@ -284,8 +285,8 @@ static void init_device(int hdev) if (device_opts->link_mode) { dr.dev_opt = device_opts->link_mode; if (ioctl(s, HCISETLINKMODE, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set link mode on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't set link mode on hci%d: %s (%d)", + hdev, strerror(errno), errno); } } @@ -293,8 +294,8 @@ static void init_device(int hdev) if (device_opts->link_policy) { dr.dev_opt = device_opts->link_policy; if (ioctl(s, HCISETLINKPOL, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set link policy on hci%d. %s(%d)\n", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't set link policy on hci%d: %s (%d)", + hdev, strerror(errno), errno); } } @@ -308,16 +309,16 @@ static void init_all_devices(int ctl) int i; if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)))) { - syslog(LOG_INFO, "Can't allocate devlist buffer. %s(%d)", - strerror(errno), errno); + syslog(LOG_INFO, "Can't allocate devlist buffer: %s (%d)", + strerror(errno), errno); exit(1); } dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; if (ioctl(ctl, HCIGETDEVLIST, (void *) dl) < 0) { - syslog(LOG_INFO, "Can't get device list. %s(%d)", - strerror(errno), errno); + syslog(LOG_INFO, "Can't get device list: %s (%d)", + strerror(errno), errno); exit(1); } @@ -325,10 +326,12 @@ static void init_all_devices(int ctl) if (hcid.auto_init) init_device(dr->dev_id); - if (hcid.auto_init && hci_test_bit(HCI_UP, &dr->dev_opt)) + if (hcid.auto_init && hci_test_bit(HCI_UP, &dr->dev_opt) && + !hci_test_bit(HCI_RAW, &dr->dev_opt)) configure_device(dr->dev_id); - if (hcid.security && hci_test_bit(HCI_UP, &dr->dev_opt)) + if (hcid.security && hci_test_bit(HCI_UP, &dr->dev_opt) && + !hci_test_bit(HCI_RAW, &dr->dev_opt)) start_security_manager(dr->dev_id); } @@ -418,8 +421,8 @@ static gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer dat if (err == G_IO_ERROR_AGAIN) return TRUE; - syslog(LOG_ERR, "Read from control socket failed. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Read from control socket failed: %s (%d)", + strerror(errno), errno); g_main_quit(event_loop); return FALSE; } @@ -527,7 +530,8 @@ int main(int argc, char *argv[], char *env[]) /* Create and bind HCI socket */ if ((hcid.sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { - syslog(LOG_ERR, "Can't open HCI socket. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", + strerror(errno), errno); exit(1); } @@ -536,14 +540,16 @@ int main(int argc, char *argv[], char *env[]) hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_STACK_INTERNAL, &flt); if (setsockopt(hcid.sock, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { - syslog(LOG_ERR, "Can't set filter. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't set filter: %s (%d)", + strerror(errno), errno); exit(1); } addr.hci_family = AF_BLUETOOTH; addr.hci_dev = HCI_DEV_NONE; if (bind(hcid.sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - syslog(LOG_ERR, "Can't bind HCI socket. %s(%d)\n", strerror(errno), errno); + syslog(LOG_ERR, "Can't bind HCI socket: %s (%d)", + strerror(errno), errno); exit(1); } diff --git a/hcid/parser.y b/hcid/parser.y index b56bd588..136a8571 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -294,7 +294,7 @@ bool: K_YES { $$ = 1; } | K_NO { $$ = 0; }; int yyerror(char *s) { - syslog(LOG_ERR, "%s line %d\n", s, lineno); + syslog(LOG_ERR, "%s line %d", s, lineno); return 0; } diff --git a/hcid/security.c b/hcid/security.c index eaa791b7..8cc25036 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -84,8 +84,8 @@ static struct link_key *__get_link_key(int f, bdaddr_t *sba, bdaddr_t *dba) while ((r = read_n(f, &k, sizeof(k)))) { if (r < 0) { - syslog(LOG_ERR, "Link key database read failed. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Link key database read failed: %s (%d)", + strerror(errno), errno); break; } @@ -106,8 +106,8 @@ static struct link_key *get_link_key(bdaddr_t *sba, bdaddr_t *dba) if (f >= 0) key = __get_link_key(f, sba, dba); else if (errno != ENOENT) - syslog(LOG_ERR, "Link key database open failed. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Link key database open failed: %s (%d)", + strerror(errno), errno); close(f); return key; } @@ -118,7 +118,7 @@ static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) char sa[18], da[18]; ba2str(sba, sa); ba2str(dba, da); - syslog(LOG_INFO, "link_key_request (sba=%s, dba=%s)\n", sa, da); + syslog(LOG_INFO, "link_key_request (sba=%s, dba=%s)", sa, da); if (key) { /* Link key found */ @@ -142,8 +142,8 @@ static void save_link_key(struct link_key *key) f = open(hcid.key_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (f < 0) { - syslog(LOG_ERR, "Link key database open failed. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Link key database open failed: %s (%d)", + strerror(errno), errno); return; } @@ -159,14 +159,14 @@ static void save_link_key(struct link_key *key) err = fcntl(f, F_SETFL, O_APPEND); if (err < 0) { - syslog(LOG_ERR, "Link key database seek failed. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Link key database seek failed: %s (%d)", + strerror(errno), errno); goto failed; } if (write_n(f, key, sizeof(*key)) < 0) { - syslog(LOG_ERR, "Link key database write failed. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Link key database write failed: %s (%d)", + strerror(errno), errno); } ba2str(&key->sba, sa); ba2str(&key->dba, da); @@ -184,7 +184,7 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) char sa[18]; ba2str(sba, sa); - syslog(LOG_INFO, "link_key_notify (sba=%s)\n", sa); + syslog(LOG_INFO, "link_key_notify (sba=%s)", sa); memcpy(key.key, evt->link_key, 16); bacpy(&key.sba, sba); @@ -204,8 +204,8 @@ int read_pin_code(void) int len; if (!(f = fopen(hcid.pin_file, "r"))) { - syslog(LOG_ERR, "Can't open PIN file %s. %s(%d)", - hcid.pin_file, strerror(errno), errno); + syslog(LOG_ERR, "Can't open PIN file %s: %s (%d)", + hcid.pin_file, strerror(errno), errno); return -1; } @@ -215,8 +215,8 @@ int read_pin_code(void) memcpy(hcid.pin_code, buf, len); hcid.pin_len = len; } else { - syslog(LOG_ERR, "Can't read PIN file %s. %s(%d)", - hcid.pin_file, strerror(errno), errno); + syslog(LOG_ERR, "Can't read PIN file %s: %s (%d)", + hcid.pin_file, strerror(errno), errno); len = -1; } fclose(f); @@ -245,15 +245,15 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) case 0: break; case -1: - syslog(LOG_ERR, "Can't fork PIN helper. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Can't fork PIN helper: %s (%d)", + strerror(errno), errno); default: return; } if (access(hcid.pin_helper, R_OK | X_OK)) { - syslog(LOG_ERR, "Can't exec PIN helper %s. %s(%d)", - hcid.pin_helper, strerror(errno), errno); + syslog(LOG_ERR, "Can't exec PIN helper %s: %s (%d)", + hcid.pin_helper, strerror(errno), errno); goto reject; } @@ -273,7 +273,8 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) pipe = popen(str, "r"); if (!pipe) { - syslog(LOG_ERR, "Can't exec PIN helper. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't exec PIN helper: %s (%d)", + strerror(errno), errno); goto reject; } @@ -326,7 +327,7 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) char sa[18], da[18]; ba2str(sba, sa); ba2str(dba, da); - syslog(LOG_INFO, "pin_code_request (sba=%s, dba=%s)\n", sa, da); + syslog(LOG_INFO, "pin_code_request (sba=%s, dba=%s)", sa, da); cr = malloc(sizeof(*cr) + sizeof(*ci)); if (!cr) @@ -335,8 +336,8 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) bacpy(&cr->bdaddr, dba); cr->type = ACL_LINK; if (ioctl(dev, HCIGETCONNINFO, (unsigned long) cr) < 0) { - syslog(LOG_ERR, "Can't get conn info %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Can't get conn info: %s (%d)", + strerror(errno), errno); goto reject; } ci = cr->conn_info; @@ -465,8 +466,8 @@ void start_security_manager(int hdev) syslog(LOG_INFO, "Starting security manager %d", hdev); if ((dev = hci_open_dev(hdev)) < 0) { - syslog(LOG_ERR, "Can't open device hci%d. %s(%d)", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't open device hci%d: %s (%d)", + hdev, strerror(errno), errno); return; } @@ -478,24 +479,24 @@ void start_security_manager(int hdev) hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { - syslog(LOG_ERR, "Can't set filter on hci%d. %s(%d)", - hdev, strerror(errno), errno); + syslog(LOG_ERR, "Can't set filter on hci%d: %s (%d)", + hdev, strerror(errno), errno); close(dev); return; } di = malloc(sizeof(*di)); if (!di) { - syslog(LOG_ERR, "Can't allocate device info buffer. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Can't allocate device info buffer: %s (%d)", + strerror(errno), errno); close(dev); return; } di->dev_id = hdev; if (ioctl(dev, HCIGETDEVINFO, (void *)di)) { - syslog(LOG_ERR, "Can't get device info. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Can't get device info: %s (%d)", + strerror(errno), errno); close(dev); return; } -- cgit From 7715ad4f56e82c9eb4cf75020b1f3039d06ce115 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 18:16:11 +0000 Subject: Cleanup the socket handling --- test/l2test.c | 295 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 177 insertions(+), 118 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index 272f40f6..ac831d97 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -76,8 +76,8 @@ static long data_size = 0; static bdaddr_t bdaddr; static unsigned short psm = 10; -/* Default number of frames to send */ -static int num_frames = -1; // Infinite +/* Default number of frames to send (-1 = infinite) */ +static int num_frames = -1; static int master = 0; static int auth = 0; @@ -166,46 +166,58 @@ static void hexdump(char *s, unsigned long l) static int do_connect(char *svr) { - struct sockaddr_l2 rem_addr, loc_addr; + struct sockaddr_l2 addr; struct l2cap_options opts; struct l2cap_conninfo conn; - int s, opt; + socklen_t optlen; + int sk, opt; - if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); return -1; } - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.l2_family = AF_BLUETOOTH; - bacpy(&loc_addr.l2_bdaddr, &bdaddr); - if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Bind to local address */ + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, &bdaddr); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto error; } /* Get default options */ memset(&opts, 0, sizeof(opts)); - opt = sizeof(opts); - if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", strerror(errno), errno); - return -1; + optlen = sizeof(opts); + + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } /* Set new options */ opts.omtu = omtu; opts.imtu = imtu; - if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", strerror(errno), errno); - return -1; + + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } /* Enable SO_LINGER */ if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; - if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + + if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); return -1; } } @@ -215,63 +227,82 @@ static int do_connect(char *svr) if (reliable) opt |= L2CAP_LM_RELIABLE; - if (setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); - exit(1); + if (setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", + strerror(errno), errno); + goto error; } - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.l2_family = AF_BLUETOOTH; - str2ba(svr, &rem_addr.l2_bdaddr); - rem_addr.l2_psm = htobs(psm); - if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0 ) { - syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); - close(s); - return -1; + /* Connect to remote device */ + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; + str2ba(svr, &addr.l2_bdaddr); + addr.l2_psm = htobs(psm); + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { + syslog(LOG_ERR, "Can't connect: %s (%d)", + strerror(errno), errno); + goto error; } + /* Get current options */ memset(&opts, 0, sizeof(opts)); - opt = sizeof(opts); - if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); - close(s); - return -1; + optlen = sizeof(opts); + + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } + /* Get connection information */ memset(&conn, 0, sizeof(conn)); - opt = sizeof(conn); - if (getsockopt(s, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", strerror(errno), errno); - close(s); - return -1; + optlen = sizeof(conn); + + if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", + strerror(errno), errno); + goto error; } - syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d, mode %d, handle %d, class 0x%02x%02x%02x]", + syslog(LOG_INFO, "Connected [imtu %d, omtu %d, flush_to %d, " + "mode %d, handle %d, class 0x%02x%02x%02x]", opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); - return s; + return sk; + +error: + close(sk); + return -1; } static void do_listen(void (*handler)(int sk)) { - struct sockaddr_l2 loc_addr, rem_addr; + struct sockaddr_l2 addr; struct l2cap_options opts; struct l2cap_conninfo conn; - int s, s1, opt; + socklen_t optlen; + int sk, nsk, opt; char ba[18]; - if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, socktype, BTPROTO_L2CAP); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); exit(1); } - loc_addr.l2_family = AF_BLUETOOTH; - bacpy(&loc_addr.l2_bdaddr, &bdaddr); - loc_addr.l2_psm = htobs(psm); - if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Bind to local address */ + addr.l2_family = AF_BLUETOOTH; + bacpy(&addr.l2_bdaddr, &bdaddr); + addr.l2_psm = htobs(psm); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto error; } /* Set link mode */ @@ -287,138 +318,166 @@ static void do_listen(void (*handler)(int sk)) if (secure) opt |= L2CAP_LM_SECURE; - if (opt && setsockopt(s, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", strerror(errno), errno); - exit(1); + if (opt && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP link mode: %s (%d)", + strerror(errno), errno); + goto error; } /* Get default options */ - opt = sizeof(opts); - if (getsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", strerror(errno), errno); - exit(1); + memset(&opts, 0, sizeof(opts)); + optlen = sizeof(opts); + + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } /* Set new options */ opts.imtu = imtu; - if (setsockopt(s, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) { - syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", strerror(errno), errno); - exit(1); + + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { + syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", + strerror(errno), errno); + goto error; } if (socktype == SOCK_DGRAM) { - handler(s); + handler(sk); return; } - if (listen(s, 10)) { - syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Listen for connections */ + if (listen(sk, 10)) { + syslog(LOG_ERR, "Can not listen on the socket: %s (%d)", + strerror(errno), errno); + goto error; } - syslog(LOG_INFO,"Waiting for connection on psm %d ...", psm); + syslog(LOG_INFO, "Waiting for connection on psm %d ...", psm); while(1) { - opt = sizeof(rem_addr); - if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { - syslog(LOG_ERR,"Accept failed: %s (%d)", strerror(errno), errno); - exit(1); + memset(&addr, 0, sizeof(addr)); + optlen = sizeof(addr); + + nsk = accept(sk, (struct sockaddr *) &addr, &optlen); + if (nsk < 0) { + syslog(LOG_ERR, "Accept failed: %s (%d)", + strerror(errno), errno); + goto error; } if (fork()) { /* Parent */ - close(s1); + close(nsk); continue; } /* Child */ + close(sk); - close(s); - + /* Get current options */ memset(&opts, 0, sizeof(opts)); - opt = sizeof(opts); - if (getsockopt(s1, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", strerror(errno), errno); - close(s1); - exit(1); + optlen = sizeof(opts); + + if (getsockopt(nsk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) { + syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)", + strerror(errno), errno); + close(nsk); + goto error; } + /* Get connection information */ memset(&conn, 0, sizeof(conn)); - opt = sizeof(conn); - if (getsockopt(s1, SOL_L2CAP, L2CAP_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", strerror(errno), errno); - close(s1); - exit(1); + optlen = sizeof(conn); + + if (getsockopt(nsk, SOL_L2CAP, L2CAP_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get L2CAP connection information: %s (%d)", + strerror(errno), errno); + close(nsk); + goto error; } - ba2str(&rem_addr.l2_bdaddr, ba); - syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d, mode %d, handle %d, class 0x%02x%02x%02x]\n", + ba2str(&addr.l2_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d, " + " mode %d, handle %d, class 0x%02x%02x%02x]", ba, opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); /* Enable SO_LINGER */ if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; - if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + + if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", - strerror(errno), errno); - exit(1); + strerror(errno), errno); + close(nsk); + goto error; } } - handler(s1); + handler(nsk); syslog(LOG_INFO, "Disconnect: %m"); exit(0); } + + return; + +error: + close(sk); + exit(1); } -static void dump_mode(int s) +static void dump_mode(int sk) { - int len; - int opt, optl; + socklen_t optlen; + int opt, len; syslog(LOG_INFO, "Receiving ..."); while (1) { fd_set rset; FD_ZERO(&rset); - FD_SET(s, &rset); + FD_SET(sk, &rset); - if (select(s + 1, &rset, NULL, NULL, NULL) < 0) + if (select(sk + 1, &rset, NULL, NULL, NULL) < 0) return; - if (!FD_ISSET(s, &rset)) + if (!FD_ISSET(sk, &rset)) continue; - len = read(s, buf, data_size); + len = read(sk, buf, data_size); if (len <= 0) { if (len < 0) { if (reliable && (errno == ECOMM)) { - syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); - optl = sizeof(opt); - if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)\n", + syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing."); + optlen = sizeof(opt); + if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", strerror(errno), errno); return; } continue; } else { - syslog(LOG_ERR, "Read error: %s(%d)\n", strerror(errno), errno); + syslog(LOG_ERR, "Read error: %s(%d)", + strerror(errno), errno); } } return; } - syslog(LOG_INFO, "Recevied %d bytes\n", len); + syslog(LOG_INFO, "Recevied %d bytes", len); hexdump(buf,len); } } -static void recv_mode(int s) +static void recv_mode(int sk) { struct timeval tv_beg,tv_end,tv_diff; long total; uint32_t seq; - int opt, optl; + socklen_t optlen; + int opt; syslog(LOG_INFO,"Receiving ..."); @@ -431,19 +490,19 @@ static void recv_mode(int s) uint16_t l; int i, r; - if ((r = recv(s, buf, data_size, 0)) <= 0) { + if ((r = recv(sk, buf, data_size, 0)) <= 0) { if (r < 0) { if (reliable && (errno == ECOMM)) { syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); - optl = sizeof(opt); - if (getsockopt(s, SOL_SOCKET, SO_ERROR, &opt, &optl ) < 0) { // Clear error - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)\n", + optlen = sizeof(opt); + if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", strerror(errno), errno); return; } continue; } else { - syslog(LOG_ERR, "Read failed. %s(%d)", + syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); } } @@ -482,7 +541,7 @@ static void recv_mode(int s) } } -static void send_mode(int s) +static void send_mode(int sk) { uint32_t seq; int i; @@ -498,20 +557,20 @@ static void send_mode(int s) *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - if (send(s, buf, data_size, 0) <= 0) { + if (send(sk, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } } syslog(LOG_INFO, "Closing channel ..."); - if (shutdown(s, SHUT_RDWR) < 0) + if (shutdown(sk, SHUT_RDWR) < 0) syslog(LOG_INFO, "Close failed: %m"); else syslog(LOG_INFO, "Done"); } -static void senddump_mode(int s) +static void senddump_mode(int sk) { uint32_t seq; int i; @@ -527,13 +586,13 @@ static void senddump_mode(int s) *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - if (send(s, buf, data_size, 0) <= 0) { + if (send(sk, buf, data_size, 0) <= 0) { syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } } - dump_mode(s); + dump_mode(sk); } static void reconnect_mode(char *svr) -- cgit From 39654da8de5f5d3f9888cb2d4d576993414642ec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 19:59:22 +0000 Subject: More cleanups --- test/l2test.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index ac831d97..82d34efa 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -597,17 +597,19 @@ static void senddump_mode(int sk) static void reconnect_mode(char *svr) { - while(1) { - int s = do_connect(svr); - close(s); + while (1) { + int sk = do_connect(svr); + close(sk); } } static void connect_mode(char *svr) { - int s; - if ((s = do_connect(svr)) < 0) + int sk; + + if ((sk = do_connect(svr)) < 0) exit(1); + sleep(99999999); } -- cgit From 54c95138efbc91165d50ee0e3e1fd906493bf68f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 20:08:11 +0000 Subject: Typo --- test/l2test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/l2test.c b/test/l2test.c index 82d34efa..30d9a2e6 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -399,7 +399,7 @@ static void do_listen(void (*handler)(int sk)) ba2str(&addr.l2_bdaddr, ba); syslog(LOG_INFO, "Connect from %s [imtu %d, omtu %d, flush_to %d, " - " mode %d, handle %d, class 0x%02x%02x%02x]", + "mode %d, handle %d, class 0x%02x%02x%02x]", ba, opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); -- cgit From 917543004017da0f09304844c578b59ca4a1802b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 20:13:19 +0000 Subject: Another bunch of cleanups --- test/l2test.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index 30d9a2e6..70b7b1fa 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -662,10 +662,8 @@ static void usage(void) int main(int argc ,char *argv[]) { - int opt, mode, s, need_addr; struct sigaction sa; - - mode = RECV; need_addr = 0; + int opt, sk, mode = RECV, need_addr = 0; bacpy(&bdaddr, BDADDR_ANY); @@ -807,10 +805,10 @@ int main(int argc ,char *argv[]) break; case CRECV: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - recv_mode(s); + recv_mode(sk); break; case DUMP: @@ -818,10 +816,10 @@ int main(int argc ,char *argv[]) break; case SEND: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - send_mode(s); + send_mode(sk); break; case LSEND: @@ -841,10 +839,10 @@ int main(int argc ,char *argv[]) break; case SENDDUMP: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - senddump_mode(s); + senddump_mode(sk); break; case LSENDDUMP: -- cgit From d23d9a99e234590f4edf5bafcf57b3e99c57c354 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 20:14:08 +0000 Subject: Cleanup the socket handling --- test/rctest.c | 214 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 133 insertions(+), 81 deletions(-) diff --git a/test/rctest.c b/test/rctest.c index 8298ab07..06ccf6ec 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -82,75 +82,99 @@ static float tv2fl(struct timeval tv) static int do_connect(char *svr) { - struct sockaddr_rc rem_addr, loc_addr; + struct sockaddr_rc addr; struct rfcomm_conninfo conn; - int s, opt; + socklen_t optlen; + int sk; - if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); return -1; } /* Enable SO_LINGER */ if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; - if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + + if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", - strerror(errno), errno); - return -1; + strerror(errno), errno); + goto error; } } - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.rc_family = AF_BLUETOOTH; - bacpy(&loc_addr.rc_bdaddr, &bdaddr); - if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Bind to local address */ + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, &bdaddr); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto error; } - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.rc_family = AF_BLUETOOTH; - str2ba(svr, &rem_addr.rc_bdaddr); - rem_addr.rc_channel = channel; - if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0) { - syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); - close(s); - return -1; + /* Connect to remote device */ + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + str2ba(svr, &addr.rc_bdaddr); + addr.rc_channel = channel; + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't connect: %s (%d)", + strerror(errno), errno); + goto error; } + /* Get connection information */ memset(&conn, 0, sizeof(conn)); - opt = sizeof(conn); - if (getsockopt(s, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", strerror(errno), errno); - close(s); - //return -1; + optlen = sizeof(conn); + + if (getsockopt(sk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", + strerror(errno), errno); + //goto error; } syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]", conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); - return s; + return sk; + +error: + close(sk); + return -1; } static void do_listen(void (*handler)(int sk)) { - struct sockaddr_rc loc_addr, rem_addr; - int s, s1, opt; + struct sockaddr_rc addr; + struct rfcomm_conninfo conn; + socklen_t optlen; + int sk, nsk, opt; char ba[18]; - if ((s = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, socktype, BTPROTO_RFCOMM); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); exit(1); } - loc_addr.rc_family = AF_BLUETOOTH; - bacpy(&loc_addr.rc_bdaddr, &bdaddr); - loc_addr.rc_channel = channel; - if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Bind to local address */ + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, &bdaddr); + addr.rc_channel = channel; + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto error; } /* Set link mode */ @@ -164,63 +188,90 @@ static void do_listen(void (*handler)(int sk)) if (secure) opt |= RFCOMM_LM_SECURE; - if (opt && setsockopt(s, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { - syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", strerror(errno), errno); - exit(1); + if (opt && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &opt, sizeof(opt)) < 0) { + syslog(LOG_ERR, "Can't set RFCOMM link mode: %s (%d)", + strerror(errno), errno); + goto error; } - if (listen(s, 10)) { - syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Listen for connections */ + if (listen(sk, 10)) { + syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", + strerror(errno), errno); + goto error; } syslog(LOG_INFO,"Waiting for connection on channel %d ...", channel); while(1) { - opt = sizeof(rem_addr); - if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { - syslog(LOG_ERR,"Accept failed: %s (%d)", strerror(errno), errno); - exit(1); + memset(&addr, 0, sizeof(addr)); + optlen = sizeof(addr); + + nsk = accept(sk, (struct sockaddr *) &addr, &optlen); + if (nsk < 0) { + syslog(LOG_ERR,"Accept failed: %s (%d)", + strerror(errno), errno); + goto error; } if (fork()) { /* Parent */ - close(s1); + close(nsk); continue; } /* Child */ + close(sk); + + /* Get connection information */ + memset(&conn, 0, sizeof(conn)); + optlen = sizeof(conn); - close(s); + if (getsockopt(nsk, SOL_RFCOMM, RFCOMM_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get RFCOMM connection information: %s (%d)", + strerror(errno), errno); + //close(nsk); + //goto error; + } - ba2str(&rem_addr.rc_bdaddr, ba); - syslog(LOG_INFO, "Connect from %s", ba); + ba2str(&addr.rc_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s [handle %d, class 0x%02x%02x%02x]", + ba, conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); /* Enable SO_LINGER */ if (linger) { struct linger l = { .l_onoff = 1, .l_linger = linger }; - if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { + + if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { syslog(LOG_ERR, "Can't enable SO_LINGER: %s (%d)", - strerror(errno), errno); - exit(1); + strerror(errno), errno); + close(nsk); + goto error; } } - handler(s1); + handler(nsk); syslog(LOG_INFO, "Disconnect: %m"); exit(0); } + + return; + +error: + close(sk); + exit(1); } -static void dump_mode(int s) +static void dump_mode(int sk) { int len; syslog(LOG_INFO, "Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) + while ((len = read(sk, buf, data_size)) > 0) syslog(LOG_INFO, "Recevied %d bytes", len); } -static void recv_mode(int s) +static void recv_mode(int sk) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -237,7 +288,7 @@ static void recv_mode(int s) //uint16_t l; int r; - if ((r = recv(s, buf, data_size, 0)) <= 0) { + if ((r = recv(sk, buf, data_size, 0)) <= 0) { if (r < 0) syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); @@ -271,12 +322,12 @@ static void recv_mode(int s) timersub(&tv_end,&tv_beg,&tv_diff); - syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s",total, + syslog(LOG_INFO,"%ld bytes in %.2f sec, %.2f kB/s", total, tv2fl(tv_diff), (float)(total / tv2fl(tv_diff) ) / 1024.0); } } -static void send_mode(int s) +static void send_mode(int sk) { uint32_t seq; int i; @@ -292,14 +343,15 @@ static void send_mode(int s) *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - if (send(s, buf, data_size, 0) <= 0) { - syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); + if (send(sk, buf, data_size, 0) <= 0) { + syslog(LOG_ERR, "Send failed: %s (%d)", + strerror(errno), errno); exit(1); } } syslog(LOG_INFO, "Closing channel ..."); - if (shutdown(s, SHUT_RDWR) < 0) + if (shutdown(sk, SHUT_RDWR) < 0) syslog(LOG_INFO, "Close failed: %m"); else syslog(LOG_INFO, "Done"); @@ -308,24 +360,26 @@ static void send_mode(int s) static void reconnect_mode(char *svr) { while(1) { - int s = do_connect(svr); - close(s); + int sk = do_connect(svr); + close(sk); } } static void multi_connect_mode(char *svr) { while (1) { - int i, s; + int i, sk; + for (i = 0; i < 10; i++) { if (fork()) continue; /* Child */ - s = do_connect(svr); + sk = do_connect(svr); usleep(500); - close(s); + close(sk); exit(0); } + sleep(2); } } @@ -357,10 +411,8 @@ static void usage(void) int main(int argc ,char *argv[]) { - int opt, mode, s, need_addr; struct sigaction sa; - - mode = RECV; need_addr = 0; + int opt, sk, mode = RECV, need_addr = 0; bacpy(&bdaddr, BDADDR_ANY); @@ -471,10 +523,10 @@ int main(int argc ,char *argv[]) break; case CRECV: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - recv_mode(s); + recv_mode(sk); break; case DUMP: @@ -482,10 +534,10 @@ int main(int argc ,char *argv[]) break; case SEND: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - send_mode(s); + send_mode(sk); break; case LSEND: @@ -501,10 +553,10 @@ int main(int argc ,char *argv[]) break; case CONNECT: - s = do_connect(argv[optind]); - if (s < 0) + sk = do_connect(argv[optind]); + if (sk < 0) exit(1); - dump_mode(s); + dump_mode(sk); break; } -- cgit From 96bbfb2039b98046fe72c88dc6f737a66ed65fde Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 20:26:31 +0000 Subject: Cleanup the socket handling --- test/attest.c | 55 +++++++++-------- test/scotest.c | 183 +++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 150 insertions(+), 88 deletions(-) diff --git a/test/attest.c b/test/attest.c index f4732cb6..cd0e93ca 100644 --- a/test/attest.c +++ b/test/attest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2001-2004 Marcel Holtmann + * Copyright (C) 2001-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,11 +33,10 @@ #include #include #include +#include #include #include -#include #include -#include #include #include @@ -85,11 +84,13 @@ static int at_command(int fd, char *cmd, int to) static int open_device(char *device) { - int fd; struct termios ti; + int fd; - if ((fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) { - printf("Can't open serial port. %s (%d)\n", strerror(errno), errno); + fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (fd < 0) { + fprintf(stderr, "Can't open serial port: %s (%d)\n", + strerror(errno), errno); return -1; } @@ -104,34 +105,40 @@ static int open_device(char *device) static int open_socket(bdaddr_t *bdaddr, uint8_t channel) { - struct sockaddr_rc remote_addr, local_addr; - int s; + struct sockaddr_rc addr; + int sk; - if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) { - printf("Can't create socket. %s (%d)\n", strerror(errno), errno); + sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (sk < 0) { + fprintf(stderr, "Can't create socket: %s (%d)\n", + strerror(errno), errno); return -1; } - memset(&local_addr, 0, sizeof(local_addr)); - local_addr.rc_family = AF_BLUETOOTH; - bacpy(&local_addr.rc_bdaddr, BDADDR_ANY); - if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { - printf("Can't bind socket. %s (%d)\n", strerror(errno), errno); - close(s); + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, BDADDR_ANY); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + fprintf(stderr, "Can't bind socket: %s (%d)\n", + strerror(errno), errno); + close(sk); return -1; } - memset(&remote_addr, 0, sizeof(remote_addr)); - remote_addr.rc_family = AF_BLUETOOTH; - bacpy(&remote_addr.rc_bdaddr, bdaddr); - remote_addr.rc_channel = channel; - if (connect(s, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) < 0) { - printf("Can't connect. %s (%d)\n", strerror(errno), errno); - close(s); + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, bdaddr); + addr.rc_channel = channel; + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + fprintf(stderr, "Can't connect: %s (%d)\n", + strerror(errno), errno); + close(sk); return -1; } - return s; + return sk; } static void usage(void) diff --git a/test/scotest.c b/test/scotest.c index 583310a0..59278460 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -67,106 +67,155 @@ static float tv2fl(struct timeval tv) static int do_connect(char *svr) { - struct sockaddr_sco rem_addr, loc_addr; + struct sockaddr_sco addr; struct sco_conninfo conn; - int s, opt; + socklen_t optlen; + int sk; - if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); return -1; } - memset(&loc_addr, 0, sizeof(loc_addr)); - loc_addr.sco_family = AF_BLUETOOTH; - bacpy(&loc_addr.sco_bdaddr, &bdaddr); - if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Bind to local address */ + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_bdaddr, &bdaddr); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto error; } - memset(&rem_addr, 0, sizeof(rem_addr)); - rem_addr.sco_family = AF_BLUETOOTH; - str2ba(svr, &rem_addr.sco_bdaddr); - if (connect(s, (struct sockaddr *) &rem_addr, sizeof(rem_addr)) < 0) { - syslog(LOG_ERR, "Can't connect: %s (%d)", strerror(errno), errno); - return -1; + /* Connect to remote device */ + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + str2ba(svr, &addr.sco_bdaddr); + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't connect: %s (%d)", + strerror(errno), errno); + goto error; } + /* Get connection information */ memset(&conn, 0, sizeof(conn)); - opt = sizeof(conn); - if (getsockopt(s, SOL_SCO, SCO_CONNINFO, &conn, &opt) < 0) { - syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)", strerror(errno), errno); - close(s); - return -1; + optlen = sizeof(conn); + + if (getsockopt(sk, SOL_SCO, SCO_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)", + strerror(errno), errno); + goto error; } syslog(LOG_INFO, "Connected [handle %d, class 0x%02x%02x%02x]", conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); - return s; + return sk; + +error: + close(sk); + return -1; } static void do_listen(void (*handler)(int sk)) { - struct sockaddr_sco loc_addr, rem_addr; - int s, s1, opt; + struct sockaddr_sco addr; + struct sco_conninfo conn; + socklen_t optlen; + int sk, nsk; char ba[18]; - if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { - syslog(LOG_ERR, "Can't create socket: %s (%d)", strerror(errno), errno); + /* Create socket */ + sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); + if (sk < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); exit(1); } - loc_addr.sco_family = AF_BLUETOOTH; - loc_addr.sco_bdaddr = bdaddr; - if (bind(s, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { - syslog(LOG_ERR, "Can't bind socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Bind to local address */ + memset(&addr, 0, sizeof(addr)); + addr.sco_family = AF_BLUETOOTH; + bacpy(&addr.sco_bdaddr, &bdaddr); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto error; } - if (listen(s, 10)) { - syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", strerror(errno), errno); - exit(1); + /* Listen for connections */ + if (listen(sk, 10)) { + syslog(LOG_ERR,"Can not listen on the socket: %s (%d)", + strerror(errno), errno); + goto error; } syslog(LOG_INFO,"Waiting for connection ..."); while (1) { - opt = sizeof(rem_addr); - if ((s1 = accept(s, (struct sockaddr *) &rem_addr, &opt)) < 0) { - syslog(LOG_ERR,"Accept failed: %s (%d)", strerror(errno), errno); - exit(1); + memset(&addr, 0, sizeof(addr)); + optlen = sizeof(addr); + + nsk = accept(sk, (struct sockaddr *) &addr, &optlen); + if (nsk < 0) { + syslog(LOG_ERR,"Accept failed: %s (%d)", + strerror(errno), errno); + goto error; } if (fork()) { /* Parent */ - close(s1); + close(nsk); continue; } /* Child */ + close(sk); + + /* Get connection information */ + memset(&conn, 0, sizeof(conn)); + optlen = sizeof(conn); - close(s); + if (getsockopt(nsk, SOL_SCO, SCO_CONNINFO, &conn, &optlen) < 0) { + syslog(LOG_ERR, "Can't get SCO connection information: %s (%d)", + strerror(errno), errno); + close(nsk); + goto error; + } - ba2str(&rem_addr.sco_bdaddr, ba); - syslog(LOG_INFO, "Connect from %s", ba); + ba2str(&addr.sco_bdaddr, ba); + syslog(LOG_INFO, "Connect from %s [handle %d, class 0x%02x%02x%02x]", + ba, conn.hci_handle, + conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); - handler(s1); + handler(nsk); syslog(LOG_INFO, "Disconnect"); exit(0); } + + return; + +error: + close(sk); + exit(1); } -static void dump_mode(int s) +static void dump_mode(int sk) { int len; syslog(LOG_INFO,"Receiving ..."); - while ((len = read(s, buf, data_size)) > 0) - syslog(LOG_INFO, "Recevied %d bytes\n", len); + while ((len = read(sk, buf, data_size)) > 0) + syslog(LOG_INFO, "Recevied %d bytes", len); } -static void recv_mode(int s) +static void recv_mode(int sk) { struct timeval tv_beg,tv_end,tv_diff; long total; @@ -180,7 +229,7 @@ static void recv_mode(int s) total = 0; while (total < data_size) { int r; - if ((r = recv(s, buf, data_size, 0)) <= 0) { + if ((r = recv(sk, buf, data_size, 0)) <= 0) { if (r < 0) syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); @@ -202,20 +251,20 @@ static void send_mode(char *svr) { struct sco_options so; uint32_t seq; - int s, i, opt; + int sk, i, opt; - if ((s = do_connect(svr)) < 0) { + if ((sk = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); exit(1); } opt = sizeof(so); - if (getsockopt(s, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { + if (getsockopt(sk, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { syslog(LOG_ERR, "Can't get SCO options: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); exit(1); - } + } syslog(LOG_INFO,"Sending ..."); @@ -228,11 +277,12 @@ static void send_mode(char *svr) *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - if (send(s, buf, so.mtu, 0) <= 0) { + if (send(sk, buf, so.mtu, 0) <= 0) { syslog(LOG_ERR, "Send failed: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); exit(1); } + usleep(1); } } @@ -240,13 +290,15 @@ static void send_mode(char *svr) static void reconnect_mode(char *svr) { while (1) { - int s; - if ((s = do_connect(svr)) < 0) { + int sk; + + if ((sk = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); exit(1); } - close(s); + + close(sk); sleep(5); } @@ -255,19 +307,22 @@ static void reconnect_mode(char *svr) static void multy_connect_mode(char *svr) { while (1) { - int i, s; + int i, sk; + for (i = 0; i < 10; i++){ if (fork()) continue; /* Child */ - if ((s = do_connect(svr)) < 0) { + sk = do_connect(svr); + if (sk < 0) { syslog(LOG_ERR, "Can't connect to the server: %s (%d)", - strerror(errno), errno); + strerror(errno), errno); } - close(s); + close(sk); exit(0); } + sleep(19); } } -- cgit From c15fb910d23b698af183312eb05f1d1038e88259 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Jan 2005 17:05:35 +0000 Subject: Don't set inquiry scan or page scan on raw devices --- tools/hciconfig.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 1a8f35d8..d24faf73 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -248,6 +248,10 @@ static void cmd_up(int ctl, int hdev, char *opt) hdev, strerror(errno), errno); exit(1); } + if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0) + return; + if (hci_test_bit(HCI_RAW, &di.flags)) + return; cmd_scan(ctl, hdev, "piscan"); } -- cgit From 747bc0b292ee5655ef2695c4e8e18f55c4037567 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Jan 2005 17:06:35 +0000 Subject: Don't configure raw devices --- hcid/main.c | 22 ++++++++++++++++++---- hcid/security.c | 3 +++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/hcid/main.c b/hcid/main.c index 21da79ad..c2c6381c 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -161,6 +161,7 @@ static void configure_device(int hdev) { struct device_opts *device_opts; struct hci_dev_req dr; + struct hci_dev_info di; int s; /* Do configuration in the separate process */ @@ -182,6 +183,13 @@ static void configure_device(int hdev) exit(1); } + di.dev_id = hdev; + if (ioctl(s, HCIGETDEVINFO, (void *) &di) < 0) + exit(1); + + if (hci_test_bit(HCI_RAW, &di.flags)) + exit(0); + dr.dev_id = hdev; device_opts = get_device_opts(s, hdev); @@ -241,6 +249,7 @@ static void init_device(int hdev) { struct device_opts *device_opts; struct hci_dev_req dr; + struct hci_dev_info di; int s; /* Do initialization in the separate process */ @@ -269,6 +278,13 @@ static void init_device(int hdev) exit(1); } + di.dev_id = hdev; + if (ioctl(s, HCIGETDEVINFO, (void *) &di) < 0) + exit(1); + + if (hci_test_bit(HCI_RAW, &di.flags)) + exit(0); + dr.dev_id = hdev; device_opts = get_device_opts(s, hdev); @@ -326,12 +342,10 @@ static void init_all_devices(int ctl) if (hcid.auto_init) init_device(dr->dev_id); - if (hcid.auto_init && hci_test_bit(HCI_UP, &dr->dev_opt) && - !hci_test_bit(HCI_RAW, &dr->dev_opt)) + if (hcid.auto_init && hci_test_bit(HCI_UP, &dr->dev_opt)) configure_device(dr->dev_id); - if (hcid.security && hci_test_bit(HCI_UP, &dr->dev_opt) && - !hci_test_bit(HCI_RAW, &dr->dev_opt)) + if (hcid.security && hci_test_bit(HCI_UP, &dr->dev_opt)) start_security_manager(dr->dev_id); } diff --git a/hcid/security.c b/hcid/security.c index 8cc25036..f0bf12bd 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -427,6 +427,9 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer ioctl(dev, HCIGETDEVINFO, (void *) di); + if (hci_test_bit(HCI_RAW, &di->flags)) + return TRUE; + switch (eh->evt) { case EVT_REMOTE_NAME_REQ_COMPLETE: remote_name_information(dev, &di->bdaddr, ptr); -- cgit From 5481f007aa304a6f5f4531a243e146f9075dc17f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Jan 2005 17:24:40 +0000 Subject: Don't forget to include getopt.h --- test/l2test.c | 1 + test/rctest.c | 1 + test/scotest.c | 1 + 3 files changed, 3 insertions(+) diff --git a/test/l2test.c b/test/l2test.c index 70b7b1fa..5857b13d 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/test/rctest.c b/test/rctest.c index 06ccf6ec..8c76859f 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/test/scotest.c b/test/scotest.c index 59278460..6447eab4 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include -- cgit From 7a23b4eeb7f7fe7b2becd884fa1e9c5db5deedea Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Jan 2005 17:43:16 +0000 Subject: Support data sizes bigger than 2048 bytes --- tools/l2ping.c | 123 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 51 deletions(-) diff --git a/tools/l2ping.c b/tools/l2ping.c index 45ddbe92..0e7a4be1 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -33,37 +33,32 @@ #endif #include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include - #include +#include +#include #include /* Defaults */ -bdaddr_t bdaddr; -int size = 20; -int ident = 200; -int delay = 1; -int count = -1; -int timeout = 10; +static bdaddr_t bdaddr; +static int size = 20; +static int ident = 200; +static int delay = 1; +static int count = -1; +static int timeout = 10; /* Stats */ -int sent_pkt = 0, recv_pkt = 0; +static int sent_pkt = 0; +static int recv_pkt = 0; static float tv2fl(struct timeval tv) { @@ -79,53 +74,77 @@ static void stat(int sig) static void ping(char *svr) { - struct sockaddr_l2 addr; struct sigaction sa; - char buf[2048]; + struct sockaddr_l2 addr; + socklen_t optlen; + unsigned char *buf; char str[18]; - int s, i, opt, lost; + int i, sk, lost; uint8_t id; memset(&sa, 0, sizeof(sa)); sa.sa_handler = stat; sigaction(SIGINT, &sa, NULL); - if ((s = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP)) < 0) { - perror("Can't create socket."); + buf = malloc(L2CAP_CMD_HDR_SIZE + size); + if (!buf) { + perror("Can't allocate buffer"); + exit(1); + } + + /* Create socket */ + sk = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); + if (sk < 0) { + perror("Can't create socket"); + free(buf); exit(1); } + /* Bind to local address */ memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; - addr.l2_bdaddr = bdaddr; - if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Can't bind socket."); + bacpy(&addr.l2_bdaddr, &bdaddr); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Can't bind socket"); + close(sk); + free(buf); exit(1); } + /* Connect to remote device */ + memset(&addr, 0, sizeof(addr)); + addr.l2_family = AF_BLUETOOTH; str2ba(svr, &addr.l2_bdaddr); - if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - perror("Can't connect."); + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("Can't connect"); + close(sk); + free(buf); exit(1); } /* Get local address */ - opt = sizeof(addr); - if (getsockname(s, (struct sockaddr *)&addr, &opt) < 0) { - perror("Can't get local address."); + memset(&addr, 0, sizeof(addr)); + optlen = sizeof(addr); + + if (getsockname(sk, (struct sockaddr *) &addr, &optlen) < 0) { + perror("Can't get local address"); + close(sk); + free(buf); exit(1); } - ba2str(&addr.l2_bdaddr, str); + ba2str(&addr.l2_bdaddr, str); printf("Ping: %s from %s (data size %d) ...\n", svr, str, size); /* Initialize buffer */ - for (i = L2CAP_CMD_HDR_SIZE; i < sizeof(buf); i++) - buf[i] = (i % 40) + 'A'; + for (i = 0; i < size; i++) + buf[L2CAP_CMD_HDR_SIZE + i] = (i % 40) + 'A'; id = ident; - while( count == -1 || count-- > 0 ){ + while (count == -1 || count-- > 0) { struct timeval tv_send, tv_recv, tv_diff; l2cap_cmd_hdr *cmd = (l2cap_cmd_hdr *) buf; @@ -137,7 +156,7 @@ static void ping(char *svr) gettimeofday(&tv_send, NULL); /* Send Echo Request */ - if (send(s, buf, size + L2CAP_CMD_HDR_SIZE, 0) <= 0) { + if (send(sk, buf, L2CAP_CMD_HDR_SIZE + size, 0) <= 0) { perror("Send failed"); exit(1); } @@ -146,9 +165,11 @@ static void ping(char *svr) lost = 0; while (1) { struct pollfd pf[1]; - register int err; + int err; + + pf[0].fd = sk; + pf[0].events = POLLIN; - pf[0].fd = s; pf[0].events = POLLIN; if ((err = poll(pf, 1, timeout * 1000)) < 0) { perror("Poll failed"); exit(1); @@ -159,7 +180,7 @@ static void ping(char *svr) break; } - if ((err = recv(s, buf, sizeof(buf), 0)) < 0) { + if ((err = recv(sk, buf, L2CAP_CMD_HDR_SIZE + size, 0)) < 0) { perror("Recv failed"); exit(1); } @@ -210,21 +231,25 @@ static void usage(void) { printf("l2ping - L2CAP ping\n"); printf("Usage:\n"); - printf("\tl2ping [-S source addr] [-s size] [-c count] [-t timeout] [-f] \n"); + printf("\tl2ping [-i device] [-s size] [-c count] [-t timeout] [-f] \n"); } -extern int optind,opterr,optopt; -extern char *optarg; - int main(int argc, char *argv[]) { - register int opt; + int opt; /* Default options */ bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"s:c:t:fS:")) != EOF) { + while ((opt=getopt(argc,argv,"i:s:c:t:f")) != EOF) { switch(opt) { + case 'i': + if (!strncasecmp(optarg, "hci", 3)) + hci_devba(atoi(optarg + 3), &bdaddr); + else + str2ba(optarg, &bdaddr); + break; + case 'f': /* Kinda flood ping */ delay = 0; @@ -242,10 +267,6 @@ int main(int argc, char *argv[]) size = atoi(optarg); break; - case 'S': - str2ba(optarg, &bdaddr); - break; - default: usage(); exit(1); -- cgit From 9befc0b1ec7820535a750bcf41259efd0f6ad3b2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Jan 2005 03:12:14 +0000 Subject: Update the copyright year --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 7fc90362..9a0dcbf2 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated Copyright (C) 2002-2003 Maxim Krasnyansky -Copyright (C) 2002-2004 Marcel Holtmann +Copyright (C) 2002-2005 Marcel Holtmann Bluetooth utilities -- cgit From 591e892366b6ccf2d7c765c47741794cb8a30e42 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 30 Jan 2005 20:38:04 +0000 Subject: Add Billionton PCMCIA card --- tools/hciattach.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index e730ab7d..33ecdf03 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -796,54 +796,58 @@ static int st(int fd, struct uart_t *u, struct termios *ti) } struct uart_t uart[] = { - { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, - { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, - { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, digi }, - { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, texas}, + { "any", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "ericsson", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson }, + { "digi", 0x0000, 0x0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, digi }, + { "texas", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, texas }, - { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "bcsp", 0x0000, 0x0000, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* Xircom PCMCIA cards: Credit Card Adapter and Real Port Adapter */ - { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "xircom", 0x0105, 0x080a, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* CSR Casira serial adapter or BrainBoxes serial dongle (BL642) */ - { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + { "csr", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, /* BrainBoxes PCMCIA card (BL620) */ - { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 115200, 460800, FLOW_CTL, csr }, + { "bboxes", 0x0160, 0x0002, HCI_UART_H4, 115200, 460800, FLOW_CTL, csr }, /* Silicon Wave kits */ - { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, swave }, + { "swave", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, swave }, /* ST Microelectronics minikits based on STLC2410/STLC2415 */ - { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, st }, + { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, st }, /* Sphinx Electronics PICO Card */ - { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "picocard", 0x025e, 0x1000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* Inventel BlueBird Module */ - { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, + { "inventel", 0x0000, 0x0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL }, /* COM One Platinium Bluetooth PC Card */ - { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "comone", 0xffff, 0x0101, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* TDK Bluetooth PC Card and IBM Bluetooth PC Card II */ - { "tdk", 0x0105, 0x4254, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "tdk", 0x0105, 0x4254, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* Socket Bluetooth CF Card (Rev G) */ - { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, bcsp }, + { "socket", 0x0104, 0x0096, HCI_UART_BCSP, 230400, 230400, 0, bcsp }, /* 3Com Bluetooth Card (Version 3.0) */ - { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, + { "3com", 0x0101, 0x0041, HCI_UART_H4, 115200, 115200, FLOW_CTL, csr }, /* AmbiCom BT2000C Bluetooth PC/CF Card */ - { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, csr }, + { "bt2000c", 0x022d, 0x2000, HCI_UART_H4, 57600, 460800, FLOW_CTL, csr }, /* Zoom Bluetooth PCMCIA Card */ - { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "zoom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, /* Sitecom CN-504 PCMCIA Card */ - { "sitecom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { "sitecom", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + + /* Billionton PCBTC1 PCMCIA Card */ + { "billionton", 0x0279, 0x950b, HCI_UART_BCSP, 115200, 115200, 0, bcsp }, + { NULL, 0 } }; -- cgit From 4ee1f291862c7bc69e5099908f5f5dd619921975 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Jan 2005 05:45:39 +0000 Subject: Don't show extended information for raw devices --- tools/hciconfig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index d24faf73..61e4d3cd 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1099,7 +1099,8 @@ static void print_dev_info(int ctl, struct hci_dev_info *di) printf("\tTX bytes:%d acl:%d sco:%d commands:%d errors:%d\n", st->byte_tx, st->acl_tx, st->sco_tx, st->cmd_tx, st->err_tx); - if (all) { + if (all && !hci_test_bit(HCI_RAW, &di->flags) && + bacmp(&di->bdaddr, BDADDR_ANY)) { print_dev_features(di, 0); print_pkt_type(di); print_link_policy(di); -- cgit From f7c95b2391493543f1f2dd73601194b4eb123632 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Jan 2005 23:16:30 +0000 Subject: Update changelog and bump version number --- ChangeLog | 13 +++++++++++++ configure.in | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4c331181..1cc32400 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +ver 2.15: + Enable the RFCOMM service level security. + Add command for reading the clock offset. + Add command for reading the clock. + Don't configure raw devices. + Don't set inquiry scan or page scan on raw devices. + Don't show extended information for raw devices. + Support L2CAP signal sizes bigger than 2048 bytes. + Cleanup of the socket handling code of the test programs. + + Note: + This version needs at least bluez-libs-2.15 + ver 2.14: Make use of additional connection information. Use library function for reading the RSSI. diff --git a/configure.in b/configure.in index 1f84efc4..02044052 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.14) +AM_INIT_AUTOMAKE(bluez-utils, 2.15) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From 02493301a7f7f30a0e18003857cbd2eb302adc95 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Feb 2005 08:08:02 +0000 Subject: Add TDK Bluetooth PC Card II --- pcmcia/bluetooth.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pcmcia/bluetooth.conf b/pcmcia/bluetooth.conf index 9f3edc61..9ddace94 100644 --- a/pcmcia/bluetooth.conf +++ b/pcmcia/bluetooth.conf @@ -34,6 +34,10 @@ card "TDK Bluetooth PC Card" version "TDK", "Bluetooth PC Card" bind "serial_cs" class "bluetooth" +card "TDK Bluetooth PC Card II" + version "TDK", "Bluetooth PC Card II" + bind "serial_cs" class "bluetooth" + card "AmbiCom BT2000C Bluetooth PC/CF Card" version "AmbiCom BT2000C", "Bluetooth PC/CF Card" bind "serial_cs" class "bluetooth" -- cgit From e4b4cf97715729084740673c44dfabcf8b29fcfe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Feb 2005 11:37:23 +0000 Subject: Fix ident calculation --- tools/l2ping.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/l2ping.c b/tools/l2ping.c index 0e7a4be1..01b1f21b 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -193,7 +193,7 @@ static void ping(char *svr) cmd->len = btohs(cmd->len); /* Check for our id */ - if( cmd->ident != id ) + if (cmd->ident != id) continue; /* Check type */ @@ -218,7 +218,7 @@ static void ping(char *svr) if (delay) sleep(delay); } else { - printf("no response from %s: id %d\n", svr, id); + printf("no response from %s: id %d\n", svr, id - ident); } if (++id > 254) -- cgit From 93070a1a7a4af492f49d2d61d25602d032d9e0aa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Feb 2005 00:21:01 +0000 Subject: Add the ALSA library plugin for A2DP --- Makefile.am | 6 +++--- acinclude.m4 | 6 +++--- alsa/Makefile.am | 17 +++++++++++++++++ alsa/pcm_a2dp.c | 0 bootstrap | 2 +- configure.in | 8 +++++++- 6 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 alsa/Makefile.am create mode 100644 alsa/pcm_a2dp.c diff --git a/Makefile.am b/Makefile.am index 0c4d3fe1..ee845b02 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,8 +2,8 @@ # $Id$ # -SUBDIRS = hcid tools rfcomm sdpd dund pand hidd cups test scripts pcmcia extra +SUBDIRS = config hcid tools rfcomm sdpd dund pand hidd cups alsa test scripts pcmcia extra MAINTAINERCLEANFILES = Makefile.in \ - aclocal.m4 configure config.h.in \ - missing install-sh mkinstalldirs + aclocal.m4 configure config.h.in config.sub config.guess \ + ltmain.sh missing install-sh mkinstalldirs diff --git a/acinclude.m4 b/acinclude.m4 index 94f665c8..fbadd434 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -137,8 +137,8 @@ AC_DEFUN([AC_PATH_ALSA], [ ALSA_CFLAGS="" test -d "${alsa_prefix}/include" && ALSA_CFLAGS="$ALSA_CFLAGS -I${alsa_prefix}/include" - CPPFLAGS="$CPPFLAGS $ALSA_CFLAGS" - AC_CHECK_HEADER(alsa/version.h, alsa_found=yes, alsa_found=no) + CPPFLAGS="$CPPFLAGS $ALSA_CFLAGS -include alsa/asoundlib.h" + AC_CHECK_HEADER(alsa/pcm_ioplug.h, alsa_found=yes, alsa_found=no) ALSA_LIBS="" if (test "${prefix}" = "${alsa_prefix}"); then @@ -149,7 +149,7 @@ AC_DEFUN([AC_PATH_ALSA], [ fi LDFLAGS="$LDFLAGS $ALSA_LIBS" - AC_CHECK_LIB(asound, snd_ctl_open, ALSA_LIBS="$ALSA_LIBS -lasound", alsa_found=no) + AC_CHECK_LIB(asound, snd_pcm_ioplug_create, ALSA_LIBS="$ALSA_LIBS -lasound", alsa_found=no) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS diff --git a/alsa/Makefile.am b/alsa/Makefile.am new file mode 100644 index 00000000..65a9aa1a --- /dev/null +++ b/alsa/Makefile.am @@ -0,0 +1,17 @@ +# +# $Id$ +# + +if ALSA +alsadir = $(libdir)/alsa-lib + +alsa_LTLIBRARIES = libasound_module_pcm_a2dp.la + +libasound_module_pcm_a2dp_la_SOURCES = pcm_a2dp.c +libasound_module_pcm_a2dp_la_LDFLAGS = -module -avoid-version -export-dynamic +libasound_module_pcm_a2dp_la_LIBADD = @ALSA_LIBS@ @BLUEZ_LIBS@ + +AM_CFLAGS = @ALSA_CFLAGS@ @BLUEZ_CFLAGS@ +endif + +MAINTAINERCLEANFILES = Makefile.in diff --git a/alsa/pcm_a2dp.c b/alsa/pcm_a2dp.c new file mode 100644 index 00000000..e69de29b diff --git a/bootstrap b/bootstrap index 3426beb4..199053bb 100755 --- a/bootstrap +++ b/bootstrap @@ -1,2 +1,2 @@ #! /bin/sh -aclocal && autoheader && automake --add-missing --copy --ignore-deps && autoconf +aclocal && autoheader && libtoolize --copy --force && automake --add-missing --copy --ignore-deps && autoconf diff --git a/configure.in b/configure.in index 02044052..602aa3a7 100644 --- a/configure.in +++ b/configure.in @@ -20,6 +20,12 @@ AC_PROG_INSTALL AC_PROG_YACC AM_PROG_LEX +m4_define([_LT_AC_TAGCONFIG], []) +m4_ifdef([AC_LIBTOOL_TAGS], [AC_LIBTOOL_TAGS([])]) + +AC_DISABLE_STATIC +AC_PROG_LIBTOOL + AC_PATH_BLUEZ AC_PATH_OPENOBEX AC_PATH_ALSA @@ -28,4 +34,4 @@ AC_PATH_DBUS AC_ARG_BLUEZ -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) +AC_OUTPUT(Makefile config/Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) -- cgit From f9bf3e36e2d88318c538702b7492f20d8c01730c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Feb 2005 00:31:21 +0000 Subject: Add the ALSA library plugin for Headset/Handsfree --- alsa/Makefile.am | 6 +++++- alsa/pcm_headset.c | 0 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 alsa/pcm_headset.c diff --git a/alsa/Makefile.am b/alsa/Makefile.am index 65a9aa1a..fb358c66 100644 --- a/alsa/Makefile.am +++ b/alsa/Makefile.am @@ -5,12 +5,16 @@ if ALSA alsadir = $(libdir)/alsa-lib -alsa_LTLIBRARIES = libasound_module_pcm_a2dp.la +alsa_LTLIBRARIES = libasound_module_pcm_a2dp.la libasound_module_pcm_headset.la libasound_module_pcm_a2dp_la_SOURCES = pcm_a2dp.c libasound_module_pcm_a2dp_la_LDFLAGS = -module -avoid-version -export-dynamic libasound_module_pcm_a2dp_la_LIBADD = @ALSA_LIBS@ @BLUEZ_LIBS@ +libasound_module_pcm_headset_la_SOURCES = pcm_headset.c +libasound_module_pcm_headset_la_LDFLAGS = -module -avoid-version -export-dynamic +libasound_module_pcm_headset_la_LIBADD = @ALSA_LIBS@ @BLUEZ_LIBS@ + AM_CFLAGS = @ALSA_CFLAGS@ @BLUEZ_CFLAGS@ endif diff --git a/alsa/pcm_headset.c b/alsa/pcm_headset.c new file mode 100644 index 00000000..e69de29b -- cgit From ecb55bb1b7bb070bbbfe012ef4bbdf89467a2fe3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Feb 2005 12:58:06 +0000 Subject: Fix the use of a wrong directory --- Makefile.am | 2 +- configure.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index ee845b02..d6d9e992 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -SUBDIRS = config hcid tools rfcomm sdpd dund pand hidd cups alsa test scripts pcmcia extra +SUBDIRS = hcid tools rfcomm sdpd dund pand hidd cups alsa test scripts pcmcia extra MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in config.sub config.guess \ diff --git a/configure.in b/configure.in index 602aa3a7..514f3a3f 100644 --- a/configure.in +++ b/configure.in @@ -34,4 +34,4 @@ AC_PATH_DBUS AC_ARG_BLUEZ -AC_OUTPUT(Makefile config/Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) +AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) -- cgit From 77f2ea7f02d5981deab6ec22d05570e06d46836e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Feb 2005 14:07:09 +0000 Subject: Support zero length data sizes --- test/l2test.c | 65 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/test/l2test.c b/test/l2test.c index 5857b13d..35e06598 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,7 @@ static int imtu = 672; static int omtu = 0; /* Default data size */ -static long data_size = 0; +static long data_size = -1; /* Default addr and psm */ static bdaddr_t bdaddr; @@ -474,7 +475,8 @@ static void dump_mode(int sk) static void recv_mode(int sk) { - struct timeval tv_beg,tv_end,tv_diff; + struct timeval tv_beg, tv_end, tv_diff; + struct pollfd p; long total; uint32_t seq; socklen_t optlen; @@ -482,6 +484,9 @@ static void recv_mode(int sk) syslog(LOG_INFO,"Receiving ..."); + p.fd = sk; + p.events = POLLIN | POLLERR | POLLHUP; + seq = 0; while (1) { gettimeofday(&tv_beg, NULL); @@ -489,27 +494,35 @@ static void recv_mode(int sk) while (total < data_size) { uint32_t sq; uint16_t l; - int i, r; - - if ((r = recv(sk, buf, data_size, 0)) <= 0) { - if (r < 0) { - if (reliable && (errno == ECOMM)) { - syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); - optlen = sizeof(opt); - if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { - syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", - strerror(errno), errno); - return; - } - continue; - } else { - syslog(LOG_ERR, "Read failed: %s (%d)", + int i, len; + + p.revents = 0; + if (poll(&p, 1, -1) <= 0) + return; + + if (p.revents & (POLLERR | POLLHUP)) + return; + + len = recv(sk, buf, data_size, 0); + if (len < 0) { + if (reliable && (errno == ECOMM)) { + syslog(LOG_INFO, "L2CAP Error ECOMM - clearing error and continuing.\n"); + optlen = sizeof(opt); + if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &opt, &optlen) < 0) { + syslog(LOG_ERR, "Couldn't getsockopt(SO_ERROR): %s (%d)", strerror(errno), errno); + return; } + continue; + } else { + syslog(LOG_ERR, "Read failed: %s (%d)", + strerror(errno), errno); } - return; } + if (len < 6) + break; + /* Check sequence */ sq = btohl(*(uint32_t *) buf); if (seq != sq) { @@ -520,18 +533,18 @@ static void recv_mode(int sk) /* Check length */ l = btohs(*(uint16_t *) (buf + 4)); - if (r != l) { - syslog(LOG_INFO, "size missmatch: %d -> %d", r, l); + if (len != l) { + syslog(LOG_INFO, "size missmatch: %d -> %d", len, l); continue; } /* Verify data */ - for (i = 6; i < r; i++) { + for (i = 6; i < len; i++) { if (buf[i] != 0x7f) syslog(LOG_INFO, "data missmatch: byte %d 0x%2.2x", i, buf[i]); } - total += r; + total += len; } gettimeofday(&tv_end, NULL); @@ -545,7 +558,7 @@ static void recv_mode(int sk) static void send_mode(int sk) { uint32_t seq; - int i; + int i, len; syslog(LOG_INFO, "Sending ..."); @@ -558,7 +571,8 @@ static void send_mode(int sk) *(uint16_t *) (buf + 4) = htobs(data_size); seq++; - if (send(sk, buf, data_size, 0) <= 0) { + len = send(sk, buf, data_size, 0); + if (len < 0 || len != data_size) { syslog(LOG_ERR, "Send failed: %s (%d)", strerror(errno), errno); exit(1); } @@ -781,7 +795,8 @@ int main(int argc ,char *argv[]) exit(1); } - if (!data_size) { + if (data_size < 0) { + data_size = 48; if (imtu > data_size) data_size = imtu; if (omtu > data_size) -- cgit From 490afac7bc8ca6b283499fe5b026a14a7f7df0cb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Feb 2005 21:02:07 +0000 Subject: Add SBC library support --- alsa/Makefile.am | 2 +- alsa/sbc.c | 1355 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ alsa/sbc.h | 58 +++ 3 files changed, 1414 insertions(+), 1 deletion(-) create mode 100644 alsa/sbc.c create mode 100644 alsa/sbc.h diff --git a/alsa/Makefile.am b/alsa/Makefile.am index fb358c66..e0c3168e 100644 --- a/alsa/Makefile.am +++ b/alsa/Makefile.am @@ -7,7 +7,7 @@ alsadir = $(libdir)/alsa-lib alsa_LTLIBRARIES = libasound_module_pcm_a2dp.la libasound_module_pcm_headset.la -libasound_module_pcm_a2dp_la_SOURCES = pcm_a2dp.c +libasound_module_pcm_a2dp_la_SOURCES = pcm_a2dp.c sbc.h sbc.c libasound_module_pcm_a2dp_la_LDFLAGS = -module -avoid-version -export-dynamic libasound_module_pcm_a2dp_la_LIBADD = @ALSA_LIBS@ @BLUEZ_LIBS@ diff --git a/alsa/sbc.c b/alsa/sbc.c new file mode 100644 index 00000000..bd767768 --- /dev/null +++ b/alsa/sbc.c @@ -0,0 +1,1355 @@ +/* + * + * Bluetooth low-complexity, subband codec (SBC) library + * + * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2005 Henryk Ploetz + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "sbc.h" + +/* A2DP specification: Appendix B, page 69 */ +static const int sbc_offset4[4][4] = { + { -1, 0, 0, 0 }, + { -2, 0, 0, 1 }, + { -2, 0, 0, 1 }, + { -2, 0, 0, 1 } +}; + +/* A2DP specification: Appendix B, page 69 */ +static const int sbc_offset8[4][8] = { + { -2, 0, 0, 0, 0, 0, 0, 1 }, + { -3, 0, 0, 0, 0, 0, 1, 2 }, + { -4, 0, 0, 0, 0, 0, 1, 2 }, + { -4, 0, 0, 0, 0, 0, 1, 2 } +}; + +/* A2DP specification: Appendix B, page 70 */ +static const float sbc_proto_4_40[40] = { + 0.00000000E+00, 5.36548976E-04, 1.49188357E-03, 2.73370904E-03, + 3.83720193E-03, 3.89205149E-03, 1.86581691E-03, -3.06012286E-03, + 1.09137620E-02, 2.04385087E-02, 2.88757392E-02, 3.21939290E-02, + 2.58767811E-02, 6.13245186E-03, -2.88217274E-02, -7.76463494E-02, + 1.35593274E-01, 1.94987841E-01, 2.46636662E-01, 2.81828203E-01, + 2.94315332E-01, 2.81828203E-01, 2.46636662E-01, 1.94987841E-01, + -1.35593274E-01, -7.76463494E-02, -2.88217274E-02, 6.13245186E-03, + 2.58767811E-02, 3.21939290E-02, 2.88757392E-02, 2.04385087E-02, + -1.09137620E-02, -3.06012286E-03, 1.86581691E-03, 3.89205149E-03, + 3.83720193E-03, 2.73370904E-03, 1.49188357E-03, 5.36548976E-04 +}; + +/* A2DP specification: Appendix B, page 70 */ +static const float sbc_proto_8_80[80] = { + 0.00000000E+00, 1.56575398E-04, 3.43256425E-04, 5.54620202E-04, + 8.23919506E-04, 1.13992507E-03, 1.47640169E-03, 1.78371725E-03, + 2.01182542E-03, 2.10371989E-03, 1.99454554E-03, 1.61656283E-03, + 9.02154502E-04, -1.78805361E-04, -1.64973098E-03, -3.49717454E-03, + 5.65949473E-03, 8.02941163E-03, 1.04584443E-02, 1.27472335E-02, + 1.46525263E-02, 1.59045603E-02, 1.62208471E-02, 1.53184106E-02, + 1.29371806E-02, 8.85757540E-03, 2.92408442E-03, -4.91578024E-03, + -1.46404076E-02, -2.61098752E-02, -3.90751381E-02, -5.31873032E-02, + 6.79989431E-02, 8.29847578E-02, 9.75753918E-02, 1.11196689E-01, + 1.23264548E-01, 1.33264415E-01, 1.40753505E-01, 1.45389847E-01, + 1.46955068E-01, 1.45389847E-01, 1.40753505E-01, 1.33264415E-01, + 1.23264548E-01, 1.11196689E-01, 9.75753918E-02, 8.29847578E-02, + -6.79989431E-02, -5.31873032E-02, -3.90751381E-02, -2.61098752E-02, + -1.46404076E-02, -4.91578024E-03, 2.92408442E-03, 8.85757540E-03, + 1.29371806E-02, 1.53184106E-02, 1.62208471E-02, 1.59045603E-02, + 1.46525263E-02, 1.27472335E-02, 1.04584443E-02, 8.02941163E-03, + -5.65949473E-03, -3.49717454E-03, -1.64973098E-03, -1.78805361E-04, + 9.02154502E-04, 1.61656283E-03, 1.99454554E-03, 2.10371989E-03, + 2.01182542E-03, 1.78371725E-03, 1.47640169E-03, 1.13992507E-03, + 8.23919506E-04, 5.54620202E-04, 3.43256425E-04, 1.56575398E-04 +}; + +/* Precomputed: synmatrix4[k][i] = cos( (i+0.5) * (k+2.0) * pi/4.0 ) */ +static const float synmatrix4[8][4] = { + { 0.707106781186548, -0.707106781186547, -0.707106781186548, 0.707106781186547 }, + { 0.38268343236509, -0.923879532511287, 0.923879532511287, -0.38268343236509 }, + { 0, 0, 0, 0 }, + { -0.38268343236509, 0.923879532511287, -0.923879532511287, 0.382683432365091 }, + { -0.707106781186547, 0.707106781186548, 0.707106781186547, -0.707106781186547 }, + { -0.923879532511287, -0.38268343236509, 0.382683432365091, 0.923879532511288 }, + { -1, -1, -1, -1 }, + { -0.923879532511287, -0.382683432365091, 0.38268343236509, 0.923879532511287 } +}; + +/* Precomputed: synmatrix8[k][i] = cos( (i+0.5) * (k+4.0) * pi/8.0 ) */ +static const float synmatrix8[16][8] = { + { 0.707106781186548, -0.707106781186547, -0.707106781186548, 0.707106781186547, + 0.707106781186548, -0.707106781186547, -0.707106781186547, 0.707106781186547 }, + { 0.555570233019602, -0.98078528040323, 0.195090322016128, 0.831469612302545, + -0.831469612302545, -0.195090322016128, 0.980785280403231, -0.555570233019602 }, + { 0.38268343236509, -0.923879532511287, 0.923879532511287, -0.38268343236509, + -0.382683432365091, 0.923879532511287, -0.923879532511286, 0.38268343236509 }, + { 0.195090322016128, -0.555570233019602, 0.831469612302545, -0.980785280403231, + 0.98078528040323, -0.831469612302545, 0.555570233019602, -0.195090322016129 }, + { 0, 0, 0, 0, + 0, 0, 0, 0 }, + { -0.195090322016128, 0.555570233019602, -0.831469612302545, 0.98078528040323, + -0.980785280403231, 0.831469612302545, -0.555570233019603, 0.19509032201613 }, + { -0.38268343236509, 0.923879532511287, -0.923879532511287, 0.382683432365091, + 0.38268343236509, -0.923879532511287, 0.923879532511288, -0.382683432365091 }, + { -0.555570233019602, 0.98078528040323, -0.195090322016128, -0.831469612302545, + 0.831469612302545, 0.195090322016128, -0.98078528040323, 0.555570233019606 }, + { -0.707106781186547, 0.707106781186548, 0.707106781186547, -0.707106781186547, + -0.707106781186546, 0.707106781186548, 0.707106781186546, -0.707106781186548 }, + { -0.831469612302545, 0.195090322016129, 0.980785280403231, 0.555570233019602, + -0.555570233019603, -0.98078528040323, -0.195090322016128, 0.831469612302547 }, + { -0.923879532511287, -0.38268343236509, 0.382683432365091, 0.923879532511288, + 0.923879532511287, 0.382683432365089, -0.382683432365091, -0.923879532511287 }, + { -0.98078528040323, -0.831469612302545, -0.555570233019602, -0.195090322016129, + 0.19509032201613, 0.555570233019606, 0.831469612302547, 0.980785280403231 }, + { -1, -1, -1, -1, + -1, -1, -1, -1 }, + { -0.98078528040323, -0.831469612302546, -0.555570233019603, -0.19509032201613, + 0.195090322016128, 0.555570233019604, 0.831469612302545, 0.98078528040323 }, + { -0.923879532511287, -0.382683432365091, 0.38268343236509, 0.923879532511287, + 0.923879532511288, 0.382683432365088, -0.382683432365089, -0.923879532511285 }, + { -0.831469612302545, 0.195090322016127, 0.98078528040323, 0.555570233019603, + -0.555570233019601, -0.98078528040323, -0.195090322016131, 0.831469612302545 } +}; + +/* Precomputed: anamatrix4[i][k] = cos( (i+0.5) * (k-2) * pi/4 ) */ +static const float anamatrix4[4][8] = { + { 0.707106781186548, 0.923879532511287, 1, 0.923879532511287, + 0.707106781186548, 0.38268343236509, 0, -0.38268343236509 }, + { -0.707106781186547, 0.38268343236509, 1, 0.38268343236509, + -0.707106781186547, -0.923879532511287, 0, 0.923879532511287 }, + { -0.707106781186548, -0.38268343236509, 1, -0.38268343236509, + -0.707106781186548, 0.923879532511287, 0, -0.923879532511287 }, + { 0.707106781186547, -0.923879532511287, 1, -0.923879532511287, + 0.707106781186547, -0.38268343236509, 0, 0.382683432365091 } +}; + +/* Precomputed: anamatrix8[i][k] = cos( (i+0.5) * (k-4) * pi/8) */ +static const float anamatrix8[8][16] = { + { 0.923879532511287, 0.98078528040323, 1, 0.98078528040323, + 0.923879532511287, 0.831469612302545, 0.707106781186548, 0.555570233019602, + 0.38268343236509, 0.195090322016128, 0, -0.195090322016128, + -0.38268343236509, -0.555570233019602, -0.707106781186547, -0.831469612302545 }, + { 0.38268343236509, 0.831469612302545, 1, 0.831469612302545, + 0.38268343236509, -0.195090322016128, -0.707106781186547, -0.98078528040323, + -0.923879532511287, -0.555570233019602, 0, 0.555570233019602, + 0.923879532511287, 0.98078528040323, 0.707106781186548, 0.195090322016129 }, + { -0.38268343236509, 0.555570233019602, 1, 0.555570233019602, + -0.38268343236509, -0.98078528040323, -0.707106781186548, 0.195090322016128, + 0.923879532511287, 0.831469612302545, 0, -0.831469612302545, + -0.923879532511287, -0.195090322016128, 0.707106781186547, 0.980785280403231 }, + { -0.923879532511287, 0.195090322016128, 1, 0.195090322016128, + -0.923879532511287, -0.555570233019602, 0.707106781186547, 0.831469612302545, + -0.38268343236509, -0.980785280403231, 0, 0.98078528040323, + 0.382683432365091, -0.831469612302545, -0.707106781186547, 0.555570233019602 }, + { -0.923879532511287, -0.195090322016128, 1, -0.195090322016128, + -0.923879532511287, 0.555570233019602, 0.707106781186548, -0.831469612302545, + -0.382683432365091, 0.98078528040323, 0, -0.980785280403231, + 0.38268343236509, 0.831469612302545, -0.707106781186546, -0.555570233019603 }, + { -0.38268343236509, -0.555570233019602, 1, -0.555570233019602, + -0.38268343236509, 0.98078528040323, -0.707106781186547, -0.195090322016128, + 0.923879532511287, -0.831469612302545, 0, 0.831469612302545, + -0.923879532511287, 0.195090322016128, 0.707106781186548, -0.98078528040323 }, + { 0.38268343236509, -0.831469612302545, 1, -0.831469612302545, + 0.38268343236509, 0.195090322016129, -0.707106781186547, 0.980785280403231, + -0.923879532511286, 0.555570233019602, 0, -0.555570233019603, + 0.923879532511288, -0.98078528040323, 0.707106781186546, -0.195090322016128 }, + { 0.923879532511287, -0.98078528040323, 1, -0.98078528040323, + 0.923879532511287, -0.831469612302545, 0.707106781186547, -0.555570233019602, + 0.38268343236509, -0.195090322016129, 0, 0.19509032201613, + -0.382683432365091, 0.555570233019606, -0.707106781186548, 0.831469612302547 } +}; + +#define fabs(x) ((x) < 0 ? (-x) : (x)) + +#define SBC_SYNCWORD 0x9C + +/* sampling frequency */ +#define SBC_FS_16 0x00 +#define SBC_FS_32 0x01 +#define SBC_FS_44 0x02 +#define SBC_FS_48 0x03 + +/* nrof_blocks */ +#define SBC_NB_4 0x00 +#define SBC_NB_8 0x01 +#define SBC_NB_12 0x02 +#define SBC_NB_16 0x03 + +/* channel mode */ +#define SBC_CM_MONO 0x00 +#define SBC_CM_DUAL_CHANNEL 0x01 +#define SBC_CM_STEREO 0x02 +#define SBC_CM_JOINT_STEREO 0x03 + +/* allocation mode */ +#define SBC_AM_LOUDNESS 0x00 +#define SBC_AM_SNR 0x01 + +/* subbands */ +#define SBC_SB_4 0x00 +#define SBC_SB_8 0x01 + +/* This structure contains an unpacked SBC frame. + Yes, there is probably quite some unused space herein */ +struct sbc_frame { + double sampling_frequency; /* in kHz */ + u_int8_t blocks; + enum { + MONO = SBC_CM_MONO, + DUAL_CHANNEL = SBC_CM_DUAL_CHANNEL, + STEREO = SBC_CM_STEREO, + JOINT_STEREO = SBC_CM_JOINT_STEREO + } channel_mode; + u_int8_t channels; + enum { + LOUDNESS = SBC_AM_LOUDNESS, + SNR = SBC_AM_SNR + } allocation_method; + u_int8_t subbands; + u_int8_t bitpool; + u_int8_t join; /* bit number x set means joint stereo has been used in subband x */ + u_int8_t scale_factor[2][8]; /* only the lower 4 bits of every element are to be used */ + u_int16_t audio_sample[16][2][8]; /* raw integer subband samples in the frame */ + double sb_sample[16][2][8]; /* modified subband samples */ + double pcm_sample[2][16*8]; /* original pcm audio samples */ +}; + +struct sbc_decoder_state { + int subbands; + float S[2][8]; /* Subband samples */ + float X[2][8]; /* Audio samples */ + float V[2][160], U[2][80], W[2][80]; /* Vectors */ +}; + +struct sbc_encoder_state { + int subbands; + float S[2][8]; /* Subband samples */ + float X[2][80], Y[2][16], Z[2][80]; /* Vectors */ +}; + +/* + * Calculates the CRC-8 of the first len bits in data + */ +static const u_int8_t crc_table[256] = { + 0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, + 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB, + 0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, + 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76, + 0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, + 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C, + 0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, + 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1, + 0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, + 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8, + 0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, + 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65, + 0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, + 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F, + 0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, + 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2, + 0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, + 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D, + 0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, + 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50, + 0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, + 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A, + 0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, + 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7, + 0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, + 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E, + 0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, + 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43, + 0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, + 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09, + 0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, + 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4 +}; + +static u_int8_t sbc_crc8(const u_int8_t * data, size_t len) +{ + u_int8_t crc = 0x0f; + size_t i; + u_int8_t octet; + + for (i = 0; i < len / 8; i++) + crc = crc_table[crc ^ data[i]]; + + octet = data[i]; + for (i = 0; i < len % 8; i++) { + char bit = ((octet ^ crc) & 0x80) >> 7; + + crc = ((crc & 0x7f) << 1) ^ (bit ? 0x1d : 0); + + octet = octet << 1; + } + + return crc; +} + +/* + * Code straight from the spec to calculate the bits array + * Takes a pointer to the frame in question, a pointer to the bits array and the sampling frequency (as 2 bit integer) + */ +static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8], u_int8_t sf) +{ + if (frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) { + int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice; + int ch, sb; + + for (ch = 0; ch < frame->channels; ch++) { + if (frame->allocation_method == SNR) { + for (sb = 0; sb < frame->subbands; sb++) { + bitneed[ch][sb] = frame->scale_factor[ch][sb]; + } + } else { + for (sb = 0; sb < frame->subbands; sb++) { + if (frame->scale_factor[ch][sb] == 0) { + bitneed[ch][sb] = -5; + } else { + if (frame->subbands == 4) { + loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb]; + } else { + loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb]; + } + if (loudness > 0) { + bitneed[ch][sb] = loudness / 2; + } else { + bitneed[ch][sb] = loudness; + } + } + } + } + + max_bitneed = 0; + for (sb = 0; sb < frame->subbands; sb++) { + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; + } + + bitcount = 0; + slicecount = 0; + bitslice = max_bitneed + 1; + do { + bitslice--; + bitcount += slicecount; + slicecount = 0; + for (sb = 0; sb < frame->subbands; sb++) { + if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16)) { + slicecount++; + } else if (bitneed[ch][sb] == bitslice + 1) { + slicecount += 2; + } + } + } while (bitcount + slicecount < frame->bitpool); + + if (bitcount + slicecount == frame->bitpool) { + bitcount += slicecount; + bitslice--; + } + + for (sb = 0; sb < frame->subbands; sb++) { + if (bitneed[ch][sb] < bitslice + 2) { + bits[ch][sb] = 0; + } else { + bits[ch][sb] = bitneed[ch][sb] - bitslice; + if (bits[ch][sb] > 16) + bits[ch][sb] = 16; + } + } + + sb = 0; + while (bitcount < frame->bitpool && sb < frame->subbands) { + if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) { + bits[ch][sb]++; + bitcount++; + } else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1)) { + bits[ch][sb] = 2; + bitcount += 2; + } + sb++; + } + + sb = 0; + while (bitcount < frame->bitpool && sb < frame->subbands) { + if (bits[ch][sb] < 16) { + bits[ch][sb]++; + bitcount++; + } + sb++; + } + + } + + } else if (frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) { + int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice; + int ch, sb; + + if (frame->allocation_method == SNR) { + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + bitneed[ch][sb] = frame->scale_factor[ch][sb]; + } + } + } else { + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (frame->scale_factor[ch][sb] == 0) { + bitneed[ch][sb] = -5; + } else { + if (frame->subbands == 4) { + loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb]; + } else { + loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb]; + } + if (loudness > 0) { + bitneed[ch][sb] = loudness / 2; + } else { + bitneed[ch][sb] = loudness; + } + } + } + } + } + + max_bitneed = 0; + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; + } + } + + bitcount = 0; + slicecount = 0; + bitslice = max_bitneed + 1; + do { + bitslice--; + bitcount += slicecount; + slicecount = 0; + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16)) { + slicecount++; + } else if (bitneed[ch][sb] == bitslice + 1) { + slicecount += 2; + } + } + } + } while (bitcount + slicecount < frame->bitpool); + if (bitcount + slicecount == frame->bitpool) { + bitcount += slicecount; + bitslice--; + } + + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (bitneed[ch][sb] < bitslice + 2) { + bits[ch][sb] = 0; + } else { + bits[ch][sb] = bitneed[ch][sb] - bitslice; + if (bits[ch][sb] > 16) + bits[ch][sb] = 16; + } + } + } + + ch = 0; + sb = 0; + while ((bitcount < frame->bitpool) && (sb < frame->subbands)) { + if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) { + bits[ch][sb]++; + bitcount++; + } else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1)) { + bits[ch][sb] = 2; + bitcount += 2; + } + if (ch == 1) { + ch = 0; + sb++; + } else { + ch = 1; + } + } + + ch = 0; + sb = 0; + while ((bitcount < frame->bitpool) && (sb < frame->subbands)) { + if (bits[ch][sb] < 16) { + bits[ch][sb]++; + bitcount++; + } + if (ch == 1) { + ch = 0; + sb++; + } else { + ch = 1; + } + } + + } + +} + +/* + * Unpacks a SBC frame at the beginning of the stream in data, + * which has at most len bytes into frame. + * Returns the length in bytes of the packed frame, or a negative + * value on error. The error codes are: + * + * -1 Data stream too short + * -2 Sync byte incorrect + * -3 CRC8 incorrect + * -4 Bitpool value out of bounds + */ +static int sbc_unpack_frame(const u_int8_t * data, struct sbc_frame *frame, size_t len) +{ + int consumed; + /* Will copy the parts of the header that are relevant to crc calculation here */ + u_int8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int crc_pos = 0; + + u_int8_t sf; /* sampling_frequency, temporarily needed as array index */ + + int ch, sb, blk, bit; /* channel, subband, block and bit standard counters */ + int bits[2][8]; /* bits distribution */ + int levels[2][8]; /* levels derived from that */ + + double scalefactor[2][8]; /* derived from frame->scale_factors */ + + if (len < 4) { + return -1; + } + + if (data[0] != SBC_SYNCWORD) { + return -2; + } + + sf = (data[1] >> 6) & 0x03; + switch (sf) { + case SBC_FS_16: + frame->sampling_frequency = 16; + break; + case SBC_FS_32: + frame->sampling_frequency = 32; + break; + case SBC_FS_44: + frame->sampling_frequency = 44.1; + break; + case SBC_FS_48: + frame->sampling_frequency = 48; + break; + } + + switch ((data[1] >> 4) & 0x03) { + case SBC_NB_4: + frame->blocks = 4; + break; + case SBC_NB_8: + frame->blocks = 8; + break; + case SBC_NB_12: + frame->blocks = 12; + break; + case SBC_NB_16: + frame->blocks = 16; + break; + } + + frame->channel_mode = (data[1] >> 2) & 0x03; + switch (frame->channel_mode) { + case MONO: + frame->channels = 1; + break; + case DUAL_CHANNEL: /* fall-through */ + case STEREO: + case JOINT_STEREO: + frame->channels = 2; + break; + } + + frame->allocation_method = (data[1] >> 1) & 0x01; + + frame->subbands = (data[1] & 0x01) ? 8 : 4; + + frame->bitpool = data[2]; + + if (((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) + && frame->bitpool > 16 * frame->subbands) + || ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) + && frame->bitpool > 32 * frame->subbands)) { + return -4; + } + + /* data[3] is crc, we're checking it later */ + + consumed = 32; + + crc_header[0] = data[1]; + crc_header[1] = data[2]; + crc_pos = 16; + + if (frame->channel_mode == JOINT_STEREO) { + if (len * 8 < consumed + frame->subbands) { + return -1; + } else { + frame->join = 0x00; + for (sb = 0; sb < frame->subbands - 1; sb++) { + frame->join |= ((data[4] >> (7 - sb)) & 0x01) << sb; + } + if (frame->subbands == 4) { + crc_header[crc_pos / 8] = data[4] & 0xf0; + } else { + crc_header[crc_pos / 8] = data[4]; + } + + consumed += frame->subbands; + crc_pos += frame->subbands; + } + } + + if (len * 8 < consumed + (4 * frame->subbands * frame->channels)) { + return -1; + } else { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + /* FIXME assert(consumed % 4 == 0); */ + frame->scale_factor[ch][sb] = (data[consumed / 8] >> (4 - (consumed % 8))) & 0x0F; + crc_header[crc_pos / 8] |= frame->scale_factor[ch][sb] << (4 - (crc_pos % 8)); + + consumed += 4; + crc_pos += 4; + } + } + } + + if (data[3] != sbc_crc8(crc_header, crc_pos)) { + return -3; + } + + sbc_calculate_bits(frame, bits, sf); + + for (blk = 0; blk < frame->blocks; blk++) { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + frame->audio_sample[blk][ch][sb] = 0; + if (bits[ch][sb] != 0) { + for (bit = 0; bit < bits[ch][sb]; bit++) { + int b; /* A bit */ + if (consumed > len * 8) { + return -1; + } + + b = (data[consumed / 8] >> (7 - (consumed % 8))) & 0x01; + frame->audio_sample[blk][ch][sb] |= b << (bits[ch][sb] - bit - 1); + + consumed++; + } + } + } + } + } + + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + levels[ch][sb] = (1 << bits[ch][sb]) - 1; + scalefactor[ch][sb] = 2 << frame->scale_factor[ch][sb]; + } + } + + for (blk = 0; blk < frame->blocks; blk++) { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (levels[ch][sb] > 0) { + frame->sb_sample[blk][ch][sb] = + scalefactor[ch][sb] * ((frame->audio_sample[blk][ch][sb] * 2.0 + 1.0) / + levels[ch][sb] - 1.0); + } else { + frame->sb_sample[blk][ch][sb] = 0; + } + } + } + } + + if (frame->channel_mode == JOINT_STEREO) { + for (blk = 0; blk < frame->blocks; blk++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (frame->join & (0x01 << sb)) { + frame->sb_sample[blk][0][sb] = + frame->sb_sample[blk][0][sb] + frame->sb_sample[blk][1][sb]; + frame->sb_sample[blk][1][sb] = + frame->sb_sample[blk][0][sb] - 2 * frame->sb_sample[blk][1][sb]; + } + } + } + } + + if (consumed % 8 != 0) + consumed += 8 - (consumed % 8); + + return consumed / 8; +} + +static void sbc_decoder_init(struct sbc_decoder_state *state, const struct sbc_frame *frame) +{ + memset(&state->S, 0, sizeof(state->S)); + memset(&state->X, 0, sizeof(state->X)); + memset(&state->V, 0, sizeof(state->V)); + memset(&state->U, 0, sizeof(state->U)); + memset(&state->W, 0, sizeof(state->W)); + state->subbands = frame->subbands; +} + +static inline void sbc_synthesize_four(struct sbc_decoder_state *state, + struct sbc_frame *frame, int ch, int blk) +{ + int i, j, k; + + /* Input 4 New Subband Samples */ + for (i = 0; i < 4; i++) + state->S[ch][i] = frame->sb_sample[blk][ch][i]; + + /* Shifting */ + for (i = 79; i >= 8; i--) + state->V[ch][i] = state->V[ch][i - 8]; + + /* Matrixing */ + for (k = 0; k < 8; k++) { + state->V[ch][k] = 0; + for (i = 0; i < 4; i++) + state->V[ch][k] += synmatrix4[k][i] * state->S[ch][i]; + } + + /* Build a 40 values vector U */ + for (i = 0; i <= 4; i++) { + for (j = 0; j < 4; j++) { + state->U[ch][i * 8 + j] = state->V[ch][i * 16 + j]; + state->U[ch][i * 8 + j + 4] = state->V[ch][i * 16 + j + 12]; + } + } + + /* Window by 40 coefficients */ + for (i = 0; i < 40; i++) + state->W[ch][i] = state->U[ch][i] * sbc_proto_4_40[i] * (-4); + + /* Calculate 4 audio samples */ + for (j = 0; j < 4; j++) { + state->X[ch][j] = 0; + for (i = 0; i < 10; i++) + state->X[ch][j] += state->W[ch][j + 4 * i]; + } + + /* Output 4 reconstructed Audio Samples */ + for (i = 0; i < 4; i++) + frame->pcm_sample[ch][blk * 4 + i] = state->X[ch][i]; +} + +static inline void sbc_synthesize_eight(struct sbc_decoder_state *state, + struct sbc_frame *frame, int ch, int blk) +{ + int i, j, k; + + /* Input 8 New Subband Samples */ + for (i = 0; i < 8; i++) + state->S[ch][i] = frame->sb_sample[blk][ch][i]; + + /* Shifting */ + for (i = 159; i >= 16; i--) + state->V[ch][i] = state->V[ch][i - 16]; + + /* Matrixing */ + for (k = 0; k < 16; k++) { + state->V[ch][k] = 0; + for (i = 0; i < 8; i++) { + state->V[ch][k] += synmatrix8[k][i] * state->S[ch][i]; + } + } + + /* Build a 80 values vector U */ + for (i = 0; i <= 4; i++) { + for (j = 0; j < 8; j++) { + state->U[ch][i * 16 + j] = state->V[ch][i * 32 + j]; + state->U[ch][i * 16 + j + 8] = state->V[ch][i * 32 + j + 24]; + } + } + + /* Window by 80 coefficients */ + for (i = 0; i < 80; i++) + state->W[ch][i] = state->U[ch][i] * sbc_proto_8_80[i] * (-4); + + /* Calculate 8 audio samples */ + for (j = 0; j < 8; j++) { + state->X[ch][j] = 0; + for (i = 0; i < 10; i++) + state->X[ch][j] += state->W[ch][j + 8 * i]; + } + + /* Ouput 8 reconstructed Audio Samples */ + for (i = 0; i < 8; i++) + frame->pcm_sample[ch][blk * 8 + i] = state->X[ch][i]; +} + +static int sbc_synthesize_audio(struct sbc_decoder_state *state, struct sbc_frame *frame) +{ + int ch, blk; + + switch (frame->subbands) { + case 4: + for (ch = 0; ch < frame->channels; ch++) { + memset(frame->pcm_sample[ch], 0, + sizeof(frame->pcm_sample[ch])); + + for (blk = 0; blk < frame->blocks; blk++) + sbc_synthesize_four(state, frame, ch, blk); + } + + return frame->blocks * 4; + + case 8: + for (ch = 0; ch < frame->channels; ch++) { + memset(frame->pcm_sample[ch], 0, + sizeof(frame->pcm_sample[ch])); + + for (blk = 0; blk < frame->blocks; blk++) + sbc_synthesize_eight(state, frame, ch, blk); + } + + return frame->blocks * 8; + + default: + return -EIO; + } +} + +static void sbc_encoder_init(struct sbc_encoder_state *state, const struct sbc_frame *frame) +{ + memset(&state->S, 0, sizeof(state->S)); + memset(&state->X, 0, sizeof(state->X)); + memset(&state->Y, 0, sizeof(state->Y)); + memset(&state->Z, 0, sizeof(state->Z)); + state->subbands = frame->subbands; +} + +static inline void sbc_analyze_four(struct sbc_encoder_state *state, + struct sbc_frame *frame, int ch, int blk) +{ + int i, k; + + /* Input 4 New Audio Samples */ + for (i = 39; i >= 4; i--) + state->X[ch][i] = state->X[ch][i - 4]; + for (i = 3; i >= 0; i--) + state->X[ch][i] = frame->pcm_sample[ch][blk * 4 + (3 - i)]; + + /* Windowing by 40 coefficients */ + for (i = 0; i < 40; i++) + state->Z[ch][i] = sbc_proto_4_40[i] * state->X[ch][i]; + + /* Partial calculation */ + for (i = 0; i < 8; i++) { + state->Y[ch][i] = 0; + for (k = 0; k < 5; k++) + state->Y[ch][i] += state->Z[ch][i + k * 8]; + } + + /* Calculate 4 subband samples by Matrixing */ + for (i = 0; i < 4; i++) { + state->S[ch][i] = 0; + for (k = 0; k < 8; k++) + state->S[ch][i] += anamatrix4[i][k] * state->Y[ch][k]; + } + + /* Output 4 Subband Samples */ + for (i = 0; i < 4; i++) + frame->sb_sample[blk][ch][i] = state->S[ch][i]; +} + +static inline void sbc_analyze_eight(struct sbc_encoder_state *state, + struct sbc_frame *frame, int ch, int blk) +{ + int i, k; + + /* Input 8 Audio Samples */ + for (i = 79; i >= 8; i--) + state->X[ch][i] = state->X[ch][i - 8]; + for (i = 7; i >= 0; i--) + state->X[ch][i] = frame->pcm_sample[ch][blk * 8 + (7 - i)]; + + /* Windowing by 80 coefficients */ + for (i = 0; i < 80; i++) + state->Z[ch][i] = sbc_proto_8_80[i] * state->X[ch][i]; + + /* Partial calculation */ + for (i = 0; i < 16; i++) { + state->Y[ch][i] = 0; + for (k = 0; k < 5; k++) + state->Y[ch][i] += state->Z[ch][i + k * 16]; + } + + /* Calculate 8 subband samples by Matrixing */ + for (i = 0; i < 8; i++) { + state->S[ch][i] = 0; + for (k = 0; k < 16; k++) + state->S[ch][i] += anamatrix8[i][k] * state->Y[ch][k]; + } + + /* Output 8 Subband Samples */ + for (i = 0; i < 8; i++) + frame->sb_sample[blk][ch][i] = state->S[ch][i]; +} + +static int sbc_analyze_audio(struct sbc_encoder_state *state, struct sbc_frame *frame) +{ + int ch, blk; + + switch (frame->subbands) { + case 4: + for (ch = 0; ch < frame->channels; ch++) + for (blk = 0; blk < frame->blocks; blk++) { + memset(frame->sb_sample[blk][ch], 0, + sizeof(frame->sb_sample[blk][ch])); + sbc_analyze_four(state, frame, ch, blk); + } + + return frame->blocks * 4; + + case 8: + for (ch = 0; ch < frame->channels; ch++) + for (blk = 0; blk < frame->blocks; blk++) { + memset(frame->sb_sample[blk][ch], 0, + sizeof(frame->sb_sample[blk][ch])); + sbc_analyze_eight(state, frame, ch, blk); + } + + return frame->blocks * 8; + + default: + return -EIO; + } +} + +/* + * Packs the SBC frame from frame into the memory at data. At most len + * bytes will be used, should more memory be needed an appropriate + * error code will be returned. Returns the length of the packed frame + * on success or a negative value on error. + * + * The error codes are: + * -1 Not enough memory reserved + * -2 Unsupported sampling rate + * -3 Unsupported number of blocks + * -4 Unsupported number of subbands + * -5 Bitpool value out of bounds + * -99 not implemented + */ + +static int sbc_pack_frame(u_int8_t * data, struct sbc_frame *frame, size_t len) +{ + int produced; + /* Will copy the header parts for CRC-8 calculation here */ + u_int8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + int crc_pos = 0; + + u_int8_t sf; /* Sampling frequency as temporary value for table lookup */ + + int ch, sb, blk, bit; /* channel, subband, block and bit counters */ + int bits[2][8]; /* bits distribution */ + int levels[2][8]; /* levels are derived from that */ + + double scalefactor[2][8]; /* derived from frame->scale_factor */ + + if (len < 4) { + return -1; + } + + /* Clear first 4 bytes of data (that's the constant length part of the SBC header) */ + memset(data, 0, 4); + + data[0] = SBC_SYNCWORD; + + if (frame->sampling_frequency == 16) { + data[1] |= (SBC_FS_16 & 0x03) << 6; + sf = SBC_FS_16; + } else if (frame->sampling_frequency == 32) { + data[1] |= (SBC_FS_32 & 0x03) << 6; + sf = SBC_FS_32; + } else if (frame->sampling_frequency == 44.1) { + data[1] |= (SBC_FS_44 & 0x03) << 6; + sf = SBC_FS_44; + } else if (frame->sampling_frequency == 48) { + data[1] |= (SBC_FS_48 & 0x03) << 6; + sf = SBC_FS_48; + } else { + return -2; + } + + switch (frame->blocks) { + case 4: + data[1] |= (SBC_NB_4 & 0x03) << 4; + break; + case 8: + data[1] |= (SBC_NB_8 & 0x03) << 4; + break; + case 12: + data[1] |= (SBC_NB_12 & 0x03) << 4; + break; + case 16: + data[1] |= (SBC_NB_16 & 0x03) << 4; + break; + default: + return -3; + break; + } + + data[1] |= (frame->channel_mode & 0x03) << 2; + + data[1] |= (frame->allocation_method & 0x01) << 1; + + switch (frame->subbands) { + case 4: + /* Nothing to do */ + break; + case 8: + data[1] |= 0x01; + break; + default: + return -4; + break; + } + + data[2] = frame->bitpool; + if (((frame->channel_mode == MONO || frame->channel_mode == DUAL_CHANNEL) + && frame->bitpool > 16 * frame->subbands) + || ((frame->channel_mode == STEREO || frame->channel_mode == JOINT_STEREO) + && frame->bitpool > 32 * frame->subbands)) { + return -5; + } + + /* Can't fill in crc yet */ + + produced = 32; + + crc_header[0] = data[1]; + crc_header[1] = data[2]; + crc_pos = 16; + + + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + frame->scale_factor[ch][sb] = 0; + scalefactor[ch][sb] = 2; + for (blk = 0; blk < frame->blocks; blk++) { + while (scalefactor[ch][sb] < fabs(frame->sb_sample[blk][ch][sb])) { + frame->scale_factor[ch][sb]++; + scalefactor[ch][sb] *= 2; + } + } + } + } + + if (frame->channel_mode == JOINT_STEREO) { + float sb_sample_j[16][2][7]; /* like frame->sb_sample but joint stereo */ + int scalefactor_j[2][7], scale_factor_j[2][7]; /* scalefactor and scale_factor in joint case */ + + /* Calculate joint stereo signal */ + for (sb = 0; sb < frame->subbands - 1; sb++) { + for (blk = 0; blk < frame->blocks; blk++) { + sb_sample_j[blk][0][sb] = (frame->sb_sample[blk][0][sb] + + frame->sb_sample[blk][1][sb]) / 2; + sb_sample_j[blk][1][sb] = (frame->sb_sample[blk][0][sb] + - frame->sb_sample[blk][1][sb]) / 2; + } + } + + /* calculate scale_factor_j and scalefactor_j for joint case */ + for (ch = 0; ch < 2; ch++) { + for (sb = 0; sb < frame->subbands - 1; sb++) { + scale_factor_j[ch][sb] = 0; + scalefactor_j[ch][sb] = 2; + for (blk = 0; blk < frame->blocks; blk++) { + while (scalefactor_j[ch][sb] < fabs(sb_sample_j[blk][ch][sb])) { + scale_factor_j[ch][sb]++; + scalefactor_j[ch][sb] *= 2; + } + } + } + } + + /* decide which subbands to join */ + frame->join = 0; + for (sb = 0; sb < frame->subbands - 1; sb++) { + if ( (scalefactor[0][sb] + scalefactor[1][sb]) > + (scalefactor_j[0][sb] + scalefactor_j[1][sb]) ) { + /* use joint stereo for this subband */ + frame->join |= 1 << sb; + frame->scale_factor[0][sb] = scale_factor_j[0][sb]; + frame->scale_factor[1][sb] = scale_factor_j[1][sb]; + scalefactor[0][sb] = scalefactor_j[0][sb]; + scalefactor[1][sb] = scalefactor_j[1][sb]; + for (blk = 0; blk < frame->blocks; blk++) { + frame->sb_sample[blk][0][sb] = sb_sample_j[blk][0][sb]; + frame->sb_sample[blk][1][sb] = sb_sample_j[blk][1][sb]; + } + } + } + + if (len * 8 < produced + frame->subbands) { + return -1; + } else { + data[4] = 0; + for (sb = 0; sb < frame->subbands - 1; sb++) { + data[4] |= ((frame->join >> sb) & 0x01) << (7 - sb); + } + if (frame->subbands == 4) { + crc_header[crc_pos / 8] = data[4] & 0xf0; + } else { + crc_header[crc_pos / 8] = data[4]; + } + + produced += frame->subbands; + crc_pos += frame->subbands; + } + } + + if (len * 8 < produced + (4 * frame->subbands * frame->channels)) { + return -1; + } else { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (produced % 8 == 0) + data[produced / 8] = 0; + data[produced / 8] |= ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (produced % 8))); + crc_header[crc_pos / 8] |= + ((frame->scale_factor[ch][sb] & 0x0F) << (4 - (crc_pos % 8))); + + produced += 4; + crc_pos += 4; + } + } + } + + data[3] = sbc_crc8(crc_header, crc_pos); + + sbc_calculate_bits(frame, bits, sf); + + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + levels[ch][sb] = (1 << bits[ch][sb]) - 1; + } + } + + for (blk = 0; blk < frame->blocks; blk++) { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (levels[ch][sb] > 0) { + frame->audio_sample[blk][ch][sb] = + (u_int16_t) (((frame->sb_sample[blk][ch][sb] / scalefactor[ch][sb] + + 1.0) * levels[ch][sb]) / 2.0); + } else { + frame->audio_sample[blk][ch][sb] = 0; + } + } + } + } + + for (blk = 0; blk < frame->blocks; blk++) { + for (ch = 0; ch < frame->channels; ch++) { + for (sb = 0; sb < frame->subbands; sb++) { + if (bits[ch][sb] != 0) { + for (bit = 0; bit < bits[ch][sb]; bit++) { + int b; /* A bit */ + if (produced > len * 8) { + return -1; + } + if (produced % 8 == 0) { + data[produced / 8] = 0; + } + b = ((frame->audio_sample[blk][ch][sb]) >> (bits[ch][sb] - bit - + 1)) & 0x01; + data[produced / 8] |= b << (7 - (produced % 8)); + produced++; + } + } + } + } + } + + if (produced % 8 != 0) { + produced += 8 - (produced % 8); + } + + return produced / 8; +} + + +struct sbc_priv { + int init; + struct sbc_frame frame; + struct sbc_decoder_state dec_state; + struct sbc_encoder_state enc_state; +}; + +int sbc_init(sbc_t *sbc, unsigned long flags) +{ + if (!sbc) + return -EIO; + + memset(sbc, 0, sizeof(sbc_t)); + + sbc->priv = malloc(sizeof(struct sbc_priv)); + if (!sbc->priv) + return -ENOMEM; + + memset(sbc->priv, 0, sizeof(struct sbc_priv)); + + return 0; +} + +int sbc_decode(sbc_t *sbc, void *data, int count) +{ + struct sbc_priv *priv; + char *ptr; + int i, ch, framelen, samples; + + if (!sbc) + return -EIO; + + priv = sbc->priv; + + framelen = sbc_unpack_frame(data, &priv->frame, count); + + if (!priv->init) { + sbc_decoder_init(&priv->dec_state, &priv->frame); + priv->init = 1; + + sbc->rate = priv->frame.sampling_frequency * 1000; + sbc->channels = priv->frame.channels; + } + + samples = sbc_synthesize_audio(&priv->dec_state, &priv->frame); + + if (!sbc->data) { + sbc->size = samples * priv->frame.channels * 2; + sbc->data = malloc(sbc->size); + } + + if (sbc->size < samples * priv->frame.channels * 2) { + sbc->size = samples * priv->frame.channels * 2; + sbc->data = realloc(sbc->data, sbc->size); + } + + if (!sbc->data) { + sbc->size = 0; + return -ENOMEM; + } + + ptr = sbc->data; + + for (i = 0; i < samples; i++) { + for (ch = 0; ch < priv->frame.channels; ch++) { + int16_t s = (int16_t)(priv->frame.pcm_sample[ch][i]); + *ptr++ = (s & 0xff00) >> 8; + *ptr++ = (s & 0x00ff); + } + } + + sbc->len = samples * priv->frame.channels * 2; + + return framelen; +} + +int sbc_encode(sbc_t *sbc, void *data, int count) +{ + struct sbc_priv *priv; + char *ptr; + int i, ch, framelen, samples; + + if (!sbc) + return -EIO; + + priv = sbc->priv; + + if (!priv->init) { + priv->frame.sampling_frequency = ((double) sbc->rate) / 1000; + priv->frame.channels = sbc->channels; + + if (sbc->channels > 1) + priv->frame.channel_mode = STEREO; + else + priv->frame.channel_mode = MONO; + + priv->frame.allocation_method = SNR; + priv->frame.subbands = 8; + priv->frame.blocks = 16; + priv->frame.bitpool = 32; + + sbc_encoder_init(&priv->enc_state, &priv->frame); + priv->init = 1; + } + + ptr = data; + + for (i = 0; i < priv->frame.subbands * priv->frame.blocks; i++) { + for (ch = 0; ch < sbc->channels; ch++) { + //int16_t s = (ptr[0] & 0xff) << 8 | (ptr[1] & 0xff); + int16_t s = (ptr[1] & 0xff) << 8 | (ptr[2] & 0xff); + ptr += 2; + priv->frame.pcm_sample[ch][i] = ((double) s); + } + } + + samples = sbc_analyze_audio(&priv->enc_state, &priv->frame); + + if (!sbc->data) { + sbc->size = 1024; + sbc->data = malloc(sbc->size); + } + + if (!sbc->data) { + sbc->size = 0; + return -ENOMEM; + } + + framelen = sbc_pack_frame(sbc->data, &priv->frame, sbc->size); + + sbc->len = framelen; + + return samples * sbc->channels * 2; +} + +void sbc_finish(sbc_t *sbc) +{ + if (!sbc) + return; + + if (sbc->data) + free(sbc->data); + + if (sbc->priv) + free(sbc->priv); + + memset(sbc, 0, sizeof(sbc_t)); +} diff --git a/alsa/sbc.h b/alsa/sbc.h new file mode 100644 index 00000000..02353160 --- /dev/null +++ b/alsa/sbc.h @@ -0,0 +1,58 @@ +/* + * + * Bluetooth low-complexity, subband codec (SBC) library + * + * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2005 Henryk Ploetz + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __SBC_H +#define __SBC_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define SBC_NULL 0x00000001 + +struct sbc_struct { + unsigned long flags; + + int rate; + int channels; + + void *data; + int size; + int len; + + void *priv; +}; + +typedef struct sbc_struct sbc_t; + +int sbc_init(sbc_t *sbc, unsigned long flags); +int sbc_decode(sbc_t *sbc, void *data, int count); +int sbc_encode(sbc_t *sbc, void *data, int count); +void sbc_finish(sbc_t *sbc); + +#ifdef __cplusplus +} +#endif + +#endif /* __SBC_H */ -- cgit From 891e3e2d7cdcb4cd301efff8c20abbf4d7cd3565 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Feb 2005 21:05:33 +0000 Subject: Add prototype version of the A2DP plugin --- alsa/pcm_a2dp.c | 358 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) diff --git a/alsa/pcm_a2dp.c b/alsa/pcm_a2dp.c index e69de29b..90ee7107 100644 --- a/alsa/pcm_a2dp.c +++ b/alsa/pcm_a2dp.c @@ -0,0 +1,358 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "sbc.h" + +//#define DBG(fmt, arg...) printf("DEBUG: %s: " fmt "\n" , __FUNCTION__ , ## arg) +#define DBG(D...) + +typedef struct snd_pcm_a2dp { + snd_pcm_ioplug_t io; + bdaddr_t src; + bdaddr_t dst; + int sk; + sbc_t sbc; + snd_pcm_sframes_t num; + unsigned char buf[1024]; + unsigned int len; + unsigned int frame_bytes; +} snd_pcm_a2dp_t; + +static int a2dp_start(snd_pcm_ioplug_t *io) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; + + DBG("a2dp %p", a2dp); + + a2dp->len = 0; + + return 0; +} + +static int a2dp_stop(snd_pcm_ioplug_t *io) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; + + DBG("a2dp %p", a2dp); + + a2dp->len = 0; + + return 0; +} + +static snd_pcm_sframes_t a2dp_pointer(snd_pcm_ioplug_t *io) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; + + return a2dp->num; +} + +static snd_pcm_sframes_t a2dp_transfer(snd_pcm_ioplug_t *io, + const snd_pcm_channel_area_t *areas, + snd_pcm_uframes_t offset, snd_pcm_uframes_t size) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; + unsigned char *buf; + int len; + + buf = (unsigned char *) areas->addr + (areas->first + areas->step * offset) / 8; + + size *= a2dp->frame_bytes; + + len = sbc_encode(&a2dp->sbc, buf, size); + if (len <= 0) + return len; + + memcpy(a2dp->buf + a2dp->len, a2dp->sbc.data, a2dp->sbc.len); + a2dp->len += a2dp->sbc.len; + + if (a2dp->len > 700) { + write(a2dp->sk, a2dp->buf, a2dp->len); + a2dp->len = 0; + } + + a2dp->num += len / a2dp->frame_bytes; + + return len / a2dp->frame_bytes; +} + +static int a2dp_close(snd_pcm_ioplug_t *io) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; + + DBG("a2dp %p", a2dp); + + a2dp->len = 0; + + if (a2dp->sk >= 0) { + shutdown(a2dp->sk, SHUT_RDWR); + sleep(1); + close(a2dp->sk); + } + + sbc_finish(&a2dp->sbc); + + free(a2dp); + return 0; +} + +static int a2dp_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; + unsigned int period_bytes; + + DBG("a2dp %p", a2dp); + + a2dp->frame_bytes = (snd_pcm_format_physical_width(io->format) * io->channels) / 8; + + period_bytes = io->period_size * a2dp->frame_bytes; + + DBG("format %s rate %d channels %d", snd_pcm_format_name(io->format), + io->rate, io->channels); + + DBG("frame_bytes %d period_byts %d period_size %ld buffer_size %ld", + a2dp->frame_bytes, period_bytes, io->period_size, io->buffer_size); + + return 0; +} + +static int a2dp_prepare(snd_pcm_ioplug_t *io) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; + + DBG("a2dp %p", a2dp); + + a2dp->sbc.rate = io->rate; + a2dp->sbc.channels = io->channels; + + return 0; +} + +static int a2dp_drain(snd_pcm_ioplug_t *io) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; + + DBG("a2dp %p", a2dp); + + a2dp->len = 0; + + return 0; +} + +static snd_pcm_ioplug_callback_t a2dp_callback = { + .start = a2dp_start, + .stop = a2dp_stop, + .pointer = a2dp_pointer, + .transfer = a2dp_transfer, + .close = a2dp_close, + .hw_params = a2dp_params, + .prepare = a2dp_prepare, + .drain = a2dp_drain, +}; + +static int a2dp_connect(snd_pcm_a2dp_t *a2dp) +{ + struct sockaddr_rc addr; + int sk; + + DBG("a2dp %p", a2dp); + + sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (sk < 0) + return -errno; + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, &a2dp->src); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(sk); + return -errno; + } + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, &a2dp->dst); + addr.rc_channel = 1; + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(sk); + return -errno; + } + + a2dp->sk = sk; + return 0; +} + +static int a2dp_constraint(snd_pcm_a2dp_t *a2dp) +{ + snd_pcm_ioplug_t *io = &a2dp->io; + snd_pcm_access_t access_list[] = { + SND_PCM_ACCESS_RW_INTERLEAVED, + SND_PCM_ACCESS_MMAP_INTERLEAVED, + }; + unsigned int format[2], channel[2], rate[2]; + int err; + + DBG("a2dp %p", a2dp); + + err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_ACCESS, 2, access_list); + if (err < 0) + return err; + + format[0] = SND_PCM_FORMAT_S16_LE; + + err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT, 1, format); + if (err < 0) + return err; + + channel[0] = 1; + channel[1] = 2; + + err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_CHANNELS, 2, channel); + if (err < 0) + return err; + + rate[0] = 44100; + rate[1] = 48000; + + err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_RATE, 2, rate); + if (err < 0) + return err; + + err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 2048, 2048); + if (err < 0) + return err; + + err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 2, 2); + if (err < 0) + return err; + + sbc_init(&a2dp->sbc, SBC_NULL); + + return 0; +} + +SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) +{ + snd_pcm_a2dp_t *a2dp; + snd_config_iterator_t i, next; + bdaddr_t src, dst; + int err; + + DBG("name %s mode %d", name, mode); + + bacpy(&src, BDADDR_ANY); + bacpy(&dst, BDADDR_ANY); + + snd_config_for_each(i, next, conf) { + snd_config_t *n = snd_config_iterator_entry(i); + const char *id, *addr; + + if (snd_config_get_id(n, &id) < 0) + continue; + + if (!strcmp(id, "comment") || !strcmp(id, "type")) + continue; + + if (!strcmp(id, "bdaddr") || !strcmp(id, "dst")) { + if (snd_config_get_string(n, &addr) < 0) { + SNDERR("Invalid type for %s", id); + return -EINVAL; + } + str2ba(addr, &dst); + continue; + } + + if (strcmp(id, "src") == 0) { + if (snd_config_get_string(n, &addr) < 0) { + SNDERR("Invalid type for %s", id); + return -EINVAL; + } + str2ba(addr, &src); + continue; + } + + SNDERR("Unknown field %s", id); + return -EINVAL; + } + + a2dp = malloc(sizeof(*a2dp)); + if (!a2dp) { + SNDERR("Cannot allocate"); + return -ENOMEM; + } + + memset(a2dp, 0, sizeof(*a2dp)); + + bacpy(&a2dp->src, &src); + bacpy(&a2dp->dst, &dst); + + err = a2dp_connect(a2dp); + if (err < 0) { + SNDERR("Cannot connect"); + goto error; + } + + a2dp->io.name = "Bluetooth Advanced Audio Distribution"; + a2dp->io.poll_fd = a2dp->sk; + a2dp->io.poll_events = POLLOUT | POLLHUP; + a2dp->io.mmap_rw = 0; + a2dp->io.callback = &a2dp_callback; + a2dp->io.private_data = a2dp; + + err = snd_pcm_ioplug_create(&a2dp->io, name, stream, mode); + if (err < 0) + goto error; + + err = a2dp_constraint(a2dp); + if (err < 0) { + snd_pcm_ioplug_delete(&a2dp->io); + return err; + } + + *pcmp = a2dp->io.pcm; + return 0; + +error: + free(a2dp); + return err; +} + +SND_PCM_PLUGIN_SYMBOL(a2dp); -- cgit From 508afd448b78e3d4c0b531c4696c5e906f259787 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Feb 2005 21:08:29 +0000 Subject: Update display of Broadcom firmware version --- tools/hciconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 61e4d3cd..1cc698d8 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1014,7 +1014,7 @@ static void print_rev_digianswer(int dd) static void print_rev_broadcom(uint16_t hci_rev, uint16_t lmp_subver) { - printf("\tFirmware %d.%d.%03d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); + printf("\tFirmware %d.%d / %d\n", hci_rev, lmp_subver >> 8, lmp_subver & 0xff); } static void print_rev_avm(uint16_t hci_rev, uint16_t lmp_subver) -- cgit From d67817be8163beb8d69d97934eb998d269221a14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Feb 2005 04:17:52 +0000 Subject: Use the clock offset when getting the remote names --- tools/hcitool.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 8b7131a0..57d23e6a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -301,7 +301,8 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - if (hci_read_remote_name(dd, &(info+i)->bdaddr, sizeof(name), name, 100000) < 0) + if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, + htobs((info+i)->clock_offset), sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); ba2str(&(info+i)->bdaddr, addr); printf("\t%s\t%s\n", addr, name); @@ -662,7 +663,7 @@ static void cmd_cc(int dev_id, int argc, char **argv) } if (hci_create_connection(dd, &bdaddr, htobs(ptype), - 0, role, &handle, 25000) < 0) + htobs(0x0000), role, &handle, 25000) < 0) perror("Can't create connection"); hci_close_dev(dd); } -- cgit From 8aebcde5f68394bc2cd27855971d26ce52da0500 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Feb 2005 05:02:24 +0000 Subject: Handle the valid bit of the clock offset --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 57d23e6a..766c084e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -223,7 +223,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { ba2str(&(info+i)->bdaddr, addr); printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", - addr, (info+i)->clock_offset, + addr, btohs((info+i)->clock_offset), (info+i)->dev_class[2], (info+i)->dev_class[1], (info+i)->dev_class[0]); @@ -302,7 +302,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - htobs((info+i)->clock_offset), sizeof(name), name, 100000) < 0) + (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); ba2str(&(info+i)->bdaddr, addr); printf("\t%s\t%s\n", addr, name); -- cgit From 8fb7ab625a24c48e7176b7e6995456080f997bf0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 17 Feb 2005 01:30:41 +0000 Subject: Update build ids for HCI 19.2 --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index d7bb65ae..e55b48a5 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -266,6 +266,8 @@ static struct { { 1734, "HCI 18.3" }, { 1735, "HCI 18.3" }, { 1737, "HCI 18.3" }, + { 1915, "HCI 19.2" }, + { 1916, "HCI 19.2" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From 337a9c4da82ea321a6613dd7c44e451e681a4a4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 02:39:41 +0000 Subject: Add build ids for new sniffer firmwares --- tools/csr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index e55b48a5..e3353cdc 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -309,6 +309,11 @@ static struct { { 1642, "Sniff 37 (2004-09-16)" }, { 1699, "Sniff 38 (2004-10-07)" }, { 1700, "Sniff 38 (2004-10-07)" }, + { 1752, "Sniff 39 (2004-11-02)" }, + { 1753, "Sniff 39 (2004-11-02)" }, + { 1759, "Sniff 40 (2004-11-03)" }, + { 1760, "Sniff 40 (2004-11-03)" }, + { 1761, "Sniff 40 (2004-11-03)" }, { 0, } }; -- cgit From 05ec11bf58edbacb68ebf4cd4b629df697224d6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 02:41:02 +0000 Subject: The transmit power level is a signed integer value --- tools/hcitool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 766c084e..225977b7 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -959,7 +959,8 @@ static void cmd_tpl(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; - uint8_t type, level; + uint8_t type; + int8_t level; int opt, dd; for_each_opt(opt, tpl_options, NULL) { -- cgit From 354b825e585790a15fc07ca382540739cbb3c155 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 15:11:32 +0000 Subject: Use pscan_rep_mode for the name resolve --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 225977b7..27ac78b7 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -302,7 +302,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); ba2str(&(info+i)->bdaddr, addr); printf("\t%s\t%s\n", addr, name); -- cgit From fa8b3a2161c997be308438040641dc0445f9d494 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 15:21:59 +0000 Subject: Always include the stdio.h header file --- dund/sdp.c | 3 ++- hcid/kword.c | 1 + pand/sdp.c | 3 ++- sdpd/cstate.c | 1 + sdpd/request.c | 1 + sdpd/service.c | 1 + sdpd/servicedb.c | 1 + 7 files changed, 9 insertions(+), 2 deletions(-) diff --git a/dund/sdp.c b/dund/sdp.c index 939c361c..45060e81 100644 --- a/dund/sdp.c +++ b/dund/sdp.c @@ -31,11 +31,12 @@ #include #endif +#include +#include #include #include #include #include -#include #include #include diff --git a/hcid/kword.c b/hcid/kword.c index 895b2410..41800b75 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -32,6 +32,7 @@ #include #endif +#include #include #include #include diff --git a/pand/sdp.c b/pand/sdp.c index 686b25b5..85edc681 100644 --- a/pand/sdp.c +++ b/pand/sdp.c @@ -31,11 +31,12 @@ #include #endif +#include +#include #include #include #include #include -#include #include #include diff --git a/sdpd/cstate.c b/sdpd/cstate.c index 8f9db218..735d5850 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -33,6 +33,7 @@ #include #endif +#include #include #include diff --git a/sdpd/request.c b/sdpd/request.c index 7bdecb7a..dbb3ff37 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -33,6 +33,7 @@ #include #endif +#include #include #include #include diff --git a/sdpd/service.c b/sdpd/service.c index a8d93994..f2457e1f 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -33,6 +33,7 @@ #include #endif +#include #include #include diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 9f87eca6..5006fbb4 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -33,6 +33,7 @@ #include #endif +#include #include #include #include -- cgit From d05333281217cd6623de9cc27b90448d7fd5d81a Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 28 Feb 2005 11:58:54 +0000 Subject: free protocol descriptor list properly --- tools/sdptool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index cfbe2bba..a3c3c551 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -892,7 +892,8 @@ static void print_service_attr(sdp_record_t *rec) if (sdp_get_access_protos(rec, &proto) == 0) { printf("Protocol Descriptor List:\n"); sdp_list_foreach(proto, print_access_protos, 0); - sdp_list_free(proto, (sdp_free_func_t)sdp_data_free); + sdp_list_foreach(proto, (sdp_list_func_t)sdp_list_free, 0); + sdp_list_free(proto, 0); } if (sdp_get_lang_attr(rec, &list) == 0) { printf("Language Base Attr List:\n"); -- cgit From 4eaf4a6acc09c87c010f31b169dac5a7b99cc1c6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 28 Feb 2005 14:09:08 +0000 Subject: Call it SIM Access --- tools/sdptool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index a3c3c551..bed5e90e 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1265,7 +1265,7 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } - printf("Handsfree service registered\n"); + printf("SIM Access service registered\n"); end: sdp_data_free(channel); sdp_list_free(proto[0], 0); -- cgit From f5b612c1e96b3bf7d5c695417ed88a26dd5be776 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 4 Mar 2005 14:31:40 +0000 Subject: Hide the server record and the public browse group root --- sdpd/main.c | 64 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/sdpd/main.c b/sdpd/main.c index eb59a6fa..fc3dd22d 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -58,16 +58,16 @@ static int l2cap_sock, unix_sock; static fd_set active_fdset; static int active_maxfd; -sdp_record_t *server; +static sdp_record_t *server; /* * List of version numbers supported by the SDP server. * Add to this list when newer versions are supported. */ static sdp_version_t sdpVnumArray[1] = { - {1, 0} + { 1, 0 } }; -const int sdpServerVnumEntries = 1; +static const int sdpServerVnumEntries = 1; /* * The service database state is an attribute of the service record @@ -99,16 +99,19 @@ static void add_lang_attr(sdp_record_t *r) sdp_list_free(langs, 0); } -static void register_public_browse_group(void) +static void register_public_browse_group(int public) { sdp_list_t *browselist; uuid_t bgscid, pbgid; sdp_data_t *sdpdata; sdp_record_t *browse = sdp_record_alloc(); - browse->handle = sdp_next_handle(); - if (browse->handle < 0x10000) - return; + if (public) { + browse->handle = sdp_next_handle(); + if (browse->handle < 0x10000) + return; + } else + browse->handle = SDP_SERVER_RECORD_HANDLE + 1; sdp_record_add(browse); sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); @@ -122,8 +125,10 @@ static void register_public_browse_group(void) sdp_set_service_classes(browse, browselist); sdp_list_free(browselist, 0); - sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); - sdp_set_group_id(browse, pbgid); + if (public) { + sdp_uuid16_create(&pbgid, PUBLIC_BROWSE_GROUP); + sdp_set_group_id(browse, pbgid); + } } /* @@ -132,7 +137,7 @@ static void register_public_browse_group(void) * discovery clients. This method constructs a service record * and stores it in the repository */ -static void register_server_service(void) +static void register_server_service(int public) { int i; sdp_list_t *classIDList, *browseList; @@ -208,10 +213,12 @@ static void register_server_service(void) sdp_data_free(version_data); sdp_list_free(pd, 0); - sdp_uuid16_create(&browseGroupId, PUBLIC_BROWSE_GROUP); - browseList = sdp_list_append(0, &browseGroupId); - sdp_set_browse_groups(server, browseList); - sdp_list_free(browseList, 0); + if (public) { + sdp_uuid16_create(&browseGroupId, PUBLIC_BROWSE_GROUP); + browseList = sdp_list_append(0, &browseGroupId); + sdp_set_browse_groups(server, browseList); + sdp_list_free(browseList, 0); + } update_db_timestamp(); } @@ -221,16 +228,16 @@ static void register_server_service(void) * l2cap and unix sockets over which discovery and registration clients * access us respectively */ -int init_server(int master) +static int init_server(int master, int public) { struct sockaddr_l2 l2addr; struct sockaddr_un unaddr; /* Register the public browse group root */ - register_public_browse_group(); + register_public_browse_group(public); /* Register the SDP server's service record */ - register_server_service(); + register_server_service(public); /* Create L2CAP socket */ l2cap_sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); @@ -278,7 +285,7 @@ int init_server(int master) return 0; } -void sig_term(int sig) +static void sig_term(int sig) { SDPINF("terminating... \n"); sdp_svcdb_reset(); @@ -287,7 +294,7 @@ void sig_term(int sig) exit(0); } -int become_daemon(void) +static int become_daemon(void) { int fd; @@ -377,7 +384,7 @@ static void check_active(fd_set *mask, int num) } } -void usage(void) +static void usage(void) { printf("sdpd version %s\n", VERSION); printf("Usage:\n" @@ -386,19 +393,21 @@ void usage(void) } static struct option main_options[] = { - {"help", 0,0, 'h'}, - {"nodaemon", 0,0, 'n'}, - {"master", 0,0, 'm'}, - {0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "nodaemon", 0, 0, 'n' }, + { "master", 0, 0, 'm' }, + { "public", 0, 0, 'p' }, + { 0, 0, 0, 0} }; int main(int argc, char **argv) { int daemon = 1; int master = 0; + int public = 0; int opt; - while ((opt = getopt_long(argc, argv, "nm", main_options, NULL)) != -1) + while ((opt = getopt_long(argc, argv, "nmp", main_options, NULL)) != -1) switch (opt) { case 'n': daemon = 0; @@ -406,6 +415,9 @@ int main(int argc, char **argv) case 'm': master = 1; break; + case 'p': + public = 1; + break; default: usage(); exit(0); @@ -418,7 +430,7 @@ int main(int argc, char **argv) argc -= optind; argv += optind; - if (init_server(master) < 0) { + if (init_server(master, public) < 0) { SDPERR("Server initialization failed"); return -1; } -- cgit From d9689662976b6e83f4c6ac9baacae98cb32700a1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Mar 2005 11:18:59 +0000 Subject: Add example for browsing the local services --- tools/sdptool.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/sdptool.1 b/tools/sdptool.1 index 8f938f92..91a28a84 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -99,6 +99,8 @@ Displays help on using sdptool. .PP sdptool browse 00:80:98:24:15:6D .PP +sdptool browse local +.PP sdptool add DUN .PP sdptool del LAN -- cgit From 64386bf323447b173ed9e6cb444d26af4b7f8db6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Mar 2005 16:06:25 +0000 Subject: Read BD_ADDR if not set and if it is a raw device --- tools/hciconfig.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 1cc698d8..d8c40e8f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -75,6 +75,12 @@ static void print_dev_list(int ctl, int flags) di.dev_id = (dr+i)->dev_id; if (ioctl(ctl, HCIGETDEVINFO, (void *) &di) < 0) continue; + if (hci_test_bit(HCI_RAW, &di.flags) && + !bacmp(&di.bdaddr, BDADDR_ANY)) { + int dd = hci_open_dev(di.dev_id); + hci_read_bd_addr(dd, &di.bdaddr, 1000); + hci_close_dev(dd); + } print_dev_info(ctl, &di); } } @@ -1217,6 +1223,13 @@ int main(int argc, char **argv, char **env) exit(1); } + if (hci_test_bit(HCI_RAW, &di.flags) && + !bacmp(&di.bdaddr, BDADDR_ANY)) { + int dd = hci_open_dev(di.dev_id); + hci_read_bd_addr(dd, &di.bdaddr, 1000); + hci_close_dev(dd); + } + while (argc > 0) { for (i = 0; command[i].cmd; i++) { if (strncmp(command[i].cmd, *argv, 5)) -- cgit From 210da6834b4b6f219b0331cddacdd6e915dbb8fe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Mar 2005 17:01:54 +0000 Subject: Add language attributes --- tools/sdptool.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index bed5e90e..5c93dd69 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -920,6 +920,20 @@ typedef struct { unsigned int channel; } svc_info_t; +static void add_lang_attr(sdp_record_t *r) +{ + sdp_lang_attr_t base_lang; + sdp_list_t *langs = 0; + + /* UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) */ + base_lang.code_ISO639 = (0x65 << 8) | 0x6e; + base_lang.encoding = 106; + base_lang.base_offset = SDP_PRIMARY_LANG_BASE; + langs = sdp_list_append(0, &base_lang); + sdp_set_lang_attr(r, langs); + sdp_list_free(langs, 0); +} + static int add_sp(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *apseq, *proto[2], *profiles, *root, *aproto; @@ -961,7 +975,9 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) aproto = sdp_list_append(0, apseq); sdp_set_access_protos(&record, aproto); - sdp_set_info_attr(&record, "Serial Port", 0, 0); + add_lang_attr(&record); + + sdp_set_info_attr(&record, "Serial Port", 0, "COM Port"); if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); -- cgit From cfb680f0660169fe231c575cb2a0c7f72826f4f4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Mar 2005 17:27:17 +0000 Subject: Use uint32_t instead of long --- sdpd/cstate.c | 10 ++++++---- sdpd/request.c | 4 ++-- sdpd/sdpd.h | 6 +++--- sdpd/servicedb.c | 4 ++-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sdpd/cstate.c b/sdpd/cstate.c index 735d5850..dd532943 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -36,7 +36,9 @@ #include #include #include +#include +#include #include #include @@ -46,7 +48,7 @@ typedef struct _sdp_cstate_list sdp_cstate_list_t; struct _sdp_cstate_list { sdp_cstate_list_t *next; - long timestamp; + uint32_t timestamp; sdp_buf_t buf; }; @@ -63,7 +65,7 @@ sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) return 0; } -long sdp_cstate_alloc_buf(sdp_buf_t *buf) +uint32_t sdp_cstate_alloc_buf(sdp_buf_t *buf) { sdp_cstate_list_t *cstate = (sdp_cstate_list_t *)malloc(sizeof(sdp_cstate_list_t)); char *data = (char *)malloc(buf->data_size); @@ -84,7 +86,7 @@ long sdp_cstate_alloc_buf(sdp_buf_t *buf) * seconds. Used for updating the service db state * attribute of the service record of the SDP server */ -long sdp_get_time() +uint32_t sdp_get_time() { /* * To handle failure in gettimeofday, so an old @@ -93,5 +95,5 @@ long sdp_get_time() static struct timeval tm; gettimeofday(&tm, NULL); - return tm.tv_sec; + return (uint32_t) tm.tv_sec; } diff --git a/sdpd/request.c b/sdpd/request.c index dbb3ff37..6a62e55f 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -238,7 +238,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) sdp_cont_state_t *cstate = NULL; char *pCacheBuffer = NULL; int handleSize = 0; - long cStateId = -1; + uint32_t cStateId = 0; short rsp_count = 0; short *pTotalRecordCount, *pCurrentRecordCount; int mtu; @@ -331,7 +331,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) } /* under both the conditions below, the rsp buffer is not built yet */ - if (cstate || cStateId != -1) { + if (cstate || cStateId > 0) { short lastIndex = 0; if (cstate) { diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index bc085c83..6d9c856a 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -61,7 +61,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp); int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp); typedef struct { - long timestamp; + uint32_t timestamp; union { uint16_t maxBytesSent; uint16_t lastIndexSent; @@ -73,7 +73,7 @@ typedef struct { sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate); void sdp_cstate_cache_init(void); void sdp_cstate_clean_buf(void); -long sdp_cstate_alloc_buf(sdp_buf_t *buf); +uint32_t sdp_cstate_alloc_buf(sdp_buf_t *buf); void sdp_svcdb_reset(void); void sdp_svcdb_collect_all(int sock); @@ -85,6 +85,6 @@ int sdp_record_remove(uint32_t handle); sdp_list_t *sdp_get_record_list(); uint32_t sdp_next_handle(void); -long sdp_get_time(); +uint32_t sdp_get_time(); #endif diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 5006fbb4..45f45b91 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -146,8 +146,8 @@ void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) void sdp_record_add(sdp_record_t *rec) { #ifdef SDP_DEBUG - SDPDBG("Adding rec : 0x%lx\n", (long)rec); - SDPDBG("with handle : 0x%lx\n", (long)rec->handle); + SDPDBG("Adding rec : 0x%lx\n", (long) rec); + SDPDBG("with handle : 0x%x\n", rec->handle); #endif service_db = sdp_list_insert_sorted(service_db, rec, record_sort); } -- cgit From ac2daf48298cb601d1a57b0e00e38887b5e0a675 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 17 Mar 2005 19:03:58 +0000 Subject: Add support for reading CSR panic and fault codes --- tools/csr.h | 3 +++ tools/hciconfig.c | 12 +++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/csr.h b/tools/csr.h index b96dd0f7..f29fc764 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -31,6 +31,9 @@ #define CSR_VARID_CHIPREV 0x281b #define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c +#define CSR_VARID_PANIC_ARG 0x6805 +#define CSR_VARID_FAULT_ARG 0x6806 + #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab char *csr_buildidtostr(uint16_t id); diff --git a/tools/hciconfig.c b/tools/hciconfig.c index d8c40e8f..defe59c9 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -974,7 +974,7 @@ static void print_rev_ericsson(int dd) static void print_rev_csr(int dd, uint16_t rev) { - uint16_t buildid, chipver, chiprev, maxkeylen, mapsco; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, error; if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { printf("\t%s\n", csr_buildidtostr(rev)); @@ -994,6 +994,16 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); + + if (!csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error)) { + if (error < 0x0100) + printf("\tPanic code: 0x%02x\n", error); + } + + if (!csr_read_varid_uint16(dd, 6, CSR_VARID_FAULT_ARG, &error)) { + if (error < 0x0100) + printf("\tFault code: 0x%02x\n", error); + } } static void print_rev_digianswer(int dd) -- cgit From d3511a69c4be601fbe4c5c3d1f0cf1a8bb499a63 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 18 Mar 2005 13:49:49 +0000 Subject: Change default ping size to 44 bytes --- tools/l2ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/l2ping.c b/tools/l2ping.c index 01b1f21b..9741dc0e 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -50,7 +50,7 @@ /* Defaults */ static bdaddr_t bdaddr; -static int size = 20; +static int size = 44; static int ident = 200; static int delay = 1; static int count = -1; -- cgit From da77c34ef4276ad800498f76a707478add8b0a69 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Mar 2005 14:22:16 +0000 Subject: Update copyright year --- tools/csr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/csr.h b/tools/csr.h index f29fc764..513a2cf2 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From f5434ca84a250bbe6a7fe7baffdc53fb79d482f9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Mar 2005 18:40:59 +0000 Subject: Whitespace cleanup --- tools/hciconfig.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index defe59c9..e66c9aa1 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -608,7 +608,7 @@ static void cmd_class(int ctl, int hdev, char *opt) if ((cls[1] & 0x1f) > sizeof(*major_devices)) printf("Invalid Device Class!\n"); else - printf("%s, %s\n", major_devices[cls[1] & 0x1f], + printf("%s, %s\n", major_devices[cls[1] & 0x1f], get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); } } @@ -743,8 +743,8 @@ static void cmd_inq_parms(int ctl, int hdev, char *opt) rq.cparam = &cp; rq.clen = WRITE_INQ_ACTIVITY_CP_SIZE; - cp.window = htobs((uint16_t)window); - cp.interval = htobs((uint16_t)interval); + cp.window = htobs((uint16_t) window); + cp.interval = htobs((uint16_t) interval); if (window < 0x12 || window > 0x1000) printf("Warning: inquiry window out of range!\n"); @@ -812,8 +812,8 @@ static void cmd_page_parms(int ctl, int hdev, char *opt) rq.cparam = &cp; rq.clen = WRITE_PAGE_ACTIVITY_CP_SIZE; - cp.window = htobs((uint16_t)window); - cp.interval = htobs((uint16_t)interval); + cp.window = htobs((uint16_t) window); + cp.interval = htobs((uint16_t) interval); if (window < 0x12 || window > 0x1000) printf("Warning: page window out of range!\n"); @@ -881,7 +881,7 @@ static void cmd_page_to(int ctl, int hdev, char *opt) rq.cparam = &cp; rq.clen = WRITE_PAGE_TIMEOUT_CP_SIZE; - cp.timeout = htobs((uint16_t)timeout); + cp.timeout = htobs((uint16_t) timeout); if (timeout < 0x01 || timeout > 0xFFFF) printf("Warning: page timeout out of range!\n"); -- cgit From 8e8b4632526b90c9a8a86d1829ee5b71033d3fbb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Mar 2005 19:19:52 +0000 Subject: Add new search command and OUI support --- tools/hcitool.c | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- tools/oui.c | 100 ++++++++++++++++++ tools/oui.h | 30 ++++++ 3 files changed, 440 insertions(+), 4 deletions(-) create mode 100644 tools/oui.c create mode 100644 tools/oui.h diff --git a/tools/hcitool.c b/tools/hcitool.c index 27ac78b7..9c4dc468 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -44,6 +44,8 @@ #include #include +#include "oui.h" + #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) static void usage(void); @@ -224,8 +226,8 @@ static void cmd_inq(int dev_id, int argc, char **argv) ba2str(&(info+i)->bdaddr, addr); printf("\t%s\tclock offset: 0x%4.4x\tclass: 0x%2.2x%2.2x%2.2x\n", addr, btohs((info+i)->clock_offset), - (info+i)->dev_class[2], - (info+i)->dev_class[1], + (info+i)->dev_class[2], + (info+i)->dev_class[1], (info+i)->dev_class[0]); } free(info); @@ -250,7 +252,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) inquiry_info *info = NULL; int num_rsp, length, flags; char addr[18]; - char name[248]; + char name[249]; int i, opt, dd; length = 8; /* ~10 seconds */ @@ -383,7 +385,7 @@ static void cmd_info(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; uint16_t handle; - char name[248]; + char name[249], oui[9], *comp; unsigned char features[8]; struct hci_version version; struct hci_dev_info di; @@ -454,6 +456,13 @@ static void cmd_info(int dev_id, int argc, char **argv) printf("\tBD Address: %s\n", argv[0]); + ba2oui(&bdaddr, oui); + comp = ouitocomp(oui); + if (comp) { + printf("\tOUI Company: %s (%s)\n", comp, oui); + free(comp); + } + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, 25000) == 0) printf("\tDevice Name: %s\n", name); @@ -482,6 +491,302 @@ static void cmd_info(int dev_id, int argc, char **argv) close(dd); } +/* Find remote devices */ + +static struct option find_options[] = { + { "help", 0, 0, 'h' }, + { "length", 1, 0, 'l' }, + { "numrsp", 1, 0, 'n' }, + { "flush", 0, 0, 'f' }, + { 0, 0, 0, 0 } +}; + +static char *find_help = + "Usage:\n" + "\tfind [--length=N] [--numrsp=N] [--flush]\n"; + +static char *get_minor_device_name(int major, int minor) +{ + switch (major) { + case 0: /* misc */ + return ""; + case 1: /* computer */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Desktop workstation"; + case 2: + return "Server"; + case 3: + return "Laptop"; + case 4: + return "Handheld"; + case 5: + return "Palm"; + case 6: + return "Wearable"; + } + break; + case 2: /* phone */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Cellular"; + case 2: + return "Cordless"; + case 3: + return "Smart phone"; + case 4: + return "Wired modem or voice gateway"; + case 5: + return "Common ISDN Access"; + case 6: + return "Sim Card Reader"; + } + break; + case 3: /* lan access */ + if (minor == 0) + return "Uncategorized"; + switch(minor / 8) { + case 0: + return "Fully available"; + case 1: + return "1-17% utilized"; + case 2: + return "17-33% utilized"; + case 3: + return "33-50% utilized"; + case 4: + return "50-67% utilized"; + case 5: + return "67-83% utilized"; + case 6: + return "83-99% utilized"; + case 7: + return "No service available"; + } + break; + case 4: /* audio/video */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Device conforms to the Headset profile"; + case 2: + return "Hands-free"; + /* 3 is reserved */ + case 4: + return "Microphone"; + case 5: + return "Loudspeaker"; + case 6: + return "Headphones"; + case 7: + return "Portable Audio"; + case 8: + return "Car Audio"; + case 9: + return "Set-top box"; + case 10: + return "HiFi Audio Device"; + case 11: + return "VCR"; + case 12: + return "Video Camera"; + case 13: + return "Camcorder"; + case 14: + return "Video Monitor"; + case 15: + return "Video Display and Loudspeaker"; + case 16: + return "Video Conferencing"; + /* 17 is reserved */ + case 18: + return "Gaming/Toy"; + } + break; + case 5: /* peripheral */ + switch(minor) { + case 16: + return "Keyboard"; + case 32: + return "Pointing device"; + case 48: + return "Combo keyboard/pointing device"; + } + break; + case 6: /* imaging */ + if (minor & 4) + return "Display"; + if (minor & 8) + return "Camera"; + if (minor & 16) + return "Scanner"; + if (minor & 32) + return "Printer"; + break; + case 63: /* uncategorised */ + return ""; + } + return "Unknown (reserved) minor device class"; +} + +static char *major_classes[] = { + "Miscellaneous", "Computer", "Phone", "LAN Access", + "Audio/Video", "Peripheral", "Imaging", "Uncategorized" +}; + +static void cmd_find(int dev_id, int argc, char **argv) +{ + inquiry_info *info = NULL; + int num_rsp, length, flags; + uint8_t cls[3]; + uint16_t handle; + char addr[18], name[249], oui[9], *comp; + unsigned char features[8]; + struct hci_version version; + struct hci_dev_info di; + struct hci_conn_info_req *cr; + int i, opt, dd, cc = 0; + + length = 8; /* ~10 seconds */ + num_rsp = 100; + flags = 0; + + for_each_opt(opt, find_options, NULL) { + switch (opt) { + case 'l': + length = atoi(optarg); + break; + + case 'n': + num_rsp = atoi(optarg); + break; + + case 'f': + flags |= IREQ_CACHE_FLUSH; + break; + + default: + printf(find_help); + return; + } + } + + if (dev_id < 0) { + dev_id = hci_get_route(NULL); + if (dev_id < 0) { + perror("Device is not available"); + exit(1); + } + } + + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + + printf("Searching ...\n"); + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + if (num_rsp < 0) { + perror("Inquiry failed"); + exit(1); + } + + dd = hci_open_dev(dev_id); + if (dd < 0) { + perror("HCI device open failed"); + free(info); + exit(1); + } + + printf("\n"); + + for (i = 0; i < num_rsp; i++) { + ba2str(&(info+i)->bdaddr, addr); + printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, + (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); + + ba2oui(&(info+i)->bdaddr, oui); + comp = ouitocomp(oui); + if (comp) { + printf("OUI company:\t%s (%s)\n", comp, oui); + free(comp); + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (cr) { + bacpy(&cr->bdaddr, &(info+i)->bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + if (hci_create_connection(dd, &(info+i)->bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + (info+i)->clock_offset | 0x8000, + 0x01, &handle, 25000) < 0) + handle = 0; + else + cc = 1; + } else + handle = htobs(cr->conn_info->handle); + } else + handle = 0; + + memset(name, 0, sizeof(name)); + if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + printf("Device name:\t%s\n", name); + + memcpy(cls, (info+i)->dev_class, 3); + printf("Device class:\t"); + if ((cls[1] & 0x1f) > sizeof(*major_classes)) + printf("Invalid"); + else + printf("%s, %s", major_classes[cls[1] & 0x1f], + get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); + printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); + + if (handle > 0) { + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + printf("Manufacturer:\t%s (%d)\n", + bt_compidtostr(version.manufacturer), + version.manufacturer); + printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", + lmp_vertostr(version.lmp_ver), + version.lmp_ver, version.lmp_subver); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" + " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + features[0], features[1], + features[2], features[3], + features[4], features[5], + features[6], features[7]); + printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); + } + + if (cc) { + usleep(10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } + } + + printf("\n"); + + if (cr) + free(cr); + } + + close(dd); + free(info); +} + /* Send arbitrary HCI commands */ static struct option cmd_options[] = { @@ -1637,6 +1942,7 @@ static struct { { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, + { "find", cmd_find, "Search for remote devices" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, diff --git a/tools/oui.c b/tools/oui.c new file mode 100644 index 00000000..7dff358b --- /dev/null +++ b/tools/oui.c @@ -0,0 +1,100 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "oui.h" + +/* http://standards.ieee.org/regauth/oui/oui.txt */ + +#define OUIFILE "/usr/share/misc/oui.txt" + +#define AWKCMD "/usr/bin/awk" +#define TRCMD "/usr/bin/tr" + +char *ouitocomp(const char *oui) +{ + struct stat st; + FILE *input; + char cmd[512]; + char *str; + size_t len; + + if (stat(OUIFILE, &st) < 0) + return NULL; + + if (stat(AWKCMD, &st) < 0) + return NULL; + + if (stat(TRCMD, &st) < 0) + return NULL; + + str = malloc(128); + if (!str) + return NULL; + + memset(str, 0, 128); + + snprintf(cmd, sizeof(cmd) - 1, "%s -F'\\t' '/^" + "%s.*\\(hex\\).*/{ print $3 }' %s" + " | %s -d '\\n\\r'", AWKCMD, oui, OUIFILE, TRCMD); + + input = popen(cmd, "r"); + if (!input) { + free(str); + return NULL; + } + + len = fread(str, 127, 1, input); + pclose(input); + + return str; +} + +int oui2comp(const char *oui, char *comp, size_t size) +{ + char *tmp; + + tmp = ouitocomp(oui); + if (!tmp) + return -1; + + snprintf(comp, size, "%s", tmp); + + free(tmp); + + return 0; +} diff --git a/tools/oui.h b/tools/oui.h new file mode 100644 index 00000000..918a248b --- /dev/null +++ b/tools/oui.h @@ -0,0 +1,30 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +char *ouitocomp(const char *oui); +int oui2comp(const char *oui, char *comp, size_t size); -- cgit From 44b78feaa5e08e10d3d61404cc8ce8de416f70c3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 28 Mar 2005 20:00:34 +0000 Subject: Add support registering PANU service record --- tools/sdptool.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index 5c93dd69..962c9ce9 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1616,6 +1616,68 @@ end: return ret; } +static int add_panu(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, ftrn_uuid, l2cap_uuid, bnep_uuid; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint16_t lp = 0x000f, ver = 0x0100; + sdp_data_t *psm, *version; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + sdp_list_free(root, NULL); + + sdp_uuid16_create(&ftrn_uuid, PANU_SVCLASS_ID); + svclass_id = sdp_list_append(NULL, &ftrn_uuid); + sdp_set_service_classes(&record, svclass_id); + sdp_list_free(svclass_id, NULL); + + sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + sdp_list_free(pfseq, NULL); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(NULL, &l2cap_uuid); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(NULL, proto[0]); + + sdp_uuid16_create(&bnep_uuid, BNEP_UUID); + proto[1] = sdp_list_append(NULL, &bnep_uuid); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(NULL, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "PAN User", NULL, NULL); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("PANU service registered\n"); +end: + sdp_data_free(version); + sdp_data_free(psm); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + static int add_ctp(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -1810,6 +1872,7 @@ struct { { "NAP", NAP_SVCLASS_ID, add_nap }, { "GN", GN_SVCLASS_ID, add_gn }, + { "PANU", PANU_SVCLASS_ID, add_panu }, { "HID", HID_SVCLASS_ID, NULL }, { "CIP", CIP_SVCLASS_ID, NULL }, -- cgit From b0f097c96eed5c5227973a48d8ad30bb5c18703e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Apr 2005 15:20:10 +0000 Subject: Add support for browsing the L2CAP group --- tools/sdptool.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 962c9ce9..980778ea 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2096,12 +2096,13 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) static struct option browse_options[] = { { "help", 0,0, 'h' }, { "tree", 0,0, 't' }, + { "l2cap", 0,0, 'l' }, { 0, 0, 0, 0 } }; static char *browse_help = "Usage:\n" - "\tbrowse [--tree] [bdaddr]\n"; + "\tbrowse [--tree] [--l2cap] [bdaddr]\n"; /* * Browse the full SDP database (i.e. list all services starting from the @@ -2115,13 +2116,16 @@ static int cmd_browse(int argc, char **argv) /* Initialise context */ memset(&context, '\0', sizeof(struct search_context)); /* We want to browse the top-level/root */ - sdp_uuid16_create(&(context.group), PUBLIC_BROWSE_GROUP); + sdp_uuid16_create(&context.group, PUBLIC_BROWSE_GROUP); for_each_opt(opt, browse_options, 0) { switch(opt) { case 't': context.tree = 1; break; + case 'l': + sdp_uuid16_create(&context.group, L2CAP_UUID); + break; default: printf(browse_help); return -1; -- cgit From 7271d875a003eab4af74e0304b2902c36fe86996 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Apr 2005 15:22:13 +0000 Subject: Include oui.[ch] for hcitool --- tools/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/Makefile.am b/tools/Makefile.am index 6470a8a9..b07f2b19 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -20,6 +20,8 @@ hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ +hcitool_SOURCES = hcitool.c oui.h oui.c + hcitool_LDADD = @BLUEZ_LIBS@ l2ping_LDADD = @BLUEZ_LIBS@ -- cgit From 9f02be3e3b3d9af1e11e158c6cf386228e12d41f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 7 Apr 2005 13:43:23 +0000 Subject: Add support to browse various UUIDs --- tools/sdptool.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 980778ea..d3da429d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2094,15 +2094,16 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) } static struct option browse_options[] = { - { "help", 0,0, 'h' }, - { "tree", 0,0, 't' }, - { "l2cap", 0,0, 'l' }, + { "help", 0, 0, 'h' }, + { "tree", 0, 0, 't' }, + { "uuid", 1, 0, 'u' }, + { "l2cap", 0, 0, 'l' }, { 0, 0, 0, 0 } }; static char *browse_help = "Usage:\n" - "\tbrowse [--tree] [--l2cap] [bdaddr]\n"; + "\tbrowse [--tree] [--uuid uuid] [--l2cap] [bdaddr]\n"; /* * Browse the full SDP database (i.e. list all services starting from the @@ -2111,7 +2112,7 @@ static char *browse_help = static int cmd_browse(int argc, char **argv) { struct search_context context; - int opt; + int opt, num; /* Initialise context */ memset(&context, '\0', sizeof(struct search_context)); @@ -2123,6 +2124,13 @@ static int cmd_browse(int argc, char **argv) case 't': context.tree = 1; break; + case 'u': + if (sscanf(optarg, "%i", &num) != 1 || num < 0 || num > 0xffff) { + printf("Invalid uuid %s\n", optarg); + return -1; + } + sdp_uuid16_create(&context.group, num); + break; case 'l': sdp_uuid16_create(&context.group, L2CAP_UUID); break; -- cgit From 7637f1adf0fa094d07379965169b7444e3ebba4d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 7 Apr 2005 15:58:44 +0000 Subject: Add build id for BlueCore4-ROM with HCI 19.2 firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/csr.c b/tools/csr.c index e3353cdc..27a6a9a4 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -268,6 +268,7 @@ static struct { { 1737, "HCI 18.3" }, { 1915, "HCI 19.2" }, { 1916, "HCI 19.2" }, + { 1958, "HCI 19.2" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From f1a83659170a8f324991061c9ed14f39393e7c10 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Apr 2005 16:06:45 +0000 Subject: Integrate find options into scan command --- tools/hcitool.c | 572 ++++++++++++++++++++++++++------------------------------ 1 file changed, 269 insertions(+), 303 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 9c4dc468..9ac890fd 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -142,6 +142,140 @@ static void hex_dump(char *pref, int width, unsigned char *buf, int len) printf("\n"); } +static char *get_minor_device_name(int major, int minor) +{ + switch (major) { + case 0: /* misc */ + return ""; + case 1: /* computer */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Desktop workstation"; + case 2: + return "Server"; + case 3: + return "Laptop"; + case 4: + return "Handheld"; + case 5: + return "Palm"; + case 6: + return "Wearable"; + } + break; + case 2: /* phone */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Cellular"; + case 2: + return "Cordless"; + case 3: + return "Smart phone"; + case 4: + return "Wired modem or voice gateway"; + case 5: + return "Common ISDN Access"; + case 6: + return "Sim Card Reader"; + } + break; + case 3: /* lan access */ + if (minor == 0) + return "Uncategorized"; + switch(minor / 8) { + case 0: + return "Fully available"; + case 1: + return "1-17% utilized"; + case 2: + return "17-33% utilized"; + case 3: + return "33-50% utilized"; + case 4: + return "50-67% utilized"; + case 5: + return "67-83% utilized"; + case 6: + return "83-99% utilized"; + case 7: + return "No service available"; + } + break; + case 4: /* audio/video */ + switch(minor) { + case 0: + return "Uncategorized"; + case 1: + return "Device conforms to the Headset profile"; + case 2: + return "Hands-free"; + /* 3 is reserved */ + case 4: + return "Microphone"; + case 5: + return "Loudspeaker"; + case 6: + return "Headphones"; + case 7: + return "Portable Audio"; + case 8: + return "Car Audio"; + case 9: + return "Set-top box"; + case 10: + return "HiFi Audio Device"; + case 11: + return "VCR"; + case 12: + return "Video Camera"; + case 13: + return "Camcorder"; + case 14: + return "Video Monitor"; + case 15: + return "Video Display and Loudspeaker"; + case 16: + return "Video Conferencing"; + /* 17 is reserved */ + case 18: + return "Gaming/Toy"; + } + break; + case 5: /* peripheral */ + switch(minor) { + case 16: + return "Keyboard"; + case 32: + return "Pointing device"; + case 48: + return "Combo keyboard/pointing device"; + } + break; + case 6: /* imaging */ + if (minor & 4) + return "Display"; + if (minor & 8) + return "Camera"; + if (minor & 16) + return "Scanner"; + if (minor & 32) + return "Printer"; + break; + case 63: /* uncategorised */ + return ""; + } + return "Unknown (reserved) minor device class"; +} + +static char *major_classes[] = { + "Miscellaneous", "Computer", "Phone", "LAN Access", + "Audio/Video", "Peripheral", "Imaging", "Uncategorized" +}; + /* Display local devices */ static struct option dev_options[] = { @@ -240,20 +374,31 @@ static struct option scan_options[] = { { "length", 1, 0, 'l' }, { "numrsp", 1, 0, 'n' }, { "flush", 0, 0, 'f' }, + { "class", 0, 0, 'c' }, + { "info", 0, 0, 'i' }, + { "oui", 0, 0, 'o' }, + { "all", 0, 0, 'a' }, + { "ext", 0, 0, 'a' }, { 0, 0, 0, 0 } }; static char *scan_help = "Usage:\n" - "\tscan [--length=N] [--numrsp=N] [--flush]\n"; + "\tscan [--length=N] [--numrsp=N] [--flush] [--class] [--info] [--oui]\n"; static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; int num_rsp, length, flags; - char addr[18]; - char name[249]; - int i, opt, dd; + uint8_t cls[3]; + uint16_t handle; + char addr[18], name[249], oui[9], *comp; + unsigned char features[8]; + struct hci_version version; + struct hci_dev_info di; + struct hci_conn_info_req *cr; + int extcls = 0, extinf = 0, extoui = 0; + int i, opt, dd, cc; length = 8; /* ~10 seconds */ num_rsp = 100; @@ -273,6 +418,24 @@ static void cmd_scan(int dev_id, int argc, char **argv) flags |= IREQ_CACHE_FLUSH; break; + case 'c': + extcls = 1; + break; + + case 'i': + extinf = 1; + break; + + case 'o': + extoui = 1; + break; + + case 'a': + extcls = 1; + extinf = 1; + extoui = 1; + break; + default: printf(scan_help); return; @@ -287,6 +450,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } + if (hci_devinfo(dev_id, &di) < 0) { + perror("Can't get device info"); + exit(1); + } + printf("Scanning ...\n"); num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); if (num_rsp < 0) { @@ -301,15 +469,110 @@ static void cmd_scan(int dev_id, int argc, char **argv) exit(1); } + if (extcls || extinf || extoui) + printf("\n"); + for (i = 0; i < num_rsp; i++) { + if (!extcls && !extinf && !extoui) { + memset(name, 0, sizeof(name)); + if (hci_read_remote_name_with_clock_offset(dd, + &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\t%s\n", addr, name); + continue; + } + + ba2str(&(info+i)->bdaddr, addr); + printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, + (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); + + if (extoui) { + ba2oui(&(info+i)->bdaddr, oui); + comp = ouitocomp(oui); + if (comp) { + printf("OUI company:\t%s (%s)\n", comp, oui); + free(comp); + } + } + + cc = 0; + + if (extinf) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (cr) { + bacpy(&cr->bdaddr, &(info+i)->bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + handle = 0; + cc = 1; + } else { + handle = htobs(cr->conn_info->handle); + cc = 0; + } + free(cr); + } + + if (cc) { + if (hci_create_connection(dd, &(info+i)->bdaddr, + htobs(di.pkt_type & ACL_PTYPE_MASK), + (info+i)->clock_offset | 0x8000, + 0x01, &handle, 25000) < 0) { + handle = 0; + cc = 0; + } + } + } + memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, (info+i)->pscan_rep_mode, (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - ba2str(&(info+i)->bdaddr, addr); - printf("\t%s\t%s\n", addr, name); + printf("Device name:\t%s\n", name); + + if (extcls) { + memcpy(cls, (info+i)->dev_class, 3); + printf("Device class:\t"); + if ((cls[1] & 0x1f) > sizeof(*major_classes)) + printf("Invalid"); + else + printf("%s, %s", major_classes[cls[1] & 0x1f], + get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); + printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); + } + + if (extinf && handle > 0) { + if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + printf("Manufacturer:\t%s (%d)\n", + bt_compidtostr(version.manufacturer), + version.manufacturer); + printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", + lmp_vertostr(version.lmp_ver), + version.lmp_ver, version.lmp_subver); + } + + if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" + " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + features[0], features[1], + features[2], features[3], + features[4], features[5], + features[6], features[7]); + printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); + } + + if (cc) { + usleep(10000); + hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); + } + } + + printf("\n"); } close(dd); @@ -491,302 +754,6 @@ static void cmd_info(int dev_id, int argc, char **argv) close(dd); } -/* Find remote devices */ - -static struct option find_options[] = { - { "help", 0, 0, 'h' }, - { "length", 1, 0, 'l' }, - { "numrsp", 1, 0, 'n' }, - { "flush", 0, 0, 'f' }, - { 0, 0, 0, 0 } -}; - -static char *find_help = - "Usage:\n" - "\tfind [--length=N] [--numrsp=N] [--flush]\n"; - -static char *get_minor_device_name(int major, int minor) -{ - switch (major) { - case 0: /* misc */ - return ""; - case 1: /* computer */ - switch(minor) { - case 0: - return "Uncategorized"; - case 1: - return "Desktop workstation"; - case 2: - return "Server"; - case 3: - return "Laptop"; - case 4: - return "Handheld"; - case 5: - return "Palm"; - case 6: - return "Wearable"; - } - break; - case 2: /* phone */ - switch(minor) { - case 0: - return "Uncategorized"; - case 1: - return "Cellular"; - case 2: - return "Cordless"; - case 3: - return "Smart phone"; - case 4: - return "Wired modem or voice gateway"; - case 5: - return "Common ISDN Access"; - case 6: - return "Sim Card Reader"; - } - break; - case 3: /* lan access */ - if (minor == 0) - return "Uncategorized"; - switch(minor / 8) { - case 0: - return "Fully available"; - case 1: - return "1-17% utilized"; - case 2: - return "17-33% utilized"; - case 3: - return "33-50% utilized"; - case 4: - return "50-67% utilized"; - case 5: - return "67-83% utilized"; - case 6: - return "83-99% utilized"; - case 7: - return "No service available"; - } - break; - case 4: /* audio/video */ - switch(minor) { - case 0: - return "Uncategorized"; - case 1: - return "Device conforms to the Headset profile"; - case 2: - return "Hands-free"; - /* 3 is reserved */ - case 4: - return "Microphone"; - case 5: - return "Loudspeaker"; - case 6: - return "Headphones"; - case 7: - return "Portable Audio"; - case 8: - return "Car Audio"; - case 9: - return "Set-top box"; - case 10: - return "HiFi Audio Device"; - case 11: - return "VCR"; - case 12: - return "Video Camera"; - case 13: - return "Camcorder"; - case 14: - return "Video Monitor"; - case 15: - return "Video Display and Loudspeaker"; - case 16: - return "Video Conferencing"; - /* 17 is reserved */ - case 18: - return "Gaming/Toy"; - } - break; - case 5: /* peripheral */ - switch(minor) { - case 16: - return "Keyboard"; - case 32: - return "Pointing device"; - case 48: - return "Combo keyboard/pointing device"; - } - break; - case 6: /* imaging */ - if (minor & 4) - return "Display"; - if (minor & 8) - return "Camera"; - if (minor & 16) - return "Scanner"; - if (minor & 32) - return "Printer"; - break; - case 63: /* uncategorised */ - return ""; - } - return "Unknown (reserved) minor device class"; -} - -static char *major_classes[] = { - "Miscellaneous", "Computer", "Phone", "LAN Access", - "Audio/Video", "Peripheral", "Imaging", "Uncategorized" -}; - -static void cmd_find(int dev_id, int argc, char **argv) -{ - inquiry_info *info = NULL; - int num_rsp, length, flags; - uint8_t cls[3]; - uint16_t handle; - char addr[18], name[249], oui[9], *comp; - unsigned char features[8]; - struct hci_version version; - struct hci_dev_info di; - struct hci_conn_info_req *cr; - int i, opt, dd, cc = 0; - - length = 8; /* ~10 seconds */ - num_rsp = 100; - flags = 0; - - for_each_opt(opt, find_options, NULL) { - switch (opt) { - case 'l': - length = atoi(optarg); - break; - - case 'n': - num_rsp = atoi(optarg); - break; - - case 'f': - flags |= IREQ_CACHE_FLUSH; - break; - - default: - printf(find_help); - return; - } - } - - if (dev_id < 0) { - dev_id = hci_get_route(NULL); - if (dev_id < 0) { - perror("Device is not available"); - exit(1); - } - } - - if (hci_devinfo(dev_id, &di) < 0) { - perror("Can't get device info"); - exit(1); - } - - printf("Searching ...\n"); - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); - if (num_rsp < 0) { - perror("Inquiry failed"); - exit(1); - } - - dd = hci_open_dev(dev_id); - if (dd < 0) { - perror("HCI device open failed"); - free(info); - exit(1); - } - - printf("\n"); - - for (i = 0; i < num_rsp; i++) { - ba2str(&(info+i)->bdaddr, addr); - printf("BD Address:\t%s [mode %d, clkoffset 0x%4.4x]\n", addr, - (info+i)->pscan_rep_mode, btohs((info+i)->clock_offset)); - - ba2oui(&(info+i)->bdaddr, oui); - comp = ouitocomp(oui); - if (comp) { - printf("OUI company:\t%s (%s)\n", comp, oui); - free(comp); - } - - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (cr) { - bacpy(&cr->bdaddr, &(info+i)->bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - if (hci_create_connection(dd, &(info+i)->bdaddr, - htobs(di.pkt_type & ACL_PTYPE_MASK), - (info+i)->clock_offset | 0x8000, - 0x01, &handle, 25000) < 0) - handle = 0; - else - cc = 1; - } else - handle = htobs(cr->conn_info->handle); - } else - handle = 0; - - memset(name, 0, sizeof(name)); - if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - (info+i)->pscan_rep_mode, - (info+i)->clock_offset | 0x8000, - sizeof(name), name, 100000) < 0) - strcpy(name, "n/a"); - printf("Device name:\t%s\n", name); - - memcpy(cls, (info+i)->dev_class, 3); - printf("Device class:\t"); - if ((cls[1] & 0x1f) > sizeof(*major_classes)) - printf("Invalid"); - else - printf("%s, %s", major_classes[cls[1] & 0x1f], - get_minor_device_name(cls[1] & 0x1f, cls[0] >> 2)); - printf(" (0x%2.2x%2.2x%2.2x)\n", cls[2], cls[1], cls[0]); - - if (handle > 0) { - if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { - printf("Manufacturer:\t%s (%d)\n", - bt_compidtostr(version.manufacturer), - version.manufacturer); - printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", - lmp_vertostr(version.lmp_ver), - version.lmp_ver, version.lmp_subver); - } - - if (hci_read_remote_features(dd, handle, features, 20000) == 0) { - printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" - " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", - features[0], features[1], - features[2], features[3], - features[4], features[5], - features[6], features[7]); - printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); - } - - if (cc) { - usleep(10000); - hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); - } - } - - printf("\n"); - - if (cr) - free(cr); - } - - close(dd); - free(info); -} - /* Send arbitrary HCI commands */ static struct option cmd_options[] = { @@ -1942,7 +1909,6 @@ static struct { { "scan", cmd_scan, "Scan for remote devices" }, { "name", cmd_name, "Get name from remote device" }, { "info", cmd_info, "Get information from remote device" }, - { "find", cmd_find, "Search for remote devices" }, { "cmd", cmd_cmd, "Submit arbitrary HCI commands" }, { "con", cmd_con, "Display active connections" }, { "cc", cmd_cc, "Create connection to remote device" }, -- cgit From 0467164fb3a90cddff16c52fc4172029f978497d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 15:19:04 +0000 Subject: Store device names in the background --- hcid/hcid.h | 1 + hcid/security.c | 4 +- hcid/storage.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 180 insertions(+), 3 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index 845e3889..bcc43e4a 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -111,3 +111,4 @@ gboolean hcid_dbus_init(void); #endif int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); +int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type); diff --git a/hcid/security.c b/hcid/security.c index f0bf12bd..92353373 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -193,6 +193,8 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) key.time = time(0); save_link_key(&key); + + write_link_key(sba, dba, evt->link_key, evt->key_type); } /* PIN code handling */ @@ -386,7 +388,7 @@ static void remote_name_information(int dev, bdaddr_t *sba, void *ptr) evt_remote_name_req_complete *evt = ptr; bdaddr_t *dba = &evt->bdaddr; - if (!evt->status) + if (evt->status) return; write_device_name(sba, dba, evt->name); diff --git a/hcid/storage.c b/hcid/storage.c index cd04b254..a025e674 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -34,15 +34,189 @@ #include #include +#include +#include +#include +#include +#include +#include #include #include #include "hcid.h" -#define DEVPATH "/etc/bluetooth/devices" +#define DEVPATH "/var/cache/bluetooth/" + +struct name_list { + bdaddr_t bdaddr; + char name[249]; + struct name_list *next; +}; + +static struct name_list *name_add(struct name_list *list, const bdaddr_t *bdaddr, const char *name) +{ + struct name_list *temp = list, *last = list; + + if (!bacmp(bdaddr, BDADDR_ANY)) + return list; + + while (temp) { + if (!bacmp(&temp->bdaddr, bdaddr)) { + memcpy(temp->name, name, sizeof(temp->name)); + return list; + } + temp = temp->next; + } + + temp = malloc(sizeof(*temp)); + if (!temp) + return list; + + memset(temp, 0, sizeof(*temp)); + + bacpy(&temp->bdaddr, bdaddr); + memcpy(temp->name, name, sizeof(temp->name)); + temp->next = NULL; + + if (!list) + return temp; + + while (last->next) + last = last->next; + + last->next = temp; + + return list; +} + +static struct name_list *name_free(struct name_list *list) +{ + struct name_list *temp = list; + + if (!list) + return NULL; + + while (list->next) { + temp = list; + list = list->next; + free(temp); + } + + return NULL; +} + +#define name_foreach(list, entry) \ + for (entry = list; entry; entry = entry->next) + +static int create_dirs(const char *filename, mode_t mode) +{ + struct stat st; + char dir[PATH_MAX + 1], *prev, *next; + int err; + + err = stat(filename, &st); + if (!err && S_ISREG(st.st_mode)) + return 0; + + memset(dir, 0, PATH_MAX + 1); + strcat(dir, "/"); + + prev = strchr(filename, '/'); + + while (prev) { + next = strchr(prev + 1, '/'); + if (!next) + break; + + if (next - prev == 1) { + prev = next; + continue; + } + + strncat(dir, prev + 1, next - prev); + mkdir(dir, mode); + + prev = next; + } + + return 0; +} int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) { - return -EIO; + struct name_list *temp, *list = NULL; + mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + mode_t mask = S_IWGRP | S_IWOTH; + char filename[PATH_MAX + 1]; + char addr[18], str[249], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int fd, pos, err = 0; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + + umask(mask); + create_dirs(filename, mode); + + fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_EX) < 0) { + err = -errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size + 200); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + list = name_add(list, &bdaddr, str); + ptr += pos; + }; + + lseek(fd, 0, SEEK_SET); + ftruncate(fd, 0); + } + + list = name_add(list, peer, name); + if (!list) { + err = -EIO; + goto unlock; + } + + name_foreach(list, temp) { + ba2str(&temp->bdaddr, addr); + snprintf(buf, 200, "%s %s\n", addr, temp->name); + write(fd, buf, strlen(buf)); + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + name_free(list); + return err; +} + +int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type) +{ + return 0; } -- cgit From 828029f202d7a7116d663ee9b9465b60c1eac030 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 15:21:18 +0000 Subject: Flag to activate flow control mode --- test/l2test.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/l2test.c b/test/l2test.c index 35e06598..f3ff2bc4 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -81,6 +81,7 @@ static unsigned short psm = 10; /* Default number of frames to send (-1 = infinite) */ static int num_frames = -1; +static int flowctl = 0; static int master = 0; static int auth = 0; static int encrypt = 0; @@ -206,6 +207,8 @@ static int do_connect(char *svr) /* Set new options */ opts.omtu = omtu; opts.imtu = imtu; + if (flowctl) + opts.mode = 2; if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", @@ -338,6 +341,8 @@ static void do_listen(void (*handler)(int sk)) /* Set new options */ opts.imtu = imtu; + if (flowctl) + opts.mode = 2; if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) { syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)", @@ -669,6 +674,7 @@ static void usage(void) "\t[-L seconds] enable SO_LINGER\n" "\t[-R] reliable mode\n" "\t[-D] use connectionless channel (datagram)\n" + "\t[-F] enable flow control\n" "\t[-A] request authentication\n" "\t[-E] request encryption\n" "\t[-S] secure connection\n" @@ -682,7 +688,7 @@ int main(int argc ,char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:RMAESL:D")) != EOF) { + while ((opt=getopt(argc,argv,"rdscuwmnxyb:i:P:I:O:N:L:RDFAESM")) != EOF) { switch(opt) { case 'r': mode = RECV; @@ -764,6 +770,10 @@ int main(int argc ,char *argv[]) master = 1; break; + case 'F': + flowctl = 1; + break; + case 'A': auth = 1; break; -- cgit From bbf5eef59916cd1230ef71dc7b9be055397b0074 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 15:54:26 +0000 Subject: Add framework for read_link_key() --- hcid/hcid.h | 1 + hcid/security.c | 26 ++++++++++++++++++-------- hcid/storage.c | 5 +++++ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index bcc43e4a..9c96d91a 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -112,3 +112,4 @@ gboolean hcid_dbus_init(void); int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type); +int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key); diff --git a/hcid/security.c b/hcid/security.c index 92353373..e66e030e 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -114,23 +114,33 @@ static struct link_key *get_link_key(bdaddr_t *sba, bdaddr_t *dba) static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) { - struct link_key *key = get_link_key(sba, dba); + unsigned char key[16]; char sa[18], da[18]; + int err; ba2str(sba, sa); ba2str(dba, da); syslog(LOG_INFO, "link_key_request (sba=%s, dba=%s)", sa, da); - if (key) { + err = read_link_key(sba, dba, key); + if (err < 0) { + struct link_key *linkkey = get_link_key(sba, dba); + if (linkkey) { + memcpy(key, linkkey->key, 16); + linkkey->time = time(0); + err = 0; + } + } + + if (err < 0) { + /* Link key not found */ + hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba); + } else { /* Link key found */ link_key_reply_cp lr; - memcpy(lr.link_key, key->key, 16); + memcpy(lr.link_key, key, 16); bacpy(&lr.bdaddr, dba); hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY, - LINK_KEY_REPLY_CP_SIZE, &lr); - key->time = time(0); - } else { - /* Link key not found */ - hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba); + LINK_KEY_REPLY_CP_SIZE, &lr); } } diff --git a/hcid/storage.c b/hcid/storage.c index a025e674..d38e6aef 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -220,3 +220,8 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c { return 0; } + +int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key) +{ + return -ENOENT; +} -- cgit From d5c864c1c4828b8a7fedca819ef6b2cb4f20a24d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 16:02:18 +0000 Subject: Create the linkkey file --- hcid/storage.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/hcid/storage.c b/hcid/storage.c index d38e6aef..aeb98480 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -146,10 +146,7 @@ static int create_dirs(const char *filename, mode_t mode) int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) { struct name_list *temp, *list = NULL; - mode_t mode = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; - mode_t mask = S_IWGRP | S_IWOTH; - char filename[PATH_MAX + 1]; - char addr[18], str[249], *buf, *ptr; + char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; bdaddr_t bdaddr; struct stat st; int fd, pos, err = 0; @@ -157,8 +154,8 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); - umask(mask); - create_dirs(filename, mode); + umask(S_IWGRP | S_IWOTH); + create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) @@ -218,6 +215,21 @@ close: int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type) { + char filename[PATH_MAX + 1], addr[18]; + int fd; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/linkkeys", DEVPATH, addr); + + umask(S_IWGRP | S_IWOTH); + create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + + fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0) + return -errno; + + close(fd); + return 0; } -- cgit From cdb1b911f93c49ab242b674f8f2a0e0a0b28d4d6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 18:31:47 +0000 Subject: Use /var/lib/bluetooth/ as base directory --- hcid/storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hcid/storage.c b/hcid/storage.c index aeb98480..05e006c2 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -46,7 +46,7 @@ #include "hcid.h" -#define DEVPATH "/var/cache/bluetooth/" +#define DEVPATH "/var/lib/bluetooth/" struct name_list { bdaddr_t bdaddr; -- cgit From 76bc6f44a3d1eecf610d9191dfb443a66a8e9db6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:07:39 +0000 Subject: Add link key storage function --- hcid/storage.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 20 deletions(-) diff --git a/hcid/storage.c b/hcid/storage.c index 05e006c2..0932e2ef 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -48,22 +48,33 @@ #define DEVPATH "/var/lib/bluetooth/" -struct name_list { +struct list { bdaddr_t bdaddr; - char name[249]; - struct name_list *next; + unsigned char *data; + size_t size; + struct list *next; }; -static struct name_list *name_add(struct name_list *list, const bdaddr_t *bdaddr, const char *name) +static struct list *list_add(struct list *list, const bdaddr_t *bdaddr, + const unsigned char *data, const size_t size) { - struct name_list *temp = list, *last = list; + struct list *temp = list, *last = list; if (!bacmp(bdaddr, BDADDR_ANY)) return list; while (temp) { if (!bacmp(&temp->bdaddr, bdaddr)) { - memcpy(temp->name, name, sizeof(temp->name)); + if (temp->data) + free(temp->data); + + temp->data = malloc(size); + if (temp->data) { + memcpy(temp->data, data, size); + temp->size = size; + } else + temp->size = 0; + return list; } temp = temp->next; @@ -76,7 +87,13 @@ static struct name_list *name_add(struct name_list *list, const bdaddr_t *bdaddr memset(temp, 0, sizeof(*temp)); bacpy(&temp->bdaddr, bdaddr); - memcpy(temp->name, name, sizeof(temp->name)); + temp->data = malloc(size); + if (temp->data) { + memcpy(temp->data, data, size); + temp->size = size; + } else + temp->size = 0; + temp->next = NULL; if (!list) @@ -90,9 +107,9 @@ static struct name_list *name_add(struct name_list *list, const bdaddr_t *bdaddr return list; } -static struct name_list *name_free(struct name_list *list) +static struct list *list_free(struct list *list) { - struct name_list *temp = list; + struct list *temp = list; if (!list) return NULL; @@ -100,13 +117,15 @@ static struct name_list *name_free(struct name_list *list) while (list->next) { temp = list; list = list->next; + if (temp->data) + free(temp->data); free(temp); } return NULL; } -#define name_foreach(list, entry) \ +#define list_foreach(list, entry) \ for (entry = list; entry; entry = entry->next) static int create_dirs(const char *filename, mode_t mode) @@ -145,7 +164,7 @@ static int create_dirs(const char *filename, mode_t mode) int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) { - struct name_list *temp, *list = NULL; + struct list *temp, *list = NULL; char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; bdaddr_t bdaddr; struct stat st; @@ -184,7 +203,7 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { str2ba(addr, &bdaddr); - list = name_add(list, &bdaddr, str); + list = list_add(list, &bdaddr, str, strlen(str) + 1); ptr += pos; }; @@ -192,15 +211,15 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n ftruncate(fd, 0); } - list = name_add(list, peer, name); + list = list_add(list, peer, name, strlen(name) + 1); if (!list) { err = -EIO; goto unlock; } - name_foreach(list, temp) { + list_foreach(list, temp) { ba2str(&temp->bdaddr, addr); - snprintf(buf, 200, "%s %s\n", addr, temp->name); + snprintf(buf, 200, "%s %s\n", addr, temp->data); write(fd, buf, strlen(buf)); } @@ -209,14 +228,17 @@ unlock: close: close(fd); - name_free(list); + list_free(list); return err; } int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type) { - char filename[PATH_MAX + 1], addr[18]; - int fd; + struct list *temp, *list = NULL; + char filename[PATH_MAX + 1], addr[18], str[35], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int i, fd, pos, err = 0; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/linkkeys", DEVPATH, addr); @@ -228,9 +250,61 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c if (fd < 0) return -errno; - close(fd); + if (flock(fd, LOCK_EX) < 0) { + err = -errno; + goto close; + } - return 0; + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size + 200); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + list = list_add(list, &bdaddr, str, strlen(str) + 1); + ptr += pos; + }; + + lseek(fd, 0, SEEK_SET); + ftruncate(fd, 0); + } + + memset(str, 0, sizeof(str)); + for (i = 0; i < 16; i++) + sprintf(str + (i * 2), "%2.2X", key[i]); + sprintf(str + 32, " %d", type); + + list = list_add(list, peer, str, strlen(str) + 1); + if (!list) { + err = -EIO; + goto unlock; + } + + list_foreach(list, temp) { + ba2str(&temp->bdaddr, addr); + snprintf(buf, 200, "%s %s\n", addr, temp->data); + write(fd, buf, strlen(buf)); + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + list_free(list); + return err; } int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key) -- cgit From c766c1afd70c27a87c0a251a1e561b79be195cef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:18:36 +0000 Subject: Add support for reading the link key --- hcid/storage.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/hcid/storage.c b/hcid/storage.c index 0932e2ef..468d273b 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -190,7 +190,7 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n goto unlock; } - buf = malloc(st.st_size + 200); + buf = malloc(st.st_size + 300); if (!buf) { err = -ENOMEM; goto unlock; @@ -219,7 +219,7 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n list_foreach(list, temp) { ba2str(&temp->bdaddr, addr); - snprintf(buf, 200, "%s %s\n", addr, temp->data); + snprintf(buf, 300, "%s %s\n", addr, temp->data); write(fd, buf, strlen(buf)); } @@ -260,7 +260,7 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c goto unlock; } - buf = malloc(st.st_size + 200); + buf = malloc(st.st_size + 100); if (!buf) { err = -ENOMEM; goto unlock; @@ -294,7 +294,7 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c list_foreach(list, temp) { ba2str(&temp->bdaddr, addr); - snprintf(buf, 200, "%s %s\n", addr, temp->data); + snprintf(buf, 100, "%s %s\n", addr, temp->data); write(fd, buf, strlen(buf)); } @@ -309,5 +309,59 @@ close: int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key) { - return -ENOENT; + char filename[PATH_MAX + 1], addr[18], str[35], tmp[3], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int i, fd, pos, err = 0; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/linkkeys", DEVPATH, addr); + + fd = open(filename, O_RDONLY); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_SH) < 0) { + err = -errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + + if (!bacmp(&bdaddr, peer)) { + memset(tmp, 0, sizeof(tmp)); + for (i = 0; i < 16; i++) { + memcpy(tmp, str + (i * 2), 2); + key[i] = (uint8_t) strtol(tmp, NULL, 16); + } + break; + } + + ptr += pos; + }; + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + return err; } -- cgit From 304b8bb466c0b015d30f9dfbc785d2a7c0a2ef79 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:46:13 +0000 Subject: Make use of the device name cache --- tools/hcitool.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 9 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 9ac890fd..947da44e 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -34,9 +34,12 @@ #include #include +#include #include #include #include +#include +#include #include #include @@ -276,6 +279,63 @@ static char *major_classes[] = { "Audio/Video", "Peripheral", "Imaging", "Uncategorized" }; +#define DEVPATH "/var/lib/bluetooth/" + +static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) +{ + char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int fd, pos, err = 0; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + + fd = open(filename, O_RDONLY); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_SH) < 0) { + err = -errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + + if (!bacmp(&bdaddr, peer)) { + snprintf(name, 249, "%s", str); + break; + } + + ptr += pos; + }; + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + return err; +} + /* Display local devices */ static struct option dev_options[] = { @@ -398,7 +458,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_dev_info di; struct hci_conn_info_req *cr; int extcls = 0, extinf = 0, extoui = 0; - int i, opt, dd, cc; + int i, opt, dd, cc, nc; length = 8; /* ~10 seconds */ num_rsp = 100; @@ -473,7 +533,17 @@ static void cmd_scan(int dev_id, int argc, char **argv) printf("\n"); for (i = 0; i < num_rsp; i++) { + memset(name, 0, sizeof(name)); + nc = read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) < 0 ? 0 : 1; + if (!extcls && !extinf && !extoui) { + ba2str(&(info+i)->bdaddr, addr); + + if (nc) { + printf("\t%s\t%s\n", addr, name); + continue; + } + memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, @@ -481,7 +551,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) (info+i)->clock_offset | 0x8000, sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); - ba2str(&(info+i)->bdaddr, addr); + printf("\t%s\t%s\n", addr, name); continue; } @@ -527,13 +597,16 @@ static void cmd_scan(int dev_id, int argc, char **argv) } } - memset(name, 0, sizeof(name)); - if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, - (info+i)->pscan_rep_mode, - (info+i)->clock_offset | 0x8000, - sizeof(name), name, 100000) < 0) - strcpy(name, "n/a"); - printf("Device name:\t%s\n", name); + if (handle > 0 || !nc) { + memset(name, 0, sizeof(name)); + if (hci_read_remote_name_with_clock_offset(dd, + &(info+i)->bdaddr, + (info+i)->pscan_rep_mode, + (info+i)->clock_offset | 0x8000, + sizeof(name), name, 100000) < 0) + strcpy(name, "n/a"); + } + printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); if (extcls) { memcpy(cls, (info+i)->dev_class, 3); -- cgit From 91ec71874613cf65ab0abdaaf62c0b4e6a56a40e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:52:36 +0000 Subject: Fix the name cache state --- tools/hcitool.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 947da44e..a17fe8bc 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -544,7 +544,6 @@ static void cmd_scan(int dev_id, int argc, char **argv) continue; } - memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, (info+i)->pscan_rep_mode, @@ -598,13 +597,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) } if (handle > 0 || !nc) { - memset(name, 0, sizeof(name)); if (hci_read_remote_name_with_clock_offset(dd, &(info+i)->bdaddr, (info+i)->pscan_rep_mode, (info+i)->clock_offset | 0x8000, - sizeof(name), name, 100000) < 0) - strcpy(name, "n/a"); + sizeof(name), name, 100000) < 0) { + if (!nc) + strcpy(name, "n/a"); + } else + nc = 0; } printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); -- cgit From 12513fafd320f210190ab574383efe9591ce6c6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 22:58:53 +0000 Subject: Fix the case if device isn't found in the name cache --- tools/hcitool.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index a17fe8bc..5106f664 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -286,7 +286,7 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; bdaddr_t bdaddr; struct stat st; - int fd, pos, err = 0; + int fd, pos, err = -ENOENT; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); @@ -321,6 +321,7 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n if (!bacmp(&bdaddr, peer)) { snprintf(name, 249, "%s", str); + err = 0; break; } @@ -534,7 +535,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - nc = read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) < 0 ? 0 : 1; + nc = (read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) == 0); if (!extcls && !extinf && !extoui) { ba2str(&(info+i)->bdaddr, addr); -- cgit From e81077a3fca56047992b0da3282bd06a60f07cef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 23:01:15 +0000 Subject: Fix case if the link key is not found --- hcid/storage.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hcid/storage.c b/hcid/storage.c index 468d273b..0d42d680 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -312,7 +312,7 @@ int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *ke char filename[PATH_MAX + 1], addr[18], str[35], tmp[3], *buf, *ptr; bdaddr_t bdaddr; struct stat st; - int i, fd, pos, err = 0; + int i, fd, pos, err = -ENOENT; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/linkkeys", DEVPATH, addr); @@ -351,6 +351,7 @@ int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *ke memcpy(tmp, str + (i * 2), 2); key[i] = (uint8_t) strtol(tmp, NULL, 16); } + err = 0; break; } -- cgit From 1c47430238df9457d4dcef1cbe01ba4cf15b2b6b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 23:37:15 +0000 Subject: Add more data checks --- hcid/storage.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hcid/storage.c b/hcid/storage.c index 0d42d680..dad0c366 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -219,8 +219,10 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n list_foreach(list, temp) { ba2str(&temp->bdaddr, addr); - snprintf(buf, 300, "%s %s\n", addr, temp->data); - write(fd, buf, strlen(buf)); + if (temp->data && temp->size > 0) { + snprintf(buf, 300, "%s %s\n", addr, temp->data); + write(fd, buf, strlen(buf)); + } } unlock: @@ -294,8 +296,10 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c list_foreach(list, temp) { ba2str(&temp->bdaddr, addr); - snprintf(buf, 100, "%s %s\n", addr, temp->data); - write(fd, buf, strlen(buf)); + if (temp->data && temp->size > 0) { + snprintf(buf, 100, "%s %s\n", addr, temp->data); + write(fd, buf, strlen(buf)); + } } unlock: -- cgit From 6cffeb529a602566218343c35b6f1dbe5a5e057f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 23:43:36 +0000 Subject: Clear buffer before creating new line --- hcid/storage.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hcid/storage.c b/hcid/storage.c index dad0c366..952d8f7d 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -220,7 +220,8 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n list_foreach(list, temp) { ba2str(&temp->bdaddr, addr); if (temp->data && temp->size > 0) { - snprintf(buf, 300, "%s %s\n", addr, temp->data); + memset(buf, 0, 300); + snprintf(buf, 299, "%s %s\n", addr, temp->data); write(fd, buf, strlen(buf)); } } @@ -297,7 +298,8 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c list_foreach(list, temp) { ba2str(&temp->bdaddr, addr); if (temp->data && temp->size > 0) { - snprintf(buf, 100, "%s %s\n", addr, temp->data); + memset(buf, 0, 100); + snprintf(buf, 99, "%s %s\n", addr, temp->data); write(fd, buf, strlen(buf)); } } -- cgit From d9b8bee3e56f58da1f71ad9d12c49031015b76d0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Apr 2005 23:57:35 +0000 Subject: Terminate scanning if end of buffer is reached --- hcid/storage.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/hcid/storage.c b/hcid/storage.c index 952d8f7d..78624231 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -201,10 +201,15 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n ptr = buf; + memset(str, 0, sizeof(str)); while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { str2ba(addr, &bdaddr); - list = list_add(list, &bdaddr, str, strlen(str) + 1); + str[sizeof(str) - 1] = '\0'; + list = list_add(list, &bdaddr, str, sizeof(str)); + memset(str, 0, sizeof(str)); ptr += pos; + if (ptr - buf >= st.st_size) + break; }; lseek(fd, 0, SEEK_SET); @@ -274,10 +279,15 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c ptr = buf; + memset(str, 0, sizeof(str)); while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { str2ba(addr, &bdaddr); - list = list_add(list, &bdaddr, str, strlen(str) + 1); + str[sizeof(str) - 1] = '\0'; + list = list_add(list, &bdaddr, str, sizeof(str)); + memset(str, 0, sizeof(str)); ptr += pos; + if (ptr - buf >= st.st_size) + break; }; lseek(fd, 0, SEEK_SET); @@ -289,7 +299,7 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c sprintf(str + (i * 2), "%2.2X", key[i]); sprintf(str + 32, " %d", type); - list = list_add(list, peer, str, strlen(str) + 1); + list = list_add(list, peer, str, sizeof(str)); if (!list) { err = -EIO; goto unlock; -- cgit From 18ebe398a14f4f26025db652c312dadeec8fa555 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 00:43:37 +0000 Subject: Add support for stored pin codes --- hcid/hcid.h | 1 + hcid/security.c | 8 +++++-- hcid/storage.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index 9c96d91a..9010f1d3 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -113,3 +113,4 @@ gboolean hcid_dbus_init(void); int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type); int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key); +int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin); diff --git a/hcid/security.c b/hcid/security.c index e66e030e..1c4d988f 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -144,6 +144,7 @@ static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) } } +#if 0 static void save_link_key(struct link_key *key) { struct link_key *exist; @@ -185,6 +186,7 @@ static void save_link_key(struct link_key *key) failed: close(f); } +#endif static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) { @@ -202,14 +204,16 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) key.type = evt->key_type; key.time = time(0); +#if 0 save_link_key(&key); +#endif write_link_key(sba, dba, evt->link_key, evt->key_type); } /* PIN code handling */ -int read_pin_code(void) +static int read_default_pin_code(void) { char buf[17]; FILE *f; @@ -542,7 +546,7 @@ void stop_security_manager(int hdev) void init_security_data(void) { /* Set local PIN code */ - if (read_pin_code() < 0) { + if (read_default_pin_code() < 0) { strcpy(hcid.pin_code, "BlueZ"); hcid.pin_len = 5; } diff --git a/hcid/storage.c b/hcid/storage.c index 78624231..da34b416 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -205,7 +205,9 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { str2ba(addr, &bdaddr); str[sizeof(str) - 1] = '\0'; + list = list_add(list, &bdaddr, str, sizeof(str)); + memset(str, 0, sizeof(str)); ptr += pos; if (ptr - buf >= st.st_size) @@ -283,7 +285,9 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { str2ba(addr, &bdaddr); str[sizeof(str) - 1] = '\0'; + list = list_add(list, &bdaddr, str, sizeof(str)); + memset(str, 0, sizeof(str)); ptr += pos; if (ptr - buf >= st.st_size) @@ -358,8 +362,10 @@ int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *ke ptr = buf; + memset(str, 0, sizeof(str)); while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { str2ba(addr, &bdaddr); + str[sizeof(str) - 1] = '\0'; if (!bacmp(&bdaddr, peer)) { memset(tmp, 0, sizeof(tmp)); @@ -371,7 +377,71 @@ int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *ke break; } + memset(str, 0, sizeof(str)); ptr += pos; + if (ptr - buf >= st.st_size) + break; + }; + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + return err; +} + +int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin) +{ + char filename[PATH_MAX + 1], addr[18], str[17], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int fd, pos, err = -ENOENT; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/pincodes", DEVPATH, addr); + + fd = open(filename, O_RDONLY); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_SH) < 0) { + err = -errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + memset(str, 0, sizeof(str)); + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + str[sizeof(str) - 1] = '\0'; + + if (!bacmp(&bdaddr, peer)) { + strncpy(pin, str, 16); + err = 0; + break; + } + + memset(str, 0, sizeof(str)); + ptr += pos; + if (ptr - buf >= st.st_size) + break; }; } -- cgit From 04e3dafbeb0b78f247140314de18c9099a1b2bae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 00:53:32 +0000 Subject: Use cached device name for PIN request --- hcid/hcid.h | 1 + hcid/security.c | 19 +++++++++--------- hcid/storage.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index 9010f1d3..36cba71f 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -111,6 +111,7 @@ gboolean hcid_dbus_init(void); #endif int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); +int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name); int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type); int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key); int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin); diff --git a/hcid/security.c b/hcid/security.c index 1c4d988f..3cb7cde9 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -248,11 +248,11 @@ static int read_default_pin_code(void) ERR - No PIN available */ -static void call_pin_helper(int dev, struct hci_conn_info *ci) +static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) { pin_code_reply_cp pr; struct sigaction sa; - char addr[18], str[255], *pin, name[20]; + char addr[18], str[255], *pin, name[249]; FILE *pipe; int ret, len; @@ -273,12 +273,13 @@ static void call_pin_helper(int dev, struct hci_conn_info *ci) goto reject; } - name[0] = 0; + memset(name, 0, sizeof(name)); + read_device_name(sba, &ci->bdaddr, name); //hci_remote_name(dev, &ci->bdaddr, sizeof(name), name, 0); ba2str(&ci->bdaddr, addr); - sprintf(str, "%s %s %s \'%s\'", hcid.pin_helper, - ci->out ? "out" : "in", addr, name); + snprintf(str, sizeof(str), "%s %s %s \'%s\'", hcid.pin_helper, + ci->out ? "out" : "in", addr, name); setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1); @@ -325,7 +326,7 @@ reject: exit(0); } -static void request_pin(int dev, struct hci_conn_info *ci) +static void request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci) { #ifdef ENABLE_DBUS if (hcid.dbus_pin_helper) { @@ -333,7 +334,7 @@ static void request_pin(int dev, struct hci_conn_info *ci) return; } #endif - call_pin_helper(dev, ci); + call_pin_helper(dev, sba, ci); } static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) @@ -382,11 +383,11 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) /* Outgoing connection */ /* Let PIN helper handle that */ - request_pin(dev, ci); + request_pin(dev, sba, ci); } } else { /* Let PIN helper handle that */ - request_pin(dev, ci); + request_pin(dev, sba, ci); } free(cr); return; diff --git a/hcid/storage.c b/hcid/storage.c index da34b416..31f7eb62 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -242,6 +242,67 @@ close: return err; } +int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) +{ + char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int fd, pos, err = -ENOENT; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + + fd = open(filename, O_RDONLY); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_SH) < 0) { + err = -errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + memset(str, 0, sizeof(str)); + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + str[sizeof(str) - 1] = '\0'; + + if (!bacmp(&bdaddr, peer)) { + snprintf(name, 249, "%s", str); + err = 0; + break; + } + + memset(str, 0, sizeof(str)); + ptr += pos; + if (ptr - buf >= st.st_size) + break; + }; + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + return err; +} + int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type) { struct list *temp, *list = NULL; -- cgit From 24793e9a7eb16ed4f749b32419154bc2a58bbc1d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 01:05:27 +0000 Subject: Improve reading device names from cache --- tools/hcitool.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/hcitool.c b/tools/hcitool.c index 5106f664..6da3d3c1 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -316,8 +316,10 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n ptr = buf; + memset(str, 0, sizeof(str)); while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { str2ba(addr, &bdaddr); + str[sizeof(str) - 1] = '\0'; if (!bacmp(&bdaddr, peer)) { snprintf(name, 249, "%s", str); @@ -325,7 +327,10 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n break; } + memset(str, 0, sizeof(str)); ptr += pos; + if (ptr - buf >= st.st_size) + break; }; } -- cgit From a803872b6d01e385a8cfced8eeae18a71f8b065d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 01:25:56 +0000 Subject: Use the pincodes file for outgoing connections --- hcid/security.c | 25 ++++++++++++++++++------- hcid/storage.c | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/hcid/security.c b/hcid/security.c index 3cb7cde9..8ac3d759 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -339,9 +339,14 @@ static void request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci) static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) { + pin_code_reply_cp pr; struct hci_conn_info_req *cr; struct hci_conn_info *ci; - char sa[18], da[18]; + char sa[18], da[18], pin[17]; + int pinlen; + + memset(&pr, 0, sizeof(pr)); + bacpy(&pr.bdaddr, dba); ba2str(sba, sa); ba2str(dba, da); syslog(LOG_INFO, "pin_code_request (sba=%s, dba=%s)", sa, da); @@ -359,6 +364,9 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) } ci = cr->conn_info; + memset(pin, 0, sizeof(pin)); + pinlen = read_pin_code(sba, dba, pin); + if (pairing == HCID_PAIRING_ONCE) { struct link_key *key = get_link_key(sba, dba); if (key) { @@ -372,18 +380,21 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) if (hcid.security == HCID_SEC_AUTO) { if (!ci->out) { /* Incomming connection */ - pin_code_reply_cp pr; - memset(&pr, 0, sizeof(pr)); - bacpy(&pr.bdaddr, dba); memcpy(pr.pin_code, hcid.pin_code, hcid.pin_len); pr.pin_len = hcid.pin_len; hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); } else { /* Outgoing connection */ - - /* Let PIN helper handle that */ - request_pin(dev, sba, ci); + if (pinlen > 0) { + memcpy(pr.pin_code, pin, pinlen); + pr.pin_len = pinlen; + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, + PIN_CODE_REPLY_CP_SIZE, &pr); + } else { + /* Let PIN helper handle that */ + request_pin(dev, sba, ci); + } } } else { /* Let PIN helper handle that */ diff --git a/hcid/storage.c b/hcid/storage.c index 31f7eb62..ca7a7d07 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -495,7 +495,7 @@ int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin) if (!bacmp(&bdaddr, peer)) { strncpy(pin, str, 16); - err = 0; + err = strlen(pin); break; } -- cgit From be58a308406fbb3160f96bb56ab37b1ebaede174 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 12:11:32 +0000 Subject: Store remote version and features information --- hcid/hcid.h | 2 + hcid/security.c | 71 ++++++++++++++++++++++++ hcid/storage.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+) diff --git a/hcid/hcid.h b/hcid/hcid.h index 36cba71f..3beebd49 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -112,6 +112,8 @@ gboolean hcid_dbus_init(void); int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name); +int write_version_info(const bdaddr_t *local, const bdaddr_t *peer, const uint16_t manufacturer, const uint8_t lmp_ver, const uint16_t lmp_subver); +int write_features_info(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *features); int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type); int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key); int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin); diff --git a/hcid/security.c b/hcid/security.c index 8ac3d759..8f5c69bc 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -73,6 +73,38 @@ void toggle_pairing(int enable) syslog(LOG_INFO, "Pairing %s", pairing ? "enabled" : "disabled"); } +static int get_bdaddr(int dev, bdaddr_t *sba, uint16_t handle, bdaddr_t *dba) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + char addr[18]; + int i; + + cl = malloc(10 * sizeof(*ci) + sizeof(*cl)); + if (!cl) + return -ENOMEM; + + ba2str(sba, addr); + cl->dev_id = hci_devid(addr); + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(dev, HCIGETCONNLIST, (void *) cl) < 0) { + free(cl); + return -EIO; + } + + for (i = 0; i < cl->conn_num; i++, ci++) + if (ci->handle == handle) { + bacpy(dba, &ci->bdaddr); + free(cl); + return 0; + } + + free(cl); + return -ENOENT; +} + /* Link Key handling */ /* This function is not reentrable */ @@ -420,6 +452,35 @@ static void remote_name_information(int dev, bdaddr_t *sba, void *ptr) write_device_name(sba, dba, evt->name); } +static void remote_version_information(int dev, bdaddr_t *sba, void *ptr) +{ + evt_read_remote_version_complete *evt = ptr; + bdaddr_t dba; + + if (evt->status) + return; + + if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) + return; + + write_version_info(sba, &dba, btohs(evt->manufacturer), + evt->lmp_ver, btohs(evt->lmp_subver)); +} + +static void remote_features_information(int dev, bdaddr_t *sba, void *ptr) +{ + evt_read_remote_features_complete *evt = ptr; + bdaddr_t dba; + + if (evt->status) + return; + + if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) + return; + + write_features_info(sba, &dba, evt->features); +} + static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; @@ -462,6 +523,14 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer case EVT_REMOTE_NAME_REQ_COMPLETE: remote_name_information(dev, &di->bdaddr, ptr); break; + + case EVT_READ_REMOTE_VERSION_COMPLETE: + remote_version_information(dev, &di->bdaddr, ptr); + break; + + case EVT_READ_REMOTE_FEATURES_COMPLETE: + remote_features_information(dev, &di->bdaddr, ptr); + break; } if (hci_test_bit(HCI_SECMGR, &di->flags)) @@ -509,6 +578,8 @@ void start_security_manager(int hdev) hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); + hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt); + hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { syslog(LOG_ERR, "Can't set filter on hci%d: %s (%d)", hdev, strerror(errno), errno); diff --git a/hcid/storage.c b/hcid/storage.c index ca7a7d07..ffc92b44 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -303,6 +303,173 @@ close: return err; } +int write_version_info(const bdaddr_t *local, const bdaddr_t *peer, const uint16_t manufacturer, const uint8_t lmp_ver, const uint16_t lmp_subver) +{ + struct list *temp, *list = NULL; + char filename[PATH_MAX + 1], addr[18], str[16], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int fd, pos, err = 0; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/manufacturers", DEVPATH, addr); + + umask(S_IWGRP | S_IWOTH); + create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + + fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_EX) < 0) { + err = -errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size + 100); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + memset(str, 0, sizeof(str)); + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + str[sizeof(str) - 1] = '\0'; + + list = list_add(list, &bdaddr, str, sizeof(str)); + + memset(str, 0, sizeof(str)); + ptr += pos; + if (ptr - buf >= st.st_size) + break; + }; + + lseek(fd, 0, SEEK_SET); + ftruncate(fd, 0); + } + + memset(str, 0, sizeof(str)); + sprintf(str, "%d %d %d", manufacturer, lmp_ver, lmp_subver); + + list = list_add(list, peer, str, sizeof(str)); + if (!list) { + err = -EIO; + goto unlock; + } + + list_foreach(list, temp) { + ba2str(&temp->bdaddr, addr); + if (temp->data && temp->size > 0) { + memset(buf, 0, 100); + snprintf(buf, 99, "%s %s\n", addr, temp->data); + write(fd, buf, strlen(buf)); + } + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + list_free(list); + return err; +} + +int write_features_info(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *features) +{ + struct list *temp, *list = NULL; + char filename[PATH_MAX + 1], addr[18], str[17], *buf, *ptr; + bdaddr_t bdaddr; + struct stat st; + int i, fd, pos, err = 0; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/features", DEVPATH, addr); + + umask(S_IWGRP | S_IWOTH); + create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + + fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_EX) < 0) { + err = -errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = -errno; + goto unlock; + } + + buf = malloc(st.st_size + 100); + if (!buf) { + err = -ENOMEM; + goto unlock; + } + + if (st.st_size > 0) { + read(fd, buf, st.st_size); + + ptr = buf; + + memset(str, 0, sizeof(str)); + while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { + str2ba(addr, &bdaddr); + str[sizeof(str) - 1] = '\0'; + + list = list_add(list, &bdaddr, str, sizeof(str)); + + memset(str, 0, sizeof(str)); + ptr += pos; + if (ptr - buf >= st.st_size) + break; + }; + + lseek(fd, 0, SEEK_SET); + ftruncate(fd, 0); + } + + memset(str, 0, sizeof(str)); + for (i = 0; i < 8; i++) + sprintf(str + (i * 2), "%2.2X", features[i]); + + list = list_add(list, peer, str, sizeof(str)); + if (!list) { + err = -EIO; + goto unlock; + } + + list_foreach(list, temp) { + ba2str(&temp->bdaddr, addr); + if (temp->data && temp->size > 0) { + memset(buf, 0, 100); + snprintf(buf, 99, "%s %s\n", addr, temp->data); + write(fd, buf, strlen(buf)); + } + } + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + list_free(list); + return err; +} + int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type) { struct list *temp, *list = NULL; -- cgit From 096a5b39b0956d1a2ef02ceda6015b4c4edb59c4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 23:20:31 +0000 Subject: Add support for supported commands and extended features --- tools/hciconfig.8 | 3 ++ tools/hciconfig.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 88 insertions(+), 15 deletions(-) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 5340978d..dabfeb36 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -187,6 +187,9 @@ bytes and SCO buffer size to .I pkt packets. .TP +.BI commands +Display supported commands. +.TP .BI features Display device features. .TP diff --git a/tools/hciconfig.c b/tools/hciconfig.c index e66c9aa1..a1232c6c 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -102,20 +102,14 @@ static void print_link_mode(struct hci_dev_info *di) static void print_dev_features(struct hci_dev_info *di, int format) { - if (!format) { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", - di->features[0], di->features[1], - di->features[2], di->features[3], - di->features[4], di->features[5], - di->features[6], di->features[7] ); - } else { - printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", - di->features[0], di->features[1], - di->features[2], di->features[3], - di->features[4], di->features[5], - di->features[6], di->features[7], - lmp_featurestostr(di->features, "\t\t", 63)); - } + printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + di->features[0], di->features[1], di->features[2], + di->features[3], di->features[4], di->features[5], + di->features[6], di->features[7]); + + if (format) + printf("%s\n", lmp_featurestostr(di->features, "\t\t", 63)); } static void cmd_rstat(int ctl, int hdev, char *opt) @@ -383,8 +377,47 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) static void cmd_features(int ctl, int hdev, char *opt) { + uint8_t max_page, features[8]; + int i, dd; + + if (!(di.features[7] & 0x80)) { + print_dev_hdr(&di); + print_dev_features(&di, 1); + return; + } + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (hci_read_local_ext_features(dd, 0, &max_page, features, 1000) < 0) { + fprintf(stderr, "Can't read extended features hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + print_dev_hdr(&di); - print_dev_features(&di, 1); + printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", + (max_page > 0) ? " page 0" : "", + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7]); + printf("%s\n", lmp_featurestostr(di.features, "\t\t", 63)); + + for (i = 1; i <= max_page; i++) { + if (hci_read_local_ext_features(dd, 1, &max_page, features, 1000) < 0) + continue; + + printf("\tFeatures page %d: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " + "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", i, + features[0], features[1], features[2], features[3], + features[4], features[5], features[6], features[7]); + } + + hci_close_dev(dd); } static void cmd_name(int ctl, int hdev, char *opt) @@ -656,6 +689,40 @@ static void cmd_voice(int ctl, int hdev, char *opt) } } +static void cmd_commands(int ctl, int hdev, char *opt) +{ + uint8_t cmds[64]; + int i, n, dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (hci_read_local_commands(dd, cmds, 1000) < 0) { + fprintf(stderr, "Can't read support commands hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + for (i = 0; i < 64; i++) { + if (!cmds[i]) + continue; + + printf("%s Octet %-2d = 0x%02x (Bit", + i ? "\t\t ": "\tCommands:", i, cmds[i]); + for (n = 0; n < 8; n++) + if (hci_test_bit(n, &cmds[i])) + printf(" %d", n); + printf(")\n"); + } + + hci_close_dev(dd); +} + static void cmd_version(int ctl, int hdev, char *opt) { struct hci_version ver; @@ -680,6 +747,8 @@ static void cmd_version(int ctl, int hdev, char *opt) hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, bt_compidtostr(ver.manufacturer), ver.manufacturer); + + hci_close_dev(dd); } static void cmd_inq_mode(int ctl, int hdev, char *opt) @@ -1166,6 +1235,7 @@ static struct { { "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" }, { "aclmtu", cmd_aclmtu, "", "Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "", "Set SCO MTU and number of packets" }, + { "commands", cmd_commands, 0, "Display supported commands" }, { "features", cmd_features, 0, "Display device features" }, { "version", cmd_version, 0, "Display version information" }, { "revision", cmd_revision, 0, "Display revision information" }, -- cgit From c3881e06e2262909d8e1c190622002c5e02d724f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 23:34:20 +0000 Subject: Check the number of pages for extended features --- tools/hcitool.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 6da3d3c1..e02cb93f 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -456,10 +456,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; int num_rsp, length, flags; - uint8_t cls[3]; + uint8_t cls[3], features[8]; uint16_t handle; char addr[18], name[249], oui[9], *comp; - unsigned char features[8]; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; @@ -728,8 +727,8 @@ static void cmd_info(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; uint16_t handle; + uint8_t max_page, features[8]; char name[249], oui[9], *comp; - unsigned char features[8]; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; @@ -826,6 +825,12 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 63)); } + if (features[7] & 0x80) { + if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) + if (max_page > 0) + printf("\tExtended features: %d pages\n", max_page); + } + if (cc) { usleep(10000); hci_disconnect(dd, handle, HCI_OE_USER_ENDED_CONNECTION, 10000); -- cgit From 089583df538a11302e504659e7652389fdfa9aeb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 12:19:26 +0000 Subject: Use mmap() for reading the OUI company name --- tools/oui.c | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/tools/oui.c b/tools/oui.c index 7dff358b..985e6e20 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -32,9 +32,12 @@ #include #include +#include +#include #include #include #include +#include #include "oui.h" @@ -42,44 +45,50 @@ #define OUIFILE "/usr/share/misc/oui.txt" -#define AWKCMD "/usr/bin/awk" -#define TRCMD "/usr/bin/tr" - char *ouitocomp(const char *oui) { struct stat st; - FILE *input; - char cmd[512]; - char *str; - size_t len; + char *str, *map, *off, *end; + int fd; - if (stat(OUIFILE, &st) < 0) - return NULL; - if (stat(AWKCMD, &st) < 0) + fd = open(OUIFILE, O_RDONLY); + if (fd < 0) return NULL; - if (stat(TRCMD, &st) < 0) + if (fstat(fd, &st) < 0) { + close(fd); return NULL; + } str = malloc(128); - if (!str) + if (!str) { + close(fd); return NULL; + } memset(str, 0, 128); - snprintf(cmd, sizeof(cmd) - 1, "%s -F'\\t' '/^" - "%s.*\\(hex\\).*/{ print $3 }' %s" - " | %s -d '\\n\\r'", AWKCMD, oui, OUIFILE, TRCMD); - - input = popen(cmd, "r"); - if (!input) { + map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) { free(str); + close(fd); return NULL; } - len = fread(str, 127, 1, input); - pclose(input); + off = strstr(map, oui); + if (off) { + off += 18; + end = strpbrk(off, "\r\n"); + strncpy(str, off, end - off); + } else { + free(str); + str = NULL; + } + + munmap(map, st.st_size); + + close(fd); return str; } -- cgit From bb30c261fcdb833bf5cac02f671822bbe443ff27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 21:09:59 +0000 Subject: Use LMP_EXT_FEAT constant --- tools/hciconfig.c | 2 +- tools/hcitool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index a1232c6c..df9b211e 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -380,7 +380,7 @@ static void cmd_features(int ctl, int hdev, char *opt) uint8_t max_page, features[8]; int i, dd; - if (!(di.features[7] & 0x80)) { + if (!(di.features[7] & LMP_EXT_FEAT)) { print_dev_hdr(&di); print_dev_features(&di, 1); return; diff --git a/tools/hcitool.c b/tools/hcitool.c index e02cb93f..0b35b1ac 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -825,7 +825,7 @@ static void cmd_info(int dev_id, int argc, char **argv) lmp_featurestostr(features, "\t\t", 63)); } - if (features[7] & 0x80) { + if (features[7] & LMP_EXT_FEAT) { if (hci_read_remote_ext_features(dd, handle, 0, &max_page, features, 20000) == 0) if (max_page > 0) printf("\tExtended features: %d pages\n", max_page); -- cgit From 959b1e8c1d5ad023e1b3c8157a844c61df44a0a1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 21:14:39 +0000 Subject: Add support for setting the inquiry mode --- hcid/hcid.h | 1 + hcid/kword.c | 1 + hcid/main.c | 9 +++++++++ hcid/parser.y | 6 +++++- 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index 3beebd49..5523d4b7 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -43,6 +43,7 @@ struct device_opts { char *name; uint32_t class; + uint8_t inqmode; uint16_t pkt_type; uint16_t scan; uint16_t link_mode; diff --git a/hcid/kword.c b/hcid/kword.c index 41800b75..bd2294b2 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -59,6 +59,7 @@ struct kword cfg_keyword[] = { { "pscan", K_PSCAN }, { "name", K_NAME }, { "class", K_CLASS }, + { "inqmode", K_INQMODE }, { "auth", K_AUTH }, { "encrypt", K_ENCRYPT }, { "pin_helper", K_PINHELP }, diff --git a/hcid/main.c b/hcid/main.c index c2c6381c..45b8231d 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -242,6 +242,15 @@ static void configure_device(int hdev) CHANGE_LOCAL_NAME_CP_SIZE, (void *) &cp); } + /* Set inquiry mode */ + if (di.features[3] & LMP_RSSI_INQ) { + write_inquiry_mode_cp cp; + + cp.mode = device_opts->inqmode; + hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, + WRITE_INQUIRY_MODE_CP_SIZE, (void *) &cp); + } + exit(0); } diff --git a/hcid/parser.y b/hcid/parser.y index 136a8571..3534fb2b 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -64,7 +64,7 @@ int yyerror(char *s); %token K_OPTIONS K_DEVICE %token K_AUTOINIT K_SECURITY K_PAIRING -%token K_PTYPE K_NAME K_CLASS K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN +%token K_PTYPE K_NAME K_CLASS K_INQMODE K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN %token K_PINHELP K_DBUSPINHELP %token K_YES K_NO @@ -190,6 +190,10 @@ device_opt: parser_device->class = $2; } + | K_INQMODE NUM { + parser_device->inqmode = $2; + } + | K_AUTH bool { parser_device->auth = $2; } -- cgit From be0264a76e5658b41a23ed7a9228eb27490abf58 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 22:23:55 +0000 Subject: Use unlimited inquiry responses as default --- tools/hcitool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 0b35b1ac..453ef2e3 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -392,7 +392,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) int i, opt; length = 8; /* ~10 seconds */ - num_rsp = 100; + num_rsp = 0; flags = 0; for_each_opt(opt, inq_options, NULL) { @@ -466,7 +466,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) int i, opt, dd, cc, nc; length = 8; /* ~10 seconds */ - num_rsp = 100; + num_rsp = 0; flags = 0; for_each_opt(opt, scan_options, NULL) { -- cgit From f6a34bc5fd6f54256080d63734b414c037f0603c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 22:27:22 +0000 Subject: Use unlimited inquiry responses --- dund/main.c | 2 +- pand/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dund/main.c b/dund/main.c index 3eb4eb7f..837073f9 100644 --- a/dund/main.c +++ b/dund/main.c @@ -328,7 +328,7 @@ static int do_connect(void) /* FIXME: Should we use non general LAP here ? */ ii = NULL; - n = hci_inquiry(src_dev, search_duration, 10, NULL, &ii, 0); + n = hci_inquiry(src_dev, search_duration, 0, NULL, &ii, 0); if (n < 0) { syslog(LOG_ERR, "Inquiry failed. %s(%d)", strerror(errno), errno); continue; diff --git a/pand/main.c b/pand/main.c index 2090f9f8..959d6057 100644 --- a/pand/main.c +++ b/pand/main.c @@ -363,7 +363,7 @@ static int do_connect(void) /* FIXME: Should we use non general LAP here ? */ ii = NULL; - n = hci_inquiry(src_dev, search_duration, 10, NULL, &ii, 0); + n = hci_inquiry(src_dev, search_duration, 0, NULL, &ii, 0); if (n < 0) { syslog(LOG_ERR, "Inquiry failed. %s(%d)", strerror(errno), errno); continue; -- cgit From 4c526ebdb8683187358e252c495a78abc32277e3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 23:12:57 +0000 Subject: Update changelog and bump version number --- ChangeLog | 21 +++++++++++++++++++++ configure.in | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1cc32400..2455abde 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +ver 2.16: + Store link keys in ASCII based file format. + Support device name caching. + Support zero length data sizes in l2test. + Change default l2ping data size to 44 bytes. + Hide the server record and the public browse group root. + Read BD_ADDR if not set and if it is a raw device. + Add SDP language attributes. + Add support for browsing the L2CAP group. + Add support for stored pin codes for outgoing connections. + Add support for local commands and extended features. + Add support for reading CSR panic and fault codes. + Add config option for setting the inquiry mode. + Add OUI decoding support. + Use unlimited inquiry responses as default. + Use cached device names for PIN request. + Use the clock offset when getting the remote names. + + Note: + This version needs at least bluez-libs-2.16 + ver 2.15: Enable the RFCOMM service level security. Add command for reading the clock offset. diff --git a/configure.in b/configure.in index 514f3a3f..15febfe9 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.15) +AM_INIT_AUTOMAKE(bluez-utils, 2.16) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From bf3f55de5b9e3c95aa53e9bd5e0a19c9655e50f5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 19 Apr 2005 11:29:19 +0000 Subject: Add build id for BlueCore3-ROM with HCI 18.4 firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/csr.c b/tools/csr.c index 27a6a9a4..8c07fabb 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -269,6 +269,7 @@ static struct { { 1915, "HCI 19.2" }, { 1916, "HCI 19.2" }, { 1958, "HCI 19.2" }, + { 1989, "HCI 18.4" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From 47a63f33131e0cbc19e51d7d4f8a27dcf3fcc6a9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 19 Apr 2005 13:55:29 +0000 Subject: Add build id for BlueCore3-MM with HCI 19.2 firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/csr.c b/tools/csr.c index 8c07fabb..c646ebde 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -269,6 +269,7 @@ static struct { { 1915, "HCI 19.2" }, { 1916, "HCI 19.2" }, { 1958, "HCI 19.2" }, + { 1981, "HCI 19.2" }, { 1989, "HCI 18.4" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, -- cgit From 303a8bfd8c49de19c482b047c9a95b94e585c1cb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 13:03:48 +0000 Subject: Read the boot mode on CSR devices --- tools/csr.h | 1 + tools/hciconfig.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/csr.h b/tools/csr.h index 513a2cf2..72d4cc4a 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -35,6 +35,7 @@ #define CSR_VARID_FAULT_ARG 0x6806 #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab +#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); diff --git a/tools/hciconfig.c b/tools/hciconfig.c index df9b211e..20ef065c 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1043,7 +1043,7 @@ static void print_rev_ericsson(int dd) static void print_rev_csr(int dd, uint16_t rev) { - uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, error; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, bootmode, error; if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { printf("\t%s\n", csr_buildidtostr(rev)); @@ -1064,6 +1064,9 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); + if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_INITIAL_BOOTMODE, &bootmode)) + printf("\tBoot mode: %d%s\n", bootmode, bootmode ? "" : " (HCI)"); + if (!csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error)) { if (error < 0x0100) printf("\tPanic code: 0x%02x\n", error); -- cgit From 41d566d35dbc0bead25e0aeabb1bccb0d4855dfa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 13:25:21 +0000 Subject: Use hci_devinfo() instead of the ioctl() --- test/bdaddr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/bdaddr.c b/test/bdaddr.c index d674c3de..2e2af6c7 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -151,7 +150,7 @@ static void usage(void) static struct option main_options[] = { { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, - { 0, 0, 0, 0} + { 0, 0, 0, 0 } }; int main(int argc, char *argv[]) @@ -192,8 +191,7 @@ int main(int argc, char *argv[]) exit(1); } - di.dev_id = dev; - if (ioctl(dd, HCIGETDEVINFO, (void *) &di) < 0) { + if (hci_devinfo(dev, &di) < 0) { fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", dev, strerror(errno), errno); hci_close_dev(dd); -- cgit From ba621583ce85d01708420f8d8ea2f6f26b336b30 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 16:06:07 +0000 Subject: Add support for writing PS key values --- tools/csr.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- tools/csr.h | 2 ++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index c646ebde..a155efcb 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -374,6 +374,18 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) } } +char *csr_pskeytostr(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: + return "Map SCO over PCM"; + case CSR_PSKEY_INITIAL_BOOTMODE: + return "Initial device bootmode"; + default: + return "Unknown"; + } +} + int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value) { unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, @@ -404,8 +416,10 @@ int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *val return -1; } - if ((rp[9] + (rp[10] << 8)) != 0) + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; return -1; + } *value = rp[11] + (rp[12] << 8); @@ -442,10 +456,51 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *val return -1; } - if ((rp[9] + (rp[10] << 8)) != 0) + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; return -1; + } *value = rp[17] + (rp[18] << 8); return 0; } + +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value) +{ + unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, + pskey & 0xff, pskey >> 8, 0x01, 0x00, 0x00, 0x00, + value & 0xff, value >> 8 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + return 0; +} diff --git a/tools/csr.h b/tools/csr.h index 72d4cc4a..79795be0 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -39,6 +39,8 @@ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); +char *csr_pskeytostr(uint16_t pskey); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); -- cgit From e9ded5ddec57defd792cb0fe7818d34c67dd6414 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 16:54:53 +0000 Subject: Support address changing for CSR chips --- test/bdaddr.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/test/bdaddr.c b/test/bdaddr.c index 2e2af6c7..e1f6921a 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -103,6 +103,53 @@ static int ericsson_store_in_flash(int dd, uint8_t user_id, uint8_t flash_length } #endif +static int csr_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + unsigned char cmd[] = { 0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + cmd[16] = bdaddr->b[2]; + cmd[17] = 0x00; + cmd[18] = bdaddr->b[0]; + cmd[19] = bdaddr->b[1]; + cmd[20] = bdaddr->b[3]; + cmd[21] = 0x00; + cmd[22] = bdaddr->b[4]; + cmd[23] = bdaddr->b[5]; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + return 0; +} + #define OCF_ZEEVO_WRITE_BD_ADDR 0x0001 typedef struct { bdaddr_t bdaddr; @@ -136,6 +183,7 @@ static struct { int (*func)(int dd, bdaddr_t *bdaddr); } vendor[] = { { 0, ericsson_write_bd_addr }, + { 10, csr_write_bd_addr }, { 18, zeevo_write_bd_addr }, { 65535, NULL }, }; @@ -205,10 +253,20 @@ int main(int argc, char *argv[]) exit(1); } + if (!bacmp(&di.bdaddr, BDADDR_ANY)) { + if (hci_read_bd_addr(dd, &bdaddr, 1000) < 0) { + fprintf(stderr, "Can't read address for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + } else + bacpy(&bdaddr, &di.bdaddr); + printf("Manufacturer: %s (%d)\n", bt_compidtostr(ver.manufacturer), ver.manufacturer); - ba2str(&di.bdaddr, addr); + ba2str(&bdaddr, addr); printf("Device address: %s\n", addr); if (argc < 1) { @@ -228,7 +286,7 @@ int main(int argc, char *argv[]) printf("New BD address: %s\n\n", addr); if (vendor[i].func(dd, &bdaddr) < 0) { - fprintf(stderr, "Can't write new address"); + fprintf(stderr, "Can't write new address\n"); hci_close_dev(dd); exit(1); } -- cgit From 7cc4137b299169997e45e07614966adc55f6f5eb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 16:56:29 +0000 Subject: Add pskey utility for changing PCM mapping and boot mode --- tools/Makefile.am | 6 +- tools/pskey.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 tools/pskey.c diff --git a/tools/Makefile.am b/tools/Makefile.am index b07f2b19..3dd69b68 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -14,7 +14,7 @@ sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool -noinst_PROGRAMS = ppporc hcisecfilter +noinst_PROGRAMS = hcisecfilter ppporc pskey hciconfig_SOURCES = hciconfig.c csr.h csr.c @@ -32,6 +32,10 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ +pskey_SOURCES = pskey.c csr.h csr.c + +pskey_LDADD = @BLUEZ_LIBS@ + if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif diff --git a/tools/pskey.c b/tools/pskey.c new file mode 100644 index 00000000..01aa921d --- /dev/null +++ b/tools/pskey.c @@ -0,0 +1,204 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "csr.h" + +#define CSR_TYPE_NULL 0 +#define CSR_TYPE_UINT16 1 + +static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) +{ + uint16_t value; + int err; + + if (type != CSR_TYPE_UINT16) { + errno = EFAULT; + return -1; + } + + if (argc != 1) { + errno = E2BIG; + return -1; + } + + value = atoi(argv[0]); + + err = csr_write_pskey_uint16(dd, 0x4711, pskey, value); + + return err; +} + +static int read_pskey(int dd, uint16_t pskey, int type) +{ + uint16_t value; + int err; + + if (type != CSR_TYPE_UINT16) { + errno = EFAULT; + return -1; + } + + err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); + if (err < 0) + return err; + + printf("%s: %d\n", csr_pskeytostr(pskey), value); + + return err; +} + +static struct { + uint16_t pskey; + int type; + char *str; +} storage[] = { + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, + { 0x0000, CSR_TYPE_NULL, NULL }, +}; + +static void usage(void) +{ + int i; + + printf("pskey - Utility for changing CSR persistent storage\n\n"); + printf("Usage:\n" + "\tpskey [-i ] [value]\n\n"); + + printf("Keys:\n\t"); + for (i = 0; storage[i].pskey; i++) + printf("%s ", storage[i].str); + printf("\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct hci_dev_info di; + struct hci_version ver; + int i, err, dd, opt, dev = 0; + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + exit(1); + } + + if (hci_devinfo(dev, &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (ver.manufacturer != 10) { + fprintf(stderr, "Unsupported manufacturer\n"); + hci_close_dev(dd); + exit(1); + } + + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + if (argc > 1) + err = write_pskey(dd, storage[i].pskey, + storage[i].type, argc - 1, argv + 1); + else + err = read_pskey(dd, storage[i].pskey, storage[i].type); + + hci_close_dev(dd); + + if (err < 0) { + fprintf(stderr, "Can't %s persistent storage: %s (%d)\n", + argc > 1 ? "write" : "read", strerror(errno), errno); + exit(1); + } + + exit(0); + } + + fprintf(stderr, "Unsupported persistent storage\n"); + + hci_close_dev(dd); + + exit(1); +} -- cgit From cdd3dd5576a585f61674a3346c6598b907e97e9d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 17:49:43 +0000 Subject: Take care of return link keys event --- hcid/security.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/hcid/security.c b/hcid/security.c index 8f5c69bc..5b2dc285 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -225,10 +225,10 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) evt_link_key_notify *evt = ptr; bdaddr_t *dba = &evt->bdaddr; struct link_key key; - char sa[18]; + char sa[18], da[18]; - ba2str(sba, sa); - syslog(LOG_INFO, "link_key_notify (sba=%s)", sa); + ba2str(sba, sa); ba2str(dba, da); + syslog(LOG_INFO, "link_key_notify (sba=%s, dba=%s)", sa, da); memcpy(key.key, evt->link_key, 16); bacpy(&key.sba, sba); @@ -243,6 +243,28 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr) write_link_key(sba, dba, evt->link_key, evt->key_type); } +static void return_link_keys(int dev, bdaddr_t *sba, void *ptr) +{ + evt_return_link_keys *evt = ptr; + uint8_t num = evt->num_keys; + unsigned char key[16]; + char sa[18], da[18]; + bdaddr_t dba; + int i; + + ba2str(sba, sa); + ptr++; + + for (i = 0; i < num; i++) { + bacpy(&dba, ptr); ba2str(&dba, da); + memcpy(key, ptr + 6, 16); + + syslog(LOG_INFO, "return_link_keys (sba=%s, dba=%s)", sa, da); + + ptr += 22; + } +} + /* PIN code handling */ static int read_default_pin_code(void) @@ -548,6 +570,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer case EVT_LINK_KEY_NOTIFY: link_key_notify(dev, &di->bdaddr, ptr); break; + + case EVT_RETURN_LINK_KEYS: + return_link_keys(dev, &di->bdaddr, ptr); + break; } return TRUE; @@ -577,6 +603,7 @@ void start_security_manager(int hdev) hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); + hci_filter_set_event(EVT_RETURN_LINK_KEYS, &flt); hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt); hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); -- cgit From 1487aa2f7c8a1bd0633d3f959699b1ccb1a5031c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 22:30:36 +0000 Subject: Support adding of Nokia ID and PC Suite service records --- tools/sdptool.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 5 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index d3da429d..83e86fb5 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * Copyright (C) 2002-2003 Jean Tourrilhes * @@ -1423,7 +1423,7 @@ end: return ret; } -static int add_file_trans(sdp_session_t *session, svc_info_t *si) +static int add_ftp(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, ftrn_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; @@ -1852,6 +1852,83 @@ done: return ret; } +static unsigned char nokid_uuid[] = { 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; + +static int add_nokia_id(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass; + uuid_t root_uuid, svclass_uuid; + uint16_t verid = 0x005f; + sdp_data_t *version = sdp_data_alloc(SDP_UINT16, &verid); + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) nokid_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_attr_add(&record, SDP_ATTR_SERVICE_VERSION, version); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + sdp_data_free(version); + return -1; + } + + printf("Nokia ID service record registered\n"); + + return 0; +} + +static unsigned char pcsuite_uuid[] = { 0x00, 0x00, 0x50, 0x02, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; + +static int add_pcsuite(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel? si->channel: 14; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid128_create(&svclass_uuid, (void *) pcsuite_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "Nokia PC Suite", NULL, NULL); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Nokia PC Suite service registered\n"); + + return 0; +} + struct { char *name; uint16_t class; @@ -1864,7 +1941,7 @@ struct { { "LAN", LAN_ACCESS_SVCLASS_ID, add_lan }, { "FAX", FAX_SVCLASS_ID, add_fax }, { "OPUSH", OBEX_OBJPUSH_SVCLASS_ID, add_opush }, - { "FTRN", OBEX_FILETRANS_SVCLASS_ID, add_file_trans }, + { "FTP", OBEX_FILETRANS_SVCLASS_ID, add_ftp }, { "HS", HEADSET_SVCLASS_ID, add_headset }, { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, @@ -1881,6 +1958,9 @@ struct { { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source}, { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, + { "NOKID", 0, add_nokia_id }, + { "PCSUITE", 0, add_pcsuite }, + { 0 } }; @@ -2339,7 +2419,7 @@ static struct { static void usage(void) { - int i; + int i, pos = 0; printf("sdptool - SDP tool v%s\n", VERSION); printf("Usage:\n" @@ -2353,8 +2433,14 @@ static void usage(void) printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc); printf("\nServices:\n\t"); - for (i = 0; service[i].name; i++) + for (i = 0; service[i].name; i++) { printf("%s ", service[i].name); + pos += strlen(service[i].name) + 1; + if (pos > 60) { + printf("\n\t"); + pos = 0; + } + } printf("\n"); } -- cgit From 62d4836a2e0449e381e2a1c757bf37e39826d660 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 23:16:43 +0000 Subject: Add definitions for host interface and USB vendor/product ids --- tools/csr.c | 6 ++++++ tools/csr.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index a155efcb..75507c41 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -379,6 +379,12 @@ char *csr_pskeytostr(uint16_t pskey) switch (pskey) { case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; + case CSR_PSKEY_HOST_INTERFACE: + return "Host interface"; + case CSR_PSKEY_USB_VENDOR_ID: + return "USB vendor identifier"; + case CSR_PSKEY_USB_PRODUCT_ID: + return "USB product identifier"; case CSR_PSKEY_INITIAL_BOOTMODE: return "Initial device bootmode"; default: diff --git a/tools/csr.h b/tools/csr.h index 79795be0..c8ac5cd3 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -35,6 +35,9 @@ #define CSR_VARID_FAULT_ARG 0x6806 #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab +#define CSR_PSKEY_HOST_INTERFACE 0x01f9 +#define CSR_PSKEY_USB_VENDOR_ID 0x02be +#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf #define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd char *csr_buildidtostr(uint16_t id); -- cgit From d354ddf51aae1d6b5315888dda3a693b7c817388 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 23:18:23 +0000 Subject: Support changing the host interface and USB vendor/product ids --- tools/pskey.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/pskey.c b/tools/pskey.c index 01aa921d..2dd10c77 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -81,7 +81,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) if (err < 0) return err; - printf("%s: %d\n", csr_pskeytostr(pskey), value); + printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); return err; } @@ -92,6 +92,9 @@ static struct { char *str; } storage[] = { { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, { 0x0000, CSR_TYPE_NULL, NULL }, }; -- cgit From 975d3e774555963b829dee6985c1698f291f01ce Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 23:45:11 +0000 Subject: Add definition for the UART baud rate --- tools/csr.c | 4 ++++ tools/csr.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 75507c41..45324d3e 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -379,12 +379,16 @@ char *csr_pskeytostr(uint16_t pskey) switch (pskey) { case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; + case CSR_PSKEY_UART_BAUDRATE: + return "UART Baud rate"; case CSR_PSKEY_HOST_INTERFACE: return "Host interface"; case CSR_PSKEY_USB_VENDOR_ID: return "USB vendor identifier"; case CSR_PSKEY_USB_PRODUCT_ID: return "USB product identifier"; + case CSR_PSKEY_USB_DFU_PRODUCT_ID: + return "USB DFU product ID"; case CSR_PSKEY_INITIAL_BOOTMODE: return "Initial device bootmode"; default: diff --git a/tools/csr.h b/tools/csr.h index c8ac5cd3..7aa90c31 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -35,9 +35,11 @@ #define CSR_VARID_FAULT_ARG 0x6806 #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab +#define CSR_PSKEY_UART_BAUDRATE 0x01be #define CSR_PSKEY_HOST_INTERFACE 0x01f9 #define CSR_PSKEY_USB_VENDOR_ID 0x02be #define CSR_PSKEY_USB_PRODUCT_ID 0x02bf +#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb #define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd char *csr_buildidtostr(uint16_t id); -- cgit From acea732b00a0f48d1e4414b303f6b2c49e71cbbe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Apr 2005 23:46:00 +0000 Subject: Support changing the UART baud rate (HCI 18.x and later) --- tools/pskey.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/pskey.c b/tools/pskey.c index 2dd10c77..edf78e8d 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -92,9 +92,11 @@ static struct { char *str; } storage[] = { { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, { 0x0000, CSR_TYPE_NULL, NULL }, }; -- cgit From f5a214f76f2d93702b5bc3b0b168389d8f8b34f2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 20:18:09 +0000 Subject: Set the storage directory through ${localstatedir} --- README | 3 ++- acinclude.m4 | 12 ++++++++++++ hcid/storage.c | 16 +++++++--------- tools/hcitool.c | 4 +--- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/README b/README index 9a0dcbf2..98ad8551 100644 --- a/README +++ b/README @@ -17,7 +17,8 @@ In order to compile Bluetooth utilities you need following software packages: - YACC (yacc, bison, byacc) To configure run: - ./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc + ./configure --prefix=/usr --mandir=/usr/share/man \ + --sysconfdir=/etc --localstatedir=/var Configure automatically searches for all required components and packages. diff --git a/acinclude.m4 b/acinclude.m4 index fbadd434..9175cf45 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -27,6 +27,11 @@ AC_DEFUN([AC_INIT_BLUEZ], [ AC_SUBST([sysconfdir], ['/etc']) fi + dnl no prefix and no localstatedir, so default to /var + if (test "$localstatedir" = '${prefix}/var'); then + AC_SUBST([localstatedir], ['/var']) + fi + dnl no prefix and no mandir, so use ${prefix}/share/man as default if (test "$mandir" = '${prefix}/man'); then AC_SUBST([mandir], ['${prefix}/share/man']) @@ -45,7 +50,14 @@ AC_DEFUN([AC_INIT_BLUEZ], [ configdir="${sysconfdir}/bluetooth" fi + if (test "$localstatedir" = '${prefix}/var'); then + storagedir="${prefix}/var/lib/bluetooth" + else + storagedir="${localstatedir}/lib/bluetooth" + fi + AC_DEFINE_UNQUOTED(CONFIGDIR, "${configdir}", [Directory for the configuration files]) + AC_DEFINE_UNQUOTED(STORAGEDIR, "${storagedir}", [Directory for the storage files]) ]) AC_DEFUN([AC_PATH_BLUEZ], [ diff --git a/hcid/storage.c b/hcid/storage.c index ffc92b44..b225b598 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -46,8 +46,6 @@ #include "hcid.h" -#define DEVPATH "/var/lib/bluetooth/" - struct list { bdaddr_t bdaddr; unsigned char *data; @@ -171,7 +169,7 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n int fd, pos, err = 0; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); umask(S_IWGRP | S_IWOTH); create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); @@ -250,7 +248,7 @@ int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) int fd, pos, err = -ENOENT; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); fd = open(filename, O_RDONLY); if (fd < 0) @@ -312,7 +310,7 @@ int write_version_info(const bdaddr_t *local, const bdaddr_t *peer, const uint16 int fd, pos, err = 0; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/manufacturers", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr); umask(S_IWGRP | S_IWOTH); create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); @@ -395,7 +393,7 @@ int write_features_info(const bdaddr_t *local, const bdaddr_t *peer, const unsig int i, fd, pos, err = 0; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/features", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/features", STORAGEDIR, addr); umask(S_IWGRP | S_IWOTH); create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); @@ -479,7 +477,7 @@ int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned c int i, fd, pos, err = 0; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/linkkeys", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); umask(S_IWGRP | S_IWOTH); create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); @@ -563,7 +561,7 @@ int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *ke int i, fd, pos, err = -ENOENT; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/linkkeys", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); fd = open(filename, O_RDONLY); if (fd < 0) @@ -628,7 +626,7 @@ int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin) int fd, pos, err = -ENOENT; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/pincodes", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/pincodes", STORAGEDIR, addr); fd = open(filename, O_RDONLY); if (fd < 0) diff --git a/tools/hcitool.c b/tools/hcitool.c index 453ef2e3..fb189760 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -279,8 +279,6 @@ static char *major_classes[] = { "Audio/Video", "Peripheral", "Imaging", "Uncategorized" }; -#define DEVPATH "/var/lib/bluetooth/" - static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) { char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; @@ -289,7 +287,7 @@ static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *n int fd, pos, err = -ENOENT; ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/names", DEVPATH, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); fd = open(filename, O_RDONLY); if (fd < 0) -- cgit From adbb22a47c9356e0c191a75daec0439e8d941bd1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 21:34:08 +0000 Subject: Use LDADD instead of LIBS --- cups/Makefile.am | 3 +-- dund/Makefile.am | 3 +-- extra/Makefile.am | 2 +- hcid/Makefile.am | 3 +-- hidd/Makefile.am | 3 +-- pand/Makefile.am | 3 +-- rfcomm/Makefile.am | 3 +-- sdpd/Makefile.am | 3 +-- test/Makefile.am | 12 +++++++++++- 9 files changed, 19 insertions(+), 16 deletions(-) diff --git a/cups/Makefile.am b/cups/Makefile.am index c43cac54..ea4aa876 100644 --- a/cups/Makefile.am +++ b/cups/Makefile.am @@ -8,8 +8,7 @@ cupsdir = $(libdir)/cups/backend cups_PROGRAMS = bluetooth bluetooth_SOURCES = main.c sdp.c spp.c hcrp.c - -LDADD = @BLUEZ_LIBS@ +bluetooth_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ endif diff --git a/dund/Makefile.am b/dund/Makefile.am index 3ff2b36c..236decc6 100644 --- a/dund/Makefile.am +++ b/dund/Makefile.am @@ -5,8 +5,7 @@ bin_PROGRAMS = dund dund_SOURCES = main.c dun.c dund.h sdp.c lib.h msdun.c - -LIBS = @BLUEZ_LIBS@ +dund_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/extra/Makefile.am b/extra/Makefile.am index 8bbaa2c8..7ce141c0 100644 --- a/extra/Makefile.am +++ b/extra/Makefile.am @@ -11,7 +11,7 @@ usb_DATA = $(datafiles) usb_PROGRAMS = bcm203x -LDADD = @USB_LIBS@ +bcm203x_LDADD = @USB_LIBS@ AM_CFLAGS = @USB_CFLAGS@ endif diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 32b02005..02dd7b56 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -19,8 +19,7 @@ dbus_hcid_cflags = endif hcid_SOURCES = main.c security.c storage.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) - -LIBS = $(dbus_hcid_libs) @BLUEZ_LIBS@ +hcid_LDADD = $(dbus_hcid_libs) @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ $(dbus_hcid_cflags) diff --git a/hidd/Makefile.am b/hidd/Makefile.am index 5519143a..0860d265 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -5,8 +5,7 @@ bin_PROGRAMS = hidd hidd_SOURCES = main.c hidd.h sdp.c - -LIBS = @BLUEZ_LIBS@ +hidd_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/pand/Makefile.am b/pand/Makefile.am index 3ed77891..9e7c3648 100644 --- a/pand/Makefile.am +++ b/pand/Makefile.am @@ -5,8 +5,7 @@ bin_PROGRAMS = pand pand_SOURCES = main.c pand.h bnep.c sdp.c - -LIBS = @BLUEZ_LIBS@ +pand_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index bedb07f6..65a5af53 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -9,8 +9,7 @@ conf_DATA = rfcomm.conf bin_PROGRAMS = rfcomm rfcomm_SOURCES = main.c parser.h parser.y lexer.l kword.h kword.c - -LIBS = @BLUEZ_LIBS@ +rfcomm_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index 44d4ba8d..f2d55754 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -5,8 +5,7 @@ sbin_PROGRAMS = sdpd sdpd_SOURCES = main.c request.c service.c cstate.c servicedb.c sdpd.h - -LIBS = @BLUEZ_LIBS@ +sdpd_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/test/Makefile.am b/test/Makefile.am index 7bfb74c3..bf41fb03 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -7,7 +7,17 @@ bin_PROGRAMS = l2test rctest noinst_PROGRAMS = scotest attest hstest bdaddr -LDADD = @BLUEZ_LIBS@ +l2test_LDADD = @BLUEZ_LIBS@ + +rctest_LDADD = @BLUEZ_LIBS@ + +scotest_LDADD = @BLUEZ_LIBS@ + +attest_LDADD = @BLUEZ_LIBS@ + +hstest_LDADD = @BLUEZ_LIBS@ + +bdaddr_LDADD = @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ endif -- cgit From cee1d7cd02c04fbb893a84c377f89835eb21cb68 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 21:45:40 +0000 Subject: Create storage directory --- hcid/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 02dd7b56..90136f28 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -6,6 +6,10 @@ confdir = $(sysconfdir)/bluetooth conf_DATA = hcid.conf +statedir = $(localstatedir)/lib/bluetooth + +state_DATA = + sbin_PROGRAMS = hcid if DBUS -- cgit From ef776753184cd3eb25fd852284945c053094105d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 21:48:34 +0000 Subject: Remove depcomp file --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index d6d9e992..251d8da1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,4 +6,4 @@ SUBDIRS = hcid tools rfcomm sdpd dund pand hidd cups alsa test scripts pcmcia ex MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in config.sub config.guess \ - ltmain.sh missing install-sh mkinstalldirs + ltmain.sh depcomp missing install-sh mkinstalldirs -- cgit From 1514cc3fbace6793f002737b08f9cfcb140bed70 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Apr 2005 21:53:11 +0000 Subject: Add the firmware upgrade utility --- acinclude.m4 | 11 +- tools/Makefile.am | 23 +- tools/dfu.c | 169 ++++++++++++ tools/dfu.h | 108 ++++++++ tools/dfutool.1 | 53 ++++ tools/dfutool.c | 763 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1119 insertions(+), 8 deletions(-) create mode 100644 tools/dfu.c create mode 100644 tools/dfu.h create mode 100644 tools/dfutool.1 create mode 100644 tools/dfutool.c diff --git a/acinclude.m4 b/acinclude.m4 index 9175cf45..15ee2ed8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -76,7 +76,7 @@ AC_DEFUN([AC_PATH_BLUEZ], [ test -d "${bluez_prefix}/include" && BLUEZ_CFLAGS="$BLUEZ_CFLAGS -I${bluez_prefix}/include" CPPFLAGS="$CPPFLAGS $BLUEZ_CFLAGS" - AC_CHECK_HEADER(bluetooth/bluetooth.h,, AC_MSG_ERROR(Bluetooth header files not found)) + AC_CHECK_HEADER(bluetooth/bluetooth.h, dummy=yes, AC_MSG_ERROR(Bluetooth header files not found)) BLUEZ_LIBS="" if (test "${prefix}" = "${bluez_prefix}"); then @@ -88,7 +88,7 @@ AC_DEFUN([AC_PATH_BLUEZ], [ LDFLAGS="$LDFLAGS $BLUEZ_LIBS" AC_CHECK_LIB(bluetooth, hci_open_dev, BLUEZ_LIBS="$BLUEZ_LIBS -lbluetooth", AC_MSG_ERROR(Bluetooth library not found)) - AC_CHECK_LIB(bluetooth, sdp_connect,, AC_CHECK_LIB(sdp, sdp_connect, BLUEZ_LIBS="$BLUEZ_LIBS -lsdp")) + AC_CHECK_LIB(bluetooth, sdp_connect, dummy=yes, AC_CHECK_LIB(sdp, sdp_connect, BLUEZ_LIBS="$BLUEZ_LIBS -lsdp")) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS @@ -262,6 +262,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ initscripts_enable=no bluepin_enable=yes hid2hci_enable=${usb_found} + dfutool_enable=no bcm203x_enable=no AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable compiling with debugging information]), [ @@ -282,6 +283,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ initscripts_enable=${enableval} bluepin_enable=${enableval} hid2hci_enable=${enableval} + dfutool_enable=${enableval} bcm203x_enable=${enableval} ]) @@ -321,6 +323,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ hid2hci_enable=${enableval} ]) + AC_ARG_ENABLE(dfutool, AC_HELP_STRING([--enable-dfutool], [install DFU firmware upgrade utility]), [ + dfutool_enable=${enableval} + ]) + AC_ARG_ENABLE(bcm203x, AC_HELP_STRING([--enable-bcm203x], [install Broadcom 203x firmware loader]), [ bcm203x_enable=${enableval} ]) @@ -343,5 +349,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [ AM_CONDITIONAL(INITSCRIPTS, test "${initscripts_enable}" = "yes") AM_CONDITIONAL(BLUEPIN, test "${bluepin_enable}" = "yes") AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes") + AM_CONDITIONAL(DFUTOOL, test "${dfutool_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(BCM203X, test "${bcm203x_enable}" = "yes" && test "${usb_found}" = "yes") ]) diff --git a/tools/Makefile.am b/tools/Makefile.am index 3dd69b68..9756a8d8 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -10,18 +10,24 @@ hid2hci_programs = hid2hci_manfiles = endif +if DFUTOOL +dfutool_programs = dfutool +dfutool_manfiles = dfutool.1 +else +dfutool_programs = +dfutool_manfiles = +endif + sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) -bin_PROGRAMS = hcitool l2ping sdptool ciptool +bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) noinst_PROGRAMS = hcisecfilter ppporc pskey hciconfig_SOURCES = hciconfig.c csr.h csr.c - hciconfig_LDADD = @BLUEZ_LIBS@ hcitool_SOURCES = hcitool.c oui.h oui.c - hcitool_LDADD = @BLUEZ_LIBS@ l2ping_LDADD = @BLUEZ_LIBS@ @@ -33,17 +39,22 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ pskey_SOURCES = pskey.c csr.h csr.c - pskey_LDADD = @BLUEZ_LIBS@ if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif +if DFUTOOL +dfutool_SOURCES = dfutool.c dfu.h dfu.c +dfutool_LDADD = @USB_LIBS@ +endif + AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ -man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 $(hid2hci_manfiles) +man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ + $(hid2hci_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) hid2hci.8 hid2hci.c +EXTRA_DIST = $(man_MANS) hid2hci.8 dfutool.1 MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/dfu.c b/tools/dfu.c new file mode 100644 index 00000000..08e256b9 --- /dev/null +++ b/tools/dfu.c @@ -0,0 +1,169 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "dfu.h" + +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif + +#ifndef USB_DIR_IN +#define USB_DIR_IN 0x80 +#endif + +#ifndef USB_DT_DFU +#define USB_DT_DFU 0x21 +#endif + +#define DFU_PACKETSIZE 0x03ff /* CSR default value: 1023 */ +#define DFU_TIMEOUT 10000 + +static uint32_t dfu_crc32_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +uint32_t crc32_init(void) +{ + return 0xffffffff; +} + +uint32_t crc32_byte(uint32_t accum, uint8_t delta) +{ + return dfu_crc32_table[(accum ^ delta) & 0xff] ^ (accum >> 8); +} + +int dfu_detach(struct usb_dev_handle *udev, int intf) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + DFU_DETACH, 0x1388, intf, NULL, 0, DFU_TIMEOUT); +} + +int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_UPLOAD, block, intf, buffer, size, DFU_TIMEOUT); +} + +int dfu_download(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, + DFU_DNLOAD, block, intf, buffer, size, DFU_TIMEOUT); +} + +int dfu_get_status(struct usb_dev_handle *udev, int intf, struct dfu_status *status) +{ + if (!udev || !status) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_GETSTATUS, 0, intf, (unsigned char *) status, DFU_STATUS_SIZE, DFU_TIMEOUT); +} + +int dfu_clear_status(struct usb_dev_handle *udev, int intf) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_CLRSTATUS, 0, intf, NULL, 0, DFU_TIMEOUT); +} + +int dfu_get_state(struct usb_dev_handle *udev, int intf, uint8_t *state) +{ + if (!udev || !state) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_GETSTATE, 0, intf, (unsigned char *) state, 1, DFU_TIMEOUT); +} + +int dfu_abort(struct usb_dev_handle *udev, int intf) +{ + if (!udev) + return -EIO; + + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + DFU_ABORT, 0, intf, NULL, 0, DFU_TIMEOUT); +} diff --git a/tools/dfu.h b/tools/dfu.h new file mode 100644 index 00000000..1a253505 --- /dev/null +++ b/tools/dfu.h @@ -0,0 +1,108 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * $Id$ + */ + +#include + +/* CRC interface */ +uint32_t crc32_init(void); +uint32_t crc32_byte(uint32_t accum, uint8_t delta); + +/* DFU descriptor */ +struct usb_dfu_descriptor { + u_int8_t bLength; + u_int8_t bDescriptorType; + u_int8_t bmAttributes; + u_int16_t wDetachTimeout; + u_int16_t wTransferSize; +}; + +/* DFU commands */ +#define DFU_DETACH 0 +#define DFU_DNLOAD 1 +#define DFU_UPLOAD 2 +#define DFU_GETSTATUS 3 +#define DFU_CLRSTATUS 4 +#define DFU_GETSTATE 5 +#define DFU_ABORT 6 + +/* DFU status */ +struct dfu_status { + uint8_t bStatus; + uint8_t bwPollTimeout[3]; + uint8_t bState; + uint8_t iString; +} __attribute__ ((packed)); +#define DFU_STATUS_SIZE 6 + +/* DFU status */ +#define DFU_OK 0x00 +#define DFU_ERR_TARGET 0x01 +#define DFU_ERR_FILE 0x02 +#define DFU_ERR_WRITE 0x03 +#define DFU_ERR_ERASE 0x04 +#define DFU_ERR_CHECK_ERASED 0x05 +#define DFU_ERR_PROG 0x06 +#define DFU_ERR_VERIFY 0x07 +#define DFU_ERR_ADDRESS 0x08 +#define DFU_ERR_NOTDONE 0x09 +#define DFU_ERR_FIRMWARE 0x0a +#define DFU_ERR_VENDOR 0x0b +#define DFU_ERR_USBR 0x0c +#define DFU_ERR_POR 0x0d +#define DFU_ERR_UNKNOWN 0x0e +#define DFU_ERR_STALLEDPKT 0x0f + +/* DFU state */ +#define DFU_STATE_APP_IDLE 0 +#define DFU_STATE_APP_DETACH 1 +#define DFU_STATE_DFU_IDLE 2 +#define DFU_STATE_DFU_DNLOAD_SYNC 3 +#define DFU_STATE_DFU_DNLOAD_BUSY 4 +#define DFU_STATE_DFU_DNLOAD_IDLE 5 +#define DFU_STATE_DFU_MANIFEST_SYNC 6 +#define DFU_STATE_DFU_MANIFEST 7 +#define DFU_STATE_MANIFEST_WAIT_RESET 8 +#define DFU_STATE_UPLOAD_IDLE 9 +#define DFU_STATE_ERROR 10 + +/* DFU suffix */ +struct dfu_suffix { + uint16_t bcdDevice; + uint16_t idProduct; + uint16_t idVendor; + uint16_t bcdDFU; + uint8_t ucDfuSignature[3]; + uint8_t bLength; + uint32_t dwCRC; +} __attribute__ ((packed)); +#define DFU_SUFFIX_SIZE 16 + +/* DFU interface */ +int dfu_detach(struct usb_dev_handle *udev, int intf); +int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size); +int dfu_download(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size); +int dfu_get_status(struct usb_dev_handle *udev, int intf, struct dfu_status *status); +int dfu_clear_status(struct usb_dev_handle *udev, int intf); +int dfu_get_state(struct usb_dev_handle *udev, int intf, uint8_t *state); +int dfu_abort(struct usb_dev_handle *udev, int intf); diff --git a/tools/dfutool.1 b/tools/dfutool.1 new file mode 100644 index 00000000..78b1fe7f --- /dev/null +++ b/tools/dfutool.1 @@ -0,0 +1,53 @@ +.\" +.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH DFUTOOL 1 "APRIL 21, 2005" "" "" + +.SH NAME +dfutool \- Device Firmware Upgrade utility +.SH SYNOPSIS +.BR "dfutool +[ +.I options +] < +.I command +> +.SH DESCRIPTION +.B dfutool +is used to verify, archive and upgrade firmware files. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands. +.TP +.BI -d " " +The command specifies the device to use. +.SH COMMANDS +.TP +.BI verify " " +Display information about the firmware file. +.TP +.BI modify " " +Change DFU specific values in the firmware file. +.TP +.BI upgrade " " +Upgrade the device with a new firmware. +.TP +.BI archive " " +Archive the current firmware of the device. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/dfutool.c b/tools/dfutool.c new file mode 100644 index 00000000..47510cef --- /dev/null +++ b/tools/dfutool.c @@ -0,0 +1,763 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dfu.h" + +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +#ifndef USB_CLASS_WIRELESS +#define USB_CLASS_WIRELESS 0xe0 +#endif + +#ifndef USB_CLASS_APPLICATION +#define USB_CLASS_APPLICATION 0xfe +#endif + +static int get_interface_number(struct usb_device *dev) +{ + int c, i, a; + + for (c = 0; c < dev->descriptor.bNumConfigurations; c++) { + struct usb_config_descriptor *config = &dev->config[c]; + + for (i = 0; i < config->bNumInterfaces; i++) { + struct usb_interface *interface = &config->interface[i]; + + for (a = 0; a < interface->num_altsetting; a++) { + struct usb_interface_descriptor *desc = &interface->altsetting[a]; + + if (desc->bInterfaceClass != USB_CLASS_APPLICATION) + continue; + if (desc->bInterfaceSubClass != 0x01) + continue; + if (desc->bInterfaceProtocol != 0x00) + continue; + + return desc->bInterfaceNumber; + } + } + } + + return -1; +} + +static void print_device(struct usb_device *dev) +{ + printf("Bus %s Device %s: ID %04x:%04x Interface %d%s\n", + dev->bus->dirname, dev->filename, + dev->descriptor.idVendor, dev->descriptor.idProduct, + get_interface_number(dev), + dev->descriptor.bDeviceClass == USB_CLASS_APPLICATION ? " (DFU mode)" : ""); +} + +static struct usb_dev_handle *open_device(char *device, struct dfu_suffix *suffix) +{ + struct usb_bus *bus; + struct usb_device *dev, *dfu_dev[10]; + struct usb_dev_handle *udev; + struct dfu_status status; + char str[8]; + int i, intf, sel, num = 0, try = 5, bus_id = -1, dev_id = -1; + + printf("Scanning USB busses ... "); + fflush(stdout); + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_get_busses(); bus; bus = bus->next) { + if (bus_id > 0) { + snprintf(str, sizeof(str) - 1, "%03i", bus_id); + if (strcmp(str, bus->dirname)) + continue; + } + + for (dev = bus->devices; dev; dev = dev->next) { + if (bus_id > 0 && dev_id > 0) { + snprintf(str, sizeof(str) - 1, "%03i", dev_id); + if (strcmp(str, dev->filename)) + continue; + } + + if (dev->descriptor.bDeviceClass == USB_CLASS_HUB) + continue; + + if (num > 9 || get_interface_number(dev) < 0) + continue; + + dfu_dev[num++] = dev; + } + } + + if (num < 1) { + printf("\rCan't find any DFU devices\n"); + return NULL; + } + + printf("\rAvailable devices with DFU support:\n\n"); + for (i = 0; i < num; i++) { + printf("\t%2d) ", i + 1); + print_device(dfu_dev[i]); + } + printf("\n"); + + do { + printf("\rSelect device (abort with 0): "); + fflush(stdout); + memset(str, 0, sizeof(str)); + fgets(str, sizeof(str) - 1, stdin); + sel = atoi(str); + } while (!isdigit(str[0]) || sel < 0 || sel > num ); + + if (sel < 1) + return NULL; + + sel--; + intf = get_interface_number(dfu_dev[sel]); + printf("\n"); + + udev = usb_open(dfu_dev[sel]); + if (!udev) { + printf("Can't open device: %s (%d)\n", strerror(errno), errno); + return NULL; + } + + if (usb_claim_interface(udev, intf) < 0) { + printf("Can't claim interface: %s (%d)\n", strerror(errno), errno); + usb_close(udev); + return NULL; + } + + if (dfu_get_status(udev, intf, &status) < 0) { + printf("Can't get status: %s (%d)\n", strerror(errno), errno); + goto error; + } + + if (status.bState == DFU_STATE_ERROR) { + if (dfu_clear_status(udev, intf) < 0) { + printf("Can't clear status: %s (%d)\n", strerror(errno), errno); + goto error; + } + if (dfu_abort(udev, intf) < 0) { + printf("Can't abort previous action: %s (%d)\n", strerror(errno), errno); + goto error; + } + if (dfu_get_status(udev, intf, &status) < 0) { + printf("Can't get status: %s (%d)\n", strerror(errno), errno); + goto error; + } + } + + if (status.bState == DFU_STATE_DFU_IDLE) { + if (suffix) { + suffix->idVendor = 0x0000; + suffix->idProduct = 0x0000; + suffix->bcdDevice = 0x0000; + } + return udev; + } + + if (status.bState != DFU_STATE_APP_IDLE) { + printf("Device is not idle, can't detach it (state %d)\n", status.bState); + goto error; + } + + printf("Switching device into DFU mode ... "); + fflush(stdout); + + if (suffix) { + suffix->idVendor = dfu_dev[sel]->descriptor.idVendor; + suffix->idProduct = dfu_dev[sel]->descriptor.idProduct; + suffix->bcdDevice = dfu_dev[sel]->descriptor.bcdDevice; + } + + if (dfu_detach(udev, intf) < 0) { + printf("\rCan't detach device: %s (%d)\n", strerror(errno), errno); + goto error; + } + + if (dfu_get_status(udev, intf, &status) < 0) { + printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); + goto error; + } + + if (status.bState != DFU_STATE_APP_DETACH) { + printf("\rDevice is not in detach mode, try again\n"); + goto error; + } + + usb_release_interface(udev, intf); + usb_reset(udev); + usb_close(udev); + + bus = dfu_dev[sel]->bus; + num = 0; + + while (num != 1 && try-- > 0) { + sleep(1); + usb_find_devices(); + + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.bDeviceClass != USB_CLASS_APPLICATION) + continue; + + if (suffix && dev->descriptor.idVendor != suffix->idVendor) + continue; + + if (num > 9 || get_interface_number(dev) != 0) + continue; + + dfu_dev[num++] = dev; + } + } + + if (num != 1) { + printf("\rCan't identify device with DFU mode\n"); + goto error; + } + + printf("\r"); + + intf = 0; + + udev = usb_open(dfu_dev[0]); + if (!udev) { + printf("Can't open device: %s (%d)\n", strerror(errno), errno); + return NULL; + } + + if (usb_claim_interface(udev, intf) < 0) { + printf("Can't claim interface: %s (%d)\n", strerror(errno), errno); + usb_close(udev); + return NULL; + } + + if (dfu_get_status(udev, intf, &status) < 0) { + printf("Can't get status: %s (%d)\n", strerror(errno), errno); + goto error; + } + + if (status.bState != DFU_STATE_DFU_IDLE) { + printf("Device is not in DFU mode, can't use it\n"); + goto error; + } + + return udev; + +error: + usb_release_interface(udev, intf); + usb_close(udev); + return NULL; +} + +static void usage(void); + +static void cmd_verify(char *device, int argc, char **argv) +{ + struct stat st; + struct dfu_suffix *suffix; + uint32_t crc; + char str[16]; + unsigned char *buf; + unsigned long size; + char *filename; + int i, fd, len; + + if (argc < 2) { + usage(); + exit(1); + } + + filename = argv[1]; + + if (stat(filename, &st) < 0) { + perror("Can't access firmware"); + exit(1); + } + + size = st.st_size; + + if (!(buf = malloc(size))) { + perror("Unable to allocate file buffer"); + exit(1); + } + + if ((fd = open(filename, O_RDONLY)) < 0) { + perror("Can't open firmware"); + free(buf); + exit(1); + } + + if (read(fd, buf, size) < size) { + perror("Can't load firmware"); + free(buf); + close(fd); + exit(1); + } + + printf("Filename\t%s\n", basename(filename)); + printf("Filesize\t%ld\n", size); + + crc = crc32_init(); + for (i = 0; i < size - 4; i++) + crc = crc32_byte(crc, buf[i]); + printf("Checksum\t%08x\n", crc); + + printf("\n"); + len = buf[size - 5]; + printf("DFU suffix\t"); + for (i = 0; i < len; i++) { + printf("%02x ", buf[size - len + i]); + } + printf("\n\n"); + + suffix = (struct dfu_suffix *) (buf + size - DFU_SUFFIX_SIZE); + + printf("idVendor\t%04x\n", suffix->idVendor); + printf("idProduct\t%04x\n", suffix->idProduct); + printf("bcdDevice\t%x\n", suffix->bcdDevice); + + printf("\n"); + + printf("bcdDFU\t\t%x.%x\n", suffix->bcdDFU >> 8, suffix->bcdDFU & 0xff); + printf("ucDfuSignature\t%c%c%c\n", suffix->ucDfuSignature[2], + suffix->ucDfuSignature[1], suffix->ucDfuSignature[0]); + printf("bLength\t\t%d\n", suffix->bLength); + printf("dwCRC\t\t%08x\n", suffix->dwCRC); + printf("\n"); + + memset(str, 0, sizeof(str)); + memcpy(str, buf, 8); + + if (!strcmp(str, "CSR-dfu1") || !strcmp(str, "CSR-dfu2")) { + crc = crc32_init(); + for (i = 0; i < size - DFU_SUFFIX_SIZE; i++) + crc = crc32_byte(crc, buf[i]); + + printf("Firmware type\t%s\n", str); + printf("Firmware check\t%s checksum\n", crc == 0 ? "valid" : "corrupt"); + printf("\n"); + } + + free(buf); + + close(fd); +} + +static void cmd_modify(char *device, int argc, char **argv) +{ +} + +static void cmd_upgrade(char *device, int argc, char **argv) +{ + struct usb_dev_handle *udev; + struct dfu_status status; + struct dfu_suffix suffix; + struct stat st; + unsigned char *buf; + unsigned long filesize, count, timeout = 0; + char *filename; + uint32_t crc; + int fd, i, block, len, size, sent = 0, try = 10; + + if (argc < 2) { + usage(); + exit(1); + } + + filename = argv[1]; + + if (stat(filename, &st) < 0) { + perror("Can't access firmware"); + exit(1); + } + + filesize = st.st_size; + + if (!(buf = malloc(filesize))) { + perror("Unable to allocate file buffer"); + exit(1); + } + + if ((fd = open(filename, O_RDONLY)) < 0) { + perror("Can't open firmware"); + free(buf); + exit(1); + } + + if (read(fd, buf, filesize) < filesize) { + perror("Can't load firmware"); + free(buf); + close(fd); + exit(1); + } + + memcpy(&suffix, buf + filesize - DFU_SUFFIX_SIZE, sizeof(suffix)); + + printf("Filename\t%s\n", basename(filename)); + printf("Filesize\t%ld\n", filesize); + + crc = crc32_init(); + for (i = 0; i < filesize - 4; i++) + crc = crc32_byte(crc, buf[i]); + printf("Checksum\t%08x (%s)\n", crc, + crc == suffix.dwCRC ? "valid" : "corrupt"); + + if (crc != suffix.dwCRC) { + free(buf); + close(fd); + exit(1); + } + + printf("\n"); + + udev = open_device(device, &suffix); + if (!udev) + exit(1); + + printf("\r" " " " " " " " " " "); + printf("\rFirmware download ... "); + fflush(stdout); + + count = filesize - DFU_SUFFIX_SIZE; + block = 0; + + while (count) { + size = (count > 1023) ? 1023 : count; + + if (dfu_get_status(udev, 0, &status) < 0) { + if (try-- > 0) { + sleep(1); + continue; + } + printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); + goto done; + } + + if (status.bStatus != DFU_OK) { + if (try-- > 0) { + dfu_clear_status(udev, 0); + sleep(1); + continue; + } + printf("\rFirmware download ... aborting (status %d state %d)\n", + status.bStatus, status.bState); + goto done; + } + + if (status.bState != DFU_STATE_DFU_IDLE && + status.bState != DFU_STATE_DFU_DNLOAD_IDLE) { + sleep(1); + continue; + } + + timeout = (status.bwPollTimeout[2] << 16) | + (status.bwPollTimeout[1] << 8) | + status.bwPollTimeout[0]; + + usleep(timeout * 1000); + + len = dfu_download(udev, 0, block, buf + sent, size); + if (len < 0) { + if (try-- > 0) { + sleep(1); + continue; + } + printf("\rCan't upload next block: %s (%d)\n", strerror(errno), errno); + goto done; + } + + printf("\rFirmware download ... %d bytes ", block * 1023 + len); + fflush(stdout); + + sent += len; + count -= len; + block++; + } + + printf("\r" " " " " " " " " " "); + printf("\rFinishing firmware download ... "); + fflush(stdout); + + sleep(1); + + if (dfu_get_status(udev, 0, &status) < 0) { + printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); + goto done; + } + + timeout = (status.bwPollTimeout[2] << 16) | + (status.bwPollTimeout[1] << 8) | + status.bwPollTimeout[0]; + + usleep(timeout * 1000); + + if (count == 0) { + len = dfu_download(udev, 0, block, NULL, 0); + if (len < 0) { + printf("\rCan't send final block: %s (%d)\n", strerror(errno), errno); + goto done; + } + } + + printf("\r" " " " " " " " " " "); + printf("\rWaiting for device ... "); + fflush(stdout); + + sleep(10); + + printf("\n"); + +done: + free(buf); + close(fd); + + usb_release_interface(udev, 0); + usb_reset(udev); + usb_close(udev); +} + +static void cmd_archive(char *device, int argc, char **argv) +{ + struct usb_dev_handle *udev; + struct dfu_status status; + struct dfu_suffix suffix; + unsigned char buf[2048]; + unsigned long timeout = 0; + char *filename; + uint32_t crc; + int fd, i, n, len, try = 8; + + if (argc < 2) { + usage(); + exit(1); + } + + filename = argv[1]; + + udev = open_device(device, &suffix); + if (!udev) + exit(1); + + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + printf("Can't open firmware file: %s (%d)\n", strerror(errno), errno); + goto done; + } + + printf("\r" " " " " " " " " " "); + printf("\rFirmware upload ... "); + fflush(stdout); + + crc = crc32_init(); + n = 0; + while (1) { + if (dfu_get_status(udev, 0, &status) < 0) { + if (try-- > 0) { + sleep(1); + continue; + } + printf("\rCan't get status: %s (%d)\n", strerror(errno), errno); + goto done; + } + + if (status.bStatus != DFU_OK) { + if (try-- > 0) { + dfu_clear_status(udev, 0); + sleep(1); + continue; + } + printf("\rFirmware upload ... aborting (status %d state %d)\n", + status.bStatus, status.bState); + goto done; + } + + if (status.bState != DFU_STATE_DFU_IDLE && + status.bState != DFU_STATE_UPLOAD_IDLE) { + sleep(1); + continue; + } + + timeout = (status.bwPollTimeout[2] << 16) | + (status.bwPollTimeout[1] << 8) | + status.bwPollTimeout[0]; + + usleep(timeout * 1000); + + len = dfu_upload(udev, 0, n, buf, 1023); + if (len < 0) { + if (try-- > 0) { + sleep(1); + continue; + } + printf("\rCan't upload next block: %s (%d)\n", strerror(errno), errno); + goto done; + } + + printf("\rFirmware upload ... %d bytes ", n * 1023 + len); + fflush(stdout); + + for (i = 0; i < len; i++) + crc = crc32_byte(crc, buf[i]); + + if (len > 0) + write(fd, buf, len); + + n++; + if (len != 1023) + break; + } + printf("\n"); + + suffix.bcdDFU = 0x0100; + suffix.ucDfuSignature[0] = 'U'; + suffix.ucDfuSignature[1] = 'F'; + suffix.ucDfuSignature[2] = 'D'; + suffix.bLength = DFU_SUFFIX_SIZE; + + memcpy(buf, &suffix, DFU_SUFFIX_SIZE); + for (i = 0; i < DFU_SUFFIX_SIZE - 4; i++) + crc = crc32_byte(crc, buf[i]); + + suffix.dwCRC = crc; + + write(fd, &suffix, DFU_SUFFIX_SIZE); + +done: + close(fd); + + usb_release_interface(udev, 0); + usb_reset(udev); + usb_close(udev); +} + +struct { + char *cmd; + char *alt; + void (*func)(char *device, int argc, char **argv); + char *opt; + char *doc; +} command[] = { + { "verify", "check", cmd_verify, "", "Check firmware file" }, + { "modify", "change", cmd_modify, "", "Change firmware attributes" }, + { "upgrade", "download", cmd_upgrade, "", "Download a new firmware" }, + { "archive", "upload", cmd_archive, "", "Upload the current firmware" }, + { NULL, NULL, NULL, 0, 0 } +}; + +static void usage(void) +{ + int i; + + printf("dfutool - Device Firmware Upgrade utility ver %s\n\n", VERSION); + + printf("Usage:\n" + "\tdfutool [options] \n" + "\n"); + + printf("Options:\n" + "\t-d, --device USB device\n" + "\t-h, --help Display help\n" + "\n"); + + printf("Commands:\n"); + for (i = 0; command[i].cmd; i++) + printf("\t%-8s %-10s\t%s\n", command[i].cmd, + command[i].opt ? command[i].opt : " ", + command[i].doc); + printf("\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'd' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + char *device = NULL; + int i, opt; + + while ((opt = getopt_long(argc, argv, "+d:h", main_options, NULL)) != -1) { + switch(opt) { + case 'd': + device = strdup(optarg); + break; + + case 'h': + usage(); + exit(0); + + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + usb_init(); + + for (i = 0; command[i].cmd; i++) { + if (strcmp(command[i].cmd, argv[0]) && strcmp(command[i].alt, argv[0])) + continue; + command[i].func(device, argc, argv); + exit(0); + } + + usage(); + exit(1); +} -- cgit From 406c627c1ae543d6b2eac8ccb3cc597b7c58c6aa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Apr 2005 11:32:10 +0000 Subject: No need to include syslog.h --- hcid/storage.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hcid/storage.c b/hcid/storage.c index b225b598..8b7de73a 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include -- cgit From 70e5fac9bd0fb2294eb7e585c005eb096ae84f5d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Apr 2005 11:52:29 +0000 Subject: Include sys/param.h for PATH_MAX --- hcid/storage.c | 1 + tools/hcitool.c | 1 + 2 files changed, 2 insertions(+) diff --git a/hcid/storage.c b/hcid/storage.c index 8b7de73a..79ec11af 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/tools/hcitool.c b/tools/hcitool.c index fb189760..a30e7098 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include -- cgit From a66a22cd29417810d91c057c6febe817f3d7b26a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Apr 2005 12:15:36 +0000 Subject: Add the textfile library for ASCII based file access --- Makefile.am | 3 +- common/Makefile.am | 9 +++++ common/textfile.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++ common/textfile.h | 29 ++++++++++++++++ configure.in | 2 +- 5 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 common/Makefile.am create mode 100644 common/textfile.c create mode 100644 common/textfile.h diff --git a/Makefile.am b/Makefile.am index 251d8da1..49650733 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,8 @@ # $Id$ # -SUBDIRS = hcid tools rfcomm sdpd dund pand hidd cups alsa test scripts pcmcia extra +SUBDIRS = common tools rfcomm hcid sdpd dund pand hidd \ + cups alsa test scripts pcmcia extra MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in config.sub config.guess \ diff --git a/common/Makefile.am b/common/Makefile.am new file mode 100644 index 00000000..ffcddf6e --- /dev/null +++ b/common/Makefile.am @@ -0,0 +1,9 @@ +# +# $Id$ +# + +noinst_LIBRARIES = libtextfile.a + +libtextfile_a_SOURCES = textfile.h textfile.c + +MAINTAINERCLEANFILES = Makefile.in diff --git a/common/textfile.c b/common/textfile.c new file mode 100644 index 00000000..6f84cfa9 --- /dev/null +++ b/common/textfile.c @@ -0,0 +1,100 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *textfile_get(const char *pathname, const char *key) +{ + struct stat st; + char *map, *off, *end, *str = NULL; + off_t size; size_t len; + int fd; + + fd = open(pathname, O_RDONLY); + if (fd < 0) + return NULL; + + if (flock(fd, LOCK_SH) < 0) + goto close; + + if (fstat(fd, &st) < 0) + goto unlock; + + size = st.st_size; + + map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) + goto close; + + off = strstr(map, key); + if (!off) + goto unmap; + + if (off > map) { + while (*(off - 1) != '\r' && *(off - 1) != '\n') { + off = strstr(map, key); + if (!off) + goto unmap; + } + } + + end = strpbrk(off, "\r\n"); + if (!end) + goto unmap; + + len = strlen(key); + str = malloc(end - off - len); + memset(str, 0, end - off - len); + if (!str) + goto unmap; + + strncpy(str, off + len + 1, end - off - len - 1); + +unmap: + munmap(map, size); + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + + return str; +} diff --git a/common/textfile.h b/common/textfile.h new file mode 100644 index 00000000..56a0bc10 --- /dev/null +++ b/common/textfile.h @@ -0,0 +1,29 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +char *textfile_get(const char *pathname, const char *key); diff --git a/configure.in b/configure.in index 15febfe9..830c4527 100644 --- a/configure.in +++ b/configure.in @@ -34,4 +34,4 @@ AC_PATH_DBUS AC_ARG_BLUEZ -AC_OUTPUT(Makefile hcid/Makefile tools/Makefile rfcomm/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) +AC_OUTPUT(Makefile common/Makefile tools/Makefile rfcomm/Makefile hcid/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) -- cgit From cb079810a52ebbc4ec46c33b2a0f31a6b9c8c778 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Apr 2005 12:18:52 +0000 Subject: Use the new textfile library --- tools/Makefile.am | 4 +++- tools/hcitool.c | 71 ++++++++++--------------------------------------------- 2 files changed, 16 insertions(+), 59 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index 9756a8d8..1743771b 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -28,7 +28,7 @@ hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ hcitool_SOURCES = hcitool.c oui.h oui.c -hcitool_LDADD = @BLUEZ_LIBS@ +hcitool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a l2ping_LDADD = @BLUEZ_LIBS@ @@ -52,6 +52,8 @@ endif AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ +INCLUDES = -I$(top_srcdir)/common + man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ $(hid2hci_manfiles) $(dfutool_manfiles) diff --git a/tools/hcitool.c b/tools/hcitool.c index a30e7098..6e225cee 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include #include #include @@ -48,6 +46,7 @@ #include #include +#include "textfile.h" #include "oui.h" #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, NULL)) != -1) @@ -280,65 +279,15 @@ static char *major_classes[] = { "Audio/Video", "Peripheral", "Imaging", "Uncategorized" }; -static int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) +static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer) { - char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int fd, pos, err = -ENOENT; + char filename[PATH_MAX + 1], addr[18]; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); - fd = open(filename, O_RDONLY); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_SH) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - if (!bacmp(&bdaddr, peer)) { - snprintf(name, 249, "%s", str); - err = 0; - break; - } - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - } - -unlock: - flock(fd, LOCK_UN); - -close: - close(fd); - return err; + ba2str(peer, addr); + return textfile_get(filename, addr); } /* Display local devices */ @@ -457,7 +406,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) int num_rsp, length, flags; uint8_t cls[3], features[8]; uint16_t handle; - char addr[18], name[249], oui[9], *comp; + char addr[18], name[249], oui[9], *comp, *tmp; struct hci_version version; struct hci_dev_info di; struct hci_conn_info_req *cr; @@ -538,7 +487,13 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (i = 0; i < num_rsp; i++) { memset(name, 0, sizeof(name)); - nc = (read_device_name(&di.bdaddr, &(info+i)->bdaddr, name) == 0); + tmp = get_device_name(&di.bdaddr, &(info+i)->bdaddr); + if (tmp) { + strncpy(name, tmp, 249); + free(tmp); + nc = 1; + } else + nc = 0; if (!extcls && !extinf && !extoui) { ba2str(&(info+i)->bdaddr, addr); -- cgit From a6c9d1b70a9b29e371cb890d417d41b58ba8a901 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 23 Apr 2005 18:44:39 +0000 Subject: Implement connection caching --- alsa/pcm_a2dp.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 24 deletions(-) diff --git a/alsa/pcm_a2dp.c b/alsa/pcm_a2dp.c index 90ee7107..be89e677 100644 --- a/alsa/pcm_a2dp.c +++ b/alsa/pcm_a2dp.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,7 @@ typedef struct snd_pcm_a2dp { snd_pcm_ioplug_t io; + int refcnt; bdaddr_t src; bdaddr_t dst; int sk; @@ -54,6 +56,31 @@ typedef struct snd_pcm_a2dp { unsigned int frame_bytes; } snd_pcm_a2dp_t; +#define MAX_CONNECTIONS 10 + +static snd_pcm_a2dp_t *connections[MAX_CONNECTIONS]; + +static void sig_alarm(int sig) +{ + int i; + + for (i = 0; i < MAX_CONNECTIONS; i++) { + snd_pcm_a2dp_t *a2dp = connections[i]; + + if (!a2dp || a2dp->refcnt > 0) + continue; + + connections[i] = NULL; + + if (a2dp->sk >= 0) + close(a2dp->sk); + + sbc_finish(&a2dp->sbc); + + free(a2dp); + } +} + static int a2dp_start(snd_pcm_ioplug_t *io) { snd_pcm_a2dp_t *a2dp = io->private_data; @@ -120,15 +147,11 @@ static int a2dp_close(snd_pcm_ioplug_t *io) a2dp->len = 0; - if (a2dp->sk >= 0) { - shutdown(a2dp->sk, SHUT_RDWR); - sleep(1); - close(a2dp->sk); - } + a2dp->refcnt--; - sbc_finish(&a2dp->sbc); + if (!a2dp->refcnt) + alarm(2); - free(a2dp); return 0; } @@ -158,6 +181,10 @@ static int a2dp_prepare(snd_pcm_ioplug_t *io) DBG("a2dp %p", a2dp); + a2dp->len = 0; + + a2dp->num = 0; + a2dp->sbc.rate = io->rate; a2dp->sbc.channels = io->channels; @@ -175,6 +202,14 @@ static int a2dp_drain(snd_pcm_ioplug_t *io) return 0; } +static int a2dp_poll(snd_pcm_ioplug_t *io, struct pollfd *ufds, + unsigned int nfds, unsigned short *revents) +{ + *revents = ufds[0].revents; + + return 0; +} + static snd_pcm_ioplug_callback_t a2dp_callback = { .start = a2dp_start, .stop = a2dp_stop, @@ -184,11 +219,13 @@ static snd_pcm_ioplug_callback_t a2dp_callback = { .hw_params = a2dp_params, .prepare = a2dp_prepare, .drain = a2dp_drain, + .poll_revents = a2dp_poll, }; static int a2dp_connect(snd_pcm_a2dp_t *a2dp) { struct sockaddr_rc addr; + socklen_t len; int sk; DBG("a2dp %p", a2dp); @@ -216,7 +253,18 @@ static int a2dp_connect(snd_pcm_a2dp_t *a2dp) return -errno; } + memset(&addr, 0, sizeof(addr)); + len = sizeof(addr); + + if (getsockname(sk, (struct sockaddr *) &addr, &len) < 0) { + close(sk); + return -errno; + } + + bacpy(&a2dp->src, &addr.rc_bdaddr); + a2dp->sk = sk; + return 0; } @@ -271,10 +319,10 @@ static int a2dp_constraint(snd_pcm_a2dp_t *a2dp) SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) { - snd_pcm_a2dp_t *a2dp; + snd_pcm_a2dp_t *a2dp = NULL; snd_config_iterator_t i, next; bdaddr_t src, dst; - int err; + int err, n, pos = -1; DBG("name %s mode %d", name, mode); @@ -300,7 +348,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) continue; } - if (strcmp(id, "src") == 0) { + if (!strcmp(id, "local") || !strcmp(id, "src")) { if (snd_config_get_string(n, &addr) < 0) { SNDERR("Invalid type for %s", id); return -EINVAL; @@ -313,26 +361,59 @@ SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) return -EINVAL; } - a2dp = malloc(sizeof(*a2dp)); - if (!a2dp) { - SNDERR("Cannot allocate"); - return -ENOMEM; + for (n = 0; n < MAX_CONNECTIONS; n++) { + if (connections[n]) { + if (!bacmp(&connections[n]->dst, &dst) && + (!bacmp(&connections[n]->src, &src) || + !bacmp(&src, BDADDR_ANY))) { + a2dp = connections[n]; + a2dp->refcnt++; + break; + } + } else if (pos < 0) + pos = n; } - memset(a2dp, 0, sizeof(*a2dp)); + if (!a2dp) { + struct sigaction sa; - bacpy(&a2dp->src, &src); - bacpy(&a2dp->dst, &dst); + if (pos < 0) { + SNDERR("Too many connections"); + return -ENOMEM; + } - err = a2dp_connect(a2dp); - if (err < 0) { - SNDERR("Cannot connect"); - goto error; + a2dp = malloc(sizeof(*a2dp)); + if (!a2dp) { + SNDERR("Cannot allocate"); + return -ENOMEM; + } + + memset(a2dp, 0, sizeof(*a2dp)); + + a2dp->refcnt = 1; + + bacpy(&a2dp->src, &src); + bacpy(&a2dp->dst, &dst); + + err = a2dp_connect(a2dp); + if (err < 0) { + SNDERR("Cannot connect"); + goto error; + } + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_alarm; + sigaction(SIGALRM, &sa, NULL); + + alarm(0); + + connections[pos] = a2dp; } a2dp->io.name = "Bluetooth Advanced Audio Distribution"; a2dp->io.poll_fd = a2dp->sk; - a2dp->io.poll_events = POLLOUT | POLLHUP; + a2dp->io.poll_events = POLLOUT; a2dp->io.mmap_rw = 0; a2dp->io.callback = &a2dp_callback; a2dp->io.private_data = a2dp; @@ -344,14 +425,18 @@ SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) err = a2dp_constraint(a2dp); if (err < 0) { snd_pcm_ioplug_delete(&a2dp->io); - return err; + goto error; } *pcmp = a2dp->io.pcm; return 0; error: - free(a2dp); + a2dp->refcnt--; + + if (!a2dp->refcnt) + alarm(2); + return err; } -- cgit From be773ea1ce058211345171cff8c0ff3590ad0f9f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 23 Apr 2005 19:13:03 +0000 Subject: The pskey tool should be used for reading the boot mode --- tools/hciconfig.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 20ef065c..df9b211e 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1043,7 +1043,7 @@ static void print_rev_ericsson(int dd) static void print_rev_csr(int dd, uint16_t rev) { - uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, bootmode, error; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, error; if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { printf("\t%s\n", csr_buildidtostr(rev)); @@ -1064,9 +1064,6 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); - if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_INITIAL_BOOTMODE, &bootmode)) - printf("\tBoot mode: %d%s\n", bootmode, bootmode ? "" : " (HCI)"); - if (!csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error)) { if (error < 0x0100) printf("\tPanic code: 0x%02x\n", error); -- cgit From c5a582daf8c31440da7ddcfcde2ae0af6dcf7da8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Apr 2005 19:02:57 +0000 Subject: Add build id for BlueCore3-MM with HCI 19.2 firmware --- tools/csr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/csr.c b/tools/csr.c index 45324d3e..7b783da9 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -270,6 +270,7 @@ static struct { { 1916, "HCI 19.2" }, { 1958, "HCI 19.2" }, { 1981, "HCI 19.2" }, + { 1982, "HCI 19.2" }, { 1989, "HCI 18.4" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, -- cgit From 2cd3e62a5415f9a0aa895ea4222606012e23d744 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 30 Apr 2005 11:48:00 +0000 Subject: Update for the Unified 20 firmware releases --- tools/csr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 7b783da9..b5691afa 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -269,9 +269,11 @@ static struct { { 1915, "HCI 19.2" }, { 1916, "HCI 19.2" }, { 1958, "HCI 19.2" }, - { 1981, "HCI 19.2" }, - { 1982, "HCI 19.2" }, + { 1981, "Unified 20a" }, + { 1982, "Unified 20a" }, { 1989, "HCI 18.4" }, + { 2062, "Unified 20a1" }, + { 2063, "Unified 20a1" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From 2bc66b1d0af2e2a01e545493510347578928ae33 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 30 Apr 2005 18:24:13 +0000 Subject: Add support for voice setting --- hcid/hcid.h | 14 +++++++++++++- hcid/kword.c | 1 + hcid/main.c | 34 ++++++++++++++++++++++------------ hcid/parser.y | 13 ++++++++++++- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index 5523d4b7..e275939f 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -40,14 +40,26 @@ #define HCID_KEY_FILE CONFIGDIR "/link_key" #define HCID_PIN_HELPER "/usr/bin/bluepin" +enum { + HCID_SET_NAME, + HCID_SET_CLASS, + HCID_SET_VOICE, + HCID_SET_INQMODE, + HCID_SET_PTYPE, + HCID_SET_LM, + HCID_SET_LP, +}; + struct device_opts { + unsigned long flags; char *name; uint32_t class; + uint16_t voice; uint8_t inqmode; uint16_t pkt_type; - uint16_t scan; uint16_t link_mode; uint16_t link_policy; + uint16_t scan; uint16_t auth; uint16_t encrypt; }; diff --git a/hcid/kword.c b/hcid/kword.c index bd2294b2..51c92e1d 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -59,6 +59,7 @@ struct kword cfg_keyword[] = { { "pscan", K_PSCAN }, { "name", K_NAME }, { "class", K_CLASS }, + { "voice", K_VOICE }, { "inqmode", K_INQMODE }, { "auth", K_AUTH }, { "encrypt", K_ENCRYPT }, diff --git a/hcid/main.c b/hcid/main.c index 45b8231d..f4736940 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -222,8 +222,18 @@ static void configure_device(int hdev) hdev, strerror(errno), errno); } + /* Set device name */ + if ((device_opts->flags & (1 << HCID_SET_NAME)) && device_opts->name) { + change_local_name_cp cp; + memset(cp.name, 0, sizeof(cp.name)); + expand_name(cp.name, sizeof(cp.name), device_opts->name, hdev); + + hci_send_cmd(s, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, + CHANGE_LOCAL_NAME_CP_SIZE, (void *) &cp); + } + /* Set device class */ - if (device_opts->class) { + if ((device_opts->flags & (1 << HCID_SET_CLASS))) { uint32_t class = htobl(device_opts->class); write_class_of_dev_cp cp; @@ -232,18 +242,18 @@ static void configure_device(int hdev) WRITE_CLASS_OF_DEV_CP_SIZE, (void *) &cp); } - /* Set device name */ - if (device_opts->name) { - change_local_name_cp cp; - memset(cp.name, 0, sizeof(cp.name)); - expand_name(cp.name, sizeof(cp.name), device_opts->name, hdev); + /* Set voice setting */ + if ((device_opts->flags & (1 << HCID_SET_VOICE))) { + write_voice_setting_cp cp; - hci_send_cmd(s, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, - CHANGE_LOCAL_NAME_CP_SIZE, (void *) &cp); + cp.voice_setting = htobl(device_opts->voice); + hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING, + WRITE_VOICE_SETTING_CP_SIZE, (void *) &cp); } /* Set inquiry mode */ - if (di.features[3] & LMP_RSSI_INQ) { + if ((device_opts->flags & (1 << HCID_SET_INQMODE)) && + (di.features[3] & LMP_RSSI_INQ)) { write_inquiry_mode_cp cp; cp.mode = device_opts->inqmode; @@ -298,7 +308,7 @@ static void init_device(int hdev) device_opts = get_device_opts(s, hdev); /* Set packet type */ - if (device_opts->pkt_type) { + if ((device_opts->flags & (1 << HCID_SET_PTYPE))) { dr.dev_opt = device_opts->pkt_type; if (ioctl(s, HCISETPTYPE, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set packet type on hci%d: %s (%d)", @@ -307,7 +317,7 @@ static void init_device(int hdev) } /* Set link mode */ - if (device_opts->link_mode) { + if ((device_opts->flags & (1 << HCID_SET_LM))) { dr.dev_opt = device_opts->link_mode; if (ioctl(s, HCISETLINKMODE, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set link mode on hci%d: %s (%d)", @@ -316,7 +326,7 @@ static void init_device(int hdev) } /* Set link policy */ - if (device_opts->link_policy) { + if ((device_opts->flags & (1 << HCID_SET_LP))) { dr.dev_opt = device_opts->link_policy; if (ioctl(s, HCISETLINKPOL, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set link policy on hci%d: %s (%d)", diff --git a/hcid/parser.y b/hcid/parser.y index 3534fb2b..a0eb13de 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -64,7 +64,7 @@ int yyerror(char *s); %token K_OPTIONS K_DEVICE %token K_AUTOINIT K_SECURITY K_PAIRING -%token K_PTYPE K_NAME K_CLASS K_INQMODE K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN +%token K_PTYPE K_NAME K_CLASS K_VOICE K_INQMODE K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN %token K_PINHELP K_DBUSPINHELP %token K_YES K_NO @@ -169,28 +169,39 @@ device_options: '{' device_opts '}'; device_opts: | device_opt ';' | error ';' | device_opts device_opt ';'; device_opt: K_PTYPE pkt_type { + parser_device->flags |= (1 << HCID_SET_PTYPE); parser_device->pkt_type = $2; } | K_LM link_mode { + parser_device->flags |= (1 << HCID_SET_LM); parser_device->link_mode = $2; } | K_LP link_policy { + parser_device->flags |= (1 << HCID_SET_LP); parser_device->link_policy = $2; } | K_NAME dev_name { if (parser_device->name) free(parser_device->name); + parser_device->flags |= (1 << HCID_SET_NAME); parser_device->name = strdup($2); } | K_CLASS NUM { + parser_device->flags |= (1 << HCID_SET_CLASS); parser_device->class = $2; } + | K_VOICE NUM { + parser_device->flags |= (1 << HCID_SET_VOICE); + parser_device->voice = $2; + } + | K_INQMODE NUM { + parser_device->flags |= (1 << HCID_SET_INQMODE); parser_device->inqmode = $2; } -- cgit From 58ceef5033eed699bfd7db9eaaf382823f2114ad Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 30 Apr 2005 18:46:01 +0000 Subject: Read the stored link keys when starting the security manager --- hcid/security.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hcid/security.c b/hcid/security.c index 5b2dc285..921875b3 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -584,6 +584,7 @@ void start_security_manager(int hdev) GIOChannel *chan = io_chan[hdev]; struct hci_dev_info *di; struct hci_filter flt; + read_stored_link_key_cp cp; int dev; if (chan) @@ -635,6 +636,12 @@ void start_security_manager(int hdev) io_security_event, (void *) di); io_chan[hdev] = chan; + + bacpy(&cp.bdaddr, BDADDR_ANY); + cp.read_all = 1; + + hci_send_cmd(dev, OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY, + READ_STORED_LINK_KEY_CP_SIZE, (void *) &cp); } void stop_security_manager(int hdev) -- cgit From d4dc3014bb2b70bee8504ed4b1a8348acef7da74 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 1 May 2005 14:54:11 +0000 Subject: Support storing and deleting of stored link keys --- tools/Makefile.am | 2 +- tools/hciconfig.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index 1743771b..e9574f3e 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -25,7 +25,7 @@ bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) noinst_PROGRAMS = hcisecfilter ppporc pskey hciconfig_SOURCES = hciconfig.c csr.h csr.c -hciconfig_LDADD = @BLUEZ_LIBS@ +hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a hcitool_SOURCES = hcitool.c oui.h oui.c hcitool_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a diff --git a/tools/hciconfig.c b/tools/hciconfig.c index df9b211e..5f72ce66 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -45,6 +45,7 @@ #include #include +#include "textfile.h" #include "csr.h" static struct hci_dev_info di; @@ -689,6 +690,101 @@ static void cmd_voice(int ctl, int hdev, char *opt) } } +static int get_link_key(const bdaddr_t *local, const bdaddr_t *peer, uint8_t *key) +{ + char filename[PATH_MAX + 1], addr[18], tmp[3], *str; + int i; + + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); + + ba2str(peer, addr); + str = textfile_get(filename, addr); + if (!str) + return -EIO; + + memset(tmp, 0, sizeof(tmp)); + for (i = 0; i < 16; i++) { + memcpy(tmp, str + (i * 2), 2); + key[i] = (uint8_t) strtol(tmp, NULL, 16); + } + + free(str); + + return 0; +} + +static void cmd_putkey(int ctl, int hdev, char *opt) +{ + struct hci_dev_info di; + bdaddr_t bdaddr; + uint8_t key[16]; + int dd; + + if (!opt) + return; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (hci_devinfo(hdev, &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + str2ba(opt, &bdaddr); + if (get_link_key(&di.bdaddr, &bdaddr, key) < 0) { + fprintf(stderr, "Can't find link key for %s on hci%d\n", opt, hdev); + exit(1); + } + + if (hci_write_stored_link_key(dd, &bdaddr, key, 1000) < 0) { + fprintf(stderr, "Can't write stored link key on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + hci_close_dev(dd); +} + +static void cmd_delkey(int ctl, int hdev, char *opt) +{ + bdaddr_t bdaddr; + uint8_t all; + int dd; + + if (!opt) + return; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (!strcasecmp(opt, "all")) { + bacpy(&bdaddr, BDADDR_ANY); + all = 1; + } else { + str2ba(opt, &bdaddr); + all = 0; + } + + if (hci_delete_stored_link_key(dd, &bdaddr, all, 1000) < 0) { + fprintf(stderr, "Can't delete stored link key on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + hci_close_dev(dd); +} + static void cmd_commands(int ctl, int hdev, char *opt) { uint8_t cmds[64]; @@ -702,7 +798,7 @@ static void cmd_commands(int ctl, int hdev, char *opt) } if (hci_read_local_commands(dd, cmds, 1000) < 0) { - fprintf(stderr, "Can't read support commands hci%d: %s (%d)\n", + fprintf(stderr, "Can't read support commands on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } @@ -1235,6 +1331,8 @@ static struct { { "afhmode", cmd_afh_mode, "[mode]", "Get/Set AFH mode" }, { "aclmtu", cmd_aclmtu, "", "Set ACL MTU and number of packets" }, { "scomtu", cmd_scomtu, "", "Set SCO MTU and number of packets" }, + { "putkey", cmd_putkey, "", "Store link key on the device" }, + { "delkey", cmd_delkey, "", "Delete link key from the device" }, { "commands", cmd_commands, 0, "Display supported commands" }, { "features", cmd_features, 0, "Display device features" }, { "version", cmd_version, 0, "Display version information" }, -- cgit From 3f8f26bc831ca52caa7cc8ca500ae814818977a8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 2 May 2005 15:45:57 +0000 Subject: Add support for Toshiba SR-1 service record --- tools/sdptool.c | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 83e86fb5..c7e58ac9 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1734,7 +1734,7 @@ end: return ret; } -static int add_audio_source(sdp_session_t *session, svc_info_t *si) +static int add_a2source(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, l2cap, avdtp, a2src; @@ -1793,7 +1793,7 @@ done: return ret; } -static int add_audio_sink(sdp_session_t *session, svc_info_t *si) +static int add_a2sink(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, l2cap, avdtp, a2snk; @@ -1855,7 +1855,7 @@ done: static unsigned char nokid_uuid[] = { 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; -static int add_nokia_id(sdp_session_t *session, svc_info_t *si) +static int add_nokiaid(sdp_session_t *session, svc_info_t *si) { sdp_record_t record; sdp_list_t *root, *svclass; @@ -1929,6 +1929,38 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) return 0; } +static unsigned char sr1_uuid[] = { 0xbc, 0x19, 0x9c, 0x24, 0x95, 0x8b, 0x4c, 0xc0, + 0xa2, 0xcb, 0xfd, 0x8a, 0x30, 0xbf, 0x32, 0x06 }; + +static int add_sr1(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass; + uuid_t root_uuid, svclass_uuid; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) sr1_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Toshiba Speech Recognition SR-1 service record registered\n"); + + return 0; +} + struct { char *name; uint16_t class; @@ -1955,11 +1987,12 @@ struct { { "CIP", CIP_SVCLASS_ID, NULL }, { "CTP", CORDLESS_TELEPHONY_SVCLASS_ID, add_ctp }, - { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_audio_source}, - { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_audio_sink }, + { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_a2source }, + { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, - { "NOKID", 0, add_nokia_id }, + { "NOKID", 0, add_nokiaid }, { "PCSUITE", 0, add_pcsuite }, + { "SR1", 0, add_sr1 }, { 0 } }; -- cgit From 3d572ed42818065ac283c0d7fda76888957188fc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 May 2005 23:19:22 +0000 Subject: Check for the sys/soundcard.h header file --- acinclude.m4 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 15ee2ed8..874bd16a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -146,6 +146,8 @@ AC_DEFUN([AC_PATH_ALSA], [ ac_save_CPPFLAGS=$CPPFLAGS ac_save_LDFLAGS=$LDFLAGS + AC_CHECK_HEADER(sys/soundcard.h, AC_DEFINE(HAVE_SYS_SOUNDCARD_H, 1, [Define to 1 if you have the header file.])) + ALSA_CFLAGS="" test -d "${alsa_prefix}/include" && ALSA_CFLAGS="$ALSA_CFLAGS -I${alsa_prefix}/include" -- cgit From 25886ef5728f16533735b778d9fb5d1ab685768e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 12:40:56 +0000 Subject: Add service registration for SyncML Client --- tools/sdptool.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index c7e58ac9..51c13e09 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1852,6 +1852,51 @@ done: return ret; } +static unsigned char syncml_uuid[] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 }; + +static int add_syncml(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; + uint8_t channel = si->channel? si->channel: 15; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) syncml_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_uuid16_create(&obex_uuid, OBEX_UUID); + proto = sdp_list_append(proto, sdp_list_append(NULL, &obex_uuid)); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_set_info_attr(&record, "SyncML Client", NULL, NULL); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("SyncML Client service record registered\n"); + + return 0; +} + static unsigned char nokid_uuid[] = { 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; @@ -1990,6 +2035,8 @@ struct { { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_a2source }, { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, + { "SYNCML", 0, add_syncml }, + { "NOKID", 0, add_nokiaid }, { "PCSUITE", 0, add_pcsuite }, { "SR1", 0, add_sr1 }, -- cgit From cc2dd8a3670f68984f324d6861a344cb68728a1a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 13:28:15 +0000 Subject: Support searching for services with UUID-128 --- tools/sdptool.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 51c13e09..b81273cb 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2010,6 +2010,7 @@ struct { char *name; uint16_t class; int (*add)(sdp_session_t *sess, svc_info_t *si); + unsigned char *uuid; } service[] = { { "DID", PNP_INFO_SVCLASS_ID, NULL, }, @@ -2035,11 +2036,10 @@ struct { { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_a2source }, { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, - { "SYNCML", 0, add_syncml }, - - { "NOKID", 0, add_nokiaid }, - { "PCSUITE", 0, add_pcsuite }, - { "SR1", 0, add_sr1 }, + { "SYNCML", 0, add_syncml, syncml_uuid }, + { "NOKID", 0, add_nokiaid, nokid_uuid }, + { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, + { "SR1", 0, add_sr1, sr1_uuid }, { 0 } }; @@ -2333,6 +2333,7 @@ static char *search_help = static int cmd_search(int argc, char **argv) { struct search_context context; + unsigned char *uuid = NULL; uint16_t class = 0; bdaddr_t bdaddr; int has_addr = 0; @@ -2363,6 +2364,7 @@ static int cmd_search(int argc, char **argv) printf(search_help); return -1; } + /* Note : we need to find a way to support search combining * multiple services - Jean II */ context.svc = strdup(argv[0]); @@ -2378,19 +2380,24 @@ static int cmd_search(int argc, char **argv) for (i = 0; service[i].name; i++) if (strcasecmp(context.svc, service[i].name) == 0) { class = service[i].class; + uuid = service[i].uuid; break; } - if (!class) { + if (!class && !uuid) { printf("Unknown service %s\n", context.svc); return -1; } - } + } - sdp_uuid16_create(&context.group, class); + if (class) + sdp_uuid16_create(&context.group, class); + else + sdp_uuid128_create(&context.group, uuid); if (has_addr) return do_search(&bdaddr, &context); - return do_search(0, &context); + + return do_search(NULL, &context); } /* -- cgit From 8d07fe695736cfc4126f1aad4144303161c61e21 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 13:51:17 +0000 Subject: Add support for the page timeout config option --- hcid/hcid.h | 2 ++ hcid/kword.c | 1 + hcid/main.c | 17 +++++++++++++---- hcid/parser.y | 7 ++++++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/hcid/hcid.h b/hcid/hcid.h index e275939f..c64016ea 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -45,6 +45,7 @@ enum { HCID_SET_CLASS, HCID_SET_VOICE, HCID_SET_INQMODE, + HCID_SET_PAGETO, HCID_SET_PTYPE, HCID_SET_LM, HCID_SET_LP, @@ -56,6 +57,7 @@ struct device_opts { uint32_t class; uint16_t voice; uint8_t inqmode; + uint16_t pageto; uint16_t pkt_type; uint16_t link_mode; uint16_t link_policy; diff --git a/hcid/kword.c b/hcid/kword.c index 51c92e1d..30db2da0 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -61,6 +61,7 @@ struct kword cfg_keyword[] = { { "class", K_CLASS }, { "voice", K_VOICE }, { "inqmode", K_INQMODE }, + { "pageto", K_PAGETO }, { "auth", K_AUTH }, { "encrypt", K_ENCRYPT }, { "pin_helper", K_PINHELP }, diff --git a/hcid/main.c b/hcid/main.c index f4736940..57637f3e 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -229,7 +229,7 @@ static void configure_device(int hdev) expand_name(cp.name, sizeof(cp.name), device_opts->name, hdev); hci_send_cmd(s, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, - CHANGE_LOCAL_NAME_CP_SIZE, (void *) &cp); + CHANGE_LOCAL_NAME_CP_SIZE, &cp); } /* Set device class */ @@ -239,7 +239,7 @@ static void configure_device(int hdev) memcpy(cp.dev_class, &class, 3); hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV, - WRITE_CLASS_OF_DEV_CP_SIZE, (void *) &cp); + WRITE_CLASS_OF_DEV_CP_SIZE, &cp); } /* Set voice setting */ @@ -248,7 +248,7 @@ static void configure_device(int hdev) cp.voice_setting = htobl(device_opts->voice); hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING, - WRITE_VOICE_SETTING_CP_SIZE, (void *) &cp); + WRITE_VOICE_SETTING_CP_SIZE, &cp); } /* Set inquiry mode */ @@ -258,7 +258,16 @@ static void configure_device(int hdev) cp.mode = device_opts->inqmode; hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, - WRITE_INQUIRY_MODE_CP_SIZE, (void *) &cp); + WRITE_INQUIRY_MODE_CP_SIZE, &cp); + } + + /* Set page timeout */ + if ((device_opts->flags & (1 << HCID_SET_PAGETO))) { + write_page_timeout_cp cp; + + cp.timeout = htobs(device_opts->pageto); + hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT, + WRITE_PAGE_TIMEOUT_CP_SIZE, &cp); } exit(0); diff --git a/hcid/parser.y b/hcid/parser.y index a0eb13de..7616ab56 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -64,7 +64,7 @@ int yyerror(char *s); %token K_OPTIONS K_DEVICE %token K_AUTOINIT K_SECURITY K_PAIRING -%token K_PTYPE K_NAME K_CLASS K_VOICE K_INQMODE K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN +%token K_PTYPE K_NAME K_CLASS K_VOICE K_INQMODE K_PAGETO K_LM K_LP K_AUTH K_ENCRYPT K_ISCAN K_PSCAN %token K_PINHELP K_DBUSPINHELP %token K_YES K_NO @@ -205,6 +205,11 @@ device_opt: parser_device->inqmode = $2; } + | K_PAGETO NUM { + parser_device->flags |= (1 << HCID_SET_PAGETO); + parser_device->pageto = $2; + } + | K_AUTH bool { parser_device->auth = $2; } -- cgit From 18cb95673231d41455528a782b168ee05f32fe2b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 14:13:41 +0000 Subject: Add command for retrieving possible service records --- tools/sdptool.1 | 2 ++ tools/sdptool.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 86 insertions(+), 14 deletions(-) diff --git a/tools/sdptool.1 b/tools/sdptool.1 index 91a28a84..c4f248eb 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -73,6 +73,8 @@ FTRN, NAP, GN, HID, CIP. .IP "\fBbrowse [--tree] [bdaddr]\fP" 10 Browse all available services on the device specified by a Bluetooth address as a parameter. +.IP "\fBrecords [--tree] bdaddr\fP" 10 +Retrieve all possible service records. .IP "\fBadd [ --channel=N ]\fP" 10 Add a service to the local \fBsdpd\fR. diff --git a/tools/sdptool.c b/tools/sdptool.c index b81273cb..64e3a464 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2085,7 +2085,7 @@ static int cmd_add(int argc, char **argv) memset(&si, 0, sizeof(si)); for_each_opt(opt, add_options, 0) { - switch(opt) { + switch (opt) { case 'c': si.channel = atoi(optarg); break; @@ -2103,11 +2103,12 @@ static int cmd_add(int argc, char **argv) } si.name = strdup(argv[0]); + return add_service(0, &si); } /* Delete local service */ -static int del_service(bdaddr_t *bdaddr, void *arg) +static int del_service(bdaddr_t *bdaddr, void *arg) { uint32_t handle, range = 0x0000ffff; sdp_list_t *attr; @@ -2118,11 +2119,13 @@ static int del_service(bdaddr_t *bdaddr, void *arg) printf("Record handle was not specified.\n"); return -1; } + sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); if (!sess) { printf("No local SDP server!\n"); return -1; } + handle = strtoul((char *)arg, 0, 16); attr = sdp_list_append(0, &range); rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attr); @@ -2132,11 +2135,13 @@ static int del_service(bdaddr_t *bdaddr, void *arg) sdp_close(sess); return -1; } + if (sdp_record_unregister(sess, rec)) { printf("Failed to unregister service record: %s\n", strerror(errno)); sdp_close(sess); return -1; } + printf("Service Record deleted.\n"); sdp_close(sess); return 0; @@ -2156,7 +2161,7 @@ static int cmd_del(int argc, char **argv) int opt; for_each_opt(opt, del_options, 0) { - switch(opt) { + switch (opt) { default: printf(del_help); return -1; @@ -2169,7 +2174,8 @@ static int cmd_del(int argc, char **argv) printf(del_help); return -1; } - return del_service(0, argv[0]); + + return del_service(NULL, argv[0]); } /* @@ -2186,6 +2192,7 @@ static void inquiry(handler_t handler, void *arg) printf("Inquiry failed\n"); return; } + for (i = 0; i < count; i++) handler(&ii[i].bdaddr, arg); } @@ -2204,12 +2211,14 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) inquiry(do_search, context); return 0; } + sess = sdp_connect(&interface, bdaddr, SDP_RETRY_IF_BUSY); ba2str(bdaddr, str); if (!sess) { printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno)); return -1; } + if (context->svc) printf("Searching for %s on %s ...\n", context->svc, str); else @@ -2249,6 +2258,7 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) free(seq); sdp_record_free(rec); } + sdp_close(sess); return 0; } @@ -2280,7 +2290,7 @@ static int cmd_browse(int argc, char **argv) sdp_uuid16_create(&context.group, PUBLIC_BROWSE_GROUP); for_each_opt(opt, browse_options, 0) { - switch(opt) { + switch (opt) { case 't': context.tree = 1; break; @@ -2307,7 +2317,8 @@ static int cmd_browse(int argc, char **argv) estr2ba(argv[0], &bdaddr); return do_search(&bdaddr, &context); } - return do_search(0, &context); + + return do_search(NULL, &context); } static struct option search_options[] = { @@ -2344,7 +2355,7 @@ static int cmd_search(int argc, char **argv) memset(&context, '\0', sizeof(struct search_context)); for_each_opt(opt, search_options, 0) { - switch(opt) { + switch (opt) { case 'b': estr2ba(optarg, &bdaddr); has_addr = 1; @@ -2405,7 +2416,7 @@ static int cmd_search(int argc, char **argv) * Not really useful to the user, just show how it can be done... * Jean II */ -static int get_service(bdaddr_t *bdaddr, struct search_context *context) +static int get_service(bdaddr_t *bdaddr, struct search_context *context, int quite) { sdp_list_t *attrid; uint32_t range = 0x0000ffff; @@ -2418,14 +2429,17 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context) printf("Failed to connect to SDP server on %s: %s\n", str, strerror(errno)); return -1; } + attrid = sdp_list_append(0, &range); rec = sdp_service_attr_req(session, context->handle, SDP_ATTR_REQ_RANGE, attrid); sdp_list_free(attrid, 0); sdp_close(session); if (!rec) { - printf("Service get request failed.\n"); + if (!quite) + printf("Service get request failed.\n"); return -1; } + if (context->tree) { /* Display full tree */ sdp_printf_service_attr(rec); @@ -2434,14 +2448,68 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context) print_service_attr(rec); } printf("\n"); + sdp_record_free(rec); return 0; } +static struct option records_options[] = { + { "help", 0, 0, 'h' }, + { "tree", 0, 0, 't' }, + { 0, 0, 0, 0 } +}; + +static char *records_help = + "Usage:\n" + "\trecords [--tree] bdaddr\n"; + +/* + * Request possible SDP service records + */ +static int cmd_records(int argc, char **argv) +{ + struct search_context context; + uint32_t base[] = { 0x10000, 0x1002e }; + bdaddr_t bdaddr; + int i, n, opt, num = 32; + + /* Initialise context */ + memset(&context, '\0', sizeof(struct search_context)); + + for_each_opt(opt, records_options, 0) { + switch (opt) { + case 't': + context.tree = 1; + break; + default: + printf(records_help); + return -1; + } + } + argc -= optind; + argv += optind; + + if (argc < 1) { + printf(records_help); + return -1; + } + + /* Convert command line parameters */ + estr2ba(argv[0], &bdaddr); + + for (i = 0; i < sizeof(base) / sizeof(uint32_t); i++) + for (n = 0; n < num; n++) { + context.handle = base[i] + n; + get_service(&bdaddr, &context, 1); + } + + return 0; +} + static struct option get_options[] = { - { "help", 0,0, 'h' }, - { "bdaddr", 1,0, 'b' }, - { "tree", 0,0, 't' }, + { "help", 0,0, 'h' }, + { "bdaddr", 1,0, 'b' }, + { "tree", 0,0, 't' }, { 0, 0, 0, 0 } }; @@ -2463,7 +2531,7 @@ static int cmd_get(int argc, char **argv) memset(&context, '\0', sizeof(struct search_context)); for_each_opt(opt, get_options, 0) { - switch(opt) { + switch (opt) { case 'b': estr2ba(optarg, &bdaddr); has_addr = 1; @@ -2483,10 +2551,11 @@ static int cmd_get(int argc, char **argv) printf(get_help); return -1; } + /* Convert command line parameters */ context.handle = strtoul(argv[0], 0, 16); - return get_service(has_addr? &bdaddr: BDADDR_LOCAL, &context); + return get_service(has_addr ? &bdaddr : BDADDR_LOCAL, &context, 0); } static struct { @@ -2496,6 +2565,7 @@ static struct { } command[] = { { "search", cmd_search, "Search for a service" }, { "browse", cmd_browse, "Browse all available services" }, + { "records", cmd_records, "Request all records" }, { "add", cmd_add, "Add local service" }, { "del", cmd_del, "Delete local service" }, { "get", cmd_get, "Get local service" }, -- cgit From e7b5f3c69c6a7303b951e7a1398c87a568a16761 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 16:10:26 +0000 Subject: Include a raw mode for showing the original record tree --- tools/sdptool.1 | 21 ++-- tools/sdptool.c | 326 +++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 289 insertions(+), 58 deletions(-) diff --git a/tools/sdptool.1 b/tools/sdptool.1 index c4f248eb..5ed9e33e 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -65,15 +65,16 @@ local \fBsdpd\fR. .SH "COMMANDS" .PP The following commands are available. -.IP "\fBsearch [--bdaddr bdaddr] [--tree] service\fP" 10 +.IP "\fBsearch [--bdaddr bdaddr] [--tree] [--raw] service\fP" 10 Search for services.. .IP "" 10 -Known service names are SP< DUN, LAN, FAX, OPUSH, -FTRN, NAP, GN, HID, CIP. -.IP "\fBbrowse [--tree] [bdaddr]\fP" 10 +Known service names are DID, SP, DUN, LAN, FAX, OPUSH, +FTP, HS, HF, SAP, NAP, GN, PANU, HID, CIP, CTP, A2SRC, A2SNK +and SYNCML. +.IP "\fBbrowse [--tree] [--raw] [bdaddr]\fP" 10 Browse all available services on the device specified by a Bluetooth address as a parameter. -.IP "\fBrecords [--tree] bdaddr\fP" 10 +.IP "\fBrecords [--tree] [--raw] bdaddr\fP" 10 Retrieve all possible service records. .IP "\fBadd [ --channel=N ]\fP" 10 Add a service to the local @@ -84,7 +85,7 @@ using the \fB--channel\fP option. .IP "\fBdel record_handle\fP" 10 Remove a service from the local \fBsdpd\fR. -.IP "\fBget [--tree] [--bdaddr bdaddr] record_handle\fP" 10 +.IP "\fBget [--tree] [--raw] [--bdaddr bdaddr] record_handle\fP" 10 Retrieve a service from the local \fBsdpd\fR. .IP "\fBsetattr record_handle attrib_id attrib_value\fP" 10 @@ -99,13 +100,13 @@ Displays help on using sdptool. .SH "EXAMPLES" .PP -sdptool browse 00:80:98:24:15:6D +sdptool browse 00:80:98:24:15:6D .PP -sdptool browse local +sdptool browse local .PP -sdptool add DUN +sdptool add DUN .PP -sdptool del LAN +sdptool del 0x10000 .SH "BUGS" .PP Documentation needs improving. diff --git a/tools/sdptool.c b/tools/sdptool.c index 64e3a464..d015f12f 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -36,9 +36,11 @@ #include #include +#include #include +#include #include -#include +#include #include #include @@ -46,6 +48,8 @@ #include #include +#include + #define for_each_opt(opt, long, short) while ((opt=getopt_long(argc, argv, short ? short:"+", long, 0)) != -1) /* @@ -61,11 +65,15 @@ static int estr2ba(char *str, bdaddr_t *ba) return str2ba(str, ba); } +#define DEFAULT_VIEW 0 /* Display only known attribute */ +#define TREE_VIEW 1 /* Display full attribute tree */ +#define RAW_VIEW 2 /* Display raw tree */ + /* Pass args to the inquiry/search handler */ struct search_context { char *svc; /* Service */ uuid_t group; /* Browse group */ - int tree; /* Display full attribute tree */ + int view; /* View mode */ uint32_t handle; /* Service record handle */ }; @@ -219,7 +227,7 @@ static struct attrib_def audio_attrib_names[] = { /* Same for the UUIDs. See BT assigned numbers */ static struct uuid_def uuid16_names[] = { /* -- Protocols -- */ - { 0x0001, "SDP (Service Discovery Protocol)", NULL, 0 }, + { 0x0001, "SDP", NULL, 0 }, { 0x0002, "UDP", NULL, 0 }, { 0x0003, "RFCOMM", NULL, 0 }, { 0x0004, "TCP", NULL, 0 }, @@ -230,7 +238,7 @@ static struct uuid_def uuid16_names[] = { { 0x000a, "FTP", NULL, 0 }, { 0x000c, "HTTP", NULL, 0 }, { 0x000e, "WSP", NULL, 0 }, - { 0x000f, "BNEP (PAN/BNEP)", NULL, 0 }, + { 0x000f, "BNEP", NULL, 0 }, { 0x0010, "UPnP/ESDP", NULL, 0 }, { 0x0011, "HIDP", NULL, 0 }, { 0x0012, "HardcopyControlChannel", NULL, 0 }, @@ -242,11 +250,11 @@ static struct uuid_def uuid16_names[] = { { 0x001d, "UDI_C-Plane", NULL, 0 }, { 0x0100, "L2CAP", NULL, 0 }, /* -- Services -- */ - { 0x1000, "ServiceDiscoveryServerServiceClassID (SDP)", + { 0x1000, "ServiceDiscoveryServerServiceClassID", sdp_attrib_names, sizeof(sdp_attrib_names)/sizeof(struct attrib_def) }, - { 0x1001, "BrowseGroupDescriptorServiceClassID (SDP)", + { 0x1001, "BrowseGroupDescriptorServiceClassID", browse_attrib_names, sizeof(browse_attrib_names)/sizeof(struct attrib_def) }, - { 0x1002, "PublicBrowseGroup (SDP)", NULL, 0 }, + { 0x1002, "PublicBrowseGroup", NULL, 0 }, { 0x1101, "SerialPort", NULL, 0 }, { 0x1102, "LANAccessUsingPPP", NULL, 0 }, { 0x1103, "DialupNetworking (DUN)", NULL, 0 }, @@ -276,7 +284,10 @@ static struct uuid_def uuid16_names[] = { pan_attrib_names, sizeof(pan_attrib_names)/sizeof(struct attrib_def) }, { 0x1118, "DirectPrinting (BPP)", NULL, 0 }, { 0x1119, "ReferencePrinting (BPP)", NULL, 0 }, - /* ... */ + { 0x111a, "Imaging (BIP)", NULL, 0 }, + { 0x111b, "ImagingResponder (BIP)", NULL, 0 }, + { 0x111c, "ImagingAutomaticArchive (BIP)", NULL, 0 }, + { 0x111d, "ImagingReferencedObjects (BIP)", NULL, 0 }, { 0x111e, "Handsfree", NULL, 0 }, { 0x111f, "HandsfreeAudioGateway", NULL, 0 }, { 0x1120, "DirectPrintingReferenceObjectsService (BPP)", NULL, 0 }, @@ -411,9 +422,9 @@ static void sdp_data_printf(sdp_data_t *sdpdata, struct attrib_context *context, char *member_name = NULL; /* Find member name. Almost black magic ;-) */ - if (context->attrib && context->attrib->members && - context->member_index < context->attrib->member_max) { - member_name = context->attrib->members[context->member_index].name; + if (context && context->attrib && context->attrib->members && + context->member_index < context->attrib->member_max) { + member_name = context->attrib->members[context->member_index].name; } switch (sdpdata->dtd) { @@ -484,7 +495,7 @@ static void sdp_data_printf(sdp_data_t *sdpdata, struct attrib_context *context, /* * Parse a single attribute. */ -static void sdp_attr_printf_func(void *value, void *userData) +static void print_tree_attr_func(void *value, void *userData) { sdp_data_t *sdpdata = NULL; uint16_t attrId; @@ -535,11 +546,191 @@ static void sdp_attr_printf_func(void *value, void *userData) * We assume the record has already been read, parsed and cached * locally. Jean II */ -static void sdp_printf_service_attr(sdp_record_t *rec) +static void print_tree_attr(sdp_record_t *rec) { if (rec && rec->attrlist) { struct service_context service = { NULL }; - sdp_list_foreach(rec->attrlist, sdp_attr_printf_func, &service); + sdp_list_foreach(rec->attrlist, print_tree_attr_func, &service); + } +} + +static void print_raw_data(sdp_data_t *data, int indent) +{ + struct uuid_def *def; + char *str; + int i, hex; + + if (!data) + return; + + for (i = 0; i < indent; i++) + printf("\t"); + + switch (data->dtd) { + case SDP_DATA_NIL: + printf("NIL\n"); + break; + case SDP_BOOL: + printf("Bool %s\n", data->val.uint8 ? "True" : "False"); + break; + case SDP_UINT8: + printf("UINT8 0x%02x\n", data->val.uint8); + break; + case SDP_UINT16: + printf("UINT16 0x%04x\n", data->val.uint16); + break; + case SDP_UINT32: + printf("UINT32 0x%08x\n", data->val.uint32); + break; + case SDP_UINT64: + printf("UINT64 0x%016llx\n", data->val.uint64); + break; + case SDP_UINT128: + printf("UINT128 ...\n"); + break; + case SDP_INT8: + printf("INT8 %d\n", data->val.int8); + break; + case SDP_INT16: + printf("INT16 %d\n", data->val.int16); + break; + case SDP_INT32: + printf("INT32 %d\n", data->val.int32); + break; + case SDP_INT64: + printf("INT64 %lld\n", data->val.int64); + break; + case SDP_INT128: + printf("INT128 ...\n"); + break; + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + switch (data->val.uuid.type) { + case SDP_UUID16: + def = NULL; + for (i = 0; i < uuid16_max; i++) + if (uuid16_names[i].num == data->val.uuid.value.uuid16) { + def = &uuid16_names[i]; + break; + } + if (def) + printf("UUID16 0x%04x - %s\n", data->val.uuid.value.uuid16, def->name); + else + printf("UUID16 0x%04x\n", data->val.uuid.value.uuid16); + break; + case SDP_UUID32: + def = NULL; + if (!(data->val.uuid.value.uuid32 & 0xffff0000)) { + uint16_t value = data->val.uuid.value.uuid32; + for (i = 0; i < uuid16_max; i++) + if (uuid16_names[i].num == value) { + def = &uuid16_names[i]; + break; + } + } + if (def) + printf("UUID32 0x%08x - %s\n", data->val.uuid.value.uuid32, def->name); + else + printf("UUID32 0x%08x\n", data->val.uuid.value.uuid32); + break; + case SDP_UUID128: + printf("UUID128 "); + for (i = 0; i < 16; i++) { + switch (i) { + case 4: + case 6: + case 8: + case 10: + printf("-"); + break; + } + printf("%02x", (unsigned char ) data->val.uuid.value.uuid128.data[i]); + } + printf("\n"); + break; + default: + printf("UUID type 0x%02x\n", data->val.uuid.type); + break; + } + break; + case SDP_TEXT_STR8: + case SDP_TEXT_STR16: + case SDP_TEXT_STR32: + str = data->val.str; + if (data->unitSize > strlen(str) + 1) { + hex = 0; + for (i = 0; i < data->unitSize - 1; i++) + if (!isprint(str[i])) { + hex = 1; + break; + } + if (str[data->unitSize - 1] != '\0') + hex = 1; + } else + hex = 0; + if (hex) { + printf("String"); + for (i = 0; i < data->unitSize; i++) + printf(" %02x", (unsigned char) str[i]); + printf("\n"); + } else + printf("String %s\n", str); + break; + case SDP_URL_STR8: + case SDP_URL_STR16: + case SDP_URL_STR32: + printf("URL %s\n", data->val.str); + break; + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + printf("Sequence\n"); + print_raw_data(data->val.dataseq, indent + 1); + break; + case SDP_ALT8: + case SDP_ALT16: + case SDP_ALT32: + printf("Alternate\n"); + print_raw_data(data->val.dataseq, indent + 1); + break; + default: + printf("Unknown type 0x%02x\n", data->dtd); + break; + } + + print_raw_data(data->next, indent); +} + +static void print_raw_attr_func(void *value, void *userData) +{ + sdp_data_t *data = (sdp_data_t *) value; + struct attrib_def *def = NULL; + int i; + + /* Search amongst the generic attributes */ + for (i = 0; i < attrib_max; i++) + if (attrib_names[i].num == data->attrId) { + def = &attrib_names[i]; + break; + } + + if (def) + printf("\tAttribute 0x%04x - %s\n", data->attrId, def->name); + else + printf("\tAttribute 0x%04x\n", data->attrId); + + if (data) + print_raw_data(data, 2); + else + printf(" NULL value\n"); +} + +static void print_raw_attr(sdp_record_t *rec) +{ + if (rec && rec->attrlist) { + printf("Sequence\n"); + sdp_list_foreach(rec->attrlist, print_raw_attr_func, 0); } } @@ -2219,10 +2410,12 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) return -1; } - if (context->svc) - printf("Searching for %s on %s ...\n", context->svc, str); - else - printf("Browsing %s ...\n", str); + if (context->view != RAW_VIEW) { + if (context->svc) + printf("Searching for %s on %s ...\n", context->svc, str); + else + printf("Browsing %s ...\n", str); + } attrid = sdp_list_append(0, &range); search = sdp_list_append(0, &context->group); @@ -2238,15 +2431,23 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) sdp_record_t *rec = (sdp_record_t *) seq->data; struct search_context sub_context; - if (context->tree) { - /* Display full tree */ - sdp_printf_service_attr(rec); - } else { + switch (context->view) { + case DEFAULT_VIEW: /* Display user friendly form */ print_service_attr(rec); + printf("\n"); + break; + case TREE_VIEW: + /* Display full tree */ + print_tree_attr(rec); + printf("\n"); + break; + default: + /* Display raw tree */ + print_raw_attr(rec); + break; } - printf("\n"); - + if (sdp_get_group_id(rec, &sub_context.group) != -1) { /* Set the subcontext for browsing the sub tree */ memcpy(&sub_context, context, sizeof(struct search_context)); @@ -2266,6 +2467,7 @@ static int do_search(bdaddr_t *bdaddr, struct search_context *context) static struct option browse_options[] = { { "help", 0, 0, 'h' }, { "tree", 0, 0, 't' }, + { "raw", 0, 0, 'r' }, { "uuid", 1, 0, 'u' }, { "l2cap", 0, 0, 'l' }, { 0, 0, 0, 0 } @@ -2273,7 +2475,7 @@ static struct option browse_options[] = { static char *browse_help = "Usage:\n" - "\tbrowse [--tree] [--uuid uuid] [--l2cap] [bdaddr]\n"; + "\tbrowse [--tree] [--raw] [--uuid uuid] [--l2cap] [bdaddr]\n"; /* * Browse the full SDP database (i.e. list all services starting from the @@ -2292,7 +2494,10 @@ static int cmd_browse(int argc, char **argv) for_each_opt(opt, browse_options, 0) { switch (opt) { case 't': - context.tree = 1; + context.view = TREE_VIEW; + break; + case 'r': + context.view = RAW_VIEW; break; case 'u': if (sscanf(optarg, "%i", &num) != 1 || num < 0 || num > 0xffff) { @@ -2322,15 +2527,16 @@ static int cmd_browse(int argc, char **argv) } static struct option search_options[] = { - { "help", 0,0, 'h' }, - { "bdaddr", 1,0, 'b' }, - { "tree", 0,0, 't' }, + { "help", 0,0, 'h' }, + { "bdaddr", 1,0, 'b' }, + { "tree", 0,0, 't' }, + { "raw", 0, 0, 'r' }, { 0, 0, 0, 0} }; static char *search_help = "Usage:\n" - "\tsearch [--bdaddr bdaddr] [--tree] SERVICE\n" + "\tsearch [--bdaddr bdaddr] [--tree] [--raw] SERVICE\n" "SERVICE is a name (string) or UUID (0x1002)\n"; /* @@ -2361,7 +2567,10 @@ static int cmd_search(int argc, char **argv) has_addr = 1; break; case 't': - context.tree = 1; + context.view = TREE_VIEW; + break; + case 'r': + context.view = RAW_VIEW; break; default: printf(search_help); @@ -2435,19 +2644,29 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context, int qui sdp_list_free(attrid, 0); sdp_close(session); if (!rec) { - if (!quite) + if (!quite) { printf("Service get request failed.\n"); - return -1; + return -1; + } else + return 0; } - if (context->tree) { - /* Display full tree */ - sdp_printf_service_attr(rec); - } else { + switch (context->view) { + case DEFAULT_VIEW: /* Display user friendly form */ print_service_attr(rec); + printf("\n"); + break; + case TREE_VIEW: + /* Display full tree */ + print_tree_attr(rec); + printf("\n"); + break; + default: + /* Display raw tree */ + print_raw_attr(rec); + break; } - printf("\n"); sdp_record_free(rec); return 0; @@ -2456,12 +2675,13 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context, int qui static struct option records_options[] = { { "help", 0, 0, 'h' }, { "tree", 0, 0, 't' }, + { "raw", 0, 0, 'r' }, { 0, 0, 0, 0 } }; static char *records_help = "Usage:\n" - "\trecords [--tree] bdaddr\n"; + "\trecords [--tree] [--raw] bdaddr\n"; /* * Request possible SDP service records @@ -2469,9 +2689,9 @@ static char *records_help = static int cmd_records(int argc, char **argv) { struct search_context context; - uint32_t base[] = { 0x10000, 0x1002e }; + uint32_t base[] = { 0x10000, 0x1002e, 0x110b }; bdaddr_t bdaddr; - int i, n, opt, num = 32; + int i, n, opt, err = 0, num = 32; /* Initialise context */ memset(&context, '\0', sizeof(struct search_context)); @@ -2479,7 +2699,10 @@ static int cmd_records(int argc, char **argv) for_each_opt(opt, records_options, 0) { switch (opt) { case 't': - context.tree = 1; + context.view = TREE_VIEW; + break; + case 'r': + context.view = RAW_VIEW; break; default: printf(records_help); @@ -2500,22 +2723,26 @@ static int cmd_records(int argc, char **argv) for (i = 0; i < sizeof(base) / sizeof(uint32_t); i++) for (n = 0; n < num; n++) { context.handle = base[i] + n; - get_service(&bdaddr, &context, 1); + err = get_service(&bdaddr, &context, 1); + if (err < 0) + goto done; } +done: return 0; } static struct option get_options[] = { - { "help", 0,0, 'h' }, - { "bdaddr", 1,0, 'b' }, - { "tree", 0,0, 't' }, + { "help", 0, 0, 'h' }, + { "bdaddr", 1, 0, 'b' }, + { "tree", 0, 0, 't' }, + { "raw", 0, 0, 'r' }, { 0, 0, 0, 0 } }; static char *get_help = "Usage:\n" - "\tget [--tree] [--bdaddr bdaddr] record_handle\n"; + "\tget [--tree] [--raw] [--bdaddr bdaddr] record_handle\n"; /* * Get a specific SDP record on the local SDP server @@ -2537,7 +2764,10 @@ static int cmd_get(int argc, char **argv) has_addr = 1; break; case 't': - context.tree = 1; + context.view = TREE_VIEW; + break; + case 'r': + context.view = RAW_VIEW; break; default: printf(get_help); -- cgit From c6f99123f1269ad3742100eec084902a31e774bd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 19:56:46 +0000 Subject: Implement textfile writing support --- common/textfile.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++---- common/textfile.h | 1 + 2 files changed, 149 insertions(+), 12 deletions(-) diff --git a/common/textfile.c b/common/textfile.c index 6f84cfa9..0bda2a94 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -40,51 +40,186 @@ #include #include +static int write_key_value(const int fd, const char *key, const char *value) +{ + char *str; + int size, err = 0; + + size = strlen(key) + strlen(value) + 2; + + str = malloc(size); + if (!str) + return ENOMEM; + + sprintf(str, "%s %s\n", key, value); + + if (write(fd, str, size) < 0) + err = errno; + + free(str); + + return err; +} + +int textfile_put(const char *pathname, const char *key, const char *value) +{ + struct stat st; + char *map, *off, *end, *str; + off_t size, pos; size_t base, len; + int fd, err = 0; + + fd = open(pathname, O_RDWR); + if (fd < 0) + return -errno; + + if (flock(fd, LOCK_EX) < 0) { + err = errno; + goto close; + } + + if (fstat(fd, &st) < 0) { + err = errno; + goto unlock; + } + + size = st.st_size; + + if (!size) { + pos = lseek(fd, size, SEEK_SET); + err = write_key_value(fd, key, value); + goto unlock; + } + + map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) { + err = errno; + goto unlock; + } + + off = strstr(map, key); + if (!off) { + munmap(map, size); + pos = lseek(fd, size, SEEK_SET); + err = write_key_value(fd, key, value); + goto unlock; + } + + if (off > map) { + while (*(off - 1) != '\r' && *(off - 1) != '\n') { + off = strstr(off, key); + if (!off) { + munmap(map, size); + pos = lseek(fd, size, SEEK_SET); + err = write_key_value(fd, key, value); + goto unlock; + } + } + } + + base = off - map; + + end = strpbrk(off, "\r\n"); + if (!end) { + err = EILSEQ; + goto unmap; + } + + len = strspn(end, "\r\n"); + end += len; + + len = size - (end - map); + + str = malloc(len); + if (!str) { + err = errno; + goto unmap; + } + + memcpy(str, end, len); + munmap(map, size); + + ftruncate(fd, base); + pos = lseek(fd, base, SEEK_SET); + + write_key_value(fd, key, value); + write(fd, str, len); + + free(str); + + goto unlock; + +unmap: + munmap(map, size); + +unlock: + flock(fd, LOCK_UN); + +close: + close(fd); + errno = err; + + return -err; +} + char *textfile_get(const char *pathname, const char *key) { struct stat st; char *map, *off, *end, *str = NULL; off_t size; size_t len; - int fd; + int fd, err = 0; fd = open(pathname, O_RDONLY); if (fd < 0) return NULL; - if (flock(fd, LOCK_SH) < 0) + if (flock(fd, LOCK_SH) < 0) { + err = errno; goto close; + } - if (fstat(fd, &st) < 0) + if (fstat(fd, &st) < 0) { + err = errno; goto unlock; + } size = st.st_size; - map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); - if (map == MAP_FAILED) - goto close; + map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) { + err = errno; + goto unlock; + } off = strstr(map, key); - if (!off) + if (!off) { + err = EILSEQ; goto unmap; + } if (off > map) { while (*(off - 1) != '\r' && *(off - 1) != '\n') { - off = strstr(map, key); - if (!off) + off = strstr(off, key); + if (!off) { + err = EILSEQ; goto unmap; + } } } end = strpbrk(off, "\r\n"); - if (!end) + if (!end) { + err = EILSEQ; goto unmap; + } len = strlen(key); str = malloc(end - off - len); - memset(str, 0, end - off - len); - if (!str) + if (!str) { + err = EILSEQ; goto unmap; + } + memset(str, 0, end - off - len); strncpy(str, off + len + 1, end - off - len - 1); unmap: @@ -95,6 +230,7 @@ unlock: close: close(fd); + errno = err; return str; } diff --git a/common/textfile.h b/common/textfile.h index 56a0bc10..8871f53c 100644 --- a/common/textfile.h +++ b/common/textfile.h @@ -26,4 +26,5 @@ * $Id$ */ +int textfile_put(const char *pathname, const char *key, const char *value); char *textfile_get(const char *pathname, const char *key); -- cgit From 163d14a25cec4bbe7bf906a3a3487756a47e42cf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 May 2005 22:18:11 +0000 Subject: Store HID information for later use --- hidd/Makefile.am | 4 ++- hidd/hidd.h | 3 +- hidd/main.c | 16 ++++++++- hidd/sdp.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 119 insertions(+), 4 deletions(-) diff --git a/hidd/Makefile.am b/hidd/Makefile.am index 0860d265..cd8b4878 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -5,10 +5,12 @@ bin_PROGRAMS = hidd hidd_SOURCES = main.c hidd.h sdp.c -hidd_LDADD = @BLUEZ_LIBS@ +hidd_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a AM_CFLAGS = @BLUEZ_CFLAGS@ +INCLUDES = -I$(top_srcdir)/common + man_MANS = hidd.1 EXTRA_DIST = $(man_MANS) diff --git a/hidd/hidd.h b/hidd/hidd.h index cd0c102c..ab8a94ec 100644 --- a/hidd/hidd.h +++ b/hidd/hidd.h @@ -29,4 +29,5 @@ #define L2CAP_PSM_HIDP_CTRL 0x11 #define L2CAP_PSM_HIDP_INTR 0x13 -int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req); +int get_stored_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req); +int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req); diff --git a/hidd/main.c b/hidd/main.c index 84d94b78..25567c9e 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -258,8 +258,12 @@ static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, req.flags = 0; req.idle_to = timeout * 60; + err = get_stored_device_info(&src, &dst, &req); + if (!err) + goto create; + if (!nosdp) { - err = get_hid_device_info(&src, &dst, &req); + err = get_sdp_device_info(&src, &dst, &req); if (err < 0) goto error; } else { @@ -280,6 +284,7 @@ static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, req.subclass = 0xc0; } +create: if (subclass != 0x00) req.subclass = subclass; @@ -399,8 +404,17 @@ static void do_show(int ctl) static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int nosdp, int encrypt, int timeout) { + struct hidp_connadd_req req; int csk, isk, err; + memset(&req, 0, sizeof(req)); + + if (get_sdp_device_info(src, dst, &req) < 0) { + perror("Can't get device information"); + close(ctl); + exit(1); + } + csk = l2cap_connect(src, dst, L2CAP_PSM_HIDP_CTRL); if (csk < 0) { perror("Can't create HID control channel"); diff --git a/hidd/sdp.c b/hidd/sdp.c index 24ed4b53..c202c763 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -32,6 +32,12 @@ #include #include +#include +#include +#include +#include +#include +#include #include #include @@ -39,6 +45,7 @@ #include #include +#include "textfile.h" #include "hidd.h" static void epox_endian_quirk(unsigned char *data, int size) @@ -66,7 +73,96 @@ static void epox_endian_quirk(unsigned char *data, int size) } } -int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *req) +static int store_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req) +{ + char filename[PATH_MAX + 1], addr[18], *str, *desc; + int i, fd, size; + + ba2str(src, addr); + snprintf(filename, PATH_MAX, "%s/%s/hidd", STORAGEDIR, addr); + + size = 15 + 3 + 3 + 5 + (req->rd_size * 2) + 1 + 9 + strlen(req->name) + 2; + str = malloc(size); + if (!str) + return -ENOMEM; + + desc = malloc((req->rd_size * 2) + 1); + if (!desc) { + free(str); + return -ENOMEM; + } + + memset(desc, 0, (req->rd_size * 2) + 1); + for (i = 0; i < req->rd_size; i++) + sprintf(desc + (i * 2), "%2.2X", req->rd_data[i]); + + snprintf(str, size - 1, "%04X:%04X:%04X %02X %02X %04X %s %08X %s", + req->vendor, req->product, req->version, + req->subclass, req->country, req->parser, desc, + req->flags, req->name); + + fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) + return -errno; + + close(fd); + + ba2str(dst, addr); + return textfile_put(filename, addr, str); +} + +int get_stored_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req) +{ + char filename[PATH_MAX + 1], addr[18], tmp[3], *str, *desc; + unsigned int vendor, product, version, subclass, country, parser, pos; + int i; + + desc = malloc(4096); + if (!desc) + return -ENOMEM; + + memset(desc, 0, 4096); + + ba2str(src, addr); + snprintf(filename, PATH_MAX, "%s/%s/hidd", STORAGEDIR, addr); + + ba2str(dst, addr); + str = textfile_get(filename, addr); + if (!str) { + free(desc); + return -EIO; + } + + sscanf(str, "%04X:%04X:%04X %02X %02X %04X %4095s %08X %n", + &vendor, &product, &version, &subclass, &country, + &parser, desc, &req->flags, &pos); + + free(str); + + req->vendor = vendor; + req->product = product; + req->version = version; + req->subclass = subclass; + req->country = country; + req->parser = parser; + + snprintf(req->name, 128, str + pos); + + req->rd_size = strlen(desc) / 2; + req->rd_data = malloc(req->rd_size); + if (!req->rd_data) + return -ENOMEM; + + memset(tmp, 0, sizeof(tmp)); + for (i = 0; i < req->rd_size; i++) { + memcpy(tmp, desc + (i * 2), 2); + req->rd_data[i] = (uint8_t) strtol(tmp, NULL, 16); + } + + return 0; +} + +int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req) { uint32_t range = 0x0000ffff; sdp_session_t *s; @@ -163,5 +259,7 @@ int get_hid_device_info(bdaddr_t *src, bdaddr_t *dst, struct hidp_connadd_req *r sdp_record_free(rec); + store_device_info(src, dst, req); + return 0; } -- cgit From 258887a0f6a798cc021837c3f686d02ff317d271 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 7 May 2005 20:40:01 +0000 Subject: Add authentication support --- dund/main.c | 11 ++++++++++- pand/main.c | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/dund/main.c b/dund/main.c index 837073f9..2bc4f9b5 100644 --- a/dund/main.c +++ b/dund/main.c @@ -70,6 +70,7 @@ static char *pppd_opts[DUN_MAX_PPP_OPTS] = static int detach = 1; static int persist; static int use_sdp = 1; +static int auth; static int encrypt; static int secure; static int master; @@ -147,6 +148,8 @@ static int do_listen(void) lm = 0; if (master) lm |= RFCOMM_LM_MASTER; + if (auth) + lm |= RFCOMM_LM_AUTH; if (encrypt) lm |= RFCOMM_LM_ENCRYPT; if (secure) @@ -390,6 +393,7 @@ static struct option main_lopts[] = { { "show", 0, 0, 'l' }, { "nodetach", 0, 0, 'n' }, { "persist", 2, 0, 'p' }, + { "auth", 0, 0, 'A' }, { "encrypt", 0, 0, 'E' }, { "secure", 0, 0, 'S' }, { "master", 0, 0, 'M' }, @@ -400,7 +404,7 @@ static struct option main_lopts[] = { { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:i:lnp::DQ::ESMP:C::P:X"; +static char main_sopts[] = "hsc:k:Kr:i:lnp::DQ::AESMP:C::P:X"; static char main_help[] = "Bluetooth LAP (LAN Access over PPP) daemon version " VERSION " \n" @@ -417,6 +421,7 @@ static char main_help[] = "\t--channel -P RFCOMM channel\n" "\t--device -i Source bdaddr\n" "\t--nosdp -D Disable SDP\n" + "\t--auth -A Enable authentication\n" "\t--encrypt -E Enable encryption\n" "\t--secure -S Secure connection\n" "\t--master -M Become the master of a piconet\n" @@ -480,6 +485,10 @@ int main(int argc, char **argv) use_sdp = 0; break; + case 'A': + auth = 1; + break; + case 'E': encrypt = 1; break; diff --git a/pand/main.c b/pand/main.c index 959d6057..c128d332 100644 --- a/pand/main.c +++ b/pand/main.c @@ -61,6 +61,7 @@ static int detach = 1; static int persist; static int use_sdp = 1; static int use_cache; +static int auth; static int encrypt; static int secure; static int master; @@ -169,6 +170,8 @@ static int do_listen(void) lm = 0; if (master) lm |= L2CAP_LM_MASTER; + if (auth) + lm |= L2CAP_LM_AUTH; if (encrypt) lm |= L2CAP_LM_ENCRYPT; if (secure) @@ -497,6 +500,7 @@ static struct option main_lopts[] = { { "show", 0, 0, 'l' }, { "nodetach", 0, 0, 'n' }, { "persist", 2, 0, 'p' }, + { "auth", 0, 0, 'A' }, { "encrypt", 0, 0, 'E' }, { "secure", 0, 0, 'S' }, { "master", 0, 0, 'M' }, @@ -506,7 +510,7 @@ static struct option main_lopts[] = { { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:e:i:lnp::DQ::ESMC::P:z"; +static char main_sopts[] = "hsc:k:Kr:e:i:lnp::DQ::AESMC::P:z"; static char main_help[] = "Bluetooth PAN daemon version " VERSION " \n" @@ -525,6 +529,7 @@ static char main_help[] = "\t--ethernet -e Network interface name\n" "\t--device -i Source bdaddr\n" "\t--nosdp -D Disable SDP\n" + "\t--auth -A Enable authentication\n" "\t--encrypt -E Enable encryption\n" "\t--secure -S Secure connection\n" "\t--master -M Become the master of a piconet\n" @@ -589,6 +594,10 @@ int main(int argc, char **argv) use_sdp = 0; break; + case 'A': + auth = 1; + break; + case 'E': encrypt = 1; break; -- cgit From b4d9988bdaadfe79fd802793e16ef1f77f8c537c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 May 2005 17:22:23 +0000 Subject: Wait until the SDP connection is closed --- hidd/main.c | 2 +- hidd/sdp.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index 25567c9e..98a8f12a 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -430,7 +430,7 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, exit(1); } - err = create_device(ctl, csk, isk, subclass, nosdp, encrypt, timeout); + err = create_device(ctl, csk, isk, subclass, 1, encrypt, timeout); if (err < 0) { fprintf(stderr, "HID create error %d (%s)\n", errno, strerror(errno)); diff --git a/hidd/sdp.c b/hidd/sdp.c index c202c763..05cacf45 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -164,6 +165,9 @@ int get_stored_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req) { + struct sockaddr_l2 addr; + socklen_t addrlen; + bdaddr_t bdaddr; uint32_t range = 0x0000ffff; sdp_session_t *s; sdp_list_t *search, *attrid, *pnp_rsp, *hid_rsp; @@ -172,7 +176,7 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co uuid_t svclass; int err; - s = sdp_connect(src, dst, 0); + s = sdp_connect(src, dst, SDP_RETRY_IF_BUSY | SDP_WAIT_ON_CLOSE); if (!s) return -1; @@ -194,6 +198,14 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co sdp_list_free(search, 0); sdp_list_free(attrid, 0); + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + + if (getsockname(s->sock, (struct sockaddr *) &addr, &addrlen) < 0) + bacpy(&bdaddr, src); + else + bacpy(&bdaddr, &addr.l2_bdaddr); + sdp_close(s); if (err || !hid_rsp) @@ -259,7 +271,8 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co sdp_record_free(rec); - store_device_info(src, dst, req); + if (bacmp(&bdaddr, BDADDR_ANY)) + store_device_info(&bdaddr, dst, req); return 0; } -- cgit From c16a9ffd5ee7ad3a184bc3c5ddac2d0049d7243d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 May 2005 10:21:09 +0000 Subject: Add support for the duration calculation --- alsa/sbc.c | 4 ++++ alsa/sbc.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/alsa/sbc.c b/alsa/sbc.c index bd767768..3cebee1f 100644 --- a/alsa/sbc.c +++ b/alsa/sbc.c @@ -1278,6 +1278,8 @@ int sbc_decode(sbc_t *sbc, void *data, int count) sbc->len = samples * priv->frame.channels * 2; + sbc->duration = (1000000 * priv->frame.subbands * priv->frame.blocks) / sbc->rate; + return framelen; } @@ -1337,6 +1339,8 @@ int sbc_encode(sbc_t *sbc, void *data, int count) sbc->len = framelen; + sbc->duration = (1000000 * priv->frame.subbands * priv->frame.blocks) / sbc->rate; + return samples * sbc->channels * 2; } diff --git a/alsa/sbc.h b/alsa/sbc.h index 02353160..568b1d7e 100644 --- a/alsa/sbc.h +++ b/alsa/sbc.h @@ -41,6 +41,8 @@ struct sbc_struct { int size; int len; + unsigned long duration; + void *priv; }; -- cgit From dc69351694d5d90c288e0aa88b67c8cc23bcc2b7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 May 2005 11:34:12 +0000 Subject: Use constructor and destructor for connection caching --- alsa/pcm_a2dp.c | 117 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 40 deletions(-) diff --git a/alsa/pcm_a2dp.c b/alsa/pcm_a2dp.c index be89e677..9bab41ef 100644 --- a/alsa/pcm_a2dp.c +++ b/alsa/pcm_a2dp.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -43,9 +44,13 @@ //#define DBG(fmt, arg...) printf("DEBUG: %s: " fmt "\n" , __FUNCTION__ , ## arg) #define DBG(D...) +static void a2dp_init(void) __attribute__ ((constructor)); +static void a2dp_exit(void) __attribute__ ((destructor)); + typedef struct snd_pcm_a2dp { snd_pcm_ioplug_t io; int refcnt; + unsigned long state; bdaddr_t src; bdaddr_t dst; int sk; @@ -56,31 +61,6 @@ typedef struct snd_pcm_a2dp { unsigned int frame_bytes; } snd_pcm_a2dp_t; -#define MAX_CONNECTIONS 10 - -static snd_pcm_a2dp_t *connections[MAX_CONNECTIONS]; - -static void sig_alarm(int sig) -{ - int i; - - for (i = 0; i < MAX_CONNECTIONS; i++) { - snd_pcm_a2dp_t *a2dp = connections[i]; - - if (!a2dp || a2dp->refcnt > 0) - continue; - - connections[i] = NULL; - - if (a2dp->sk >= 0) - close(a2dp->sk); - - sbc_finish(&a2dp->sbc); - - free(a2dp); - } -} - static int a2dp_start(snd_pcm_ioplug_t *io) { snd_pcm_a2dp_t *a2dp = io->private_data; @@ -134,7 +114,8 @@ static snd_pcm_sframes_t a2dp_transfer(snd_pcm_ioplug_t *io, a2dp->len = 0; } - a2dp->num += len / a2dp->frame_bytes; + if (a2dp->state == BT_CONNECTED) + a2dp->num += len / a2dp->frame_bytes; return len / a2dp->frame_bytes; } @@ -149,9 +130,6 @@ static int a2dp_close(snd_pcm_ioplug_t *io) a2dp->refcnt--; - if (!a2dp->refcnt) - alarm(2); - return 0; } @@ -205,8 +183,24 @@ static int a2dp_drain(snd_pcm_ioplug_t *io) static int a2dp_poll(snd_pcm_ioplug_t *io, struct pollfd *ufds, unsigned int nfds, unsigned short *revents) { + snd_pcm_a2dp_t *a2dp = io->private_data; + struct timeval tv; + *revents = ufds[0].revents; + if (a2dp->state == BT_CLOSED) + return 0; + + if (ufds[0].revents & POLLHUP) { + a2dp->state = BT_CLOSED; + a2dp->io.poll_fd = -1; + a2dp->io.poll_events = POLLIN; + snd_pcm_ioplug_reinit_status(&a2dp->io); + } + + if (gettimeofday(&tv, NULL) < 0) + return 0; + return 0; } @@ -317,6 +311,53 @@ static int a2dp_constraint(snd_pcm_a2dp_t *a2dp) return 0; } +#define MAX_CONNECTIONS 10 + +static snd_pcm_a2dp_t *connections[MAX_CONNECTIONS]; + +static inline void a2dp_free(snd_pcm_a2dp_t *a2dp) +{ + if (a2dp->sk >= 0) + close(a2dp->sk); + + sbc_finish(&a2dp->sbc); + + free(a2dp); +} + +static inline void a2dp_delete(snd_pcm_a2dp_t *a2dp) +{ + int i; + + for (i = 0; i < MAX_CONNECTIONS; i++) + if (connections[i] == a2dp) { + connections[i] = NULL; + a2dp_free(a2dp); + } +} + +static void a2dp_init(void) +{ + int i; + + for (i = 0; i < MAX_CONNECTIONS; i++) + connections[i] = NULL; +} + +static void a2dp_exit(void) +{ + int i; + + for (i = 0; i < MAX_CONNECTIONS; i++) { + snd_pcm_a2dp_t *a2dp = connections[i]; + if (!a2dp) + continue; + + connections[i] = NULL; + a2dp_free(a2dp); + } +} + SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) { snd_pcm_a2dp_t *a2dp = NULL; @@ -375,8 +416,6 @@ SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) } if (!a2dp) { - struct sigaction sa; - if (pos < 0) { SNDERR("Too many connections"); return -ENOMEM; @@ -390,25 +429,23 @@ SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) memset(a2dp, 0, sizeof(*a2dp)); + connections[pos] = a2dp; + a2dp->refcnt = 1; + a2dp->state = BT_CONNECT; bacpy(&a2dp->src, &src); bacpy(&a2dp->dst, &dst); + } + if (a2dp->state != BT_CONNECTED) { err = a2dp_connect(a2dp); if (err < 0) { SNDERR("Cannot connect"); goto error; } - memset(&sa, 0, sizeof(sa)); - sa.sa_flags = SA_NOCLDSTOP; - sa.sa_handler = sig_alarm; - sigaction(SIGALRM, &sa, NULL); - - alarm(0); - - connections[pos] = a2dp; + a2dp->state = BT_CONNECTED; } a2dp->io.name = "Bluetooth Advanced Audio Distribution"; @@ -435,7 +472,7 @@ error: a2dp->refcnt--; if (!a2dp->refcnt) - alarm(2); + a2dp_delete(a2dp); return err; } -- cgit From dbcb5d496a5adbf895cee6c705522cc0778e1445 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 May 2005 13:02:59 +0000 Subject: Update changelog and bump version number --- ChangeLog | 20 ++++++++++++++++++++ configure.in | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2455abde..b2850b6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +ver 2.17: + Set the storage directory through ${localstatedir}. + Add the textfile library for ASCII based file access. + Add support for return link keys event. + Add support for voice setting configuration. + Add support for page scan timeout configuration. + Add support for storing and deleting of stored link keys. + Add support for searching for services with UUID-128. + Add support for retrieving all possible service records. + Add support for a raw mode view of service records. + Add support for HID information caching in hidd. + Add support for authentication in pand and dund. + Add support for changing BD_ADDR of CSR chips. + Add pskey utility for changing CSR persistent storage values. + Add the firmware upgrade utility. + Add connection caching for the A2DP ALSA plugin. + + Note: + This version needs at least bluez-libs-2.17 + ver 2.16: Store link keys in ASCII based file format. Support device name caching. diff --git a/configure.in b/configure.in index 830c4527..72fc841f 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.16) +AM_INIT_AUTOMAKE(bluez-utils, 2.17) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From cb25df80c6bd65cea3ec869fa210b3feb2c78049 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 14 May 2005 10:43:22 +0000 Subject: Support D-Bus version 0.23 and 0.33 --- acinclude.m4 | 3 +++ hcid/dbus.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 874bd16a..5c27b5a8 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -244,6 +244,9 @@ AC_DEFUN([AC_PATH_DBUS], [ LDFLAGS="$LDFLAGS $DBUS_LIBS" AC_CHECK_LIB(dbus-1, dbus_error_init, DBUS_LIBS="$DBUS_LIBS -ldbus-1", dbus_found=no) + AC_CHECK_LIB(dbus-1, dbus_pending_call_steal_reply, AC_DEFINE(HAVE_DBUS_PENDING_CALL_STEAL_REPLY, 1, [Define to 1 if you have the dbus_pending_call_steal_reply() function.])) + AC_CHECK_LIB(dbus-1, dbus_message_iter_get_basic, AC_DEFINE(HAVE_DBUS_MESSAGE_ITER_GET_BASIC, 1, [Define to 1 if you have the dbus_message_iter_get_basic() function.])) + AC_CHECK_LIB(dbus-1, dbus_message_append_args, AC_DEFINE(HAVE_DBUS_MESSAGE_APPEND_ARGS, 1, [Define to 1 if you have the dbus_message_append_args() function.])) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS diff --git a/hcid/dbus.c b/hcid/dbus.c index 4d12bf11..683cf6fb 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -72,7 +72,11 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) size_t len; char *pin; +#ifdef HAVE_DBUS_PENDING_CALL_STEAL_REPLY + message = dbus_pending_call_steal_reply(call); +#else message = dbus_pending_call_get_reply(call); +#endif if (dbus_message_is_error(message, WRONG_ARGS_ERROR)) goto error; @@ -83,7 +87,12 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) if (type != DBUS_TYPE_STRING) goto error; +#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC + dbus_message_iter_get_basic(&iter, &pin); +#else pin = dbus_message_iter_get_string(&iter); +#endif + len = strlen(pin); memset(&pr, 0, sizeof(pr)); @@ -93,11 +102,13 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); + dbus_message_unref(message); + return; error: - hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, - 6, &req->bda); + hci_send_cmd(req->dev, OGF_LINK_CTL, + OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); } @@ -109,7 +120,9 @@ static void free_pin_req(void *req) void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) { DBusMessage *message; +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS DBusMessageIter iter; +#endif DBusPendingCall *pending = NULL; struct pin_request *req; @@ -124,14 +137,20 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) req->dev = dev; bacpy(&req->bda, &ci->bdaddr); +#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS + dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &ci->out, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &ci->bdaddr, sizeof(bdaddr_t), DBUS_TYPE_INVALID); +#else dbus_message_append_iter_init(message, &iter); dbus_message_iter_append_boolean(&iter, ci->out); dbus_message_iter_append_byte_array(&iter, (unsigned char *) &ci->bdaddr, sizeof(ci->bdaddr)); +#endif if (dbus_connection_send_with_reply(connection, message, - &pending, TIMEOUT) == FALSE) { + &pending, TIMEOUT) == FALSE) { syslog(LOG_ERR, "D-BUS send failed"); goto failed; } @@ -139,16 +158,16 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) dbus_pending_call_set_notify(pending, reply_handler_function, req, free_pin_req); - dbus_connection_flush (connection); + dbus_connection_flush(connection); - dbus_message_unref (message); + dbus_message_unref(message); return; failed: - dbus_message_unref (message); - hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, - 6, &ci->bdaddr); + dbus_message_unref(message); + hci_send_cmd(dev, OGF_LINK_CTL, + OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); } gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data) -- cgit From 211002ea1a8e4b94afebc67f5b13eff46e09eb6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:21:43 +0000 Subject: Support reading of complex varid values --- tools/csr.c | 41 +++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index b5691afa..6ed0a08f 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -399,6 +399,47 @@ char *csr_pskeytostr(uint16_t pskey) } } +int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + unsigned char cmd[] = { 0x00, 0x00, (length + 5) & 0xff, (length + 5) >> 8, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + memcpy(cp + 11, value, length); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 11, length); + + return 0; +} + int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value) { unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, diff --git a/tools/csr.h b/tools/csr.h index 7aa90c31..c8ed9445 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -26,13 +26,37 @@ * $Id$ */ -#define CSR_VARID_BUILDID 0x2819 -#define CSR_VARID_CHIPVER 0x281a -#define CSR_VARID_CHIPREV 0x281b -#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c - -#define CSR_VARID_PANIC_ARG 0x6805 -#define CSR_VARID_FAULT_ARG 0x6806 +#define CSR_VARID_BC01_STATUS 0x2801 /* uint16 */ +#define CSR_VARID_BUILDID 0x2819 /* uint16 */ +#define CSR_VARID_CHIPVER 0x281a /* uint16 */ +#define CSR_VARID_CHIPREV 0x281b /* uint16 */ +#define CSR_VARID_INTERFACE_VERSION 0x2825 /* uint16 */ +#define CSR_VARID_RAND 0x282a /* uint16 */ +#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c /* uint16 */ +#define CSR_VARID_CHIPANAREV 0x2836 /* uint16 */ +#define CSR_VARID_BUILDID_LOADER 0x2838 /* uint16 */ +#define CSR_VARID_BT_CLOCK 0x2c00 /* uint32 */ +#define CSR_VARID_CRYPT_KEY_LENGTH 0x3008 /* complex */ +#define CSR_VARID_PICONET_INSTANCE 0x3009 /* complex */ +#define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ +#define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ +#define CSR_VARID_COLD_RESET 0x4001 /* valueless */ +#define CSR_VARID_WARM_RESET 0x4002 /* valueless */ +#define CSR_VARID_COLD_HALT 0x4003 /* valueless */ +#define CSR_VARID_WARM_HALT 0x4004 /* valueless */ +#define CSR_VARID_INIT_BT_STACK 0x4005 /* valueless */ +#define CSR_VARID_ACTIVATE_BT_STACK 0x4006 /* valueless */ +#define CSR_VARID_ENABLE_TX 0x4007 /* valueless */ +#define CSR_VARID_DISABLE_TX 0x4008 /* valueless */ +#define CSR_VARID_RECAL 0x4009 /* valueless */ +#define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */ +#define CSR_VARID_MAP_SCO_PCM 0x481c /* uint16 */ +#define CSR_VARID_NO_VARIABLE 0x6000 /* valueless */ +#define CSR_VARID_CONFIG_UART 0x6802 /* uint16 */ +#define CSR_VARID_PANIC_ARG 0x6805 /* uint16 */ +#define CSR_VARID_FAULT_ARG 0x6806 /* uint16 */ +#define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ +#define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab #define CSR_PSKEY_UART_BAUDRATE 0x01be @@ -46,6 +70,7 @@ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); +int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); -- cgit From ffa2b0a23afbb3616fd6f1fc9ec89cd116b61675 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:25:12 +0000 Subject: Fix length calculation for complex data --- tools/csr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/csr.c b/tools/csr.c index 6ed0a08f..d1932cf4 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -401,7 +401,7 @@ char *csr_pskeytostr(uint16_t pskey) int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { - unsigned char cmd[] = { 0x00, 0x00, (length + 5) & 0xff, (length + 5) >> 8, + unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 5) & 0xff, ((length / 2) + 5) >> 8, seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -- cgit From ef1e3cfb87d1313ff2ebd4e4128be9a6e17072b2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:41:03 +0000 Subject: Add PSKEYs for min and max encryption key length --- tools/csr.c | 4 ++++ tools/csr.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index d1932cf4..9fbdba17 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -380,6 +380,10 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) char *csr_pskeytostr(uint16_t pskey) { switch (pskey) { + case CSR_PSKEY_ENC_KEY_LMIN: + return "Minimum encryption key length"; + case CSR_PSKEY_ENC_KEY_LMAX: + return "Maximum encryption key length"; case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; case CSR_PSKEY_UART_BAUDRATE: diff --git a/tools/csr.h b/tools/csr.h index c8ed9445..42dfb8d0 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -58,6 +58,8 @@ #define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ +#define CSR_PSKEY_ENC_KEY_LMIN 0x00da +#define CSR_PSKEY_ENC_KEY_LMAX 0x00db #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab #define CSR_PSKEY_UART_BAUDRATE 0x01be #define CSR_PSKEY_HOST_INTERFACE 0x01f9 -- cgit From 186a4118ec7cc9f105f4e23b49e71c2b0e46cfa4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:46:09 +0000 Subject: Support minimum and maximum encryption key length --- tools/pskey.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/pskey.c b/tools/pskey.c index edf78e8d..f0ce1b4a 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -91,6 +91,8 @@ static struct { int type; char *str; } storage[] = { + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, -- cgit From fd1420fe08910f599bbb3bc84840318d1b99f748 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 May 2005 11:51:27 +0000 Subject: Add tool for the CSR BCCMD interface --- tools/Makefile.am | 5 +- tools/bccmd.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 tools/bccmd.c diff --git a/tools/Makefile.am b/tools/Makefile.am index e9574f3e..66839dd7 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -22,7 +22,7 @@ sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) -noinst_PROGRAMS = hcisecfilter ppporc pskey +noinst_PROGRAMS = hcisecfilter ppporc pskey bccmd hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a @@ -41,6 +41,9 @@ ppporc_LDADD = @BLUEZ_LIBS@ pskey_SOURCES = pskey.c csr.h csr.c pskey_LDADD = @BLUEZ_LIBS@ +bccmd_SOURCES = bccmd.c csr.h csr.c +bccmd_LDADD = @BLUEZ_LIBS@ + if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif diff --git a/tools/bccmd.c b/tools/bccmd.c new file mode 100644 index 00000000..4b4a1fb4 --- /dev/null +++ b/tools/bccmd.c @@ -0,0 +1,193 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "csr.h" + +static int cmd_keylen(int dd, int argc, char *argv[]) +{ + uint8_t buf[8]; + uint16_t handle, keylen; + int err; + + if (argc < 1) { + errno = EINVAL; + return -1; + } + + if (argc > 1) { + errno = E2BIG; + return -1; + } + + handle = atoi(argv[0]); + + memset(buf, 0, sizeof(buf)); + buf[0] = handle & 0xff; + buf[1] = handle >> 8; + + err = csr_read_varid_complex(dd, 0x4711, + CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); + if (err < 0) { + errno = -err; + return -1; + } + + handle = buf[0] | (buf[1] << 8); + keylen = buf[2] | (buf[3] << 8); + + printf("Crypt key length: %d bit\n", keylen * 8); + + return 0; +} + +static struct { + char *str; + int (*func)(int dd, int argc, char **argv); + char *arg; + char *doc; +} commands[] = { + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { NULL }, +}; + +static void usage(void) +{ + int i; + + printf("bccmd - Utility for the CSR BCCMD interface\n\n"); + printf("Usage:\n" + "\tbccmd [-i ] \n\n"); + + printf("Commands:\n"); + for (i = 0; commands[i].str; i++) + printf("\t%s\t%s\t%s\n", commands[i].str, + commands[i].arg, commands[i].doc); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "device", 1, 0, 'i' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct hci_dev_info di; + struct hci_version ver; + int i, err, dd, opt, dev = 0; + + while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + switch (opt) { + case 'i': + dev = hci_devid(optarg); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + exit(1); + } + + if (hci_devinfo(dev, &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + exit(1); + } + + if (ver.manufacturer != 10) { + fprintf(stderr, "Unsupported manufacturer\n"); + hci_close_dev(dd); + exit(1); + } + + for (i = 0; commands[i].str; i++) { + if (strcasecmp(commands[i].str, argv[0])) + continue; + + err = commands[i].func(dd, argc - 1, argv + 1); + + hci_close_dev(dd); + + if (err < 0) { + fprintf(stderr, "Can't execute command: %s (%d)\n", + strerror(errno), errno); + exit(1); + } + + exit(0); + } + + fprintf(stderr, "Unsupported command\n"); + + hci_close_dev(dd); + + exit(1); +} -- cgit From 350e6ad62c8f3c32dd15e368ff5519ac656992db Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 May 2005 14:06:11 +0000 Subject: Handle the plugin version field --- alsa/pcm_a2dp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/alsa/pcm_a2dp.c b/alsa/pcm_a2dp.c index 9bab41ef..fcacce75 100644 --- a/alsa/pcm_a2dp.c +++ b/alsa/pcm_a2dp.c @@ -448,6 +448,10 @@ SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) a2dp->state = BT_CONNECTED; } +#ifdef SND_PCM_IOPLUG_VERSION + a2dp->io.version = SND_PCM_IOPLUG_VERSION; +#endif + a2dp->io.name = "Bluetooth Advanced Audio Distribution"; a2dp->io.poll_fd = a2dp->sk; a2dp->io.poll_events = POLLOUT; -- cgit From 51efc88dd3dcd082c9a95bdfa499641f927cbf07 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 May 2005 14:36:56 +0000 Subject: Add disconnect timer support and set plugin version --- alsa/pcm_a2dp.c | 267 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 203 insertions(+), 64 deletions(-) diff --git a/alsa/pcm_a2dp.c b/alsa/pcm_a2dp.c index fcacce75..f5dff96a 100644 --- a/alsa/pcm_a2dp.c +++ b/alsa/pcm_a2dp.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -50,6 +49,7 @@ static void a2dp_exit(void) __attribute__ ((destructor)); typedef struct snd_pcm_a2dp { snd_pcm_ioplug_t io; int refcnt; + int timeout; unsigned long state; bdaddr_t src; bdaddr_t dst; @@ -61,6 +61,20 @@ typedef struct snd_pcm_a2dp { unsigned int frame_bytes; } snd_pcm_a2dp_t; +static void inline a2dp_get(snd_pcm_a2dp_t *a2dp) +{ + a2dp->refcnt++; + a2dp->timeout = 0; +} + +static void inline a2dp_put(snd_pcm_a2dp_t *a2dp) +{ + a2dp->refcnt--; + + if (a2dp->refcnt <= 0) + a2dp->timeout = 2; +} + static int a2dp_start(snd_pcm_ioplug_t *io) { snd_pcm_a2dp_t *a2dp = io->private_data; @@ -100,20 +114,18 @@ static snd_pcm_sframes_t a2dp_transfer(snd_pcm_ioplug_t *io, buf = (unsigned char *) areas->addr + (areas->first + areas->step * offset) / 8; - size *= a2dp->frame_bytes; - - len = sbc_encode(&a2dp->sbc, buf, size); + len = sbc_encode(&a2dp->sbc, buf, size * a2dp->frame_bytes); if (len <= 0) return len; - memcpy(a2dp->buf + a2dp->len, a2dp->sbc.data, a2dp->sbc.len); - a2dp->len += a2dp->sbc.len; - - if (a2dp->len > 700) { + if (a2dp->len + a2dp->sbc.len > sizeof(a2dp->buf)) { write(a2dp->sk, a2dp->buf, a2dp->len); a2dp->len = 0; } + memcpy(a2dp->buf + a2dp->len, a2dp->sbc.data, a2dp->sbc.len); + a2dp->len += a2dp->sbc.len; + if (a2dp->state == BT_CONNECTED) a2dp->num += len / a2dp->frame_bytes; @@ -128,7 +140,7 @@ static int a2dp_close(snd_pcm_ioplug_t *io) a2dp->len = 0; - a2dp->refcnt--; + a2dp_put(a2dp); return 0; } @@ -180,40 +192,64 @@ static int a2dp_drain(snd_pcm_ioplug_t *io) return 0; } -static int a2dp_poll(snd_pcm_ioplug_t *io, struct pollfd *ufds, - unsigned int nfds, unsigned short *revents) +static int a2dp_descriptors_count(snd_pcm_ioplug_t *io) { snd_pcm_a2dp_t *a2dp = io->private_data; - struct timeval tv; - *revents = ufds[0].revents; + if (a2dp->state == BT_CLOSED) + return 0; + + return 1; +} + +static int a2dp_descriptors(snd_pcm_ioplug_t *io, struct pollfd *pfds, unsigned int space) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; if (a2dp->state == BT_CLOSED) return 0; - if (ufds[0].revents & POLLHUP) { - a2dp->state = BT_CLOSED; - a2dp->io.poll_fd = -1; - a2dp->io.poll_events = POLLIN; - snd_pcm_ioplug_reinit_status(&a2dp->io); + if (space < 1) { + SNDERR("Can't fill in descriptors"); + return 0; } - if (gettimeofday(&tv, NULL) < 0) + pfds[0].fd = a2dp->sk; + pfds[0].events = POLLOUT; + + return 1; +} + +static int a2dp_poll(snd_pcm_ioplug_t *io, struct pollfd *pfds, + unsigned int nfds, unsigned short *revents) +{ + snd_pcm_a2dp_t *a2dp = io->private_data; + + *revents = pfds[0].revents; + + if (a2dp->state == BT_CLOSED) return 0; + if (pfds[0].revents & POLLHUP) { + a2dp->state = BT_CLOSED; + snd_pcm_ioplug_reinit_status(&a2dp->io); + } + return 0; } static snd_pcm_ioplug_callback_t a2dp_callback = { - .start = a2dp_start, - .stop = a2dp_stop, - .pointer = a2dp_pointer, - .transfer = a2dp_transfer, - .close = a2dp_close, - .hw_params = a2dp_params, - .prepare = a2dp_prepare, - .drain = a2dp_drain, - .poll_revents = a2dp_poll, + .start = a2dp_start, + .stop = a2dp_stop, + .pointer = a2dp_pointer, + .transfer = a2dp_transfer, + .close = a2dp_close, + .hw_params = a2dp_params, + .prepare = a2dp_prepare, + .drain = a2dp_drain, + .poll_descriptors_count = a2dp_descriptors_count, + .poll_descriptors = a2dp_descriptors, + .poll_revents = a2dp_poll, }; static int a2dp_connect(snd_pcm_a2dp_t *a2dp) @@ -257,6 +293,8 @@ static int a2dp_connect(snd_pcm_a2dp_t *a2dp) bacpy(&a2dp->src, &addr.rc_bdaddr); + fcntl(sk, F_SETFL, fcntl(sk, F_GETFL) | O_NONBLOCK); + a2dp->sk = sk; return 0; @@ -298,7 +336,7 @@ static int a2dp_constraint(snd_pcm_a2dp_t *a2dp) if (err < 0) return err; - err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 2048, 2048); + err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 8192, 8192); if (err < 0) return err; @@ -306,8 +344,6 @@ static int a2dp_constraint(snd_pcm_a2dp_t *a2dp) if (err < 0) return err; - sbc_init(&a2dp->sbc, SBC_NULL); - return 0; } @@ -315,9 +351,45 @@ static int a2dp_constraint(snd_pcm_a2dp_t *a2dp) static snd_pcm_a2dp_t *connections[MAX_CONNECTIONS]; +static snd_timer_t *timer = NULL; + +static volatile sig_atomic_t __locked = 0; + +static inline void a2dp_lock(void) +{ + while (__locked) + usleep(100); + + __locked = 1; +} + +static inline void a2dp_unlock(void) +{ + __locked = 0; +} + +static inline snd_pcm_a2dp_t *a2dp_alloc(void) +{ + snd_pcm_a2dp_t *a2dp; + + a2dp = malloc(sizeof(*a2dp)); + if (!a2dp) + return NULL; + + memset(a2dp, 0, sizeof(*a2dp)); + + a2dp->refcnt = 1; + + a2dp->state = BT_OPEN; + + sbc_init(&a2dp->sbc, SBC_NULL); + + return a2dp; +} + static inline void a2dp_free(snd_pcm_a2dp_t *a2dp) { - if (a2dp->sk >= 0) + if (a2dp->sk > fileno(stderr)) close(a2dp->sk); sbc_finish(&a2dp->sbc); @@ -325,37 +397,111 @@ static inline void a2dp_free(snd_pcm_a2dp_t *a2dp) free(a2dp); } -static inline void a2dp_delete(snd_pcm_a2dp_t *a2dp) +static void a2dp_timer(snd_async_handler_t *async) { - int i; + snd_timer_t *handle = snd_async_handler_get_timer(async); + snd_timer_read_t tr; + int i, ticks = 0; - for (i = 0; i < MAX_CONNECTIONS; i++) - if (connections[i] == a2dp) { - connections[i] = NULL; - a2dp_free(a2dp); + while (snd_timer_read(handle, &tr, sizeof(tr)) == sizeof(tr)) + ticks += tr.ticks; + + a2dp_lock(); + + for (i = 0; i < MAX_CONNECTIONS; i++) { + snd_pcm_a2dp_t *a2dp = connections[i]; + + if (a2dp && a2dp->refcnt <= 0) { + a2dp->timeout = ((a2dp->timeout * 1000) - ticks) / 1000; + if (a2dp->timeout <= 0) { + connections[i] = NULL; + a2dp_free(a2dp); + } } + } + + a2dp_unlock(); } static void a2dp_init(void) { - int i; + snd_async_handler_t *async; + snd_timer_info_t *info; + snd_timer_params_t *params; + long resolution; + char timername[64]; + int err, i; + + a2dp_lock(); for (i = 0; i < MAX_CONNECTIONS; i++) connections[i] = NULL; + + a2dp_unlock(); + + snd_timer_info_alloca(&info); + snd_timer_params_alloca(¶ms); + + sprintf(timername, "hw:CLASS=%i,SCLASS=%i,CARD=%i,DEV=%i,SUBDEV=%i", + SND_TIMER_CLASS_GLOBAL, SND_TIMER_CLASS_NONE, 0, + SND_TIMER_GLOBAL_SYSTEM, 0); + + err = snd_timer_open(&timer, timername, SND_TIMER_OPEN_NONBLOCK); + if (err < 0) { + SNDERR("Can't open global timer"); + return; + } + + err = snd_timer_info(timer, info); + if (err < 0) { + SNDERR("Can't get global timer info"); + return; + } + + snd_timer_params_set_auto_start(params, 1); + + resolution = snd_timer_info_get_resolution(info); + snd_timer_params_set_ticks(params, 1000000000 / resolution); + if (snd_timer_params_get_ticks(params) < 1) + snd_timer_params_set_ticks(params, 1); + + err = snd_timer_params(timer, params); + if (err < 0) { + SNDERR("Can't set global timer parameters"); + snd_timer_close(timer); + return; + } + + err = snd_async_add_timer_handler(&async, timer, a2dp_timer, NULL); + if (err < 0) { + SNDERR("Can't create global async callback"); + snd_timer_close(timer); + return; + } + + err = snd_timer_start(timer); } static void a2dp_exit(void) { - int i; + int err, i; + + err = snd_timer_stop(timer); + + err = snd_timer_close(timer); + + a2dp_lock(); for (i = 0; i < MAX_CONNECTIONS; i++) { snd_pcm_a2dp_t *a2dp = connections[i]; - if (!a2dp) - continue; - connections[i] = NULL; - a2dp_free(a2dp); + if (a2dp) { + connections[i] = NULL; + a2dp_free(a2dp); + } } + + a2dp_unlock(); } SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) @@ -402,13 +548,15 @@ SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) return -EINVAL; } + a2dp_lock(); + for (n = 0; n < MAX_CONNECTIONS; n++) { if (connections[n]) { if (!bacmp(&connections[n]->dst, &dst) && (!bacmp(&connections[n]->src, &src) || !bacmp(&src, BDADDR_ANY))) { a2dp = connections[n]; - a2dp->refcnt++; + a2dp_get(a2dp); break; } } else if (pos < 0) @@ -421,42 +569,36 @@ SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) return -ENOMEM; } - a2dp = malloc(sizeof(*a2dp)); + a2dp = a2dp_alloc(); if (!a2dp) { - SNDERR("Cannot allocate"); + SNDERR("Can't allocate"); return -ENOMEM; } - memset(a2dp, 0, sizeof(*a2dp)); - connections[pos] = a2dp; - a2dp->refcnt = 1; a2dp->state = BT_CONNECT; bacpy(&a2dp->src, &src); bacpy(&a2dp->dst, &dst); } + a2dp_unlock(); + if (a2dp->state != BT_CONNECTED) { err = a2dp_connect(a2dp); if (err < 0) { - SNDERR("Cannot connect"); + SNDERR("Can't connect"); goto error; } a2dp->state = BT_CONNECTED; } -#ifdef SND_PCM_IOPLUG_VERSION - a2dp->io.version = SND_PCM_IOPLUG_VERSION; -#endif - - a2dp->io.name = "Bluetooth Advanced Audio Distribution"; - a2dp->io.poll_fd = a2dp->sk; - a2dp->io.poll_events = POLLOUT; - a2dp->io.mmap_rw = 0; - a2dp->io.callback = &a2dp_callback; + a2dp->io.version = SND_PCM_IOPLUG_VERSION; + a2dp->io.name = "Bluetooth Advanced Audio Distribution"; + a2dp->io.mmap_rw = 0; + a2dp->io.callback = &a2dp_callback; a2dp->io.private_data = a2dp; err = snd_pcm_ioplug_create(&a2dp->io, name, stream, mode); @@ -473,10 +615,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(a2dp) return 0; error: - a2dp->refcnt--; - - if (!a2dp->refcnt) - a2dp_delete(a2dp); + a2dp_put(a2dp); return err; } -- cgit From 3d6b20f58304faafcb7e3804ac29d1d81379e79e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 May 2005 14:47:49 +0000 Subject: Make SBC parameters configurable --- alsa/sbc.c | 17 +++++++++++++---- alsa/sbc.h | 3 +++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/alsa/sbc.c b/alsa/sbc.c index 3cebee1f..3eda2910 100644 --- a/alsa/sbc.c +++ b/alsa/sbc.c @@ -1225,6 +1225,12 @@ int sbc_init(sbc_t *sbc, unsigned long flags) memset(sbc->priv, 0, sizeof(struct sbc_priv)); + sbc->rate = 44100; + sbc->channels = 2; + sbc->subbands = 8; + sbc->blocks = 16; + sbc->bitpool = 32; + return 0; } @@ -1245,8 +1251,11 @@ int sbc_decode(sbc_t *sbc, void *data, int count) sbc_decoder_init(&priv->dec_state, &priv->frame); priv->init = 1; - sbc->rate = priv->frame.sampling_frequency * 1000; + sbc->rate = priv->frame.sampling_frequency * 1000; sbc->channels = priv->frame.channels; + sbc->subbands = priv->frame.subbands; + sbc->blocks = priv->frame.blocks; + sbc->bitpool = priv->frame.bitpool; } samples = sbc_synthesize_audio(&priv->dec_state, &priv->frame); @@ -1304,9 +1313,9 @@ int sbc_encode(sbc_t *sbc, void *data, int count) priv->frame.channel_mode = MONO; priv->frame.allocation_method = SNR; - priv->frame.subbands = 8; - priv->frame.blocks = 16; - priv->frame.bitpool = 32; + priv->frame.subbands = sbc->subbands; + priv->frame.blocks = sbc->blocks; + priv->frame.bitpool = sbc->bitpool; sbc_encoder_init(&priv->enc_state, &priv->frame); priv->init = 1; diff --git a/alsa/sbc.h b/alsa/sbc.h index 568b1d7e..f0c6c09d 100644 --- a/alsa/sbc.h +++ b/alsa/sbc.h @@ -36,6 +36,9 @@ struct sbc_struct { int rate; int channels; + int blocks; + int subbands; + int bitpool; void *data; int size; -- cgit From 72a919e9b1ae03645a63e27dfa6f4190ade6c924 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 19 May 2005 17:06:50 +0000 Subject: Detect hangup in connect mode --- test/l2test.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/test/l2test.c b/test/l2test.c index f3ff2bc4..8d337a9d 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -275,6 +275,9 @@ static int do_connect(char *svr) opts.imtu, opts.omtu, opts.flush_to, opts.mode, conn.hci_handle, conn.dev_class[2], conn.dev_class[1], conn.dev_class[0]); + if (data_size > opts.omtu) + data_size = opts.omtu; + return sk; error: @@ -625,12 +628,24 @@ static void reconnect_mode(char *svr) static void connect_mode(char *svr) { + struct pollfd p; int sk; if ((sk = do_connect(svr)) < 0) exit(1); - sleep(99999999); + p.fd = sk; + p.events = POLLERR | POLLHUP; + + while (1) { + p.revents = 0; + if (poll(&p, 1, 100)) + break; + } + + syslog(LOG_INFO, "Disconnected"); + + close(sk); } static void multi_connect_mode(char *svr) -- cgit From 34e0b4d0b4513834ec1c982ee201331579ec3e45 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 May 2005 19:49:56 +0000 Subject: Add build id for BlueCore2-PnG with Unified 18f firmware --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 9fbdba17..4829a66d 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -274,6 +274,8 @@ static struct { { 1989, "HCI 18.4" }, { 2062, "Unified 20a1" }, { 2063, "Unified 20a1" }, + { 2067, "Unified 18f" }, + { 2068, "Unified 18f" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From b07abfc01ed48a0e74e134fb36ef35ce8590ecc7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 8 Jun 2005 09:42:37 +0000 Subject: Add support for changing local and remote version information --- tools/csr.h | 21 ++++++++++++--------- tools/pskey.c | 34 ++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/tools/csr.h b/tools/csr.h index 42dfb8d0..347e1d54 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -58,15 +58,18 @@ #define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ -#define CSR_PSKEY_ENC_KEY_LMIN 0x00da -#define CSR_PSKEY_ENC_KEY_LMAX 0x00db -#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab -#define CSR_PSKEY_UART_BAUDRATE 0x01be -#define CSR_PSKEY_HOST_INTERFACE 0x01f9 -#define CSR_PSKEY_USB_VENDOR_ID 0x02be -#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf -#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb -#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd +#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xFE8f, 0xF99B, 0x8000 } */ +#define CSR_PSKEY_ENC_KEY_LMIN 0x00da +#define CSR_PSKEY_ENC_KEY_LMAX 0x00db +#define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ +#define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab +#define CSR_PSKEY_UART_BAUDRATE 0x01be +#define CSR_PSKEY_HOST_INTERFACE 0x01f9 +#define CSR_PSKEY_USB_VENDOR_ID 0x02be +#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf +#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb +#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); diff --git a/tools/pskey.c b/tools/pskey.c index f0ce1b4a..2b4bc210 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -42,15 +42,16 @@ #include "csr.h" -#define CSR_TYPE_NULL 0 -#define CSR_TYPE_UINT16 1 +#define CSR_TYPE_NULL 0 +#define CSR_TYPE_UINT8 1 +#define CSR_TYPE_UINT16 2 static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { uint16_t value; int err; - if (type != CSR_TYPE_UINT16) { + if (type != CSR_TYPE_UINT8 && type != CSR_TYPE_UINT16) { errno = EFAULT; return -1; } @@ -60,7 +61,10 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) return -1; } - value = atoi(argv[0]); + if (!strncasecmp(argv[0], "0x", 2)) + value = strtol(argv[0] + 2, NULL, 16); + else + value = atoi(argv[0]); err = csr_write_pskey_uint16(dd, 0x4711, pskey, value); @@ -72,7 +76,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) uint16_t value; int err; - if (type != CSR_TYPE_UINT16) { + if (type != CSR_TYPE_UINT8 && type != CSR_TYPE_UINT16) { errno = EFAULT; return -1; } @@ -91,15 +95,17 @@ static struct { int type; char *str; } storage[] = { - { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, - { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, - { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, - { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, - { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, - { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, - { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, - { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, - { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, + { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, + { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, { 0x0000, CSR_TYPE_NULL, NULL }, }; -- cgit From 9ea3fe29624242544794b25154dc1b246e5e10cf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 9 Jun 2005 01:47:57 +0000 Subject: Support -d parameter --- pand/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pand/main.c b/pand/main.c index c128d332..98b1720d 100644 --- a/pand/main.c +++ b/pand/main.c @@ -510,7 +510,7 @@ static struct option main_lopts[] = { { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:e:i:lnp::DQ::AESMC::P:z"; +static char main_sopts[] = "hsc:k:Kr:d:e:i:lnp::DQ::AESMC::P:z"; static char main_help[] = "Bluetooth PAN daemon version " VERSION " \n" -- cgit From f285dc875c194aab8b1048b53d9681b43fa1a18c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 10 Jun 2005 05:30:28 +0000 Subject: Allow reading of complex PS keys --- tools/csr.c | 48 +++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + tools/pskey.c | 73 ++++++++++++++++++++++++++++++++++++++++------------------- 3 files changed, 99 insertions(+), 23 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 4829a66d..6b34fc3f 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -386,6 +386,12 @@ char *csr_pskeytostr(uint16_t pskey) return "Minimum encryption key length"; case CSR_PSKEY_ENC_KEY_LMAX: return "Maximum encryption key length"; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return "Local supported features block"; + case CSR_PSKEY_HCI_LMP_LOCAL_VERSION: + return "The HCI and LMP version reported locally"; + case CSR_PSKEY_LMP_REMOTE_VERSION: + return "The LMP version reported remotely"; case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; case CSR_PSKEY_UART_BAUDRATE: @@ -486,6 +492,48 @@ int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *val return 0; } +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length) +{ + unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, + seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, + pskey & 0xff, pskey >> 8, + (length / 2) & 0xff, (length / 2) >> 8, + 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 17, length); + + return 0; +} + int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value) { unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, diff --git a/tools/csr.h b/tools/csr.h index 347e1d54..61df145e 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -77,5 +77,6 @@ char *csr_pskeytostr(uint16_t pskey); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); diff --git a/tools/pskey.c b/tools/pskey.c index 2b4bc210..9a4dd547 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -43,8 +43,9 @@ #include "csr.h" #define CSR_TYPE_NULL 0 -#define CSR_TYPE_UINT8 1 -#define CSR_TYPE_UINT16 2 +#define CSR_TYPE_ARRAY 1 +#define CSR_TYPE_UINT8 2 +#define CSR_TYPE_UINT16 3 static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { @@ -73,19 +74,38 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) static int read_pskey(int dd, uint16_t pskey, int type) { - uint16_t value; - int err; + uint8_t array[64]; + uint16_t value = 0; + int i, err, size = sizeof(array); - if (type != CSR_TYPE_UINT8 && type != CSR_TYPE_UINT16) { + memset(array, 0, sizeof(array)); + + if (type != CSR_TYPE_ARRAY && + type != CSR_TYPE_UINT8 && + type != CSR_TYPE_UINT16) { errno = EFAULT; return -1; } - err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); - if (err < 0) - return err; + if (type != CSR_TYPE_ARRAY) { + err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); + if (err < 0) + return err; + + printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); + } else { + if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) + size = 8; - printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); + err = csr_read_pskey_complex(dd, 0x4711, pskey, array, size); + if (err < 0) + return err; + + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < size; i++) + printf(" 0x%02x", array[i]); + printf("\n"); + } return err; } @@ -95,31 +115,38 @@ static struct { int type; char *str; } storage[] = { - { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, - { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, - { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, - { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, - { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, - { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, - { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, - { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, - { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, - { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, - { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, + { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, + { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, + { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, { 0x0000, CSR_TYPE_NULL, NULL }, }; static void usage(void) { - int i; + int i, pos = 0; printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" "\tpskey [-i ] [value]\n\n"); printf("Keys:\n\t"); - for (i = 0; storage[i].pskey; i++) - printf("%s ", storage[i].str); + for (i = 0; storage[i].pskey; i++) { + printf("%s ", storage[i].str); + pos += strlen(storage[i].str) + 1; + if (pos > 60) { + printf("\n\t"); + pos = 0; + } + } printf("\n"); } -- cgit From adb76ec0bc45fe4d8b481db3418a86d686591d84 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 10 Jun 2005 06:59:27 +0000 Subject: Add build ids for new sniffer firmwares --- tools/csr.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 6b34fc3f..fd547ad3 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -322,6 +322,18 @@ static struct { { 1759, "Sniff 40 (2004-11-03)" }, { 1760, "Sniff 40 (2004-11-03)" }, { 1761, "Sniff 40 (2004-11-03)" }, + { 2009, "Sniff 41 (2005-04-06)" }, + { 2010, "Sniff 41 (2005-04-06)" }, + { 2011, "Sniff 41 (2005-04-06)" }, + { 2016, "Sniff 42 (2005-04-11)" }, + { 2017, "Sniff 42 (2005-04-11)" }, + { 2018, "Sniff 42 (2005-04-11)" }, + { 2023, "Sniff 43 (2005-04-14)" }, + { 2024, "Sniff 43 (2005-04-14)" }, + { 2025, "Sniff 43 (2005-04-14)" }, + { 2032, "Sniff 44 (2005-04-18)" }, + { 2033, "Sniff 44 (2005-04-18)" }, + { 2034, "Sniff 44 (2005-04-18)" }, { 0, } }; -- cgit From f31fbabd2aa6a30523afb53396d039f4b8a6de1b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Jun 2005 14:02:56 +0000 Subject: Add support for inquiry scan type --- tools/hciconfig.8 | 6 ++++++ tools/hciconfig.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index dabfeb36..9fb8b552 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -133,6 +133,12 @@ With no prints out the current inquiry mode. Otherwise, sets inquiry mode to .IR mode . .TP +.BI inqtype " [type]" +With no +.IR type , +prints out the current inquiry scan type. Otherwise, sets inquiry scan type to +.IR type . +.TP .BI inqparms " [win:int]" With no .IR win:int , diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 5f72ce66..f6c932e4 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -881,6 +881,40 @@ static void cmd_inq_mode(int ctl, int hdev, char *opt) } } +static void cmd_inq_type(int ctl, int hdev, char *opt) +{ + int dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (opt) { + uint8_t type = atoi(opt); + + if (hci_write_inquiry_scan_type(dd, type, 2000) < 0) { + fprintf(stderr, "Can't set inquiry scan type on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint8_t type; + + if (hci_read_inquiry_scan_type(dd, &type, 1000) < 0) { + fprintf(stderr, "Can't read inquiry scan type on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + printf("\tInquiry scan type: %s\n", + type == 1 ? "Interlaced Inquiry Scan" : "Standard Inquiry Scan"); + } +} + static void cmd_inq_parms(int ctl, int hdev, char *opt) { struct hci_request rq; @@ -1325,6 +1359,7 @@ static struct { { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { "inqmode", cmd_inq_mode, "[mode]", "Get/set inquiry mode" }, + { "inqtype", cmd_inq_type, "[type]", "Get/set inquiry scan type" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, -- cgit From 8937ece83f3e3317a84214028ec81b1fc042a040 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Jun 2005 18:01:04 +0000 Subject: Fix direction bit for clear status and abort commands --- tools/dfu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/dfu.c b/tools/dfu.c index 08e256b9..b46027a0 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -146,7 +146,7 @@ int dfu_clear_status(struct usb_dev_handle *udev, int intf) if (!udev) return -EIO; - return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, DFU_CLRSTATUS, 0, intf, NULL, 0, DFU_TIMEOUT); } @@ -164,6 +164,6 @@ int dfu_abort(struct usb_dev_handle *udev, int intf) if (!udev) return -EIO; - return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, DFU_ABORT, 0, intf, NULL, 0, DFU_TIMEOUT); } -- cgit From 3257d9b3a8f59561960c75f310fea33d23858024 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Jun 2005 21:25:49 +0000 Subject: Fix program error codes on memory allocations --- tools/hcitool.c | 72 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 6e225cee..210ab2ba 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1030,8 +1030,10 @@ static void cmd_dc(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1165,8 +1167,10 @@ static void cmd_rssi(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1236,8 +1240,10 @@ static void cmd_lq(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1309,8 +1315,10 @@ static void cmd_tpl(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1382,8 +1390,10 @@ static void cmd_afh(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1465,8 +1475,10 @@ static void cmd_cpt(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1546,8 +1558,10 @@ static void cmd_lst(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1631,8 +1645,10 @@ static void cmd_auth(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1700,8 +1716,10 @@ static void cmd_enc(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1770,8 +1788,10 @@ static void cmd_key(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1839,8 +1859,10 @@ static void cmd_clkoff(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; @@ -1912,8 +1934,10 @@ static void cmd_clock(int dev_id, int argc, char **argv) } cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) - return; + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; -- cgit From 1d2e71b109d907473939864caa5afec86000d58a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Jun 2005 12:10:54 +0000 Subject: Replace non-printable characters in device names --- hcid/storage.c | 11 +++++++++-- tools/hcitool.c | 13 +++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/hcid/storage.c b/hcid/storage.c index 79ec11af..c5f5eaed 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -166,7 +167,7 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; bdaddr_t bdaddr; struct stat st; - int fd, pos, err = 0; + int i, fd, pos, err = 0; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); @@ -216,7 +217,13 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n ftruncate(fd, 0); } - list = list_add(list, peer, name, strlen(name) + 1); + memset(str, 0, sizeof(str)); + strncpy(str, name, 248); + for (i = 0; i < 248 && str[i]; i++) + if (!isprint(str[i])) + str[i] = '.'; + + list = list_add(list, peer, str, strlen(str) + 1); if (!list) { err = -EIO; goto unlock; diff --git a/tools/hcitool.c b/tools/hcitool.c index 210ab2ba..e6561feb 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -411,7 +412,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_dev_info di; struct hci_conn_info_req *cr; int extcls = 0, extinf = 0, extoui = 0; - int i, opt, dd, cc, nc; + int i, n, opt, dd, cc, nc; length = 8; /* ~10 seconds */ num_rsp = 0; @@ -510,6 +511,10 @@ static void cmd_scan(int dev_id, int argc, char **argv) sizeof(name), name, 100000) < 0) strcpy(name, "n/a"); + for (n = 0; n < 248 && name[n]; n++) + if (!isprint(name[n])) + name[n] = '.'; + printf("\t%s\t%s\n", addr, name); continue; } @@ -563,8 +568,12 @@ static void cmd_scan(int dev_id, int argc, char **argv) sizeof(name), name, 100000) < 0) { if (!nc) strcpy(name, "n/a"); - } else + } else { + for (n = 0; n < 248 && name[n]; n++) + if (!isprint(name[n])) + name[n] = '.'; nc = 0; + } } printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); -- cgit From 4cf1f07d58e85915f12099d9eb5560e7acbf4deb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 21 Jun 2005 16:49:26 +0000 Subject: Don't use hci_uart.h anymore --- tools/hciattach.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 33ecdf03..b7f6dab6 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -49,7 +49,18 @@ #include #include #include -#include + +#ifndef N_HCI +#define N_HCI 15 +#endif + +#define HCIUARTSETPROTO _IOW('U', 200, int) +#define HCIUARTGETPROTO _IOR('U', 201, int) + +#define HCI_UART_H4 0 +#define HCI_UART_BCSP 1 +#define HCI_UART_3WIRE 2 +#define HCI_UART_H4DS 3 struct uart_t { char *type; -- cgit From ef24c2a9db8b95032e4d87b730dcffdf1b9901a4 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Fri, 24 Jun 2005 13:56:56 +0000 Subject: fix help message --- tools/sdptool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index d015f12f..97282e8d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2812,8 +2812,8 @@ static void usage(void) printf("Usage:\n" "\tsdptool [options] [command parameters]\n"); printf("Options:\n" - "\t--help\t\tDisplay help\n" - "\t--source\tSpecify source interface\n"); + "\t-h\t\tDisplay help\n" + "\t-i\t\tSpecify source interface\n"); printf("Commands:\n"); for (i = 0; command[i].cmd; i++) -- cgit From a32c06bc2990f56420782e8966aa5de08b61d505 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:08:26 +0000 Subject: Update reading of local Bluetooth clock --- tools/hcitool.1 | 2 +- tools/hcitool.c | 51 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/tools/hcitool.1 b/tools/hcitool.1 index d863e7d1..01ef03a8 100644 --- a/tools/hcitool.1 +++ b/tools/hcitool.1 @@ -175,7 +175,7 @@ Change the connection link key for the device with Bluetooth address Read the clock offset for the device with Bluetooth address .IR bdaddr . .TP -.BI clock " [which clock]" +.BI clock " [bdaddr] [which clock]" Read the clock for the device with Bluetooth address .IR bdaddr . The clock can be diff --git a/tools/hcitool.c b/tools/hcitool.c index e6561feb..7f0cc23a 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1900,14 +1900,14 @@ static struct option clock_options[] = { static char *clock_help = "Usage:\n" - "\tclock [which clock]\n"; + "\tclock [bdaddr] [which clock]\n"; static void cmd_clock(int dev_id, int argc, char **argv) { struct hci_conn_info_req *cr; bdaddr_t bdaddr; uint8_t which; - uint32_t clock; + uint32_t handle, clock; uint16_t accuracy; int opt, dd; @@ -1921,12 +1921,13 @@ static void cmd_clock(int dev_id, int argc, char **argv) argc -= optind; argv += optind; - if (argc < 1) { - printf(clock_help); - return; - } + if (argc > 0) + str2ba(argv[0], &bdaddr); + else + bacpy(&bdaddr, BDADDR_ANY); - str2ba(argv[0], &bdaddr); + if (!bacmp(&bdaddr, BDADDR_ANY)) + dev_id = hci_get_route(NULL); if (dev_id < 0) { dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); @@ -1942,22 +1943,31 @@ static void cmd_clock(int dev_id, int argc, char **argv) exit(1); } - cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); - if (!cr) { - perror("Can't allocate memory"); - exit(1); - } + if (bacmp(&bdaddr, BDADDR_ANY)) { + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + perror("Can't allocate memory"); + exit(1); + } - bacpy(&cr->bdaddr, &bdaddr); - cr->type = ACL_LINK; - if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { - perror("Get connection info failed"); - exit(1); - } + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { + perror("Get connection info failed"); + free(cr); + exit(1); + } + + handle = htobs(cr->conn_info->handle); + which = (argc > 1) ? atoi(argv[1]) : 0x01; - which = (argc > 1) ? atoi(argv[1]) : 0x01; + free(cr); + } else { + handle = 0x00; + which = 0x00; + } - if (hci_read_clock(dd, htobs(cr->conn_info->handle), which, &clock, &accuracy, 1000) < 0) { + if (hci_read_clock(dd, handle, which, &clock, &accuracy, 1000) < 0) { perror("Reading clock failed"); exit(1); } @@ -1968,7 +1978,6 @@ static void cmd_clock(int dev_id, int argc, char **argv) printf("Accuracy: %.2f msec\n", (float) accuracy * 0.3125); close(dd); - free(cr); } static struct { -- cgit From 2dd0e662aaec1ec73b7783a625c1645020dc29d7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:09:51 +0000 Subject: Add support for reading uint32 values --- tools/csr.c | 40 ++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 41 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index fd547ad3..4648d9fa 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -504,6 +504,46 @@ int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *val return 0; } +int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value) +{ + unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + *value = ((rp[11] + (rp[12] << 8)) << 16) + (rp[13] + (rp[14] << 8)); + + return 0; +} + int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, diff --git a/tools/csr.h b/tools/csr.h index 61df145e..5098a69d 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -77,6 +77,7 @@ char *csr_pskeytostr(uint16_t pskey); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); +int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); -- cgit From ab788511066ea30c788d907fd44c8427f97b6e54 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:10:34 +0000 Subject: Add support for getting the local Bluetooth clock --- tools/bccmd.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/bccmd.c b/tools/bccmd.c index 4b4a1fb4..5e358b01 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -79,6 +79,22 @@ static int cmd_keylen(int dd, int argc, char *argv[]) return 0; } +static int cmd_clock(int dd, int argc, char *argv[]) +{ + uint32_t clock = 0; + int err; + + err = csr_read_varid_uint32(dd, 0x4711, CSR_VARID_BT_CLOCK, &clock); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Bluetooth clock: 0x%04x (%d)\n", clock, clock); + + return 0; +} + static struct { char *str; int (*func)(int dd, int argc, char **argv); @@ -86,6 +102,7 @@ static struct { char *doc; } commands[] = { { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { NULL }, }; @@ -99,7 +116,7 @@ static void usage(void) printf("Commands:\n"); for (i = 0; commands[i].str; i++) - printf("\t%s\t%s\t%s\n", commands[i].str, + printf("\t%s\t%-8s\t%s\n", commands[i].str, commands[i].arg, commands[i].doc); } -- cgit From bee17a8b3e9f220f4064069e3cc9a485663ce057 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:42:56 +0000 Subject: Add Audio/Video control utility --- acinclude.m4 | 17 ++-- tools/Makefile.am | 18 ++++- tools/avctrl.8 | 38 +++++++++ tools/avctrl.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 298 insertions(+), 8 deletions(-) create mode 100644 tools/avctrl.8 create mode 100644 tools/avctrl.c diff --git a/acinclude.m4 b/acinclude.m4 index 5c27b5a8..ed00a60e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -265,10 +265,11 @@ AC_DEFUN([AC_ARG_BLUEZ], [ cups_enable=no pcmcia_enable=no initscripts_enable=no - bluepin_enable=yes + avctrl_enable=${usb_found} hid2hci_enable=${usb_found} dfutool_enable=no bcm203x_enable=no + bluepin_enable=yes AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable compiling with debugging information]), [ debug_enable=${enableval} @@ -286,10 +287,11 @@ AC_DEFUN([AC_ARG_BLUEZ], [ cups_enable=${enableval} pcmcia_enable=${enableval} initscripts_enable=${enableval} - bluepin_enable=${enableval} + avctrl_enable=${enableval} hid2hci_enable=${enableval} dfutool_enable=${enableval} bcm203x_enable=${enableval} + bluepin_enable=${enableval} ]) AC_ARG_ENABLE(obex, AC_HELP_STRING([--enable-obex], [enable OBEX support]), [ @@ -320,8 +322,8 @@ AC_DEFUN([AC_ARG_BLUEZ], [ initscripts_enable=${enableval} ]) - AC_ARG_ENABLE(bluepin, AC_HELP_STRING([--enable-bluepin], [install Python based PIN helper utility]), [ - bluepin_enable=${enableval} + AC_ARG_ENABLE(avctrl, AC_HELP_STRING([--enable-avctrl], [install Audio/Video control utility]), [ + avctrl_enable=${enableval} ]) AC_ARG_ENABLE(hid2hci, AC_HELP_STRING([--enable-hid2hci], [install HID mode switching utility]), [ @@ -336,6 +338,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ bcm203x_enable=${enableval} ]) + AC_ARG_ENABLE(bluepin, AC_HELP_STRING([--enable-bluepin], [install Python based PIN helper utility]), [ + bluepin_enable=${enableval} + ]) + if (test "${debug_enable}" = "yes" && test "${ac_cv_prog_cc_g}" = "yes"); then CFLAGS="$CFLAGS -g" fi @@ -352,8 +358,9 @@ AC_DEFUN([AC_ARG_BLUEZ], [ AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") AM_CONDITIONAL(PCMCIA, test "${pcmcia_enable}" = "yes") AM_CONDITIONAL(INITSCRIPTS, test "${initscripts_enable}" = "yes") - AM_CONDITIONAL(BLUEPIN, test "${bluepin_enable}" = "yes") + AM_CONDITIONAL(AVCTRL, test "${avctrl_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(DFUTOOL, test "${dfutool_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(BCM203X, test "${bcm203x_enable}" = "yes" && test "${usb_found}" = "yes") + AM_CONDITIONAL(BLUEPIN, test "${bluepin_enable}" = "yes") ]) diff --git a/tools/Makefile.am b/tools/Makefile.am index 66839dd7..adff35b9 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -2,6 +2,14 @@ # $Id$ # +if AVCTRL +avctrl_programs = avctrl +avctrl_manfiles = avctrl.8 +else +avctrl_programs = +avctrl_manfiles = +endif + if HID2HCI hid2hci_programs = hid2hci hid2hci_manfiles = hid2hci.8 @@ -18,7 +26,7 @@ dfutool_programs = dfutool_manfiles = endif -sbin_PROGRAMS = hciattach hciconfig $(hid2hci_programs) +sbin_PROGRAMS = hciattach hciconfig $(avctrl_programs) $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) @@ -44,6 +52,10 @@ pskey_LDADD = @BLUEZ_LIBS@ bccmd_SOURCES = bccmd.c csr.h csr.c bccmd_LDADD = @BLUEZ_LIBS@ +if AVCTRL +avctrl_LDADD = @USB_LIBS@ +endif + if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif @@ -58,8 +70,8 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ - $(hid2hci_manfiles) $(dfutool_manfiles) + $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) hid2hci.8 dfutool.1 +EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 dfutool.1 MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/avctrl.8 b/tools/avctrl.8 new file mode 100644 index 00000000..f791cf9e --- /dev/null +++ b/tools/avctrl.8 @@ -0,0 +1,38 @@ +.\" +.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH AVCTRL 8 "JUNE 6, 2005" "" "" + +.SH NAME +avctrl \- Bluetooth Audio/Video control utility +.SH SYNOPSIS +.BR "avctrl +[ +.I options +] +.SH DESCRIPTION +.B avctrl +is used to control the Audio/Video dongles. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible options. +.TP +.BI -q +Don't display any messages. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/avctrl.c b/tools/avctrl.c new file mode 100644 index 00000000..120a382f --- /dev/null +++ b/tools/avctrl.c @@ -0,0 +1,233 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif + +#ifndef USB_DIR_IN +#define USB_DIR_IN 0x80 +#endif + +#define HID_REQ_GET_REPORT 0x01 +#define HID_REQ_GET_IDLE 0x02 +#define HID_REQ_GET_PROTOCOL 0x03 +#define HID_REQ_SET_REPORT 0x09 +#define HID_REQ_SET_IDLE 0x0a +#define HID_REQ_SET_PROTOCOL 0x0b + +struct device_info; + +struct device_id { + uint16_t vendor; + uint16_t product; + int (*func)(struct device_info *dev); +}; + +struct device_info { + struct usb_device *dev; + struct device_id *id; +}; + +#define GET_STATE 0x01 +#define GET_REMOTE_BDADDR 0x02 +#define DISCOVER 0x03 +#define SWITCH_TO_DFU 0x04 +#define READ_CODEC 0x05 + +static int dongle_csr(struct device_info *devinfo) +{ + unsigned char buf[8]; + struct usb_dev_handle *udev; + int err, intf = 2; + + udev = usb_open(devinfo->dev); + if (!udev) + return -errno; + + if (usb_claim_interface(udev, intf) < 0) { + err = -errno; + usb_close(udev); + return err; + } + + memset(buf, 0, sizeof(buf)); + buf[0] = SWITCH_TO_DFU; + + err = usb_control_msg(udev, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + HID_REQ_SET_REPORT, 0x03 << 8, intf, buf, sizeof(buf), 10000); + + if (err == 0) { + err = -1; + errno = EALREADY; + } else { + if (errno == ETIMEDOUT) + err = 0; + } + + usb_release_interface(udev, intf); + usb_close(udev); + + return err; +} + +static struct device_id device_list[] = { + { 0x0a12, 0x1004, dongle_csr }, + { -1 } +}; + +static struct device_id *match_device(uint16_t vendor, uint16_t product) +{ + int i; + + for (i = 0; device_list[i].func; i++) { + if (vendor == device_list[i].vendor && + product == device_list[i].product) + return &device_list[i]; + } + + return NULL; +} + +static int find_devices(struct device_info *devinfo, size_t size) +{ + struct usb_bus *bus; + struct usb_device *dev; + struct device_id *id; + int count = 0; + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) { + id = match_device(dev->descriptor.idVendor, + dev->descriptor.idProduct); + if (!id) + continue; + + if (count < size) { + devinfo[count].dev = dev; + devinfo[count].id = id; + count++; + } + } + + return count; +} + +static void usage(void) +{ + printf("avctrl - Bluetooth Audio/Video control utility\n\n"); + + printf("Usage:\n" + "\tavctrl [options]\n" + "\n"); + + printf("Options:\n" + "\t-h, --help Display help\n" + "\t-q, --quiet Don't display any messages\n" + "\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { "quiet", 0, 0, 'q' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + struct device_info dev[16]; + int i, opt, num, quiet = 0; + + while ((opt = getopt_long(argc, argv, "+qh", main_options, NULL)) != -1) { + switch (opt) { + case 'q': + quiet = 1; + break; + case 'h': + usage(); + exit(0); + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + usb_init(); + + num = find_devices(dev, sizeof(dev) / sizeof(dev[0])); + if (num <= 0) { + if (!quiet) + fprintf(stderr, "No Audio/Video devices found\n"); + exit(1); + } + + for (i = 0; i < num; i++) { + struct device_id *id = dev[i].id; + + if (!quiet) + printf("Switching device %04x:%04x ", + id->vendor, id->product); + fflush(stdout); + + if (id->func(&dev[i]) < 0) { + if (!quiet) + printf("failed (%s)\n", strerror(errno)); + } else { + if (!quiet) + printf("was successful\n"); + } + } + + return 0; +} -- cgit From f05a85d0eac39614d5c75e58ddbc8de3ba641f00 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 10:44:52 +0000 Subject: Use textfile library for device name storage --- hcid/Makefile.am | 4 +- hcid/storage.c | 140 ++++++------------------------------------------------- 2 files changed, 18 insertions(+), 126 deletions(-) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 90136f28..875de7cd 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -23,10 +23,12 @@ dbus_hcid_cflags = endif hcid_SOURCES = main.c security.c storage.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) -hcid_LDADD = $(dbus_hcid_libs) @BLUEZ_LIBS@ +hcid_LDADD = $(dbus_hcid_libs) @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ $(dbus_hcid_cflags) +INCLUDES = -I$(top_srcdir)/common + man_MANS = hcid.8 hcid.conf.5 AM_YFLAGS = -d diff --git a/hcid/storage.c b/hcid/storage.c index c5f5eaed..284952f4 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -45,6 +45,7 @@ #include +#include "textfile.h" #include "hcid.h" struct list { @@ -163,59 +164,8 @@ static int create_dirs(const char *filename, mode_t mode) int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) { - struct list *temp, *list = NULL; - char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int i, fd, pos, err = 0; - - ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); - - umask(S_IWGRP | S_IWOTH); - create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - - fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_EX) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size + 300); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - list = list_add(list, &bdaddr, str, sizeof(str)); - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - - lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); - } + char filename[PATH_MAX + 1], addr[18], str[249]; + int i; memset(str, 0, sizeof(str)); strncpy(str, name, 248); @@ -223,89 +173,29 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n if (!isprint(str[i])) str[i] = '.'; - list = list_add(list, peer, str, strlen(str) + 1); - if (!list) { - err = -EIO; - goto unlock; - } - - list_foreach(list, temp) { - ba2str(&temp->bdaddr, addr); - if (temp->data && temp->size > 0) { - memset(buf, 0, 300); - snprintf(buf, 299, "%s %s\n", addr, temp->data); - write(fd, buf, strlen(buf)); - } - } - -unlock: - flock(fd, LOCK_UN); + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); -close: - close(fd); - list_free(list); - return err; + ba2str(peer, addr); + return textfile_put(filename, addr, str); } int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) { - char filename[PATH_MAX + 1], addr[18], str[249], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int fd, pos, err = -ENOENT; + char filename[PATH_MAX + 1], addr[18], *str; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); - fd = open(filename, O_RDONLY); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_SH) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - if (!bacmp(&bdaddr, peer)) { - snprintf(name, 249, "%s", str); - err = 0; - break; - } - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - } + ba2str(peer, addr); + str = textfile_get(filename, addr); + if (!str) + return -ENOENT; -unlock: - flock(fd, LOCK_UN); + memset(name, 0, 249); + strncpy(name, str, 248); -close: - close(fd); - return err; + return 0; } int write_version_info(const bdaddr_t *local, const bdaddr_t *peer, const uint16_t manufacturer, const uint8_t lmp_ver, const uint16_t lmp_subver) -- cgit From 457544cfedb41c4ea5e70992498c8311a8737b28 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 11:12:28 +0000 Subject: Fix a small typo --- alsa/pcm_a2dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsa/pcm_a2dp.c b/alsa/pcm_a2dp.c index f5dff96a..e2f8bde4 100644 --- a/alsa/pcm_a2dp.c +++ b/alsa/pcm_a2dp.c @@ -159,7 +159,7 @@ static int a2dp_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params) DBG("format %s rate %d channels %d", snd_pcm_format_name(io->format), io->rate, io->channels); - DBG("frame_bytes %d period_byts %d period_size %ld buffer_size %ld", + DBG("frame_bytes %d period_bytes %d period_size %ld buffer_size %ld", a2dp->frame_bytes, period_bytes, io->period_size, io->buffer_size); return 0; -- cgit From cbbe4f3f909cde4356f1323e0bd157e2fe9320de Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 13:01:52 +0000 Subject: Don't show empty names --- tools/hcitool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 7f0cc23a..ceddeda5 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -575,7 +575,9 @@ static void cmd_scan(int dev_id, int argc, char **argv) nc = 0; } } - printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); + + if (strlen(name) > 0) + printf("Device name:\t%s%s\n", name, nc ? " [cached]" : ""); if (extcls) { memcpy(cls, (info+i)->dev_class, 3); -- cgit From 4f32352b05190a3f70828c38f4a4f25655bb696e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 13:13:17 +0000 Subject: Move CSR panic and fault code reading to the bccmd tool --- tools/bccmd.c | 42 +++++++++++++++++++++++++++++++++++++++--- tools/hciconfig.c | 12 +----------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/tools/bccmd.c b/tools/bccmd.c index 5e358b01..df39a3df 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -95,14 +95,50 @@ static int cmd_clock(int dd, int argc, char *argv[]) return 0; } +static int cmd_panicarg(int dd, int argc, char *argv[]) +{ + uint16_t error = 0; + int err; + + err = csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Panic code: 0x%02x (%s)\n", error, + error < 0x100 ? "valid" : "invalid"); + + return 0; +} + +static int cmd_faultarg(int dd, int argc, char *argv[]) +{ + uint16_t error = 0; + int err; + + err = csr_read_varid_uint16(dd, 5, CSR_VARID_FAULT_ARG, &error); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Fault code: 0x%02x (%s)\n", error, + error < 0x100 ? "valid" : "invalid"); + + return 0; +} + static struct { char *str; int (*func)(int dd, int argc, char **argv); char *arg; char *doc; } commands[] = { - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, { NULL }, }; @@ -116,7 +152,7 @@ static void usage(void) printf("Commands:\n"); for (i = 0; commands[i].str; i++) - printf("\t%s\t%-8s\t%s\n", commands[i].str, + printf("\t%-10s%-8s\t%s\n", commands[i].str, commands[i].arg, commands[i].doc); } diff --git a/tools/hciconfig.c b/tools/hciconfig.c index f6c932e4..4dfb57a7 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1173,7 +1173,7 @@ static void print_rev_ericsson(int dd) static void print_rev_csr(int dd, uint16_t rev) { - uint16_t buildid, chipver, chiprev, maxkeylen, mapsco, error; + uint16_t buildid, chipver, chiprev, maxkeylen, mapsco; if (csr_read_varid_uint16(dd, 0, CSR_VARID_BUILDID, &buildid) < 0) { printf("\t%s\n", csr_buildidtostr(rev)); @@ -1193,16 +1193,6 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); - - if (!csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error)) { - if (error < 0x0100) - printf("\tPanic code: 0x%02x\n", error); - } - - if (!csr_read_varid_uint16(dd, 6, CSR_VARID_FAULT_ARG, &error)) { - if (error < 0x0100) - printf("\tFault code: 0x%02x\n", error); - } } static void print_rev_digianswer(int dd) -- cgit From 4b995c638ce04473845e16b24b315e42353c4905 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 15:02:28 +0000 Subject: Update changelog and bump version number --- ChangeLog | 14 ++++++++++++++ configure.in | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b2850b6a..0d69d477 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +ver 2.18: + Support D-Bus 0.23 and 0.33 API versions. + Support reading of complex BCCMD values. + Support minimum and maximum encryption key length. + Add support for inquiry scan type. + Add tool for the CSR BCCMD interface. + Add first draft of the Audio/Video control utility. + Add disconnect timer support for the A2DP ALSA plugin. + Make SBC parameters configurable. + Replace non-printable characters in device names. + + Note: + This version needs at least bluez-libs-2.18 + ver 2.17: Set the storage directory through ${localstatedir}. Add the textfile library for ASCII based file access. diff --git a/configure.in b/configure.in index 72fc841f..a0407c26 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.17) +AM_INIT_AUTOMAKE(bluez-utils, 2.18) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From db90836e94acf58c4433281e2762e2560440ef51 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 4 Jul 2005 16:59:12 +0000 Subject: Add daemon directory --- Makefile.am | 2 +- configure.in | 2 +- daemon/Makefile.am | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 daemon/Makefile.am diff --git a/Makefile.am b/Makefile.am index 49650733..a0042ed8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # $Id$ # -SUBDIRS = common tools rfcomm hcid sdpd dund pand hidd \ +SUBDIRS = common daemon tools rfcomm hcid sdpd dund pand hidd \ cups alsa test scripts pcmcia extra MAINTAINERCLEANFILES = Makefile.in \ diff --git a/configure.in b/configure.in index a0407c26..e965827c 100644 --- a/configure.in +++ b/configure.in @@ -34,4 +34,4 @@ AC_PATH_DBUS AC_ARG_BLUEZ -AC_OUTPUT(Makefile common/Makefile tools/Makefile rfcomm/Makefile hcid/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) +AC_OUTPUT(Makefile common/Makefile daemon/Makefile tools/Makefile rfcomm/Makefile hcid/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) diff --git a/daemon/Makefile.am b/daemon/Makefile.am new file mode 100644 index 00000000..930bbe6e --- /dev/null +++ b/daemon/Makefile.am @@ -0,0 +1,5 @@ +# +# $Id$ +# + +MAINTAINERCLEANFILES = Makefile.in -- cgit From 952e7cc56afa29f77a828aa256985ba38a06fa80 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 4 Jul 2005 17:29:17 +0000 Subject: Add Bluetooth daemon skeleton --- daemon/Makefile.am | 12 ++++++++++++ daemon/main.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 daemon/main.c diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 930bbe6e..df307144 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -2,4 +2,16 @@ # $Id$ # +if DBUS +sbin_PROGRAMS = bluetoothd + +bluetoothd_SOURCES = main.c + +bluetoothd_LDADD = @DBUS_LIBS@ @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a +endif + +AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ + +INCLUDES = -I$(top_srcdir)/common + MAINTAINERCLEANFILES = Makefile.in diff --git a/daemon/main.c b/daemon/main.c new file mode 100644 index 00000000..df39a66c --- /dev/null +++ b/daemon/main.c @@ -0,0 +1,41 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + return 0; +} -- cgit From 1f422e5f2b343d35a8c77ce4be16f74b2819b2bf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jul 2005 21:15:41 +0000 Subject: Fix some GCC 4.0 warnings --- cups/hcrp.c | 3 ++- dund/dun.c | 3 ++- dund/main.c | 3 ++- extra/bcm203x.c | 4 ++-- hcid/main.c | 4 ++-- hcid/parser.y | 12 ++++++------ hcid/security.c | 6 +++--- hcid/storage.c | 2 +- pand/main.c | 11 +++++++---- rfcomm/main.c | 6 ++++-- sdpd/main.c | 2 +- test/attest.c | 2 +- test/hstest.c | 3 ++- test/l2test.c | 4 ++-- test/scotest.c | 7 ++++--- tools/avctrl.c | 2 +- tools/ciptool.c | 3 ++- tools/dfu.c | 8 ++++---- tools/dfu.h | 4 ++-- tools/dfutool.c | 4 ++-- tools/hcitool.c | 8 +++++--- tools/hid2hci.c | 2 +- tools/sdptool.c | 4 ++-- 23 files changed, 60 insertions(+), 47 deletions(-) diff --git a/cups/hcrp.c b/cups/hcrp.c index 75171524..c8c26f92 100644 --- a/cups/hcrp.c +++ b/cups/hcrp.c @@ -176,8 +176,9 @@ int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned s { struct sockaddr_l2 addr; struct l2cap_options opts; + socklen_t size; unsigned char buf[2048]; - int i, size, ctrl_sk, data_sk, mtu, count, len, timeout = 0; + int i, ctrl_sk, data_sk, mtu, count, len, timeout = 0; uint8_t status; uint16_t tid = 0; uint32_t tmp, credit = 0; diff --git a/dund/dun.c b/dund/dun.c index 6611ad86..0593cb85 100644 --- a/dund/dun.c +++ b/dund/dun.c @@ -182,7 +182,8 @@ static int dun_create_tty(int sk, char *tty, int size) { struct sockaddr_rc sa; struct stat st; - int id, alen, try = 3; + socklen_t alen; + int id, try = 3; struct rfcomm_dev_req req = { flags: (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP), diff --git a/dund/main.c b/dund/main.c index 2bc4f9b5..a620c8de 100644 --- a/dund/main.c +++ b/dund/main.c @@ -163,7 +163,8 @@ static int do_listen(void) listen(sk, 10); while (!terminate) { - int alen = sizeof(sa), nsk; + socklen_t alen = sizeof(sa); + int nsk; char ba[40]; char ch[10]; diff --git a/extra/bcm203x.c b/extra/bcm203x.c index 1aa9257b..5990ae8c 100644 --- a/extra/bcm203x.c +++ b/extra/bcm203x.c @@ -58,7 +58,7 @@ static char *fw_path = "/lib/firmware"; static int load_file(struct usb_dev_handle *udev, char *filename) { - unsigned char buf[4096]; + char buf[4096]; int fd, err, len; fd = open(filename, O_RDONLY); @@ -100,7 +100,7 @@ static void load_firmware(struct usb_device *dev) { struct usb_dev_handle *udev; char filename[PATH_MAX + 1]; - unsigned char buf[16]; + char buf[16]; udev = usb_open(dev); if (!udev) { diff --git a/hcid/main.c b/hcid/main.c index 57637f3e..ecfc7db6 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -226,7 +226,7 @@ static void configure_device(int hdev) if ((device_opts->flags & (1 << HCID_SET_NAME)) && device_opts->name) { change_local_name_cp cp; memset(cp.name, 0, sizeof(cp.name)); - expand_name(cp.name, sizeof(cp.name), device_opts->name, hdev); + expand_name((char *) cp.name, sizeof(cp.name), device_opts->name, hdev); hci_send_cmd(s, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, CHANGE_LOCAL_NAME_CP_SIZE, &cp); @@ -459,7 +459,7 @@ static gboolean io_stack_event(GIOChannel *chan, GIOCondition cond, gpointer dat ptr = buf; - if ((err = g_io_channel_read(chan, buf, sizeof(buf), &len))) { + if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { if (err == G_IO_ERROR_AGAIN) return TRUE; diff --git a/hcid/parser.y b/hcid/parser.y index 7616ab56..d3cbd936 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -262,14 +262,14 @@ bdaddr: pkt_type: WORD { - int opt; + unsigned int opt; if (!hci_strtoptype($1, &opt)) cfg_error("Unknown packet type '%s'", $1); $$ = opt; } | LIST { - int opt; + unsigned int opt; if (!hci_strtoptype($1, &opt)) cfg_error("Unknown packet type '%s'", $1); $$ = opt; @@ -278,14 +278,14 @@ pkt_type: link_mode: WORD { - int opt; + unsigned int opt; if (!hci_strtolm($1, &opt)) cfg_error("Unknown link mode '%s'", $1); $$ = opt; } | LIST { - int opt; + unsigned int opt; if (!hci_strtolm($1, &opt)) cfg_error("Unknown link mode '%s'", $1); $$ = opt; @@ -294,14 +294,14 @@ link_mode: link_policy: WORD { - int opt; + unsigned int opt; if (!hci_strtolp($1, &opt)) cfg_error("Unknown link policy '%s'", $1); $$ = opt; } | LIST { - int opt; + unsigned int opt; if (!hci_strtolp($1, &opt)) cfg_error("Unknown link policy '%s'", $1); $$ = opt; diff --git a/hcid/security.c b/hcid/security.c index 921875b3..04f5b9b8 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -471,7 +471,7 @@ static void remote_name_information(int dev, bdaddr_t *sba, void *ptr) if (evt->status) return; - write_device_name(sba, dba, evt->name); + write_device_name(sba, dba, (char *) evt->name); } static void remote_version_information(int dev, bdaddr_t *sba, void *ptr) @@ -518,7 +518,7 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer return FALSE; } - if ((err = g_io_channel_read(chan, buf, sizeof(buf), &len))) { + if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { if (err == G_IO_ERROR_AGAIN) return TRUE; g_io_channel_close(chan); @@ -664,7 +664,7 @@ void init_security_data(void) { /* Set local PIN code */ if (read_default_pin_code() < 0) { - strcpy(hcid.pin_code, "BlueZ"); + strcpy((char *) hcid.pin_code, "BlueZ"); hcid.pin_len = 5; } diff --git a/hcid/storage.c b/hcid/storage.c index 284952f4..459ebff6 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -56,7 +56,7 @@ struct list { }; static struct list *list_add(struct list *list, const bdaddr_t *bdaddr, - const unsigned char *data, const size_t size) + const char *data, const size_t size) { struct list *temp = list, *last = list; diff --git a/pand/main.c b/pand/main.c index 98b1720d..20fbec19 100644 --- a/pand/main.c +++ b/pand/main.c @@ -127,7 +127,8 @@ static int do_listen(void) { struct l2cap_options l2o; struct sockaddr_l2 l2a; - int sk, olen, lm; + socklen_t olen; + int sk, lm; if (use_sdp) bnep_sdp_register(role); @@ -185,7 +186,7 @@ static int do_listen(void) listen(sk, 10); while (!terminate) { - int alen = sizeof(l2a); + socklen_t alen = sizeof(l2a); int nsk; nsk = accept(sk, (struct sockaddr *) &l2a, &alen); if (nsk < 0) { @@ -243,7 +244,8 @@ static int w4_hup(int sk) } if (n) { - int err = 0, olen = sizeof(err); + int err = 0; + socklen_t olen = sizeof(err); getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &olen); syslog(LOG_INFO, "%s disconnected%s%s", netdev, err ? " : " : "", err ? strerror(err) : ""); @@ -265,7 +267,8 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) { struct l2cap_options l2o; struct sockaddr_l2 l2a; - int sk, olen, r = 0; + socklen_t olen; + int sk, r = 0; syslog(LOG_INFO, "Connecting to %s", dst); diff --git a/rfcomm/main.c b/rfcomm/main.c index 86331b9d..decabcc6 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -258,8 +258,9 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg struct termios ti; struct sigaction sa; struct pollfd p; + socklen_t alen; char dst[18], devname[MAXPATHLEN]; - int sk, fd, alen, try = 3; + int sk, fd, try = 3; laddr.rc_family = AF_BLUETOOTH; bacpy(&laddr.rc_bdaddr, bdaddr); @@ -395,8 +396,9 @@ static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv struct termios ti; struct sigaction sa; struct pollfd p; + socklen_t alen; char dst[18], devname[MAXPATHLEN]; - int sk, nsk, fd, alen, try = 3; + int sk, nsk, fd, try = 3; laddr.rc_family = AF_BLUETOOTH; bacpy(&laddr.rc_bdaddr, bdaddr); diff --git a/sdpd/main.c b/sdpd/main.c index fc3dd22d..b80fc0bb 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -316,7 +316,7 @@ static int become_daemon(void) static inline void handle_request(int sk, char *data, int len) { struct sockaddr_l2 sa; - int size; + socklen_t size; sdp_req_t req; size = sizeof(sa); diff --git a/test/attest.c b/test/attest.c index cd0e93ca..6e7d3808 100644 --- a/test/attest.c +++ b/test/attest.c @@ -47,7 +47,7 @@ static int at_command(int fd, char *cmd, int to) { fd_set rfds; struct timeval timeout; - unsigned char buf[1024]; + char buf[1024]; int sel, len, i, n; write(fd, cmd, strlen(cmd)); diff --git a/test/hstest.c b/test/hstest.c index f269621c..8949be4b 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -89,7 +89,8 @@ static int sco_connect(bdaddr_t *src, bdaddr_t *dst, uint16_t *handle, uint16_t struct sockaddr_sco addr; struct sco_conninfo conn; struct sco_options opts; - int s, size; + socklen_t size; + int s; if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) { return -1; diff --git a/test/l2test.c b/test/l2test.c index 8d337a9d..f475aa4b 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -131,7 +131,7 @@ static char *ctoh(char c, char* s) return s; } -static void hexdump(char *s, unsigned long l) +static void hexdump(unsigned char *s, unsigned long l) { char bfr[80]; char *pb; @@ -477,7 +477,7 @@ static void dump_mode(int sk) } syslog(LOG_INFO, "Recevied %d bytes", len); - hexdump(buf,len); + hexdump(buf, len); } } diff --git a/test/scotest.c b/test/scotest.c index 6447eab4..22a95fed 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -251,8 +251,9 @@ static void recv_mode(int sk) static void send_mode(char *svr) { struct sco_options so; + socklen_t len; uint32_t seq; - int sk, i, opt; + int i, sk; if ((sk = do_connect(svr)) < 0) { syslog(LOG_ERR, "Can't connect to the server: %s (%d)", @@ -260,8 +261,8 @@ static void send_mode(char *svr) exit(1); } - opt = sizeof(so); - if (getsockopt(sk, SOL_SCO, SCO_OPTIONS, &so, &opt) < 0) { + len = sizeof(so); + if (getsockopt(sk, SOL_SCO, SCO_OPTIONS, &so, &len) < 0) { syslog(LOG_ERR, "Can't get SCO options: %s (%d)", strerror(errno), errno); exit(1); diff --git a/tools/avctrl.c b/tools/avctrl.c index 120a382f..14d42e4a 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -82,7 +82,7 @@ struct device_info { static int dongle_csr(struct device_info *devinfo) { - unsigned char buf[8]; + char buf[8]; struct usb_dev_handle *udev; int err, intf = 2; diff --git a/tools/ciptool.c b/tools/ciptool.c index 7c952cf4..38446f93 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -134,7 +134,8 @@ static int do_connect(int ctl, int dev_id, bdaddr_t *src, bdaddr_t *dst, unsigne struct hci_dev_info di; struct sockaddr_l2 addr; struct l2cap_options opts; - int sk, size; + socklen_t size; + int sk; hci_devinfo(dev_id, &di); if (!(di.link_policy & HCI_LP_RSWITCH)) { diff --git a/tools/dfu.c b/tools/dfu.c index b46027a0..bfbc0f2d 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -114,7 +114,7 @@ int dfu_detach(struct usb_dev_handle *udev, int intf) DFU_DETACH, 0x1388, intf, NULL, 0, DFU_TIMEOUT); } -int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size) +int dfu_upload(struct usb_dev_handle *udev, int intf, int block, char *buffer, int size) { if (!udev) return -EIO; @@ -123,7 +123,7 @@ int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char * DFU_UPLOAD, block, intf, buffer, size, DFU_TIMEOUT); } -int dfu_download(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size) +int dfu_download(struct usb_dev_handle *udev, int intf, int block, char *buffer, int size) { if (!udev) return -EIO; @@ -138,7 +138,7 @@ int dfu_get_status(struct usb_dev_handle *udev, int intf, struct dfu_status *sta return -EIO; return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, - DFU_GETSTATUS, 0, intf, (unsigned char *) status, DFU_STATUS_SIZE, DFU_TIMEOUT); + DFU_GETSTATUS, 0, intf, (char *) status, DFU_STATUS_SIZE, DFU_TIMEOUT); } int dfu_clear_status(struct usb_dev_handle *udev, int intf) @@ -156,7 +156,7 @@ int dfu_get_state(struct usb_dev_handle *udev, int intf, uint8_t *state) return -EIO; return usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, - DFU_GETSTATE, 0, intf, (unsigned char *) state, 1, DFU_TIMEOUT); + DFU_GETSTATE, 0, intf, (char *) state, 1, DFU_TIMEOUT); } int dfu_abort(struct usb_dev_handle *udev, int intf) diff --git a/tools/dfu.h b/tools/dfu.h index 1a253505..915efd8c 100644 --- a/tools/dfu.h +++ b/tools/dfu.h @@ -100,8 +100,8 @@ struct dfu_suffix { /* DFU interface */ int dfu_detach(struct usb_dev_handle *udev, int intf); -int dfu_upload(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size); -int dfu_download(struct usb_dev_handle *udev, int intf, int block, unsigned char *buffer, int size); +int dfu_upload(struct usb_dev_handle *udev, int intf, int block, char *buffer, int size); +int dfu_download(struct usb_dev_handle *udev, int intf, int block, char *buffer, int size); int dfu_get_status(struct usb_dev_handle *udev, int intf, struct dfu_status *status); int dfu_clear_status(struct usb_dev_handle *udev, int intf); int dfu_get_state(struct usb_dev_handle *udev, int intf, uint8_t *state); diff --git a/tools/dfutool.c b/tools/dfutool.c index 47510cef..06da5248 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -400,7 +400,7 @@ static void cmd_upgrade(char *device, int argc, char **argv) struct dfu_status status; struct dfu_suffix suffix; struct stat st; - unsigned char *buf; + char *buf; unsigned long filesize, count, timeout = 0; char *filename; uint32_t crc; @@ -568,7 +568,7 @@ static void cmd_archive(char *device, int argc, char **argv) struct usb_dev_handle *udev; struct dfu_status status; struct dfu_suffix suffix; - unsigned char buf[2048]; + char buf[2048]; unsigned long timeout = 0; char *filename; uint32_t crc; diff --git a/tools/hcitool.c b/tools/hcitool.c index ceddeda5..156b0790 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -819,7 +819,7 @@ static char *cmd_help = static void cmd_cmd(int dev_id, int argc, char **argv) { - char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; + unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_filter flt; hci_event_hdr *hdr; int i, opt, len, dd; @@ -940,9 +940,10 @@ static char *cc_help = static void cmd_cc(int dev_id, int argc, char **argv) { bdaddr_t bdaddr; - int opt, ptype, dd; uint16_t handle; uint8_t role; + unsigned int ptype; + int dd, opt; role = 0x01; ptype = HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5; @@ -1451,7 +1452,8 @@ static void cmd_cpt(int dev_id, int argc, char **argv) set_conn_ptype_cp cp; evt_conn_ptype_changed rp; bdaddr_t bdaddr; - int opt, dd, ptype; + unsigned int ptype; + int dd, opt; for_each_opt(opt, cpt_options, NULL) { switch (opt) { diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 115e0ef5..9a85c1fd 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -130,7 +130,7 @@ static int switch_hidproxy(struct device_info *devinfo) return err; } -static int send_report(int fd, const unsigned char *buf, size_t size) +static int send_report(int fd, const char *buf, size_t size) { struct hiddev_report_info rinfo; struct hiddev_usage_ref uref; diff --git a/tools/sdptool.c b/tools/sdptool.c index 97282e8d..3a2ce834 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -874,7 +874,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri if (!strncasecmp(argv[i], "u0x", 3)) { /* UUID16 */ uint16_t value_int = strtoul((argv[i]) + 3, NULL, 16); - uuid_t *value_uuid = (uuid_t *)malloc(sizeof(uuid_t)); + uuid_t *value_uuid = (uuid_t *) malloc(sizeof(uuid_t)); allocArray[i] = value_uuid; sdp_uuid16_create(value_uuid, value_int); @@ -883,7 +883,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri valueArray[i] = &value_uuid->value.uuid16; } else if (!strncasecmp(argv[i], "0x", 2)) { /* Int */ - uint32_t *value_int = (int *)malloc(sizeof(int)); + uint32_t *value_int = (uint32_t *) malloc(sizeof(int)); allocArray[i] = value_int; *value_int = strtoul((argv[i]) + 2, NULL, 16); -- cgit From e063c0ede09c386be3a5fb579f3cdf75f5826493 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jul 2005 21:23:02 +0000 Subject: Add build id for BlueCore3-Audio with Unified 18e firmware --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 4648d9fa..6fb93f06 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -276,6 +276,8 @@ static struct { { 2063, "Unified 20a1" }, { 2067, "Unified 18f" }, { 2068, "Unified 18f" }, + { 2243, "Unified 18e" }, + { 2244, "Unified 18e" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From e2a54220b404119a2516a3cac5edc5b2bcf6089a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 6 Jul 2005 00:12:58 +0000 Subject: Fix more GCC 4.0 warnings --- sdpd/cstate.c | 2 +- sdpd/main.c | 4 ++-- sdpd/request.c | 30 +++++++++++++++--------------- sdpd/sdpd.h | 2 +- sdpd/service.c | 8 ++++---- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sdpd/cstate.c b/sdpd/cstate.c index dd532943..c983ef74 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -68,7 +68,7 @@ sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) uint32_t sdp_cstate_alloc_buf(sdp_buf_t *buf) { sdp_cstate_list_t *cstate = (sdp_cstate_list_t *)malloc(sizeof(sdp_cstate_list_t)); - char *data = (char *)malloc(buf->data_size); + uint8_t *data = malloc(buf->data_size); memcpy(data, buf->data, buf->data_size); memset((char *)cstate, 0, sizeof(sdp_cstate_list_t)); diff --git a/sdpd/main.c b/sdpd/main.c index b80fc0bb..51accc9a 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -313,7 +313,7 @@ static int become_daemon(void) return 1; } -static inline void handle_request(int sk, char *data, int len) +static inline void handle_request(int sk, uint8_t *data, int len) { struct sockaddr_l2 sa; socklen_t size; @@ -357,7 +357,7 @@ static void check_active(fd_set *mask, int num) { sdp_pdu_hdr_t hdr; int size, fd, count, r; - char *buf; + uint8_t *buf; for (fd = 0, count = 0; fd <= active_maxfd && count < num; fd++) { if (fd == l2cap_sock || fd == unix_sock || !FD_ISSET(fd, mask)) diff --git a/sdpd/request.c b/sdpd/request.c index 6a62e55f..356ce1d8 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -57,7 +57,7 @@ * sequence. The data type of elements found in the * sequence is returned in the reference pDataType */ -static int extract_des(char *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType) +static int extract_des(uint8_t *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, uint8_t expectedType) { uint8_t seqType; int data_size = 0; @@ -67,7 +67,7 @@ static int extract_des(char *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, ui sdp_list_t *pSeq = NULL; uint8_t dataType; int status = 0; - const char *p; + const uint8_t *p; SDPDBG("Seq type : %d\n", seqType); if (!scanned || (seqType != SDP_SEQ8 && seqType != SDP_SEQ16)) { @@ -142,7 +142,7 @@ static int extract_des(char *buf, sdp_list_t **svcReqSeq, uint8_t *pDataType, ui static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate) { - char *pdata = buf->data + buf->data_size; + uint8_t *pdata = buf->data + buf->data_size; int length = 0; if (cstate) { @@ -162,9 +162,9 @@ static int sdp_set_cstate_pdu(sdp_buf_t *buf, sdp_cont_state_t *cstate) return length; } -static sdp_cont_state_t *sdp_cstate_get(char *buffer) +static sdp_cont_state_t *sdp_cstate_get(uint8_t *buffer) { - char *pdata = buffer; + uint8_t *pdata = buffer; uint8_t cStateSize = *(uint8_t *)pdata; /* @@ -233,16 +233,16 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) { int status = 0, i, plen, mlen; sdp_list_t *pattern = NULL; - int expected, actual; + uint16_t expected, actual; uint8_t dtd; sdp_cont_state_t *cstate = NULL; - char *pCacheBuffer = NULL; + uint8_t *pCacheBuffer = NULL; int handleSize = 0; uint32_t cStateId = 0; short rsp_count = 0; short *pTotalRecordCount, *pCurrentRecordCount; int mtu; - char *pdata = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); int scanned = extract_des(pdata, &pattern, &dtd, SDP_TYPE_UUID); SDPDBG(""); @@ -361,7 +361,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) * current record count and increment the cached * buffer pointer to beyond the counters */ - pdata = (char *)pCurrentRecordCount + sizeof(uint16_t); + pdata = (uint8_t *) pCurrentRecordCount + sizeof(uint16_t); /* increment beyond the totalCount and the currentCount */ pCacheBuffer += 2 * sizeof(uint16_t); @@ -486,14 +486,14 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, uint8_t dtd, sdp_bu static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf) { sdp_cont_state_t *cstate = NULL; - char *pResponse = NULL; + uint8_t *pResponse = NULL; short cstate_size = 0; sdp_list_t *seq = NULL; uint8_t dtd = 0; int scanned = 0; int max_rsp_size; int status = 0, plen, mlen; - char *pdata = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)pdata)); SDPDBG(""); @@ -605,7 +605,7 @@ done: static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) { int status = 0, plen, totscanned; - char *pdata, *pResponse = NULL; + uint8_t *pdata, *pResponse = NULL; int scanned, max, rsp_count = 0; sdp_list_t *pattern = NULL, *seq = NULL, *svcList; sdp_cont_state_t *cstate = NULL; @@ -653,7 +653,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) svcList = sdp_get_record_list(); - tmpbuf.data = (char *)malloc(USHRT_MAX); + tmpbuf.data = malloc(USHRT_MAX); tmpbuf.data_size = 0; tmpbuf.buf_size = USHRT_MAX; memset(tmpbuf.data, 0, USHRT_MAX); @@ -765,13 +765,13 @@ void process_request(sdp_req_t *req) sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)req->buf; sdp_pdu_hdr_t *rsphdr; sdp_buf_t rsp; - char *buf = (char *)malloc(USHRT_MAX); + uint8_t *buf = malloc(USHRT_MAX); int sent = 0; int status = SDP_INVALID_SYNTAX; SDPDBG(""); - memset((void *)buf, 0, USHRT_MAX); + memset(buf, 0, USHRT_MAX); rsp.data = buf + sizeof(sdp_pdu_hdr_t); rsp.data_size = 0; rsp.buf_size = USHRT_MAX - sizeof(sdp_pdu_hdr_t); diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 6d9c856a..3df83fca 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -50,7 +50,7 @@ typedef struct request { int sock; int mtu; int flags; - char *buf; + uint8_t *buf; int len; } sdp_req_t; diff --git a/sdpd/service.c b/sdpd/service.c index f2457e1f..843371ea 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -46,7 +46,7 @@ extern void update_db_timestamp(void); // FIXME: refactor for server-side -static sdp_record_t *extract_pdu_server(char *p, uint32_t handleExpected, int *scanned) +static sdp_record_t *extract_pdu_server(uint8_t *p, uint32_t handleExpected, int *scanned) { int extractStatus = -1, localExtractedLength = 0; uint8_t dtd; @@ -129,7 +129,7 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) { int scanned = 0; sdp_data_t *handle; - char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); sdp_record_t *rec; req->flags = *p++; @@ -175,7 +175,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) { sdp_record_t *orec; int status = 0, scanned = 0; - char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); SDPDBG(""); @@ -217,7 +217,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) */ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) { - char *p = req->buf + sizeof(sdp_pdu_hdr_t); + uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); sdp_record_t *rec; int status = 0; -- cgit From 20f65cf4e0ab67ac3e528d84a877a5fe6161904a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 7 Jul 2005 16:50:07 +0000 Subject: Send D-Bus messages for inquiry results and remote name resolves --- hcid/dbus.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hcid/hcid.h | 11 +++++++- hcid/security.c | 53 ++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 683cf6fb..69a3a6cb 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -170,6 +170,94 @@ failed: OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); } +void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer) +{ + DBusMessage *message; +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS + DBusMessageIter iter; +#endif + char local_addr[18], peer_addr[18]; + + ba2str(local, local_addr); + ba2str(peer, peer_addr); + + message = dbus_message_new_signal("/org/bluez/DevAgent", + "org.bluez.DevAgent", "InquiryResult"); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS inquiry result message"); + goto failed; + } + +#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS + dbus_message_append_args(message, + DBUS_TYPE_STRING, local_addr, + DBUS_TYPE_STRING, peer_addr, + DBUS_TYPE_INVALID); +#else + dbus_message_append_iter_init(message, &iter); + + dbus_message_iter_append_string(&iter, local_addr); + dbus_message_iter_append_string(&iter, peer_addr); +#endif + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS inquiry result message"); + goto failed; + } + + dbus_connection_flush(connection); + +failed: + dbus_message_unref(message); + + return; +} + +void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) +{ + DBusMessage *message; +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS + DBusMessageIter iter; +#endif + char local_addr[18], peer_addr[18]; + + ba2str(local, local_addr); + ba2str(peer, peer_addr); + + message = dbus_message_new_signal("/org/bluez/DevAgent", + "org.bluez.DevAgent", "RemoteName"); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); + goto failed; + } + +#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS + dbus_message_append_args(message, + DBUS_TYPE_STRING, local_addr, + DBUS_TYPE_STRING, peer_addr, + DBUS_TYPE_STRING, name, + DBUS_TYPE_INVALID); +#else + dbus_message_append_iter_init(message, &iter); + + dbus_message_iter_append_string(&iter, local_addr); + dbus_message_iter_append_string(&iter, peer_addr); + dbus_message_iter_append_string(&iter, name); +#endif + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS remote name message"); + goto failed; + } + + dbus_connection_flush(connection); + +failed: + dbus_message_unref(message); + + return; +} + gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data) { DBusWatch *watch = (DBusWatch *) data; diff --git a/hcid/hcid.h b/hcid/hcid.h index c64016ea..5e835807 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -121,8 +121,17 @@ void stop_security_manager(int hdev); void toggle_pairing(int enable); #ifdef ENABLE_DBUS -void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); gboolean hcid_dbus_init(void); +void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); +void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer); +void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); +#else +static inline void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer) +{ +} +static inline void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) +{ +} #endif int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); diff --git a/hcid/security.c b/hcid/security.c index 04f5b9b8..148c3237 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -471,6 +471,8 @@ static void remote_name_information(int dev, bdaddr_t *sba, void *ptr) if (evt->status) return; + hcid_dbus_remote_name(sba, dba, (char *) evt->name); + write_device_name(sba, dba, (char *) evt->name); } @@ -489,6 +491,47 @@ static void remote_version_information(int dev, bdaddr_t *sba, void *ptr) evt->lmp_ver, btohs(evt->lmp_subver)); } +static void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) +{ + uint8_t num = *(uint8_t *)ptr++; + int i; + + for (i = 0; i < num; i++) { + inquiry_info *info = ptr; + + hcid_dbus_inquiry_result(sba, &info->bdaddr); + + ptr += INQUIRY_INFO_SIZE; + } +} + +static void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr) +{ + uint8_t num = *(uint8_t *)ptr++; + int i; + + if (!num) + return; + + if ((plen - 1) / num == INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE) { + for (i = 0; i < num; i++) { + inquiry_info_with_rssi_and_pscan_mode *info = ptr; + + hcid_dbus_inquiry_result(sba, &info->bdaddr); + + ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; + } + } else { + for (i = 0; i < num; i++) { + inquiry_info_with_rssi *info = ptr; + + hcid_dbus_inquiry_result(sba, &info->bdaddr); + + ptr += INQUIRY_INFO_WITH_RSSI_SIZE; + } + } +} + static void remote_features_information(int dev, bdaddr_t *sba, void *ptr) { evt_read_remote_features_complete *evt = ptr; @@ -553,6 +596,14 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer case EVT_READ_REMOTE_FEATURES_COMPLETE: remote_features_information(dev, &di->bdaddr, ptr); break; + + case EVT_INQUIRY_RESULT: + inquiry_result(dev, &di->bdaddr, eh->plen, ptr); + break; + + case EVT_INQUIRY_RESULT_WITH_RSSI: + inquiry_result_with_rssi(dev, &di->bdaddr, eh->plen, ptr); + break; } if (hci_test_bit(HCI_SECMGR, &di->flags)) @@ -608,6 +659,8 @@ void start_security_manager(int hdev) hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt); hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); + hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); + hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { syslog(LOG_ERR, "Can't set filter on hci%d: %s (%d)", hdev, strerror(errno), errno); -- cgit From bee20248caf216429bba4e2d1f104f9aab03596d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 7 Jul 2005 19:36:35 +0000 Subject: Support class of device and RSSI values in D-Bus message --- hcid/dbus.c | 6 +++++- hcid/hcid.h | 4 ++-- hcid/security.c | 21 ++++++++++++++++----- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 69a3a6cb..d8a07dd9 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -170,7 +170,7 @@ failed: OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); } -void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer) +void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer, const uint32_t class, const int8_t rssi) { DBusMessage *message; #ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS @@ -192,12 +192,16 @@ void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer) dbus_message_append_args(message, DBUS_TYPE_STRING, local_addr, DBUS_TYPE_STRING, peer_addr, + DBUS_TYPE_UINT32, class, + DBUS_TYPE_INT32, rssi, DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); dbus_message_iter_append_string(&iter, local_addr); dbus_message_iter_append_string(&iter, peer_addr); + dbus_message_iter_append_uint32(&iter, class); + dbus_message_iter_append_int32(&iter, rssi); #endif if (dbus_connection_send(connection, message, NULL) == FALSE) { diff --git a/hcid/hcid.h b/hcid/hcid.h index 5e835807..3ba69833 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -123,10 +123,10 @@ void toggle_pairing(int enable); #ifdef ENABLE_DBUS gboolean hcid_dbus_init(void); void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); -void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer); +void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer, const uint32_t class, const int8_t rssi); void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); #else -static inline void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer) +static inline void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer, uint32_t class, const int8_t rssi) { } static inline void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) diff --git a/hcid/security.c b/hcid/security.c index 148c3237..108887ce 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -493,13 +493,16 @@ static void remote_version_information(int dev, bdaddr_t *sba, void *ptr) static void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) { - uint8_t num = *(uint8_t *)ptr++; + uint8_t num = *(uint8_t *) ptr++; int i; for (i = 0; i < num; i++) { inquiry_info *info = ptr; + uint32_t class = info->dev_class[0] + | (info->dev_class[1] << 8) + | (info->dev_class[2] << 16); - hcid_dbus_inquiry_result(sba, &info->bdaddr); + hcid_dbus_inquiry_result(sba, &info->bdaddr, class, 0); ptr += INQUIRY_INFO_SIZE; } @@ -507,7 +510,7 @@ static void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) static void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr) { - uint8_t num = *(uint8_t *)ptr++; + uint8_t num = *(uint8_t *) ptr++; int i; if (!num) @@ -516,16 +519,24 @@ static void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr if ((plen - 1) / num == INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE) { for (i = 0; i < num; i++) { inquiry_info_with_rssi_and_pscan_mode *info = ptr; + uint32_t class = info->dev_class[0] + | (info->dev_class[1] << 8) + | (info->dev_class[2] << 16); - hcid_dbus_inquiry_result(sba, &info->bdaddr); + hcid_dbus_inquiry_result(sba, &info->bdaddr, + class, info->rssi); ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; } } else { for (i = 0; i < num; i++) { inquiry_info_with_rssi *info = ptr; + uint32_t class = info->dev_class[0] + | (info->dev_class[1] << 8) + | (info->dev_class[2] << 16); - hcid_dbus_inquiry_result(sba, &info->bdaddr); + hcid_dbus_inquiry_result(sba, &info->bdaddr, + class, info->rssi); ptr += INQUIRY_INFO_WITH_RSSI_SIZE; } -- cgit From 0bf15aa0833fccedbb038830bee423f29e6b1d5e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Jul 2005 17:19:40 +0000 Subject: Update some wording in the manual page --- tools/sdptool.1 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/sdptool.1 b/tools/sdptool.1 index 5ed9e33e..781a91e5 100644 --- a/tools/sdptool.1 +++ b/tools/sdptool.1 @@ -64,8 +64,14 @@ performing SDP queries on Bluetooth devices, and administering a local \fBsdpd\fR. .SH "COMMANDS" .PP -The following commands are available. -.IP "\fBsearch [--bdaddr bdaddr] [--tree] [--raw] service\fP" 10 +The following commands are available. In all cases \fBbdaddr\fR +specifies the device to search or browse. If \fIlocal\fP is used +for \fBbdaddr\fP, then the local \fBsdpd\fR is searched. +.PP +Services are identified and manipulated with a 4-byte \fBrecord_handle\fP +(NOT the service name). To find a service's \fBrecord_handle\fP, look for the +"Service RecHandle" line in the \fBsearch\fP or \fBbrowse\fP results +.IP "\fBsearch [--bdaddr bdaddr] [--tree] [--raw] service_name\fP" 10 Search for services.. .IP "" 10 Known service names are DID, SP, DUN, LAN, FAX, OPUSH, -- cgit From 489f776973a6b46016edc0cd978918018a93b9a1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 14 Jul 2005 09:20:35 +0000 Subject: Add build id for BlueCore3-MM with Unified 20d firmware --- tools/csr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 6fb93f06..6832ec6d 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -278,6 +278,8 @@ static struct { { 2068, "Unified 18f" }, { 2243, "Unified 18e" }, { 2244, "Unified 18e" }, + { 2258, "Unified 20d" }, + { 2259, "Unified 20d" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From b0ba2fc57a3da851aa0bb7ff6bbf78347c838221 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 3 Aug 2005 07:57:12 +0000 Subject: Add device specific register functionality --- sdpd/main.c | 11 ++++++++--- sdpd/sdpd.h | 3 ++- sdpd/service.c | 20 ++++++++++++-------- sdpd/servicedb.c | 2 +- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/sdpd/main.c b/sdpd/main.c index 51accc9a..734b8bda 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -113,7 +113,7 @@ static void register_public_browse_group(int public) } else browse->handle = SDP_SERVER_RECORD_HANDLE + 1; - sdp_record_add(browse); + sdp_record_add(BDADDR_ANY, browse); sdpdata = sdp_data_alloc(SDP_UINT32, &browse->handle); sdp_attr_add(browse, SDP_ATTR_RECORD_HANDLE, sdpdata); @@ -155,7 +155,7 @@ static void register_server_service(int public) /* Force the record to be SDP_SERVER_RECORD_HANDLE */ server->handle = SDP_SERVER_RECORD_HANDLE; - sdp_record_add(server); + sdp_record_add(BDADDR_ANY, server); sdp_attr_add(server, SDP_ATTR_RECORD_HANDLE, sdp_data_alloc(SDP_UINT32, &server->handle)); /* @@ -320,7 +320,7 @@ static inline void handle_request(int sk, uint8_t *data, int len) sdp_req_t req; size = sizeof(sa); - if (getpeername(sk, (struct sockaddr *)&sa, &size) < 0) + if (getpeername(sk, (struct sockaddr *) &sa, &size) < 0) return; if (sa.l2_family == AF_BLUETOOTH) { @@ -331,7 +331,12 @@ static inline void handle_request(int sk, uint8_t *data, int len) req.bdaddr = sa.l2_bdaddr; req.mtu = lo.omtu; req.local = 0; + memset(&sa, 0, sizeof(sa)); + size = sizeof(sa); + getsockname(sk, (struct sockaddr *) &sa, &size); + req.device = sa.l2_bdaddr; } else { + req.device = *BDADDR_ANY; req.bdaddr = *BDADDR_LOCAL; req.mtu = 2048; req.local = 1; diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 3df83fca..0bca315f 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -45,6 +45,7 @@ #endif typedef struct request { + bdaddr_t device; bdaddr_t bdaddr; int local; int sock; @@ -80,7 +81,7 @@ void sdp_svcdb_collect_all(int sock); void sdp_svcdb_set_collectable(sdp_record_t *rec, int sock); void sdp_svcdb_collect(sdp_record_t *rec); sdp_record_t *sdp_record_find(uint32_t handle); -void sdp_record_add(sdp_record_t *rec); +void sdp_record_add(bdaddr_t *device, sdp_record_t *rec); int sdp_record_remove(uint32_t handle); sdp_list_t *sdp_get_record_list(); uint32_t sdp_next_handle(void); diff --git a/sdpd/service.c b/sdpd/service.c index 843371ea..437bcd69 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -46,7 +46,7 @@ extern void update_db_timestamp(void); // FIXME: refactor for server-side -static sdp_record_t *extract_pdu_server(uint8_t *p, uint32_t handleExpected, int *scanned) +static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t handleExpected, int *scanned) { int extractStatus = -1, localExtractedLength = 0; uint8_t dtd; @@ -71,15 +71,15 @@ static sdp_record_t *extract_pdu_server(uint8_t *p, uint32_t handleExpected, int } else if (handleExpected != 0xffffffff) rec = sdp_record_find(handleExpected); - if (rec == NULL) { + if (!rec) { rec = sdp_record_alloc(); rec->attrlist = NULL; if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { rec->handle = handle; - sdp_record_add(rec); + sdp_record_add(device, rec); } else if (handleExpected != 0xffffffff) { rec->handle = handleExpected; - sdp_record_add(rec); + sdp_record_add(device, rec); } } @@ -133,10 +133,14 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_record_t *rec; req->flags = *p++; + if (req->flags & SDP_DEVICE_RECORD) { + bacpy(&req->device, (bdaddr_t *) p); + p += sizeof(bdaddr_t); + } // save image of PDU: we need it when clients request this attribute - rec = extract_pdu_server(p, 0xffffffff, &scanned); - if (rec == NULL) { + rec = extract_pdu_server(&req->device, p, 0xffffffff, &scanned); + if (!rec) { sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *)rsp->data); rsp->data_size = sizeof(uint16_t); return -1; @@ -146,7 +150,7 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) if (rec->handle < 0x10000) return -1; - sdp_record_add(rec); + sdp_record_add(&req->device, rec); if (!(req->flags & SDP_RECORD_PERSIST)) sdp_svcdb_set_collectable(rec, req->sock); handle = sdp_data_alloc(SDP_UINT32, &rec->handle); @@ -189,7 +193,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) SDPDBG("SvcRecOld: 0x%x\n", (uint32_t)orec); if (orec) { - sdp_record_t *nrec = extract_pdu_server(p, handle, &scanned); + sdp_record_t *nrec = extract_pdu_server(BDADDR_ANY, p, handle, &scanned); if (nrec && handle == nrec->handle) update_db_timestamp(); else { diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 45f45b91..c977bc81 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -143,7 +143,7 @@ void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) /* * Add a service record to the repository */ -void sdp_record_add(sdp_record_t *rec) +void sdp_record_add(bdaddr_t *device, sdp_record_t *rec) { #ifdef SDP_DEBUG SDPDBG("Adding rec : 0x%lx\n", (long) rec); -- cgit From 028619a565a8dd60da011170f8ce326de78a1e47 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 02:59:23 +0000 Subject: Add support for device specific SDP records --- sdpd/main.c | 16 +++---- sdpd/request.c | 10 ++-- sdpd/sdpd.h | 4 +- sdpd/servicedb.c | 138 +++++++++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 131 insertions(+), 37 deletions(-) diff --git a/sdpd/main.c b/sdpd/main.c index 734b8bda..27d2f800 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -328,18 +328,18 @@ static inline void handle_request(int sk, uint8_t *data, int len) memset(&lo, 0, sizeof(lo)); size = sizeof(lo); getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &lo, &size); - req.bdaddr = sa.l2_bdaddr; - req.mtu = lo.omtu; - req.local = 0; + bacpy(&req.bdaddr, &sa.l2_bdaddr); + req.mtu = lo.omtu; + req.local = 0; memset(&sa, 0, sizeof(sa)); size = sizeof(sa); getsockname(sk, (struct sockaddr *) &sa, &size); - req.device = sa.l2_bdaddr; + bacpy(&req.device, &sa.l2_bdaddr); } else { - req.device = *BDADDR_ANY; - req.bdaddr = *BDADDR_LOCAL; - req.mtu = 2048; - req.local = 1; + bacpy(&req.device, BDADDR_ANY); + bacpy(&req.bdaddr, BDADDR_LOCAL); + req.mtu = 2048; + req.local = 1; } req.sock = sk; req.buf = data; diff --git a/sdpd/request.c b/sdpd/request.c index 356ce1d8..07051f9f 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -298,11 +298,12 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf) handleSize = 0; for (; list && rsp_count < expected; list = list->next) { - sdp_record_t *rec = (sdp_record_t *)list->data; + sdp_record_t *rec = (sdp_record_t *) list->data; SDPDBG("Checking svcRec : 0x%x\n", rec->handle); - if (sdp_match_uuid(pattern, rec->pattern) > 0) { + if (sdp_match_uuid(pattern, rec->pattern) > 0 && + sdp_check_access(rec->handle, &req->device)) { rsp_count++; sdp_put_unaligned(htonl(rec->handle), (uint32_t *)pdata); pdata += sizeof(uint32_t); @@ -672,8 +673,9 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf) /* no continuation state -> create new response */ sdp_list_t *p; for (p = svcList; p; p = p->next) { - sdp_record_t *rec = (sdp_record_t *)p->data; - if (sdp_match_uuid(pattern, rec->pattern) > 0) { + sdp_record_t *rec = (sdp_record_t *) p->data; + if (sdp_match_uuid(pattern, rec->pattern) > 0 && + sdp_check_access(rec->handle, &req->device)) { rsp_count++; status = extract_attrs(rec, seq, dtd, &tmpbuf); diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 0bca315f..af028a4f 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -83,7 +83,9 @@ void sdp_svcdb_collect(sdp_record_t *rec); sdp_record_t *sdp_record_find(uint32_t handle); void sdp_record_add(bdaddr_t *device, sdp_record_t *rec); int sdp_record_remove(uint32_t handle); -sdp_list_t *sdp_get_record_list(); +sdp_list_t *sdp_get_record_list(void); +sdp_list_t *sdp_get_access_list(void); +int sdp_check_access(uint32_t handle, bdaddr_t *device); uint32_t sdp_next_handle(void); uint32_t sdp_get_time(); diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index c977bc81..6a1e2279 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -46,6 +46,12 @@ #include "sdpd.h" static sdp_list_t *service_db; +static sdp_list_t *access_db; + +typedef struct { + uint32_t handle; + bdaddr_t device; +} sdp_access_t; /* * Ordering function called when inserting a service record. @@ -54,22 +60,42 @@ static sdp_list_t *service_db; */ static int record_sort(const void *r1, const void *r2) { - const sdp_record_t *rec1 = (const sdp_record_t *)r1; - const sdp_record_t *rec2 = (const sdp_record_t *)r2; + const sdp_record_t *rec1 = (const sdp_record_t *) r1; + const sdp_record_t *rec2 = (const sdp_record_t *) r2; if (!rec1 || !rec2) { SDPERR("NULL RECORD LIST FATAL\n"); return -1; } + return rec1->handle - rec2->handle; } +static int access_sort(const void *r1, const void *r2) +{ + const sdp_access_t *rec1 = (const sdp_access_t *) r1; + const sdp_access_t *rec2 = (const sdp_access_t *) r2; + + if (!rec1 || !rec2) { + SDPERR("NULL RECORD LIST FATAL\n"); + return -1; + } + + return rec1->handle - rec2->handle; +} + +static void access_free(void *p) +{ + free(p); +} + /* * Reset the service repository by deleting its contents */ void sdp_svcdb_reset() { - sdp_list_free(service_db, (sdp_free_func_t)sdp_record_free); + sdp_list_free(service_db, (sdp_free_func_t) sdp_record_free); + sdp_list_free(access_db, access_free); } typedef struct _indexed { @@ -86,8 +112,8 @@ void sdp_svcdb_collect_all(int sock) { sdp_list_t *p, *q; - for (p=socket_index, q=0; p; ) { - sdp_indexed_t *item = (sdp_indexed_t *)p->data; + for (p = socket_index, q = 0; p; ) { + sdp_indexed_t *item = (sdp_indexed_t *) p->data; if (item->sock == sock) { sdp_list_t *next = p->next; sdp_record_remove(item->record->handle); @@ -111,8 +137,8 @@ void sdp_svcdb_collect(sdp_record_t *rec) { sdp_list_t *p, *q; - for (p=socket_index, q=0; p; q=p, p=p->next) { - sdp_indexed_t *item = (sdp_indexed_t *)p->data; + for (p = socket_index, q = 0; p; q = p, p = p->next) { + sdp_indexed_t *item = (sdp_indexed_t *) p->data; if (rec == item->record) { free(item); if (q) @@ -127,14 +153,14 @@ void sdp_svcdb_collect(sdp_record_t *rec) static int compare_indices(const void *i1, const void *i2) { - const sdp_indexed_t *s1 = (const sdp_indexed_t *)i1; - const sdp_indexed_t *s2 = (const sdp_indexed_t *)i2; + const sdp_indexed_t *s1 = (const sdp_indexed_t *) i1; + const sdp_indexed_t *s2 = (const sdp_indexed_t *) i2; return s1->sock - s2->sock; } void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) { - sdp_indexed_t *item = (sdp_indexed_t *)malloc(sizeof(sdp_indexed_t)); + sdp_indexed_t *item = malloc(sizeof(sdp_indexed_t)); item->sock = sock; item->record = record; socket_index = sdp_list_insert_sorted(socket_index, item, compare_indices); @@ -145,11 +171,22 @@ void sdp_svcdb_set_collectable(sdp_record_t *record, int sock) */ void sdp_record_add(bdaddr_t *device, sdp_record_t *rec) { + sdp_access_t *dev; + #ifdef SDP_DEBUG SDPDBG("Adding rec : 0x%lx\n", (long) rec); SDPDBG("with handle : 0x%x\n", rec->handle); #endif service_db = sdp_list_insert_sorted(service_db, rec, record_sort); + + dev = malloc(sizeof(*dev)); + if (!dev) + return; + + bacpy(&dev->device, device); + dev->handle = rec->handle; + + access_db = sdp_list_insert_sorted(access_db, dev, access_sort); } static sdp_list_t *record_locate(uint32_t handle) @@ -162,8 +199,24 @@ static sdp_list_t *record_locate(uint32_t handle) p = sdp_list_find(service_db, &r, record_sort); return p; } + SDPDBG("Could not find svcRec for : 0x%x\n", handle); - return 0; + return NULL; +} + +static sdp_list_t *access_locate(uint32_t handle) +{ + if (access_db) { + sdp_list_t *p; + sdp_access_t a; + + a.handle = handle; + p = sdp_list_find(access_db, &a, access_sort); + return p; + } + + SDPDBG("Could not find access data for : 0x%x\n", handle); + return NULL; } /* @@ -171,12 +224,14 @@ static sdp_list_t *record_locate(uint32_t handle) */ sdp_record_t *sdp_record_find(uint32_t handle) { - sdp_list_t *p = record_locate(handle); + sdp_list_t *p = record_locate(handle); + + if (!p) { + SDPDBG("Couldn't find record for : 0x%x\n", handle); + return 0; + } - if (p) - return (sdp_record_t *)p->data; - SDPDBG("Couldn't find record for : 0x%x\n", handle); - return 0; + return (sdp_record_t *) p->data; } /* @@ -185,26 +240,61 @@ sdp_record_t *sdp_record_find(uint32_t handle) int sdp_record_remove(uint32_t handle) { sdp_list_t *p = record_locate(handle); + sdp_record_t *r; + sdp_access_t *a; + + if (!p) { + SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); + return -1; + } + + r = (sdp_record_t *) p->data; + if (r) + service_db = sdp_list_remove(service_db, r); + p = access_locate(handle); if (p) { - sdp_record_t *r = (sdp_record_t *)p->data; - if (r) { - service_db = sdp_list_remove(service_db, r); - return 0; - } + a = (sdp_access_t *) p->data; + if (a) + access_db = sdp_list_remove(access_db, a); } - SDPERR("Remove : Couldn't find record for : 0x%x\n", handle); - return -1; + + return 0; } /* * Return a pointer to the linked list containing the records in sorted order */ -sdp_list_t *sdp_get_record_list() +sdp_list_t *sdp_get_record_list(void) { return service_db; } +sdp_list_t *sdp_get_access_list(void) +{ + return access_db; +} + +int sdp_check_access(uint32_t handle, bdaddr_t *device) +{ + sdp_list_t *p = access_locate(handle); + sdp_access_t *a; + + if (!p) + return 1; + + a = (sdp_access_t *) p->data; + if (!a) + return 1; + + if (bacmp(&a->device, device) && + bacmp(&a->device, BDADDR_ANY) && + bacmp(device, BDADDR_ANY)) + return 0; + + return 1; +} + uint32_t sdp_next_handle(void) { uint32_t handle = 0x10000; -- cgit From ef05ec89bbe7f2460d64e1206799c63913c71df5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 02:59:49 +0000 Subject: Use the new device specific functions --- tools/sdptool.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 3a2ce834..b3f4648c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -782,7 +782,7 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha } /* Update on the server */ - if (sdp_record_update(sess, rec)) { + if (sdp_device_record_update(sess, &interface, rec)) { printf("Service Record update failed (%d).\n", errno); return -1; } @@ -904,7 +904,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri sdp_attr_replace(rec, attrib, pSequenceHolder); /* Update on the server */ - if (sdp_record_update(session, rec)) { + if (sdp_device_record_update(session, &interface, rec)) { printf("Service Record update failed (%d).\n", errno); return -1; } @@ -1170,7 +1170,7 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Serial Port", 0, "COM Port"); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1228,7 +1228,7 @@ static int add_dun(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Dial-Up Networking", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1284,7 +1284,7 @@ static int add_lan(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "LAN Access over PPP", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1343,7 +1343,7 @@ static int add_headset(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Headset", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1405,7 +1405,7 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Handsfree", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1467,7 +1467,7 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "SIM Access", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1525,7 +1525,7 @@ static int add_fax(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Fax", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1598,7 +1598,7 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "OBEX Object Push", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1659,7 +1659,7 @@ static int add_ftp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "OBEX File Transfer", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1732,7 +1732,7 @@ static int add_nap(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Network Access Point Service", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1791,7 +1791,7 @@ static int add_gn(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Group Network Service", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1853,7 +1853,7 @@ static int add_panu(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "PAN User", NULL, NULL); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1910,7 +1910,7 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Cordless Telephony", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto end; @@ -1968,7 +1968,7 @@ static int add_a2source(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Audio Source", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto done; @@ -2027,7 +2027,7 @@ static int add_a2sink(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Audio Sink", 0, 0); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); ret = -1; goto done; @@ -2078,7 +2078,7 @@ static int add_syncml(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "SyncML Client", NULL, NULL); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); return -1; } @@ -2112,7 +2112,7 @@ static int add_nokiaid(sdp_session_t *session, svc_info_t *si) sdp_attr_add(&record, SDP_ATTR_SERVICE_VERSION, version); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); sdp_data_free(version); return -1; @@ -2155,7 +2155,7 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "Nokia PC Suite", NULL, NULL); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); return -1; } @@ -2187,7 +2187,7 @@ static int add_sr1(sdp_session_t *session, svc_info_t *si) sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL); - if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { printf("Service Record registration failed\n"); return -1; } @@ -2327,7 +2327,7 @@ static int del_service(bdaddr_t *bdaddr, void *arg) return -1; } - if (sdp_record_unregister(sess, rec)) { + if (sdp_device_record_unregister(sess, &interface, rec)) { printf("Failed to unregister service record: %s\n", strerror(errno)); sdp_close(sess); return -1; -- cgit From 60c5a5c604ce503104b6de2dd52ff5ef9df521e4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 03:04:36 +0000 Subject: Don't install bluetoothd at the moment --- daemon/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index df307144..9eacf7da 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -3,7 +3,7 @@ # if DBUS -sbin_PROGRAMS = bluetoothd +noinst_PROGRAMS = bluetoothd bluetoothd_SOURCES = main.c -- cgit From 8ac83f1424fe8c726aeeccda705c6840d5b31ab9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 03:24:28 +0000 Subject: Correctly terminate the device name string --- tools/hciconfig.c | 3 ++- tools/hcitool.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 4dfb57a7..ca44831f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -437,7 +437,7 @@ static void cmd_name(int ctl, int hdev, char *opt) exit(1); } } else { - char name[248]; + char name[249]; int i; if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n", @@ -447,6 +447,7 @@ static void cmd_name(int ctl, int hdev, char *opt) for (i = 0; i < 248 && name[i]; i++) if (!isprint(name[i])) name[i] = '.'; + name[248] = '\0'; print_dev_hdr(&di); printf("\tName: '%s'\n", name); } diff --git a/tools/hcitool.c b/tools/hcitool.c index 156b0790..ba8ba823 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -514,6 +514,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (n = 0; n < 248 && name[n]; n++) if (!isprint(name[n])) name[n] = '.'; + name[248] = '\0'; printf("\t%s\t%s\n", addr, name); continue; @@ -572,6 +573,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) for (n = 0; n < 248 && name[n]; n++) if (!isprint(name[n])) name[n] = '.'; + name[248] = '\0'; nc = 0; } } -- cgit From 1a3907a17151a5cdae2d395865a2951090c07ac5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 03:26:40 +0000 Subject: Replace non-printable characters in the device name --- hcid/security.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/hcid/security.c b/hcid/security.c index 108887ce..7dfa4a17 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -33,22 +33,18 @@ #endif #include -#include +#include +#include +#include #include +#include +#include #include #include -#include #include -#include -#include -#include #include - #include #include -#include -#include -#include #include #include @@ -308,7 +304,7 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) struct sigaction sa; char addr[18], str[255], *pin, name[249]; FILE *pipe; - int ret, len; + int i, ret, len; /* Run PIN helper in the separate process */ switch (fork()) { @@ -331,6 +327,11 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) read_device_name(sba, &ci->bdaddr, name); //hci_remote_name(dev, &ci->bdaddr, sizeof(name), name, 0); + for (i = 0; i < 248 && name[i]; i++) + if (!isprint(name[i])) + name[i] = '.'; + name[248] = '\0'; + ba2str(&ci->bdaddr, addr); snprintf(str, sizeof(str), "%s %s %s \'%s\'", hcid.pin_helper, ci->out ? "out" : "in", addr, name); -- cgit From 69ae05c1fc41eba63442939e1ea69433271de3da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 03:52:04 +0000 Subject: Most X servers are now Xorg --- scripts/bluepin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bluepin b/scripts/bluepin index 607facba..741765b7 100755 --- a/scripts/bluepin +++ b/scripts/bluepin @@ -15,7 +15,7 @@ pygtk.require('2.0') def set_display(): disp = ":0" auth = "" - proc = "-C X -C XFree86" + proc = "-C X -C Xorg -C XFree86" ps = "/bin/ps " + proc + " --format args --no-headers" r,w = popen2.popen2(ps) -- cgit From e41fb20b888901da7c29bc9fa096f6cc4b6b3542 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 04:28:34 +0000 Subject: Fix security problem with escape characters in device name --- hcid/security.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/hcid/security.c b/hcid/security.c index 7dfa4a17..718fff3d 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -302,7 +302,7 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) { pin_code_reply_cp pr; struct sigaction sa; - char addr[18], str[255], *pin, name[249]; + char addr[18], str[512], *pin, name[249], tmp[499], *ptr; FILE *pipe; int i, ret, len; @@ -327,14 +327,20 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) read_device_name(sba, &ci->bdaddr, name); //hci_remote_name(dev, &ci->bdaddr, sizeof(name), name, 0); + memset(tmp, 0, sizeof(tmp)); + ptr = tmp; + for (i = 0; i < 248 && name[i]; i++) - if (!isprint(name[i])) - name[i] = '.'; - name[248] = '\0'; + if (isprint(name[i])) { + if (name[i] == '"') + *ptr++ = '\\'; + *ptr++ = name[i]; + } else + *ptr++ = '.'; ba2str(&ci->bdaddr, addr); - snprintf(str, sizeof(str), "%s %s %s \'%s\'", hcid.pin_helper, - ci->out ? "out" : "in", addr, name); + snprintf(str, sizeof(str), "%s %s %s \"%s\"", hcid.pin_helper, + ci->out ? "out" : "in", addr, tmp); setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1); -- cgit From 6bba8994c83cb007356c0b358bdc5dda9bdff59a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 05:37:39 +0000 Subject: Escape more shell specific characters --- hcid/security.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/hcid/security.c b/hcid/security.c index 718fff3d..fb4c813e 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -302,7 +302,7 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) { pin_code_reply_cp pr; struct sigaction sa; - char addr[18], str[512], *pin, name[249], tmp[499], *ptr; + char addr[18], str[512], *pin, name[249], tmp[497], *ptr; FILE *pipe; int i, ret, len; @@ -332,8 +332,13 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) for (i = 0; i < 248 && name[i]; i++) if (isprint(name[i])) { - if (name[i] == '"') + switch (name[i]) { + case '"': + case '`': + case '$': + case '\\': *ptr++ = '\\'; + } *ptr++ = name[i]; } else *ptr++ = '.'; -- cgit From ad3049f07e580ee1ffb235afea1e368c4c46a639 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 07:34:55 +0000 Subject: Use bt_free() to free the memory allocated by lmp_featurestostr() --- tools/hciconfig.c | 12 +++++++++--- tools/hcitool.c | 14 +++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index ca44831f..745ed74f 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -109,8 +109,11 @@ static void print_dev_features(struct hci_dev_info *di, int format) di->features[3], di->features[4], di->features[5], di->features[6], di->features[7]); - if (format) - printf("%s\n", lmp_featurestostr(di->features, "\t\t", 63)); + if (format) { + char *tmp = lmp_featurestostr(di->features, "\t\t", 63); + printf("%s\n", tmp); + bt_free(tmp); + } } static void cmd_rstat(int ctl, int hdev, char *opt) @@ -379,6 +382,7 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) static void cmd_features(int ctl, int hdev, char *opt) { uint8_t max_page, features[8]; + char *tmp; int i, dd; if (!(di.features[7] & LMP_EXT_FEAT)) { @@ -401,12 +405,14 @@ static void cmd_features(int ctl, int hdev, char *opt) } print_dev_hdr(&di); + tmp = lmp_featurestostr(di.features, "\t\t", 63); printf("\tFeatures%s: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x " "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", (max_page > 0) ? " page 0" : "", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7]); - printf("%s\n", lmp_featurestostr(di.features, "\t\t", 63)); + printf("%s\n", tmp); + bt_free(tmp); for (i = 1; i <= max_page; i++) { if (hci_read_local_ext_features(dd, 1, &max_page, features, 1000) < 0) diff --git a/tools/hcitool.c b/tools/hcitool.c index ba8ba823..bc09ea07 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -379,7 +379,8 @@ static void cmd_inq(int dev_id, int argc, char **argv) (info+i)->dev_class[1], (info+i)->dev_class[0]); } - free(info); + + bt_free(info); } /* Device scanning */ @@ -603,13 +604,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + char *tmp = lmp_featurestostr(features, "\t\t", 63); printf("LMP features:\t0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x" " 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", features[0], features[1], features[2], features[3], features[4], features[5], features[6], features[7]); - printf("%s\n", lmp_featurestostr(features, "\t\t", 63)); + printf("%s\n", tmp); + bt_free(tmp); } if (cc) { @@ -622,7 +625,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) } close(dd); - free(info); + bt_free(info); } /* Remote name */ @@ -786,10 +789,11 @@ static void cmd_info(int dev_id, int argc, char **argv) } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { + char *tmp = lmp_featurestostr(features, "\t\t", 63); printf("\tFeatures: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n%s\n", features[0], features[1], features[2], features[3], - features[4], features[5], features[6], features[7], - lmp_featurestostr(features, "\t\t", 63)); + features[4], features[5], features[6], features[7], tmp); + bt_free(tmp); } if (features[7] & LMP_EXT_FEAT) { -- cgit From 1b67c5337c0704d147ed5e2ce143e553a79a43c5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 08:43:42 +0000 Subject: Update the textfile library --- common/textfile.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- common/textfile.h | 4 ++-- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/common/textfile.c b/common/textfile.c index 0bda2a94..ca6f08f3 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -39,12 +39,51 @@ #include #include #include +#include -static int write_key_value(const int fd, const char *key, const char *value) +static int create_dirs(char *filename, mode_t mode) +{ + struct stat st; + char dir[PATH_MAX + 1], *prev, *next; + int err; + + err = stat(filename, &st); + if (!err && S_ISREG(st.st_mode)) + return 0; + + memset(dir, 0, PATH_MAX + 1); + strcat(dir, "/"); + + prev = strchr(filename, '/'); + + while (prev) { + next = strchr(prev + 1, '/'); + if (!next) + break; + + if (next - prev == 1) { + prev = next; + continue; + } + + strncat(dir, prev + 1, next - prev); + mkdir(dir, mode); + + prev = next; + } + + return 0; +} + +static int write_key_value(int fd, char *key, char *value) { char *str; int size, err = 0; + /* This check is needed, because other it will segfault */ + if (strlen(value) == 9) + return -EIO; + size = strlen(key) + strlen(value) + 2; str = malloc(size); @@ -61,7 +100,7 @@ static int write_key_value(const int fd, const char *key, const char *value) return err; } -int textfile_put(const char *pathname, const char *key, const char *value) +int textfile_put(char *pathname, char *key, char *value) { struct stat st; char *map, *off, *end, *str; @@ -90,7 +129,7 @@ int textfile_put(const char *pathname, const char *key, const char *value) goto unlock; } - map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, fd, 0); if (map == MAP_FAILED) { err = errno; goto unlock; @@ -129,6 +168,11 @@ int textfile_put(const char *pathname, const char *key, const char *value) len = size - (end - map); + if (len <= 0 || len > size) { + err = EILSEQ; + goto unmap; + } + str = malloc(len); if (!str) { err = errno; @@ -161,7 +205,7 @@ close: return -err; } -char *textfile_get(const char *pathname, const char *key) +char *textfile_get(char *pathname, char *key) { struct stat st; char *map, *off, *end, *str = NULL; diff --git a/common/textfile.h b/common/textfile.h index 8871f53c..4f3cf3d4 100644 --- a/common/textfile.h +++ b/common/textfile.h @@ -26,5 +26,5 @@ * $Id$ */ -int textfile_put(const char *pathname, const char *key, const char *value); -char *textfile_get(const char *pathname, const char *key); +int textfile_put(char *pathname, char *key, char *value); +char *textfile_get(char *pathname, char *key); -- cgit From f5cf0bce5206b17ae6ce1661a15253bef5827eaf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 08:45:17 +0000 Subject: Use more textfile functions and remove usage of const attribute --- hcid/dbus.c | 4 +- hcid/hcid.h | 22 +-- hcid/security.c | 28 ++-- hcid/storage.c | 506 ++++++-------------------------------------------------- 4 files changed, 84 insertions(+), 476 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index d8a07dd9..7f98c32f 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -170,7 +170,7 @@ failed: OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); } -void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer, const uint32_t class, const int8_t rssi) +void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) { DBusMessage *message; #ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS @@ -217,7 +217,7 @@ failed: return; } -void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) +void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) { DBusMessage *message; #ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS diff --git a/hcid/hcid.h b/hcid/hcid.h index 3ba69833..4a433984 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -123,21 +123,21 @@ void toggle_pairing(int enable); #ifdef ENABLE_DBUS gboolean hcid_dbus_init(void); void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); -void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer, const uint32_t class, const int8_t rssi); -void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); +void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi); +void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name); #else -static inline void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer, uint32_t class, const int8_t rssi) +static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) { } -static inline void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) +static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) { } #endif -int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); -int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name); -int write_version_info(const bdaddr_t *local, const bdaddr_t *peer, const uint16_t manufacturer, const uint8_t lmp_ver, const uint16_t lmp_subver); -int write_features_info(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *features); -int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type); -int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key); -int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin); +int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); +int read_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); +int write_version_info(bdaddr_t *local, bdaddr_t *peer, uint16_t manufacturer, uint8_t lmp_ver, uint16_t lmp_subver); +int write_features_info(bdaddr_t *local, bdaddr_t *peer, unsigned char *features); +int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, int type); +int read_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key); +int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin); diff --git a/hcid/security.c b/hcid/security.c index fb4c813e..ab22f14d 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -69,7 +69,7 @@ void toggle_pairing(int enable) syslog(LOG_INFO, "Pairing %s", pairing ? "enabled" : "disabled"); } -static int get_bdaddr(int dev, bdaddr_t *sba, uint16_t handle, bdaddr_t *dba) +static inline int get_bdaddr(int dev, bdaddr_t *sba, uint16_t handle, bdaddr_t *dba) { struct hci_conn_list_req *cl; struct hci_conn_info *ci; @@ -340,8 +340,10 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) *ptr++ = '\\'; } *ptr++ = name[i]; - } else + } else { + name[i] = '.'; *ptr++ = '.'; + } ba2str(&ci->bdaddr, addr); snprintf(str, sizeof(str), "%s %s %s \"%s\"", hcid.pin_helper, @@ -475,20 +477,26 @@ reject: return; } -static void remote_name_information(int dev, bdaddr_t *sba, void *ptr) +static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr) { evt_remote_name_req_complete *evt = ptr; - bdaddr_t *dba = &evt->bdaddr; + char name[249]; + bdaddr_t dba; if (evt->status) return; - hcid_dbus_remote_name(sba, dba, (char *) evt->name); + memset(name, 0, sizeof(name)); + memcpy(name, evt->name, 248); + + bacpy(&dba, &evt->bdaddr); + + hcid_dbus_remote_name(sba, &dba, name); - write_device_name(sba, dba, (char *) evt->name); + write_device_name(sba, &dba, name); } -static void remote_version_information(int dev, bdaddr_t *sba, void *ptr) +static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr) { evt_read_remote_version_complete *evt = ptr; bdaddr_t dba; @@ -503,7 +511,7 @@ static void remote_version_information(int dev, bdaddr_t *sba, void *ptr) evt->lmp_ver, btohs(evt->lmp_subver)); } -static void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) +static inline void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) { uint8_t num = *(uint8_t *) ptr++; int i; @@ -520,7 +528,7 @@ static void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) } } -static void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr) +static inline void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr) { uint8_t num = *(uint8_t *) ptr++; int i; @@ -555,7 +563,7 @@ static void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr } } -static void remote_features_information(int dev, bdaddr_t *sba, void *ptr) +static inline void remote_features_information(int dev, bdaddr_t *sba, void *ptr) { evt_read_remote_features_complete *evt = ptr; bdaddr_t dba; diff --git a/hcid/storage.c b/hcid/storage.c index 459ebff6..63bf3397 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -48,129 +48,16 @@ #include "textfile.h" #include "hcid.h" -struct list { - bdaddr_t bdaddr; - unsigned char *data; - size_t size; - struct list *next; -}; - -static struct list *list_add(struct list *list, const bdaddr_t *bdaddr, - const char *data, const size_t size) -{ - struct list *temp = list, *last = list; - - if (!bacmp(bdaddr, BDADDR_ANY)) - return list; - - while (temp) { - if (!bacmp(&temp->bdaddr, bdaddr)) { - if (temp->data) - free(temp->data); - - temp->data = malloc(size); - if (temp->data) { - memcpy(temp->data, data, size); - temp->size = size; - } else - temp->size = 0; - - return list; - } - temp = temp->next; - } - - temp = malloc(sizeof(*temp)); - if (!temp) - return list; - - memset(temp, 0, sizeof(*temp)); - - bacpy(&temp->bdaddr, bdaddr); - temp->data = malloc(size); - if (temp->data) { - memcpy(temp->data, data, size); - temp->size = size; - } else - temp->size = 0; - - temp->next = NULL; - - if (!list) - return temp; - - while (last->next) - last = last->next; - - last->next = temp; - - return list; -} - -static struct list *list_free(struct list *list) -{ - struct list *temp = list; - - if (!list) - return NULL; - - while (list->next) { - temp = list; - list = list->next; - if (temp->data) - free(temp->data); - free(temp); - } - - return NULL; -} - -#define list_foreach(list, entry) \ - for (entry = list; entry; entry = entry->next) - -static int create_dirs(const char *filename, mode_t mode) -{ - struct stat st; - char dir[PATH_MAX + 1], *prev, *next; - int err; - - err = stat(filename, &st); - if (!err && S_ISREG(st.st_mode)) - return 0; - - memset(dir, 0, PATH_MAX + 1); - strcat(dir, "/"); - - prev = strchr(filename, '/'); - - while (prev) { - next = strchr(prev + 1, '/'); - if (!next) - break; - - if (next - prev == 1) { - prev = next; - continue; - } - - strncat(dir, prev + 1, next - prev); - mkdir(dir, mode); - - prev = next; - } - - return 0; -} - -int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) +int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name) { char filename[PATH_MAX + 1], addr[18], str[249]; int i; memset(str, 0, sizeof(str)); - strncpy(str, name, 248); - for (i = 0; i < 248 && str[i]; i++) - if (!isprint(str[i])) + for (i = 0; i < 248 && name[i]; i++) + if (isprint(name[i])) + str[i] = name[i]; + else str[i] = '.'; ba2str(local, addr); @@ -180,9 +67,10 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n return textfile_put(filename, addr, str); } -int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) +int read_device_name(bdaddr_t *local, bdaddr_t *peer, char *name) { char filename[PATH_MAX + 1], addr[18], *str; + int len; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); @@ -192,386 +80,98 @@ int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) if (!str) return -ENOENT; - memset(name, 0, 249); - strncpy(name, str, 248); + len = strlen(str); + if (len > 248) + str[248] = '\0'; + strcpy(name, str); return 0; } -int write_version_info(const bdaddr_t *local, const bdaddr_t *peer, const uint16_t manufacturer, const uint8_t lmp_ver, const uint16_t lmp_subver) +int write_version_info(bdaddr_t *local, bdaddr_t *peer, uint16_t manufacturer, uint8_t lmp_ver, uint16_t lmp_subver) { - struct list *temp, *list = NULL; - char filename[PATH_MAX + 1], addr[18], str[16], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int fd, pos, err = 0; - - ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr); - - umask(S_IWGRP | S_IWOTH); - create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - - fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_EX) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size + 100); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - list = list_add(list, &bdaddr, str, sizeof(str)); - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - - lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); - } + char filename[PATH_MAX + 1], addr[18], str[16]; memset(str, 0, sizeof(str)); sprintf(str, "%d %d %d", manufacturer, lmp_ver, lmp_subver); - list = list_add(list, peer, str, sizeof(str)); - if (!list) { - err = -EIO; - goto unlock; - } - - list_foreach(list, temp) { - ba2str(&temp->bdaddr, addr); - if (temp->data && temp->size > 0) { - memset(buf, 0, 100); - snprintf(buf, 99, "%s %s\n", addr, temp->data); - write(fd, buf, strlen(buf)); - } - } - -unlock: - flock(fd, LOCK_UN); + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr); -close: - close(fd); - list_free(list); - return err; + ba2str(peer, addr); + return textfile_put(filename, addr, str); } -int write_features_info(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *features) +int write_features_info(bdaddr_t *local, bdaddr_t *peer, unsigned char *features) { - struct list *temp, *list = NULL; - char filename[PATH_MAX + 1], addr[18], str[17], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int i, fd, pos, err = 0; - - ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/features", STORAGEDIR, addr); - - umask(S_IWGRP | S_IWOTH); - create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - - fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_EX) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size + 100); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - list = list_add(list, &bdaddr, str, sizeof(str)); - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - - lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); - } + char filename[PATH_MAX + 1], addr[18], str[17]; + int i; memset(str, 0, sizeof(str)); for (i = 0; i < 8; i++) sprintf(str + (i * 2), "%2.2X", features[i]); - list = list_add(list, peer, str, sizeof(str)); - if (!list) { - err = -EIO; - goto unlock; - } - - list_foreach(list, temp) { - ba2str(&temp->bdaddr, addr); - if (temp->data && temp->size > 0) { - memset(buf, 0, 100); - snprintf(buf, 99, "%s %s\n", addr, temp->data); - write(fd, buf, strlen(buf)); - } - } - -unlock: - flock(fd, LOCK_UN); + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/features", STORAGEDIR, addr); -close: - close(fd); - list_free(list); - return err; + ba2str(peer, addr); + return textfile_put(filename, addr, str); } -int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type) +int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, int type) { - struct list *temp, *list = NULL; - char filename[PATH_MAX + 1], addr[18], str[35], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int i, fd, pos, err = 0; - - ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); - - umask(S_IWGRP | S_IWOTH); - create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - - fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_EX) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size + 100); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - list = list_add(list, &bdaddr, str, sizeof(str)); - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - - lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); - } + char filename[PATH_MAX + 1], addr[18], str[35]; + int i; memset(str, 0, sizeof(str)); for (i = 0; i < 16; i++) sprintf(str + (i * 2), "%2.2X", key[i]); sprintf(str + 32, " %d", type); - list = list_add(list, peer, str, sizeof(str)); - if (!list) { - err = -EIO; - goto unlock; - } - - list_foreach(list, temp) { - ba2str(&temp->bdaddr, addr); - if (temp->data && temp->size > 0) { - memset(buf, 0, 100); - snprintf(buf, 99, "%s %s\n", addr, temp->data); - write(fd, buf, strlen(buf)); - } - } - -unlock: - flock(fd, LOCK_UN); + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); -close: - close(fd); - list_free(list); - return err; + ba2str(peer, addr); + return textfile_put(filename, addr, str); } -int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key) +int read_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key) { - char filename[PATH_MAX + 1], addr[18], str[35], tmp[3], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int i, fd, pos, err = -ENOENT; + char filename[PATH_MAX + 1], addr[18], tmp[3], *str; + int i; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); - fd = open(filename, O_RDONLY); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_SH) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size); - if (!buf) { - err = -ENOMEM; - goto unlock; - } + ba2str(peer, addr); + str = textfile_get(filename, addr); + if (!str) + return -ENOENT; - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - if (!bacmp(&bdaddr, peer)) { - memset(tmp, 0, sizeof(tmp)); - for (i = 0; i < 16; i++) { - memcpy(tmp, str + (i * 2), 2); - key[i] = (uint8_t) strtol(tmp, NULL, 16); - } - err = 0; - break; - } - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; + memset(tmp, 0, sizeof(tmp)); + for (i = 0; i < 16; i++) { + memcpy(tmp, str + (i * 2), 2); + key[i] = (uint8_t) strtol(tmp, NULL, 16); } -unlock: - flock(fd, LOCK_UN); - -close: - close(fd); - return err; + return 0; } -int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin) +int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin) { - char filename[PATH_MAX + 1], addr[18], str[17], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int fd, pos, err = -ENOENT; + char filename[PATH_MAX + 1], addr[18], *str; + int len; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/pincodes", STORAGEDIR, addr); - fd = open(filename, O_RDONLY); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_SH) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - if (!bacmp(&bdaddr, peer)) { - strncpy(pin, str, 16); - err = strlen(pin); - break; - } - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - } + ba2str(peer, addr); + str = textfile_get(filename, addr); + if (!str) + return -ENOENT; -unlock: - flock(fd, LOCK_UN); + strncpy(pin, str, 16); + len = strlen(pin); -close: - close(fd); - return err; + return len; } -- cgit From 6419dcad3732c1be03bbe570c6c64c82b33ad599 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 11:07:34 +0000 Subject: Add textfile regression test --- common/Makefile.am | 4 +++ common/test_textfile.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 common/test_textfile.c diff --git a/common/Makefile.am b/common/Makefile.am index ffcddf6e..3cc9318d 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -6,4 +6,8 @@ noinst_LIBRARIES = libtextfile.a libtextfile_a_SOURCES = textfile.h textfile.c +noinst_PROGRAMS = test_textfile + +test_textfile_LDADD = libtextfile.a + MAINTAINERCLEANFILES = Makefile.in diff --git a/common/test_textfile.c b/common/test_textfile.c new file mode 100644 index 00000000..88579296 --- /dev/null +++ b/common/test_textfile.c @@ -0,0 +1,66 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "textfile.h" + +int main(int argc, char *argv[]) +{ + char filename[] = "/tmp/textfile"; + char key[18], value[512]; + int i, j, fd; + + fd = creat(filename, 0644); + close(fd); + + for (i = 1; i < 101; i++) { + sprintf(key, "00:00:00:00:00:%02X", i); + + memset(value, 0, sizeof(value)); + for (j = 0; j < i; j++) + value[j] = 'x'; + + printf("%s %s\n", key, value); + + if (textfile_put(filename, key, value) < 0) { + fprintf(stderr, "%s (%d)\n", strerror(errno), errno); + break; + } + } + + return 0; +} -- cgit From 7d19ed074bfea793e960c4f86af8085251ba613a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 6 Aug 2005 06:27:05 +0000 Subject: Fix off by one memory allocation error --- common/textfile.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/common/textfile.c b/common/textfile.c index ca6f08f3..08cd5a9f 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -75,18 +75,15 @@ static int create_dirs(char *filename, mode_t mode) return 0; } -static int write_key_value(int fd, char *key, char *value) +static inline int write_key_value(int fd, char *key, char *value) { char *str; - int size, err = 0; - - /* This check is needed, because other it will segfault */ - if (strlen(value) == 9) - return -EIO; + size_t size; + int err = 0; size = strlen(key) + strlen(value) + 2; - str = malloc(size); + str = malloc(size + 1); if (!str) return ENOMEM; -- cgit From 3e6da0a081eef2c4498ee045b30392e39a92dc5a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 6 Aug 2005 06:27:40 +0000 Subject: Add test for reading values --- common/test_textfile.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/test_textfile.c b/common/test_textfile.c index 88579296..54202d2c 100644 --- a/common/test_textfile.c +++ b/common/test_textfile.c @@ -41,7 +41,7 @@ int main(int argc, char *argv[]) { char filename[] = "/tmp/textfile"; - char key[18], value[512]; + char key[18], value[512], *str; int i, j, fd; fd = creat(filename, 0644); @@ -60,6 +60,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "%s (%d)\n", strerror(errno), errno); break; } + + str = textfile_get(filename, key); + if (!str) + fprintf(stderr, "No value for %s\n", key); } return 0; -- cgit From 7ba9b7fda144865222a5d254b36bf484d5af99e7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 6 Aug 2005 06:42:20 +0000 Subject: Use bt_free() instead of free() for inquiry results --- dund/main.c | 2 +- hidd/main.c | 2 +- pand/main.c | 2 +- tools/ciptool.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dund/main.c b/dund/main.c index a620c8de..ca841aeb 100644 --- a/dund/main.c +++ b/dund/main.c @@ -348,7 +348,7 @@ static int do_connect(void) break; } } - free(ii); + bt_free(ii); } while (!terminate && persist); return r; diff --git a/hidd/main.c b/hidd/main.c index 98a8f12a..9ff02705 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -477,7 +477,7 @@ static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int nosdp, in } } - free(info); + bt_free(info); if (!num_rsp) { fprintf(stderr, "\tNo devices in range or visible\n"); diff --git a/pand/main.c b/pand/main.c index 20fbec19..72e607a9 100644 --- a/pand/main.c +++ b/pand/main.c @@ -393,7 +393,7 @@ static int do_connect(void) break; } } - free(ii); + bt_free(ii); } while (!terminate && persist); return r; diff --git a/tools/ciptool.c b/tools/ciptool.c index 38446f93..263e0573 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -256,7 +256,7 @@ static void cmd_search(int ctl, bdaddr_t *bdaddr, int argc, char **argv) if (!get_psm(&src, &dst, &psm)) continue; - free(info); + bt_free(info); printf("\tConnecting to device %s\n", addr); do_connect(ctl, dev_id, &src, &dst, psm, 0); @@ -264,7 +264,7 @@ static void cmd_search(int ctl, bdaddr_t *bdaddr, int argc, char **argv) } } - free(info); + bt_free(info); fprintf(stderr, "\tNo devices in range or visible\n"); exit(1); } -- cgit From 81b4c05b47e57505f56742b9349bee21116ba704 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 6 Aug 2005 07:00:03 +0000 Subject: Remove the create_dirs() function --- common/textfile.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/common/textfile.c b/common/textfile.c index 08cd5a9f..a5d0a58b 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -41,40 +41,6 @@ #include #include -static int create_dirs(char *filename, mode_t mode) -{ - struct stat st; - char dir[PATH_MAX + 1], *prev, *next; - int err; - - err = stat(filename, &st); - if (!err && S_ISREG(st.st_mode)) - return 0; - - memset(dir, 0, PATH_MAX + 1); - strcat(dir, "/"); - - prev = strchr(filename, '/'); - - while (prev) { - next = strchr(prev + 1, '/'); - if (!next) - break; - - if (next - prev == 1) { - prev = next; - continue; - } - - strncat(dir, prev + 1, next - prev); - mkdir(dir, mode); - - prev = next; - } - - return 0; -} - static inline int write_key_value(int fd, char *key, char *value) { char *str; -- cgit From e0af13c92c3e65d7fdca1f9699e8c4208fcd0293 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 6 Aug 2005 07:02:57 +0000 Subject: Create directories before calling the textfile functions --- hcid/storage.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/hcid/storage.c b/hcid/storage.c index 63bf3397..eed3e694 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -48,6 +48,56 @@ #include "textfile.h" #include "hcid.h" +static int create_dirs(char *filename, mode_t mode) +{ + struct stat st; + char dir[PATH_MAX + 1], *prev, *next; + int err; + + err = stat(filename, &st); + if (!err && S_ISREG(st.st_mode)) + return 0; + + memset(dir, 0, PATH_MAX + 1); + strcat(dir, "/"); + + prev = strchr(filename, '/'); + + while (prev) { + next = strchr(prev + 1, '/'); + if (!next) + break; + + if (next - prev == 1) { + prev = next; + continue; + } + + strncat(dir, prev + 1, next - prev); + mkdir(dir, mode); + + prev = next; + } + + return 0; +} + +static inline int create_file(char *filename, mode_t mode) +{ + int fd; + + umask(S_IWGRP | S_IWOTH); + create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + + fd = open(filename, O_RDWR | O_CREAT, mode); + if (fd < 0) + return fd; + + close(fd); + + return 0; +} + int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name) { char filename[PATH_MAX + 1], addr[18], str[249]; @@ -63,6 +113,8 @@ int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name) ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); + create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + ba2str(peer, addr); return textfile_put(filename, addr, str); } @@ -98,6 +150,8 @@ int write_version_info(bdaddr_t *local, bdaddr_t *peer, uint16_t manufacturer, u ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr); + create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + ba2str(peer, addr); return textfile_put(filename, addr, str); } @@ -114,6 +168,8 @@ int write_features_info(bdaddr_t *local, bdaddr_t *peer, unsigned char *features ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/features", STORAGEDIR, addr); + create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + ba2str(peer, addr); return textfile_put(filename, addr, str); } @@ -131,6 +187,8 @@ int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, int type ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); + create_file(filename, S_IRUSR | S_IWUSR); + ba2str(peer, addr); return textfile_put(filename, addr, str); } -- cgit From ddefb55b4fec8598ce8ec0bc78e8321030269f59 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 6 Aug 2005 08:20:44 +0000 Subject: Update changelog and bump version number --- ChangeLog | 10 ++++++++++ configure.in | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 0d69d477..a67f3ce8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +ver 2.19: + Fix the GCC 4.0 warnings. + Fix off by one memory allocation error. + Fix security problem with escape characters in device name. + Send D-Bus signals for inquiry results and remote name resolves. + Add support for device specific SDP records. + + Note: + This version needs at least bluez-libs-2.19 + ver 2.18: Support D-Bus 0.23 and 0.33 API versions. Support reading of complex BCCMD values. diff --git a/configure.in b/configure.in index e965827c..ad75274c 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.18) +AM_INIT_AUTOMAKE(bluez-utils, 2.19) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From 76823d4777869743af04038d82705cd7249657b8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Aug 2005 06:22:38 +0000 Subject: Use device specific service record register function --- dund/dund.h | 2 +- dund/main.c | 2 +- dund/sdp.c | 4 ++-- pand/main.c | 2 +- pand/pand.h | 2 +- pand/sdp.c | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dund/dund.h b/dund/dund.h index 92626310..97c54174 100644 --- a/dund/dund.h +++ b/dund/dund.h @@ -45,6 +45,6 @@ int dun_kill_all_connections(void); int dun_open_connection(int sk, char *pppd, char **pppd_opts, int wait); /* SDP functions */ -int dun_sdp_register(uint8_t channel, int mrouter); +int dun_sdp_register(bdaddr_t *device, uint8_t channel, int mrouter); void dun_sdp_unregister(void); int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int mrouter); diff --git a/dund/main.c b/dund/main.c index ca841aeb..b00ccab7 100644 --- a/dund/main.c +++ b/dund/main.c @@ -122,7 +122,7 @@ static int do_listen(void) channel = DUN_DEFAULT_CHANNEL; if (use_sdp) - dun_sdp_register(channel, mrouter); + dun_sdp_register(&src_addr, channel, mrouter); if (mrouter) syslog(LOG_INFO, "Waiting for mRouter callback on channel %d", channel); diff --git a/dund/sdp.c b/dund/sdp.c index 45060e81..16ef09f4 100644 --- a/dund/sdp.c +++ b/dund/sdp.c @@ -56,7 +56,7 @@ void dun_sdp_unregister(void) sdp_close(session); } -int dun_sdp_register(uint8_t channel, int mrouter) +int dun_sdp_register(bdaddr_t *device, uint8_t channel, int mrouter) { sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; uuid_t root_uuid, l2cap, rfcomm, dun; @@ -104,7 +104,7 @@ int dun_sdp_register(uint8_t channel, int mrouter) sdp_set_info_attr(record, mrouter ? "mRouter" : "LAN Access Point", NULL, NULL); - status = sdp_record_register(session, record, 0); + status = sdp_device_record_register(session, device, record, 0); if (status) { syslog(LOG_ERR, "SDP registration failed."); sdp_record_free(record); record = NULL; diff --git a/pand/main.c b/pand/main.c index 72e607a9..b5a4ee95 100644 --- a/pand/main.c +++ b/pand/main.c @@ -131,7 +131,7 @@ static int do_listen(void) int sk, lm; if (use_sdp) - bnep_sdp_register(role); + bnep_sdp_register(&src_addr, role); /* Create L2CAP socket and bind it to PSM BNEP */ sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); diff --git a/pand/pand.h b/pand/pand.h index b0052676..2981168b 100644 --- a/pand/pand.h +++ b/pand/pand.h @@ -46,6 +46,6 @@ int bnep_accept_connection(int sk, uint16_t role, char *dev); int bnep_create_connection(int sk, uint16_t role, uint16_t svc, char *dev); /* SDP functions */ -int bnep_sdp_register(uint16_t role); +int bnep_sdp_register(bdaddr_t *device, uint16_t role); void bnep_sdp_unregister(void); int bnep_sdp_search(bdaddr_t *src, bdaddr_t *dst, uint16_t service); diff --git a/pand/sdp.c b/pand/sdp.c index 85edc681..802887b1 100644 --- a/pand/sdp.c +++ b/pand/sdp.c @@ -58,7 +58,7 @@ void bnep_sdp_unregister(void) sdp_close(session); } -int bnep_sdp_register(uint16_t role) +int bnep_sdp_register(bdaddr_t *device, uint16_t role) { sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; uuid_t root_uuid, pan, l2cap, bnep; @@ -173,7 +173,7 @@ int bnep_sdp_register(uint16_t role) break; } - status = sdp_record_register(session, record, 0); + status = sdp_device_record_register(session, device, record, 0); if (status) { syslog(LOG_ERR, "SDP registration failed."); sdp_record_free(record); record = NULL; -- cgit From 08ecd7d64afc3493046db2e09e5e8f875571ee84 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Aug 2005 11:24:49 +0000 Subject: Add UUIDs for phonebook access profile --- tools/sdptool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index b3f4648c..f6a47ddf 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -302,6 +302,8 @@ static struct uuid_def uuid16_names[] = { { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, { 0x112d, "SIM Access (SAP)", NULL, 0 }, + { 0x112e, "Phonebook Access (PBAP) - PCE", NULL, 0 }, + { 0x112f, "Phonebook Access (PBAP) - PSE", NULL, 0 }, /* ... */ { 0x1200, "PnPInformation", did_attrib_names, sizeof(did_attrib_names)/sizeof(struct attrib_def) }, -- cgit From 326acb25fa999f4cf908a69412e9dc6f429f9d49 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Aug 2005 11:28:27 +0000 Subject: Add missing UUID translations --- tools/sdptool.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index f6a47ddf..96a95cc8 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -301,6 +301,9 @@ static struct uuid_def uuid16_names[] = { { 0x1127, "HCR_Scan (HCR)", NULL, 0 }, { 0x1128, "Common ISDN Access (CIP)", NULL, 0 }, { 0x1129, "VideoConferencingGW (VCP)", NULL, 0 }, + { 0x112a, "UDI-MT", NULL, 0 }, + { 0x112b, "UDI-TA", NULL, 0 }, + { 0x112c, "Audio/Video", NULL, 0 }, { 0x112d, "SIM Access (SAP)", NULL, 0 }, { 0x112e, "Phonebook Access (PBAP) - PCE", NULL, 0 }, { 0x112f, "Phonebook Access (PBAP) - PSE", NULL, 0 }, @@ -312,6 +315,10 @@ static struct uuid_def uuid16_names[] = { { 0x1203, "GenericAudio", audio_attrib_names, sizeof(audio_attrib_names)/sizeof(struct attrib_def) }, { 0x1204, "GenericTelephony", NULL, 0 }, + /* ... */ + { 0x1303, "VideoSource", NULL, 0 }, + { 0x1304, "VideoSink", NULL, 0 }, + { 0x1305, "VideoDistribution", NULL, 0 }, }; static const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); -- cgit From 6b4fc0af31df1b4736c2209893b2b7d8890b0ed7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Aug 2005 11:42:07 +0000 Subject: Add support for HotSync service records --- tools/sdptool.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index 96a95cc8..41e2fc09 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2097,6 +2097,36 @@ static int add_syncml(sdp_session_t *session, svc_info_t *si) return 0; } +static unsigned char hotsync_uuid[] = { 0xF5, 0xBE, 0xB6, 0x51, 0x41, 0x71, 0x40, 0x51, + 0xAC, 0xF5, 0x6C, 0xA7, 0x20, 0x22, 0x42, 0xF0 }; + +static int add_hotsync(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass; + uuid_t root_uuid, svclass_uuid; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) hotsync_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("HotSync service record registered\n"); + + return 0; +} + static unsigned char nokid_uuid[] = { 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; @@ -2237,6 +2267,7 @@ struct { { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, { "SYNCML", 0, add_syncml, syncml_uuid }, + { "HOTSYNC", 0, add_hotsync, hotsync_uuid }, { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, { "SR1", 0, add_sr1, sr1_uuid }, -- cgit From 3a082ca7bd37268e851a0fd78772df2f5200beca Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 16 Aug 2005 15:16:45 +0000 Subject: Filter out more meta characters --- hcid/security.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hcid/security.c b/hcid/security.c index ab22f14d..d1aee4e2 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -336,6 +336,8 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) case '"': case '`': case '$': + case '|': + case ';': case '\\': *ptr++ = '\\'; } -- cgit From 6fd874af5d76b8cbffcf795fcb40b04b92cce8e0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 16 Aug 2005 18:06:07 +0000 Subject: Update manual page and fix spelling mistakes --- dund/dund.1 | 17 ++++++++++++++++- dund/main.c | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/dund/dund.1 b/dund/dund.1 index 41354774..2056b145 100644 --- a/dund/dund.1 +++ b/dund/dund.1 @@ -5,7 +5,7 @@ dund \- BlueZ Bluetooth dial-up networking daemon .SH DESCRIPTION DUN daemon .SH SYNOPSIS -dund +dund [pppd options] .SH OPTIONS .TP \fB\-\-show\fR \fB\-\-list\fR \fB\-l\fR @@ -17,6 +17,9 @@ Listen for DUN connections \fB\-\-connect\fR \fB\-c\fR Create DUN connection .TP +\fB\-\-mrouter\fR \fB\-m\fR +Create mRouter connection +.TP \fB\-\-search\fR \fB\-Q[duration]\fR Search and connect .TP @@ -35,6 +38,9 @@ Source bdaddr \fB\-\-nosdp\fR \fB\-D\fR Disable SDP .TP +\fB\-\-auth\fR \fB\-A\fR +Enable authentification +.TP \fB\-\-encrypt\fR \fB\-E\fR Enable encryption .TP @@ -49,4 +55,13 @@ Do not become a daemon .TP \fB\-\-persist\fR \fB\-p[interval]\fR Persist mode +.TP +\fB\-\-pppd\fR \fB\-d\fR +Location of the PPP daemon (pppd) +.TP +\fB\-\-msdun\fR \fB\-X\fR [timeo] +Enable Microsoft dialup networking support +.TP +\fB\-\-cache\fR \fB\-C\fR [valid] +Enable address cache diff --git a/dund/main.c b/dund/main.c index b00ccab7..83be167c 100644 --- a/dund/main.c +++ b/dund/main.c @@ -430,7 +430,7 @@ static char main_help[] = "\t--persist -p[interval] Persist mode\n" "\t--pppd -d Location of the PPP daemon (pppd)\n" "\t--msdun -X[timeo] Enable Microsoft dialup networking support\n" - "\t--cache -C[valid] Enable addess cache\n"; + "\t--cache -C[valid] Enable address cache\n"; int main(int argc, char **argv) { -- cgit From 9781497af59916008927db6089cd38f782e16261 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Aug 2005 14:40:45 +0000 Subject: Add support for HotSync and ActiveSync profiles --- tools/sdptool.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 41e2fc09..fd824c2c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2097,10 +2097,94 @@ static int add_syncml(sdp_session_t *session, svc_info_t *si) return 0; } -static unsigned char hotsync_uuid[] = { 0xF5, 0xBE, 0xB6, 0x51, 0x41, 0x71, 0x40, 0x51, - 0xAC, 0xF5, 0x6C, 0xA7, 0x20, 0x22, 0x42, 0xF0 }; +static unsigned char async_uuid[] = { 0x03, 0x50, 0x27, 0x8F, 0x3D, 0xCA, 0x4E, 0x62, + 0x83, 0x1D, 0xA4, 0x11, 0x65, 0xFF, 0x90, 0x6C }; + +static int add_activesync(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel? si->channel: 21; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid128_create(&svclass_uuid, (void *) async_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "Microsoft ActiveSync", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("ActiveSync service record registered\n"); + + return 0; +} + +static unsigned char hotsync_uuid[] = { 0xD8, 0x0C, 0xF9, 0xEA, 0x13, 0x4C, 0x11, 0xD5, + 0x83, 0xCE, 0x00, 0x30, 0x65, 0x7C, 0x54, 0x3C }; static int add_hotsync(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel? si->channel: 22; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid128_create(&svclass_uuid, (void *) hotsync_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "PalmOS HotSync", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("HotSync service record registered\n"); + + return 0; +} + +static unsigned char palmos_uuid[] = { 0xF5, 0xBE, 0xB6, 0x51, 0x41, 0x71, 0x40, 0x51, + 0xAC, 0xF5, 0x6C, 0xA7, 0x20, 0x22, 0x42, 0xF0 }; + +static int add_palmos(sdp_session_t *session, svc_info_t *si) { sdp_record_t record; sdp_list_t *root, *svclass; @@ -2122,7 +2206,7 @@ static int add_hotsync(sdp_session_t *session, svc_info_t *si) return -1; } - printf("HotSync service record registered\n"); + printf("PalmOS service record registered\n"); return 0; } @@ -2267,7 +2351,9 @@ struct { { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, { "SYNCML", 0, add_syncml, syncml_uuid }, + { "ACTIVESYNC", 0, add_activesync, async_uuid }, { "HOTSYNC", 0, add_hotsync, hotsync_uuid }, + { "PALMOS", 0, add_palmos, palmos_uuid }, { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, { "SR1", 0, add_sr1, sr1_uuid }, -- cgit From 50b0825682e67eb4a094261c5a0249c37bb84694 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Aug 2005 15:47:42 +0000 Subject: Identify the extended inquiry mode correctly --- tools/hciconfig.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 745ed74f..3bf3b292 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -883,8 +883,21 @@ static void cmd_inq_mode(int ctl, int hdev, char *opt) } print_dev_hdr(&di); - printf("\tInquiry mode: %s\n", - mode == 1 ? "Inquiry with RSSI" : "Standard Inquiry"); + printf("\tInquiry mode: "); + switch (mode) { + case 0: + printf("Standard Inquiry\n"); + break; + case 1: + printf("Inquiry with RSSI\n"); + break; + case 2: + printf("Inquiry with RSSI or Extended Inquiry\n"); + break; + default: + printf("Unknown (0x%02x)\n", mode); + break; + } } } -- cgit From ad0ddadb14111da30387acce8c47459906ed0759 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Aug 2005 15:48:55 +0000 Subject: Escape for shell meta characters --- hcid/security.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hcid/security.c b/hcid/security.c index d1aee4e2..ffc73f8e 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -337,6 +337,9 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) case '`': case '$': case '|': + case '>': + case '<': + case '&': case ';': case '\\': *ptr++ = '\\'; -- cgit From 7d463a7ae8a9775fd091131659a849baca993e53 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Aug 2005 08:56:10 +0000 Subject: Add ActiveSync networking support --- dund/dun.c | 2 +- dund/dund.1 | 4 +++- dund/dund.h | 17 +++++++++------ dund/lib.h | 2 +- dund/main.c | 67 +++++++++++++++++++++++++++++++++--------------------------- dund/msdun.c | 2 +- dund/sdp.c | 64 +++++++++++++++++++++++++++++++++++++++++++++------------ 7 files changed, 105 insertions(+), 53 deletions(-) diff --git a/dund/dun.c b/dund/dun.c index 0593cb85..d5724cfb 100644 --- a/dund/dun.c +++ b/dund/dun.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/dund/dund.1 b/dund/dund.1 index 2056b145..895fc97a 100644 --- a/dund/dund.1 +++ b/dund/dund.1 @@ -62,6 +62,8 @@ Location of the PPP daemon (pppd) \fB\-\-msdun\fR \fB\-X\fR [timeo] Enable Microsoft dialup networking support .TP +\fB\-\-activesync\fR \fB\-a\fR +Enable Microsoft ActiveSync networking +.TP \fB\-\-cache\fR \fB\-C\fR [valid] Enable address cache - diff --git a/dund/dund.h b/dund/dund.h index 97c54174..f2a9b026 100644 --- a/dund/dund.h +++ b/dund/dund.h @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -28,11 +28,16 @@ */ /* DUN scripts & commands */ -#define DUN_CONFIG_DIR "/etc/bluetooth/dun" +#define DUN_CONFIG_DIR "/etc/bluetooth/dun" -#define DUN_DEFAULT_CHANNEL 1 +#define DUN_DEFAULT_CHANNEL 1 -#define DUN_MAX_PPP_OPTS 40 +#define DUN_MAX_PPP_OPTS 40 + +/* DUN types */ +#define LANACCESS 0 +#define MROUTER 1 +#define ACTIVESYNC 2 /* DUN functions */ int dun_init(void); @@ -45,6 +50,6 @@ int dun_kill_all_connections(void); int dun_open_connection(int sk, char *pppd, char **pppd_opts, int wait); /* SDP functions */ -int dun_sdp_register(bdaddr_t *device, uint8_t channel, int mrouter); +int dun_sdp_register(bdaddr_t *device, uint8_t channel, int type); void dun_sdp_unregister(void); -int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int mrouter); +int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int type); diff --git a/dund/lib.h b/dund/lib.h index 3835d41c..c9b0f0a4 100644 --- a/dund/lib.h +++ b/dund/lib.h @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/dund/main.c b/dund/main.c index 83be167c..e58e382b 100644 --- a/dund/main.c +++ b/dund/main.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -74,7 +74,7 @@ static int auth; static int encrypt; static int secure; static int master; -static int mrouter; +static int type = LANACCESS; static int search_duration = 10; static uint use_cache; @@ -107,11 +107,11 @@ static int do_listen(void) struct sockaddr_rc sa; int sk, lm; - if (mrouter) { + if (type == MROUTER) { if (!cache.valid) return -1; - if (create_connection(cache.dst, &cache.bdaddr, mrouter) < 0) { + if (create_connection(cache.dst, &cache.bdaddr, type) < 0) { syslog(LOG_ERR, "Cannot connect to mRouter device. %s(%d)", strerror(errno), errno); return -1; @@ -122,9 +122,9 @@ static int do_listen(void) channel = DUN_DEFAULT_CHANNEL; if (use_sdp) - dun_sdp_register(&src_addr, channel, mrouter); + dun_sdp_register(&src_addr, channel, type); - if (mrouter) + if (type == MROUTER) syslog(LOG_INFO, "Waiting for mRouter callback on channel %d", channel); /* Create RFCOMM socket */ @@ -181,7 +181,7 @@ static int do_listen(void) syslog(LOG_ERR, "Fork failed. %s(%d)", strerror(errno), errno); default: close(nsk); - if (mrouter) { + if (type == MROUTER) { close(sk); terminate = 1; } @@ -381,31 +381,32 @@ void sig_term(int sig) } static struct option main_lopts[] = { - { "help", 0, 0, 'h' }, - { "listen", 0, 0, 's' }, - { "connect", 1, 0, 'c' }, - { "search", 2, 0, 'Q' }, - { "kill", 1, 0, 'k' }, - { "killall", 0, 0, 'K' }, - { "channel", 1, 0, 'P' }, - { "device", 1, 0, 'i' }, - { "nosdp", 0, 0, 'D' }, - { "list", 0, 0, 'l' }, - { "show", 0, 0, 'l' }, - { "nodetach", 0, 0, 'n' }, - { "persist", 2, 0, 'p' }, - { "auth", 0, 0, 'A' }, - { "encrypt", 0, 0, 'E' }, - { "secure", 0, 0, 'S' }, - { "master", 0, 0, 'M' }, - { "cache", 0, 0, 'C' }, - { "pppd", 1, 0, 'd' }, - { "msdun", 2, 0, 'X' }, - { "mrouter", 1, 0, 'm' }, + { "help", 0, 0, 'h' }, + { "listen", 0, 0, 's' }, + { "connect", 1, 0, 'c' }, + { "search", 2, 0, 'Q' }, + { "kill", 1, 0, 'k' }, + { "killall", 0, 0, 'K' }, + { "channel", 1, 0, 'P' }, + { "device", 1, 0, 'i' }, + { "nosdp", 0, 0, 'D' }, + { "list", 0, 0, 'l' }, + { "show", 0, 0, 'l' }, + { "nodetach", 0, 0, 'n' }, + { "persist", 2, 0, 'p' }, + { "auth", 0, 0, 'A' }, + { "encrypt", 0, 0, 'E' }, + { "secure", 0, 0, 'S' }, + { "master", 0, 0, 'M' }, + { "cache", 0, 0, 'C' }, + { "pppd", 1, 0, 'd' }, + { "msdun", 2, 0, 'X' }, + { "activesync", 0, 0, 'a' }, + { "mrouter", 1, 0, 'm' }, { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:i:lnp::DQ::AESMP:C::P:X"; +static char main_sopts[] = "hsc:k:Kr:i:lnp::DQ::AESMP:C::P:Xa"; static char main_help[] = "Bluetooth LAP (LAN Access over PPP) daemon version " VERSION " \n" @@ -430,6 +431,7 @@ static char main_help[] = "\t--persist -p[interval] Persist mode\n" "\t--pppd -d Location of the PPP daemon (pppd)\n" "\t--msdun -X[timeo] Enable Microsoft dialup networking support\n" + "\t--activesync -a Enable Microsoft ActiveSync networking\n" "\t--cache -C[valid] Enable address cache\n"; int main(int argc, char **argv) @@ -531,10 +533,15 @@ int main(int argc, char **argv) msdun = 10; break; + case 'a': + msdun = 10; + type = ACTIVESYNC; + break; + case 'm': mode = LISTEN; dst = strdup(optarg); - mrouter = 1; + type = MROUTER; break; case 'h': diff --git a/dund/msdun.c b/dund/msdun.c index 20749760..f035971b 100644 --- a/dund/msdun.c +++ b/dund/msdun.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/dund/sdp.c b/dund/sdp.c index 16ef09f4..74cafb55 100644 --- a/dund/sdp.c +++ b/dund/sdp.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -46,6 +46,9 @@ #include "dund.h" +static unsigned char async_uuid[] = { 0x03, 0x50, 0x27, 0x8F, 0x3D, 0xCA, 0x4E, 0x62, + 0x83, 0x1D, 0xA4, 0x11, 0x65, 0xFF, 0x90, 0x6C }; + static sdp_record_t *record; static sdp_session_t *session; @@ -56,7 +59,7 @@ void dun_sdp_unregister(void) sdp_close(session); } -int dun_sdp_register(bdaddr_t *device, uint8_t channel, int mrouter) +int dun_sdp_register(bdaddr_t *device, uint8_t channel, int type) { sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; uuid_t root_uuid, l2cap, rfcomm, dun; @@ -93,27 +96,51 @@ int dun_sdp_register(bdaddr_t *device, uint8_t channel, int mrouter) aproto = sdp_list_append(NULL, apseq); sdp_set_access_protos(record, aproto); - sdp_uuid16_create(&dun, mrouter ? SERIAL_PORT_SVCLASS_ID : LAN_ACCESS_SVCLASS_ID); + switch (type) { + case MROUTER: + sdp_uuid16_create(&dun, SERIAL_PORT_SVCLASS_ID); + break; + case ACTIVESYNC: + sdp_uuid128_create(&dun, (void *) async_uuid); + break; + default: + sdp_uuid16_create(&dun, LAN_ACCESS_SVCLASS_ID); + break; + } + svclass = sdp_list_append(NULL, &dun); sdp_set_service_classes(record, svclass); - sdp_uuid16_create(&profile[0].uuid, mrouter ? SERIAL_PORT_PROFILE_ID : LAN_ACCESS_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(record, pfseq); - - sdp_set_info_attr(record, mrouter ? "mRouter" : "LAN Access Point", NULL, NULL); + if (type == LANACCESS) { + sdp_uuid16_create(&profile[0].uuid, LAN_ACCESS_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(record, pfseq); + } + + switch (type) { + case MROUTER: + sdp_set_info_attr(record, "mRouter", NULL, NULL); + break; + case ACTIVESYNC: + sdp_set_info_attr(record, "ActiveSync", NULL, NULL); + break; + default: + sdp_set_info_attr(record, "LAN Access Point", NULL, NULL); + break; + } status = sdp_device_record_register(session, device, record, 0); if (status) { syslog(LOG_ERR, "SDP registration failed."); - sdp_record_free(record); record = NULL; + sdp_record_free(record); + record = NULL; return -1; } return 0; } -int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int mrouter) +int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int type) { sdp_session_t *s; sdp_list_t *srch, *attrs, *rsp; @@ -128,7 +155,18 @@ int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int mrouter) return -1; } - sdp_uuid16_create(&svclass, mrouter ? SERIAL_PORT_SVCLASS_ID : LAN_ACCESS_SVCLASS_ID); + switch (type) { + case MROUTER: + sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID); + break; + case ACTIVESYNC: + sdp_uuid128_create(&svclass, (void *) async_uuid); + break; + default: + sdp_uuid16_create(&svclass, LAN_ACCESS_SVCLASS_ID); + break; + } + srch = sdp_list_append(NULL, &svclass); attr = SDP_ATTR_PROTO_DESC_LIST; @@ -137,7 +175,7 @@ int dun_sdp_search(bdaddr_t *src, bdaddr_t *dst, int *channel, int mrouter) err = sdp_service_search_attr_req(s, srch, SDP_ATTR_REQ_INDIVIDUAL, attrs, &rsp); sdp_close(s); - + if (err) return 0; -- cgit From 0cc4f1817bef34823a547f21911b8b7ceb581a1a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 21 Aug 2005 14:00:29 +0000 Subject: Reset the device after changing the address --- test/bdaddr.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/test/bdaddr.c b/test/bdaddr.c index e1f6921a..e34cc961 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -150,6 +151,34 @@ static int csr_write_bd_addr(int dd, bdaddr_t *bdaddr) return 0; } +static int csr_reset_device(int dd) +{ + unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + return 0; +} + #define OCF_ZEEVO_WRITE_BD_ADDR 0x0001 typedef struct { bdaddr_t bdaddr; @@ -180,12 +209,13 @@ static int zeevo_write_bd_addr(int dd, bdaddr_t *bdaddr) static struct { uint16_t compid; - int (*func)(int dd, bdaddr_t *bdaddr); + int (*write_bd_addr)(int dd, bdaddr_t *bdaddr); + int (*reset_device)(int dd); } vendor[] = { - { 0, ericsson_write_bd_addr }, - { 10, csr_write_bd_addr }, - { 18, zeevo_write_bd_addr }, - { 65535, NULL }, + { 0, ericsson_write_bd_addr, NULL }, + { 10, csr_write_bd_addr, csr_reset_device }, + { 18, zeevo_write_bd_addr, NULL }, + { 65535, NULL, NULL }, }; static void usage(void) @@ -285,13 +315,24 @@ int main(int argc, char *argv[]) ba2str(&bdaddr, addr); printf("New BD address: %s\n\n", addr); - if (vendor[i].func(dd, &bdaddr) < 0) { + if (vendor[i].write_bd_addr(dd, &bdaddr) < 0) { fprintf(stderr, "Can't write new address\n"); hci_close_dev(dd); exit(1); } - printf("Address changed - Reset device now\n"); + printf("Address changed - "); + + if (vendor[i].reset_device) { + if (vendor[i].reset_device(dd) < 0) { + printf("Reset device manually\n"); + } else { + ioctl(dd, HCIDEVRESET, dev); + printf("Device reset successully\n"); + } + } else { + printf("Reset device now\n"); + } //ioctl(dd, HCIDEVRESET, dev); //ioctl(dd, HCIDEVDOWN, dev); -- cgit From b207244243cb0407728fbbb5ff8cbe95f9d74260 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 22 Aug 2005 20:36:28 +0000 Subject: Add support for writing valueless BCCMD variables --- tools/csr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 47 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 6832ec6d..1f1ab229 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -427,6 +427,52 @@ char *csr_pskeytostr(uint16_t pskey) } } +int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid) +{ + unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return hci_send_cmd(dd, OGF_VENDOR_CMD, 0x00, sizeof(cmd) + 1, cp); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + return 0; +} + int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 5) & 0xff, ((length / 2) + 5) >> 8, diff --git a/tools/csr.h b/tools/csr.h index 5098a69d..acb30641 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -75,6 +75,7 @@ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); +int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); -- cgit From 87af78afc0d5753583825f061c36f7705762c576 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 22 Aug 2005 20:38:18 +0000 Subject: Add support for reset and transmitter modification --- tools/bccmd.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/tools/bccmd.c b/tools/bccmd.c index df39a3df..e476165e 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -95,6 +95,22 @@ static int cmd_clock(int dd, int argc, char *argv[]) return 0; } +static int cmd_rand(int dd, int argc, char *argv[]) +{ + uint16_t rand = 0; + int err; + + err = csr_read_varid_uint16(dd, 5, CSR_VARID_RAND, &rand); + if (err < 0) { + errno = -err; + return -1; + } + + printf("Random number: 0x%02x (%d)\n", rand, rand); + + return 0; +} + static int cmd_panicarg(int dd, int argc, char *argv[]) { uint16_t error = 0; @@ -129,16 +145,41 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) return 0; } +static int cmd_coldreset(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, CSR_VARID_COLD_RESET); +} + +static int cmd_warmreset(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, CSR_VARID_WARM_RESET); +} + +static int cmd_disabletx(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, CSR_VARID_DISABLE_TX); +} + +static int cmd_enabletx(int dd, int argc, char *argv[]) +{ + return csr_write_varid_valueless(dd, 0, CSR_VARID_ENABLE_TX); +} + static struct { char *str; int (*func)(int dd, int argc, char **argv); char *arg; char *doc; } commands[] = { - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, - { "panicarg", cmd_panicarg, "", "Get panic code argument" }, - { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "rand", cmd_rand, "", "Get random number" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "coldreset", cmd_coldreset, "", "Perform cold reset" }, + { "warmreset", cmd_warmreset, "", "Perform warm reset" }, + { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, + { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, { NULL }, }; -- cgit From ba84f1e3781ef52666228d38ec6a0c27c5454d30 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 24 Aug 2005 21:08:17 +0000 Subject: Fix D-Bus crashes --- hcid/dbus.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 7f98c32f..d9d74d7a 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -120,7 +120,9 @@ static void free_pin_req(void *req) void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS + uint8_t *addr = (uint8_t *) &ci->bdaddr; +#else DBusMessageIter iter; #endif DBusPendingCall *pending = NULL; @@ -140,7 +142,7 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) #ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &ci->out, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, - &ci->bdaddr, sizeof(bdaddr_t), DBUS_TYPE_INVALID); + &addr, sizeof(bdaddr_t), DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); @@ -173,10 +175,12 @@ failed: void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS + char local_addr[18], peer_addr[18]; +#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS + char *local_ptr = local_addr, *peer_ptr = peer_addr; +#else DBusMessageIter iter; #endif - char local_addr[18], peer_addr[18]; ba2str(local, local_addr); ba2str(peer, peer_addr); @@ -190,10 +194,10 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i #ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS dbus_message_append_args(message, - DBUS_TYPE_STRING, local_addr, - DBUS_TYPE_STRING, peer_addr, - DBUS_TYPE_UINT32, class, - DBUS_TYPE_INT32, rssi, + DBUS_TYPE_STRING, &local_ptr, + DBUS_TYPE_STRING, &peer_ptr, + DBUS_TYPE_UINT32, &class, + DBUS_TYPE_INT32, &rssi, DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); @@ -220,10 +224,13 @@ failed: void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS + char local_addr[18], peer_addr[18]; +#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS + char *local_ptr = local_addr, *peer_ptr = peer_addr; + char *name_ptr = name; +#else DBusMessageIter iter; #endif - char local_addr[18], peer_addr[18]; ba2str(local, local_addr); ba2str(peer, peer_addr); @@ -237,9 +244,9 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) #ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS dbus_message_append_args(message, - DBUS_TYPE_STRING, local_addr, - DBUS_TYPE_STRING, peer_addr, - DBUS_TYPE_STRING, name, + DBUS_TYPE_STRING, &local_ptr, + DBUS_TYPE_STRING, &peer_ptr, + DBUS_TYPE_STRING, &name_ptr, DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); -- cgit From 21163a201bdde01099a3054024e0219f0ed10166 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 24 Aug 2005 21:09:48 +0000 Subject: Add missing unref call --- hcid/dbus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hcid/dbus.c b/hcid/dbus.c index d9d74d7a..de51eee6 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -103,6 +103,7 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) PIN_CODE_REPLY_CP_SIZE, &pr); dbus_message_unref(message); + dbus_pending_call_unref(call); return; -- cgit From a4d0ca683bcbdda57c1035764752669bceb5b339 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 24 Aug 2005 23:14:41 +0000 Subject: Add support for extended inquiry results --- hcid/security.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/hcid/security.c b/hcid/security.c index ffc73f8e..7eec9e76 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -568,6 +568,23 @@ static inline void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, vo } } +static inline void extended_inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) +{ + uint8_t num = *(uint8_t *) ptr++; + int i; + + for (i = 0; i < num; i++) { + extended_inquiry_info *info = ptr; + uint32_t class = info->dev_class[0] + | (info->dev_class[1] << 8) + | (info->dev_class[2] << 16); + + hcid_dbus_inquiry_result(sba, &info->bdaddr, class, info->rssi); + + ptr += EXTENDED_INQUIRY_INFO_SIZE; + } +} + static inline void remote_features_information(int dev, bdaddr_t *sba, void *ptr) { evt_read_remote_features_complete *evt = ptr; @@ -640,6 +657,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer case EVT_INQUIRY_RESULT_WITH_RSSI: inquiry_result_with_rssi(dev, &di->bdaddr, eh->plen, ptr); break; + + case EVT_EXTENDED_INQUIRY_RESULT: + extended_inquiry_result(dev, &di->bdaddr, eh->plen, ptr); + break; } if (hci_test_bit(HCI_SECMGR, &di->flags)) @@ -697,6 +718,7 @@ void start_security_manager(int hdev) hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); + hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { syslog(LOG_ERR, "Can't set filter on hci%d: %s (%d)", hdev, strerror(errno), errno); -- cgit From 4eb7a31e82e765a2ccb74b0fb4637c3cdf386786 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Aug 2005 18:32:40 +0000 Subject: Update D-Bus support for inquiry and connection tracking --- hcid/dbus.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++-------- hcid/hcid.h | 16 +++++--- hcid/security.c | 59 +++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 22 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index de51eee6..b6f516c0 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -112,7 +112,6 @@ error: OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); } - static void free_pin_req(void *req) { free(req); @@ -173,15 +172,93 @@ failed: OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); } -void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) +void hcid_dbus_inquiry_start(bdaddr_t *local) { DBusMessage *message; - char local_addr[18], peer_addr[18]; +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS + DBusMessageIter iter; +#endif + char local_addr[18]; + + ba2str(local, local_addr); + + message = dbus_message_new_signal("/org/bluez/DevAgent", + "org.bluez.DevAgent", "InquiryStart"); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS inquiry start message"); + goto failed; + } + #ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS - char *local_ptr = local_addr, *peer_ptr = peer_addr; + dbus_message_append_args(message, + DBUS_TYPE_STRING, local_addr, + DBUS_TYPE_INVALID); #else + dbus_message_append_iter_init(message, &iter); + + dbus_message_iter_append_string(&iter, local_addr); +#endif + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS inquiry start message"); + goto failed; + } + + dbus_connection_flush(connection); + +failed: + dbus_message_unref(message); + + return; +} + +void hcid_dbus_inquiry_complete(bdaddr_t *local) +{ + DBusMessage *message; +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS DBusMessageIter iter; #endif + char local_addr[18]; + + ba2str(local, local_addr); + + message = dbus_message_new_signal("/org/bluez/DevAgent", + "org.bluez.DevAgent", "InquiryComplete"); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); + goto failed; + } + +#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS + dbus_message_append_args(message, + DBUS_TYPE_STRING, local_addr, + DBUS_TYPE_INVALID); +#else + dbus_message_append_iter_init(message, &iter); + + dbus_message_iter_append_string(&iter, local_addr); +#endif + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS inquiry complete message"); + goto failed; + } + + dbus_connection_flush(connection); + +failed: + dbus_message_unref(message); + + return; +} + +void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) +{ + DBusMessage *message; +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS + DBusMessageIter iter; +#endif + char local_addr[18], peer_addr[18]; ba2str(local, local_addr); ba2str(peer, peer_addr); @@ -195,10 +272,10 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i #ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS dbus_message_append_args(message, - DBUS_TYPE_STRING, &local_ptr, - DBUS_TYPE_STRING, &peer_ptr, - DBUS_TYPE_UINT32, &class, - DBUS_TYPE_INT32, &rssi, + DBUS_TYPE_STRING, local_addr, + DBUS_TYPE_STRING, peer_addr, + DBUS_TYPE_UINT32, class, + DBUS_TYPE_INT32, rssi, DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); @@ -225,13 +302,10 @@ failed: void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) { DBusMessage *message; - char local_addr[18], peer_addr[18]; -#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS - char *local_ptr = local_addr, *peer_ptr = peer_addr; - char *name_ptr = name; -#else +#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS DBusMessageIter iter; #endif + char local_addr[18], peer_addr[18]; ba2str(local, local_addr); ba2str(peer, peer_addr); @@ -245,9 +319,9 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) #ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS dbus_message_append_args(message, - DBUS_TYPE_STRING, &local_ptr, - DBUS_TYPE_STRING, &peer_ptr, - DBUS_TYPE_STRING, &name_ptr, + DBUS_TYPE_STRING, local_addr, + DBUS_TYPE_STRING, peer_addr, + DBUS_TYPE_STRING, name, DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); @@ -270,6 +344,14 @@ failed: return; } +void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) +{ +} + +void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) +{ +} + gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data) { DBusWatch *watch = (DBusWatch *) data; diff --git a/hcid/hcid.h b/hcid/hcid.h index 4a433984..39b2cd09 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -123,15 +123,19 @@ void toggle_pairing(int enable); #ifdef ENABLE_DBUS gboolean hcid_dbus_init(void); void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); +void hcid_dbus_inquiry_start(bdaddr_t *local); +void hcid_dbus_inquiry_complete(bdaddr_t *local); void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi); void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name); +void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer); +void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason); #else -static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) -{ -} -static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) -{ -} +static inline void hcid_dbus_inquiry_start(bdaddr_t *local) {} +static inline void hcid_dbus_inquiry_complete(bdaddr_t *local) {} +static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) {} +static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) {} +static inline void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) {} +static inline void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) {} #endif int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); diff --git a/hcid/security.c b/hcid/security.c index 7eec9e76..00204ace 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -482,6 +482,17 @@ reject: return; } +static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr) +{ + evt_cmd_status *evt = ptr; + + if (evt->status) + return; + + if (evt->opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) + hcid_dbus_inquiry_start(sba); +} + static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr) { evt_remote_name_req_complete *evt = ptr; @@ -516,6 +527,11 @@ static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr) evt->lmp_ver, btohs(evt->lmp_subver)); } +static inline void inquiry_complete(int dev, bdaddr_t *sba, void *ptr) +{ + hcid_dbus_inquiry_complete(sba); +} + static inline void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) { uint8_t num = *(uint8_t *) ptr++; @@ -599,6 +615,29 @@ static inline void remote_features_information(int dev, bdaddr_t *sba, void *ptr write_features_info(sba, &dba, evt->features); } +static inline void conn_complete(int dev, bdaddr_t *sba, void *ptr) +{ + evt_conn_complete *evt = ptr; + + if (evt->status) + return; + + hcid_dbus_conn_complete(sba, &evt->bdaddr); +} + +static inline void disconn_complete(int dev, bdaddr_t *sba, void *ptr) +{ + evt_disconn_complete *evt = ptr; + bdaddr_t dba; + + if (evt->status) + return; + + bacpy(&dba, BDADDR_ANY); + + hcid_dbus_disconn_complete(sba, &dba, evt->reason); +} + static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; @@ -638,6 +677,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer return TRUE; switch (eh->evt) { + case EVT_CMD_STATUS: + cmd_status(dev, &di->bdaddr, ptr); + break; + case EVT_REMOTE_NAME_REQ_COMPLETE: remote_name_information(dev, &di->bdaddr, ptr); break; @@ -650,6 +693,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer remote_features_information(dev, &di->bdaddr, ptr); break; + case EVT_INQUIRY_COMPLETE: + inquiry_complete(dev, &di->bdaddr, ptr); + break; + case EVT_INQUIRY_RESULT: inquiry_result(dev, &di->bdaddr, eh->plen, ptr); break; @@ -661,6 +708,14 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer case EVT_EXTENDED_INQUIRY_RESULT: extended_inquiry_result(dev, &di->bdaddr, eh->plen, ptr); break; + + case EVT_CONN_COMPLETE: + conn_complete(dev, &di->bdaddr, ptr); + break; + + case EVT_DISCONN_COMPLETE: + disconn_complete(dev, &di->bdaddr, ptr); + break; } if (hci_test_bit(HCI_SECMGR, &di->flags)) @@ -709,6 +764,7 @@ void start_security_manager(int hdev) /* Set filter */ hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); + hci_filter_set_event(EVT_CMD_STATUS, &flt); hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); @@ -716,9 +772,12 @@ void start_security_manager(int hdev) hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt); hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); + hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); + hci_filter_set_event(EVT_CONN_COMPLETE, &flt); + hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt); if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { syslog(LOG_ERR, "Can't set filter on hci%d: %s (%d)", hdev, strerror(errno), errno); -- cgit From ea567c62de2fd8f0d44e02c8f0d3805943a77040 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 26 Aug 2005 22:40:38 +0000 Subject: Fix D-Bus 0.2x and 0.3x problems --- acinclude.m4 | 2 -- hcid/dbus.c | 76 ++++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 35 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index ed00a60e..83adb960 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -244,9 +244,7 @@ AC_DEFUN([AC_PATH_DBUS], [ LDFLAGS="$LDFLAGS $DBUS_LIBS" AC_CHECK_LIB(dbus-1, dbus_error_init, DBUS_LIBS="$DBUS_LIBS -ldbus-1", dbus_found=no) - AC_CHECK_LIB(dbus-1, dbus_pending_call_steal_reply, AC_DEFINE(HAVE_DBUS_PENDING_CALL_STEAL_REPLY, 1, [Define to 1 if you have the dbus_pending_call_steal_reply() function.])) AC_CHECK_LIB(dbus-1, dbus_message_iter_get_basic, AC_DEFINE(HAVE_DBUS_MESSAGE_ITER_GET_BASIC, 1, [Define to 1 if you have the dbus_message_iter_get_basic() function.])) - AC_CHECK_LIB(dbus-1, dbus_message_append_args, AC_DEFINE(HAVE_DBUS_MESSAGE_APPEND_ARGS, 1, [Define to 1 if you have the dbus_message_append_args() function.])) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS diff --git a/hcid/dbus.c b/hcid/dbus.c index b6f516c0..5ffa97e2 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -72,11 +72,7 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) size_t len; char *pin; -#ifdef HAVE_DBUS_PENDING_CALL_STEAL_REPLY message = dbus_pending_call_steal_reply(call); -#else - message = dbus_pending_call_get_reply(call); -#endif if (dbus_message_is_error(message, WRONG_ARGS_ERROR)) goto error; @@ -120,7 +116,7 @@ static void free_pin_req(void *req) void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) { DBusMessage *message; -#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC uint8_t *addr = (uint8_t *) &ci->bdaddr; #else DBusMessageIter iter; @@ -139,7 +135,7 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) req->dev = dev; bacpy(&req->bda, &ci->bdaddr); -#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &ci->out, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, sizeof(bdaddr_t), DBUS_TYPE_INVALID); @@ -175,12 +171,13 @@ failed: void hcid_dbus_inquiry_start(bdaddr_t *local) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifndef HAVE_DBUS_MESSAGE_ITER_GET_BASIC DBusMessageIter iter; #endif - char local_addr[18]; + char *local_addr; + bdaddr_t tmp; - ba2str(local, local_addr); + baswap(&tmp, local); local_addr = batostr(&tmp); message = dbus_message_new_signal("/org/bluez/DevAgent", "org.bluez.DevAgent", "InquiryStart"); @@ -189,9 +186,9 @@ void hcid_dbus_inquiry_start(bdaddr_t *local) goto failed; } -#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, - DBUS_TYPE_STRING, local_addr, + DBUS_TYPE_STRING, &local_addr, DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); @@ -209,18 +206,21 @@ void hcid_dbus_inquiry_start(bdaddr_t *local) failed: dbus_message_unref(message); + bt_free(local_addr); + return; } void hcid_dbus_inquiry_complete(bdaddr_t *local) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifndef HAVE_DBUS_MESSAGE_ITER_GET_BASIC DBusMessageIter iter; #endif - char local_addr[18]; + char *local_addr; + bdaddr_t tmp; - ba2str(local, local_addr); + baswap(&tmp, local); local_addr = batostr(&tmp); message = dbus_message_new_signal("/org/bluez/DevAgent", "org.bluez.DevAgent", "InquiryComplete"); @@ -229,9 +229,9 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local) goto failed; } -#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, - DBUS_TYPE_STRING, local_addr, + DBUS_TYPE_STRING, &local_addr, DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); @@ -249,19 +249,22 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local) failed: dbus_message_unref(message); + bt_free(local_addr); + return; } void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifndef HAVE_DBUS_MESSAGE_ITER_GET_BASIC DBusMessageIter iter; #endif - char local_addr[18], peer_addr[18]; + char *local_addr, *peer_addr; + bdaddr_t tmp; - ba2str(local, local_addr); - ba2str(peer, peer_addr); + baswap(&tmp, local); local_addr = batostr(&tmp); + baswap(&tmp, peer); peer_addr = batostr(&tmp); message = dbus_message_new_signal("/org/bluez/DevAgent", "org.bluez.DevAgent", "InquiryResult"); @@ -270,12 +273,12 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i goto failed; } -#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, - DBUS_TYPE_STRING, local_addr, - DBUS_TYPE_STRING, peer_addr, - DBUS_TYPE_UINT32, class, - DBUS_TYPE_INT32, rssi, + DBUS_TYPE_STRING, &local_addr, + DBUS_TYPE_STRING, &peer_addr, + DBUS_TYPE_UINT32, &class, + DBUS_TYPE_INT32, &rssi, DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); @@ -296,19 +299,23 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i failed: dbus_message_unref(message); + bt_free(local_addr); + bt_free(peer_addr); + return; } void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifndef HAVE_DBUS_MESSAGE_ITER_GET_BASIC DBusMessageIter iter; #endif - char local_addr[18], peer_addr[18]; + char *local_addr, *peer_addr; + bdaddr_t tmp; - ba2str(local, local_addr); - ba2str(peer, peer_addr); + baswap(&tmp, local); local_addr = batostr(&tmp); + baswap(&tmp, peer); peer_addr = batostr(&tmp); message = dbus_message_new_signal("/org/bluez/DevAgent", "org.bluez.DevAgent", "RemoteName"); @@ -317,11 +324,11 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) goto failed; } -#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS +#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, - DBUS_TYPE_STRING, local_addr, - DBUS_TYPE_STRING, peer_addr, - DBUS_TYPE_STRING, name, + DBUS_TYPE_STRING, &local_addr, + DBUS_TYPE_STRING, &peer_addr, + DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); #else dbus_message_append_iter_init(message, &iter); @@ -341,6 +348,9 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) failed: dbus_message_unref(message); + bt_free(local_addr); + bt_free(peer_addr); + return; } -- cgit From 3882b4e761ed1411406e375ec1b4b0790509939e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 27 Aug 2005 13:33:41 +0000 Subject: Update changelog and bump version number --- ChangeLog | 10 ++++++++++ configure.in | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a67f3ce8..7ff90c84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +ver 2.20: + Add support for extended inquiry response. + Add support for HotSync service record. + Add support for ActiveSync service record. + Add ActiveSync networking support. + Fix D-Bus crashes with new API versions. + + Note: + This version needs at least bluez-libs-2.20 + ver 2.19: Fix the GCC 4.0 warnings. Fix off by one memory allocation error. diff --git a/configure.in b/configure.in index ad75274c..18690966 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.19) +AM_INIT_AUTOMAKE(bluez-utils, 2.20) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From 44385c0baa98b0e27dad39cb8bd0e33ce5a027f6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 30 Aug 2005 00:35:39 +0000 Subject: Move create_dirs() and create_file() into the textfile library --- common/textfile.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ common/textfile.h | 3 +++ hcid/storage.c | 50 -------------------------------------------------- hidd/sdp.c | 8 ++------ 4 files changed, 55 insertions(+), 56 deletions(-) diff --git a/common/textfile.c b/common/textfile.c index a5d0a58b..26cbbea7 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -41,6 +41,56 @@ #include #include +int create_dirs(char *filename, mode_t mode) +{ + struct stat st; + char dir[PATH_MAX + 1], *prev, *next; + int err; + + err = stat(filename, &st); + if (!err && S_ISREG(st.st_mode)) + return 0; + + memset(dir, 0, PATH_MAX + 1); + strcat(dir, "/"); + + prev = strchr(filename, '/'); + + while (prev) { + next = strchr(prev + 1, '/'); + if (!next) + break; + + if (next - prev == 1) { + prev = next; + continue; + } + + strncat(dir, prev + 1, next - prev); + mkdir(dir, mode); + + prev = next; + } + + return 0; +} + +int create_file(char *filename, mode_t mode) +{ + int fd; + + umask(S_IWGRP | S_IWOTH); + create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + + fd = open(filename, O_RDWR | O_CREAT, mode); + if (fd < 0) + return fd; + + close(fd); + + return 0; +} + static inline int write_key_value(int fd, char *key, char *value) { char *str; diff --git a/common/textfile.h b/common/textfile.h index 4f3cf3d4..bd7c7470 100644 --- a/common/textfile.h +++ b/common/textfile.h @@ -26,5 +26,8 @@ * $Id$ */ +int create_dirs(char *filename, mode_t mode); +int create_file(char *filename, mode_t mode); + int textfile_put(char *pathname, char *key, char *value); char *textfile_get(char *pathname, char *key); diff --git a/hcid/storage.c b/hcid/storage.c index eed3e694..e270cbd8 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -48,56 +48,6 @@ #include "textfile.h" #include "hcid.h" -static int create_dirs(char *filename, mode_t mode) -{ - struct stat st; - char dir[PATH_MAX + 1], *prev, *next; - int err; - - err = stat(filename, &st); - if (!err && S_ISREG(st.st_mode)) - return 0; - - memset(dir, 0, PATH_MAX + 1); - strcat(dir, "/"); - - prev = strchr(filename, '/'); - - while (prev) { - next = strchr(prev + 1, '/'); - if (!next) - break; - - if (next - prev == 1) { - prev = next; - continue; - } - - strncat(dir, prev + 1, next - prev); - mkdir(dir, mode); - - prev = next; - } - - return 0; -} - -static inline int create_file(char *filename, mode_t mode) -{ - int fd; - - umask(S_IWGRP | S_IWOTH); - create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - - fd = open(filename, O_RDWR | O_CREAT, mode); - if (fd < 0) - return fd; - - close(fd); - - return 0; -} - int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name) { char filename[PATH_MAX + 1], addr[18], str[249]; diff --git a/hidd/sdp.c b/hidd/sdp.c index 05cacf45..ea76894b 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -77,7 +77,7 @@ static void epox_endian_quirk(unsigned char *data, int size) static int store_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req) { char filename[PATH_MAX + 1], addr[18], *str, *desc; - int i, fd, size; + int i, size; ba2str(src, addr); snprintf(filename, PATH_MAX, "%s/%s/hidd", STORAGEDIR, addr); @@ -102,11 +102,7 @@ static int store_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hi req->subclass, req->country, req->parser, desc, req->flags, req->name); - fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) - return -errno; - - close(fd); + create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); ba2str(dst, addr); return textfile_put(filename, addr, str); -- cgit From 082b69d2c075d1ec468a0a3bcd16b5f077a3fd3f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 6 Sep 2005 20:57:54 +0000 Subject: Document the putkey and delkey commands --- tools/hciconfig.8 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 9fb8b552..53c60526 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -193,6 +193,16 @@ bytes and SCO buffer size to .I pkt packets. .TP +.BI putkey " " +This command stores the link key for +.I bdaddr +on the device. +.TP +.BI delkey " " +This command deletes the stored link key for +.I bdaddr +from the device. +.TP .BI commands Display supported commands. .TP -- cgit From 033622dcb3935c1d6a7147bfbbf753c1011e6ba0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 6 Sep 2005 21:51:34 +0000 Subject: Make the reset optional --- test/bdaddr.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/bdaddr.c b/test/bdaddr.c index e34cc961..5331a8dc 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -222,12 +222,13 @@ static void usage(void) { printf("bdaddr - Utility for changing the Bluetooth device address\n\n"); printf("Usage:\n" - "\tbdaddr [-i ] [new bdaddr]\n"); + "\tbdaddr [-i ] [-r] [new bdaddr]\n"); } static struct option main_options[] = { - { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, + { "reset", 0, 0, 'r' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -237,11 +238,11 @@ int main(int argc, char *argv[]) struct hci_version ver; bdaddr_t bdaddr; char addr[18]; - int i, dd, opt, dev = 0; + int i, dd, opt, dev = 0, reset = 0; bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -251,6 +252,10 @@ int main(int argc, char *argv[]) } break; + case 'r': + reset = 1; + break; + case 'h': default: usage(); @@ -323,7 +328,7 @@ int main(int argc, char *argv[]) printf("Address changed - "); - if (vendor[i].reset_device) { + if (reset && vendor[i].reset_device) { if (vendor[i].reset_device(dd) < 0) { printf("Reset device manually\n"); } else { -- cgit From 97dc071487f722e3ec91534e79313a843b85fb3e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 6 Sep 2005 22:01:30 +0000 Subject: Don't retrieve stored link keys for RAW devices --- hcid/security.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hcid/security.c b/hcid/security.c index 00204ace..eb50ee32 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -807,6 +807,9 @@ void start_security_manager(int hdev) io_chan[hdev] = chan; + if (hci_test_bit(HCI_RAW, &di->flags)) + return; + bacpy(&cp.bdaddr, BDADDR_ANY); cp.read_all = 1; -- cgit From 9848c1fa4ee7b49d425cb790fe9ab5edff8761dd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Sep 2005 16:15:39 +0000 Subject: Show supported commands also in clear text --- tools/hciconfig.c | 18 ++++++++++++++++-- tools/hcitool.c | 10 ++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 3bf3b292..0d13542d 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -795,6 +795,7 @@ static void cmd_delkey(int ctl, int hdev, char *opt) static void cmd_commands(int ctl, int hdev, char *opt) { uint8_t cmds[64]; + char *str; int i, n, dd; dd = hci_open_dev(hdev); @@ -823,12 +824,17 @@ static void cmd_commands(int ctl, int hdev, char *opt) printf(")\n"); } + str = hci_commandstostr(cmds, "\t", 71); + printf("%s\n", str); + bt_free(str); + hci_close_dev(dd); } static void cmd_version(int ctl, int hdev, char *opt) { struct hci_version ver; + char *hciver, *lmpver; int dd; dd = hci_open_dev(hdev); @@ -844,13 +850,21 @@ static void cmd_version(int ctl, int hdev, char *opt) exit(1); } + hciver = hci_vertostr(ver.hci_ver); + lmpver = lmp_vertostr(ver.hci_ver); + print_dev_hdr(&di); printf("\tHCI Ver: %s (0x%x) HCI Rev: 0x%x LMP Ver: %s (0x%x) LMP Subver: 0x%x\n" "\tManufacturer: %s (%d)\n", - hci_vertostr(ver.hci_ver), ver.hci_ver, ver.hci_rev, - lmp_vertostr(ver.lmp_ver), ver.lmp_ver, ver.lmp_subver, + hciver ? hciver : "n/a", ver.hci_ver, ver.hci_rev, + lmpver ? lmpver : "n/a", ver.lmp_ver, ver.lmp_subver, bt_compidtostr(ver.manufacturer), ver.manufacturer); + if (hciver) + bt_free(hciver); + if (lmpver) + bt_free(lmpver); + hci_close_dev(dd); } diff --git a/tools/hcitool.c b/tools/hcitool.c index bc09ea07..2865ec42 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -595,12 +595,15 @@ static void cmd_scan(int dev_id, int argc, char **argv) if (extinf && handle > 0) { if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + char *ver = lmp_vertostr(version.lmp_ver); printf("Manufacturer:\t%s (%d)\n", bt_compidtostr(version.manufacturer), version.manufacturer); printf("LMP version:\t%s (0x%x) [subver 0x%x]\n", - lmp_vertostr(version.lmp_ver), + ver ? ver : "n/a", version.lmp_ver, version.lmp_subver); + if (ver) + bt_free(ver); } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { @@ -779,13 +782,16 @@ static void cmd_info(int dev_id, int argc, char **argv) printf("\tDevice Name: %s\n", name); if (hci_read_remote_version(dd, handle, &version, 20000) == 0) { + char *ver = lmp_vertostr(version.lmp_ver); printf("\tLMP Version: %s (0x%x) LMP Subversion: 0x%x\n" "\tManufacturer: %s (%d)\n", - lmp_vertostr(version.lmp_ver), + ver ? ver : "n/a", version.lmp_ver, version.lmp_subver, bt_compidtostr(version.manufacturer), version.manufacturer); + if (ver) + bt_free(ver); } if (hci_read_remote_features(dd, handle, features, 20000) == 0) { -- cgit From a8b5fad54044c7b5e7c6aa30ad24e5a86fc51daf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Sep 2005 17:23:00 +0000 Subject: Fix memory leaks with textfile_get() usage --- common/test_textfile.c | 3 +++ hcid/storage.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/common/test_textfile.c b/common/test_textfile.c index 54202d2c..5a783d20 100644 --- a/common/test_textfile.c +++ b/common/test_textfile.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include "textfile.h" @@ -64,6 +65,8 @@ int main(int argc, char *argv[]) str = textfile_get(filename, key); if (!str) fprintf(stderr, "No value for %s\n", key); + else + free(str); } return 0; diff --git a/hcid/storage.c b/hcid/storage.c index e270cbd8..e8d2ce1c 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +88,8 @@ int read_device_name(bdaddr_t *local, bdaddr_t *peer, char *name) str[248] = '\0'; strcpy(name, str); + free(str); + return 0; } @@ -162,6 +165,8 @@ int read_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key) key[i] = (uint8_t) strtol(tmp, NULL, 16); } + free(str); + return 0; } @@ -181,5 +186,7 @@ int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin) strncpy(pin, str, 16); len = strlen(pin); + free(str); + return len; } -- cgit From 50195243cfcac56a039480c3506acd0f5c5f80e0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Sep 2005 17:31:56 +0000 Subject: Let textfile_put() also replace the last key value pair --- common/textfile.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/common/textfile.c b/common/textfile.c index 26cbbea7..095e0355 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -180,8 +180,15 @@ int textfile_put(char *pathname, char *key, char *value) end += len; len = size - (end - map); + if (!len) { + munmap(map, size); + ftruncate(fd, base); + pos = lseek(fd, base, SEEK_SET); + err = write_key_value(fd, key, value); + goto unlock; + } - if (len <= 0 || len > size) { + if (len < 0 || len > size) { err = EILSEQ; goto unmap; } @@ -193,12 +200,12 @@ int textfile_put(char *pathname, char *key, char *value) } memcpy(str, end, len); - munmap(map, size); + munmap(map, size); ftruncate(fd, base); pos = lseek(fd, base, SEEK_SET); + err = write_key_value(fd, key, value); - write_key_value(fd, key, value); write(fd, str, len); free(str); -- cgit From fdc6176107c8ef2a88a225a335cca3c6cd2a0808 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Sep 2005 21:47:05 +0000 Subject: Add an example for the PSR file format --- tools/Makefile.am | 2 +- tools/example.psr | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 tools/example.psr diff --git a/tools/Makefile.am b/tools/Makefile.am index adff35b9..e3983a17 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -72,6 +72,6 @@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 dfutool.1 +EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 dfutool.1 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/example.psr b/tools/example.psr new file mode 100644 index 00000000..bbbec73a --- /dev/null +++ b/tools/example.psr @@ -0,0 +1,12 @@ +// PSKEY_BDADDR +&0001 = 0001 2821 005b 6789 +// PSKEY_ANA_FTRIM +&01f6 = 0025 +// PSKEY_HOST_INTERFACE +&01f9 = 0001 +// PSKEY_UART_BAUD_RATE +&0204 = 01d8 +// PSKEY_ANA_FREQ +&01fe = 0004 +// PSKEY_UART_CONFIG +&0205 = 0006 -- cgit From 0738cf5e684464d157816be73c0b19efb7dd4fc7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 Sep 2005 00:24:52 +0000 Subject: Support volatile changes of the BD_ADDR for CSR chips --- test/bdaddr.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/bdaddr.c b/test/bdaddr.c index 5331a8dc..57d9b005 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -41,6 +41,8 @@ #include #include +static int transient = 0; + #define OCF_ERICSSON_WRITE_BD_ADDR 0x000d typedef struct { bdaddr_t bdaddr; @@ -113,6 +115,9 @@ static int csr_write_bd_addr(int dd, bdaddr_t *bdaddr) unsigned char cp[254], rp[254]; struct hci_request rq; + if (transient) + cmd[14] = 0x08; + cmd[16] = bdaddr->b[2]; cmd[17] = 0x00; cmd[18] = bdaddr->b[0]; @@ -160,6 +165,9 @@ static int csr_reset_device(int dd) unsigned char cp[254], rp[254]; struct hci_request rq; + if (transient) + cmd[6] = 0x02; + memset(&cp, 0, sizeof(cp)); cp[0] = 0xc2; memcpy(cp + 1, cmd, sizeof(cmd)); @@ -222,12 +230,13 @@ static void usage(void) { printf("bdaddr - Utility for changing the Bluetooth device address\n\n"); printf("Usage:\n" - "\tbdaddr [-i ] [-r] [new bdaddr]\n"); + "\tbdaddr [-i ] [-r] [-t] [new bdaddr]\n"); } static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, + { "transient", 0, 0, 't' }, { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -242,7 +251,7 @@ int main(int argc, char *argv[]) bacpy(&bdaddr, BDADDR_ANY); - while ((opt=getopt_long(argc, argv, "+i:rh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rth", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -256,6 +265,10 @@ int main(int argc, char *argv[]) reset = 1; break; + case 't': + transient = 1; + break; + case 'h': default: usage(); -- cgit From 36e1d1d1f94e5cf10e9d5cf7de1d2878b3d33ed8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 Sep 2005 10:54:30 +0000 Subject: Add skeleton for the csrinit utility --- acinclude.m4 | 7 ++++ tools/Makefile.am | 19 ++++++++-- tools/csrinit.8 | 35 +++++++++++++++++++ tools/csrinit.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 tools/csrinit.8 create mode 100644 tools/csrinit.c diff --git a/acinclude.m4 b/acinclude.m4 index 83adb960..4d49dc81 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -265,6 +265,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ initscripts_enable=no avctrl_enable=${usb_found} hid2hci_enable=${usb_found} + csrinit_enable=no dfutool_enable=no bcm203x_enable=no bluepin_enable=yes @@ -287,6 +288,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ initscripts_enable=${enableval} avctrl_enable=${enableval} hid2hci_enable=${enableval} + csrinit_enable=${enableval} dfutool_enable=${enableval} bcm203x_enable=${enableval} bluepin_enable=${enableval} @@ -328,6 +330,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ hid2hci_enable=${enableval} ]) + AC_ARG_ENABLE(csrinit, AC_HELP_STRING([--enable-csrinit], [install CSR ROM chip setup utility]), [ + csrinit_enable=${enableval} + ]) + AC_ARG_ENABLE(dfutool, AC_HELP_STRING([--enable-dfutool], [install DFU firmware upgrade utility]), [ dfutool_enable=${enableval} ]) @@ -358,6 +364,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ AM_CONDITIONAL(INITSCRIPTS, test "${initscripts_enable}" = "yes") AM_CONDITIONAL(AVCTRL, test "${avctrl_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes") + AM_CONDITIONAL(CSRINIT, test "${csrinit_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(DFUTOOL, test "${dfutool_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(BCM203X, test "${bcm203x_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(BLUEPIN, test "${bluepin_enable}" = "yes") diff --git a/tools/Makefile.am b/tools/Makefile.am index e3983a17..3a018bb7 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -18,6 +18,14 @@ hid2hci_programs = hid2hci_manfiles = endif +if CSRINIT +csrinit_programs = csrinit +csrinit_manfiles = csrinit.8 +else +csrinit_programs = +csrinit_manfiles = +endif + if DFUTOOL dfutool_programs = dfutool dfutool_manfiles = dfutool.1 @@ -26,7 +34,7 @@ dfutool_programs = dfutool_manfiles = endif -sbin_PROGRAMS = hciattach hciconfig $(avctrl_programs) $(hid2hci_programs) +sbin_PROGRAMS = hciattach hciconfig $(avctrl_programs) $(hid2hci_programs) $(csrinit_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) @@ -60,6 +68,11 @@ if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif +if CSRINIT +csrinit_SOURCES = csrinit.c csr.h +csrinit_LDADD = @USB_LIBS@ +endif + if DFUTOOL dfutool_SOURCES = dfutool.c dfu.h dfu.c dfutool_LDADD = @USB_LIBS@ @@ -70,8 +83,8 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ - $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) + $(avctrl_manfiles) $(hid2hci_manfiles) $(csrinit_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 dfutool.1 example.psr +EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 csrinit.8 dfutool.1 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/csrinit.8 b/tools/csrinit.8 new file mode 100644 index 00000000..35a033d9 --- /dev/null +++ b/tools/csrinit.8 @@ -0,0 +1,35 @@ +.\" +.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. +.\" +.\" +.TH CSRINIT 8 "SEPTEMBER 8, 2005" "" "" + +.SH NAME +csrinit \- Utility for the setting up CSR ROM chips +.SH SYNOPSIS +.BR "csrinit +[ +.I options +] +.SH DESCRIPTION +.B csrinit +is used to setup the ROM chips from CSR. +.SH OPTIONS +.TP +.BI -h +Gives a list of possible options. +.SH AUTHOR +Written by Marcel Holtmann . +.br diff --git a/tools/csrinit.c b/tools/csrinit.c new file mode 100644 index 00000000..07310175 --- /dev/null +++ b/tools/csrinit.c @@ -0,0 +1,101 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "csr.h" + +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif + +#ifndef USB_DIR_IN +#define USB_DIR_IN 0x80 +#endif + +static void usage(void) +{ + printf("csrinit - Utility for the setting up CSR ROM chips\n\n"); + + printf("Usage:\n" + "\tcsrinit [options]\n" + "\n"); + + printf("Options:\n" + "\t-h, --help Display help\n" + "\n"); +} + +static struct option main_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +int main(int argc, char *argv[]) +{ + int opt; + + while ((opt = getopt_long(argc, argv, "+h", main_options, NULL)) != -1) { + switch (opt) { + case 'h': + usage(); + exit(0); + + default: + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + usb_init(); + + return 0; +} -- cgit From 5a1c827dde80ace68f94641edb21d39c1ccacbbc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 Sep 2005 11:51:20 +0000 Subject: Update security filter definitions --- tools/hcisecfilter.c | 152 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 61 deletions(-) diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index d3c658c8..02d0d554 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -45,82 +45,112 @@ int main(void) uint32_t ocf_mask[4]; /* Packet types */ - memset((void *)&type_mask, 0, sizeof(type_mask)); + memset(&type_mask, 0, sizeof(type_mask)); hci_set_bit(HCI_EVENT_PKT, &type_mask); - printf("Type mask: { 0x%x }\n", type_mask); + printf("Type mask: { 0x%02x }\n", type_mask); /* Events */ - memset((void *)event_mask, 0, sizeof(event_mask)); - hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); - hci_set_bit(EVT_INQUIRY_RESULT, event_mask); - - hci_set_bit(EVT_CONN_COMPLETE, event_mask); - hci_set_bit(EVT_CONN_REQUEST, event_mask); - hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); - - hci_set_bit(EVT_AUTH_COMPLETE, event_mask); - hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); - - hci_set_bit(EVT_CMD_COMPLETE, event_mask); - hci_set_bit(EVT_CMD_STATUS, event_mask); - - hci_set_bit(EVT_READ_REMOTE_FEATURES_COMPLETE, event_mask); - hci_set_bit(EVT_READ_REMOTE_VERSION_COMPLETE, event_mask); - hci_set_bit(EVT_REMOTE_NAME_REQ_COMPLETE, event_mask); - - printf("Event mask: { 0x%x, 0x%x }\n", event_mask[0], event_mask[1]); + memset(event_mask, 0, sizeof(event_mask)); + hci_set_bit(EVT_INQUIRY_COMPLETE, event_mask); + hci_set_bit(EVT_INQUIRY_RESULT, event_mask); + hci_set_bit(EVT_CONN_COMPLETE, event_mask); + hci_set_bit(EVT_CONN_REQUEST, event_mask); + hci_set_bit(EVT_DISCONN_COMPLETE, event_mask); + hci_set_bit(EVT_AUTH_COMPLETE, event_mask); + hci_set_bit(EVT_REMOTE_NAME_REQ_COMPLETE, event_mask); + hci_set_bit(EVT_ENCRYPT_CHANGE, event_mask); + hci_set_bit(EVT_READ_REMOTE_FEATURES_COMPLETE, event_mask); + hci_set_bit(EVT_READ_REMOTE_VERSION_COMPLETE, event_mask); + hci_set_bit(EVT_CMD_COMPLETE, event_mask); + hci_set_bit(EVT_CMD_STATUS, event_mask); + hci_set_bit(EVT_READ_CLOCK_OFFSET_COMPLETE, event_mask); + hci_set_bit(EVT_INQUIRY_RESULT_WITH_RSSI, event_mask); + hci_set_bit(EVT_READ_REMOTE_EXT_FEATURES_COMPLETE, event_mask); + hci_set_bit(EVT_SYNC_CONN_COMPLETE, event_mask); + hci_set_bit(EVT_SYNC_CONN_CHANGED, event_mask); + //hci_set_bit(EVT_EXTENDED_INQUIRY_RESULT, event_mask); + + printf("Event mask: { 0x%08x, 0x%08x }\n", + event_mask[0], event_mask[1]); /* OGF_LINK_CTL */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_INQUIRY, ocf_mask); - hci_set_bit(OCF_REMOTE_NAME_REQ, ocf_mask); - hci_set_bit(OCF_READ_REMOTE_FEATURES, ocf_mask); - hci_set_bit(OCF_READ_REMOTE_VERSION, ocf_mask); - - printf("OGF_LINK_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", - ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_INQUIRY, ocf_mask); + hci_set_bit(OCF_INQUIRY_CANCEL, ocf_mask); + hci_set_bit(OCF_REMOTE_NAME_REQ, ocf_mask); + hci_set_bit(OCF_REMOTE_NAME_REQ_CANCEL, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_EXT_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_REMOTE_VERSION, ocf_mask); + hci_set_bit(OCF_READ_CLOCK_OFFSET, ocf_mask); + hci_set_bit(OCF_READ_LMP_HANDLE, ocf_mask); + + printf("OGF_LINK_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_LINK_POLICY */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); - hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_ROLE_DISCOVERY, ocf_mask); + hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); + hci_set_bit(OCF_READ_DEFAULT_LINK_POLICY, ocf_mask); - printf("OGF_LINK_POLICY: { 0x%x, 0x%x, 0x%x, 0x%x }\n", + printf("OGF_LINK_POLICY: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_HOST_CTL */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_READ_AUTH_ENABLE, ocf_mask); - hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); - hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); - hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); - hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); - hci_set_bit(OCF_READ_TRANSMIT_POWER_LEVEL, ocf_mask); - - printf("OGF_HOST_CTL: { 0x%x, 0x%x, 0x%x, 0x%x }\n", - ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_PIN_TYPE, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_NAME, ocf_mask); + hci_set_bit(OCF_READ_CONN_ACCEPT_TIMEOUT, ocf_mask); + hci_set_bit(OCF_READ_PAGE_TIMEOUT, ocf_mask); + hci_set_bit(OCF_READ_SCAN_ENABLE, ocf_mask); + hci_set_bit(OCF_READ_PAGE_ACTIVITY, ocf_mask); + hci_set_bit(OCF_READ_INQ_ACTIVITY, ocf_mask); + hci_set_bit(OCF_READ_AUTH_ENABLE, ocf_mask); + hci_set_bit(OCF_READ_ENCRYPT_MODE, ocf_mask); + hci_set_bit(OCF_READ_CLASS_OF_DEV, ocf_mask); + hci_set_bit(OCF_READ_VOICE_SETTING, ocf_mask); + hci_set_bit(OCF_READ_AUTOMATIC_FLUSH_TIMEOUT, ocf_mask); + hci_set_bit(OCF_READ_NUM_BROADCAST_RETRANS, ocf_mask); + hci_set_bit(OCF_READ_HOLD_MODE_ACTIVITY, ocf_mask); + hci_set_bit(OCF_READ_TRANSMIT_POWER_LEVEL, ocf_mask); + hci_set_bit(OCF_READ_LINK_SUPERVISION_TIMEOUT, ocf_mask); + hci_set_bit(OCF_READ_NUM_SUPPORTED_IAC, ocf_mask); + hci_set_bit(OCF_READ_CURRENT_IAC_LAP, ocf_mask); + hci_set_bit(OCF_READ_PAGE_SCAN_PERIOD_MODE, ocf_mask); + hci_set_bit(OCF_READ_PAGE_SCAN_MODE, ocf_mask); + hci_set_bit(OCF_READ_INQUIRY_SCAN_TYPE, ocf_mask); + hci_set_bit(OCF_READ_INQUIRY_MODE, ocf_mask); + hci_set_bit(OCF_READ_PAGE_SCAN_TYPE, ocf_mask); + hci_set_bit(OCF_READ_AFH_MODE, ocf_mask); + + printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_INFO_PARAM */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_READ_LOCAL_VERSION, ocf_mask); - hci_set_bit(OCF_READ_LOCAL_FEATURES, ocf_mask); - hci_set_bit(OCF_READ_BUFFER_SIZE, ocf_mask); - hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); - hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_LOCAL_VERSION, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_COMMANDS, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_LOCAL_EXT_FEATURES, ocf_mask); + hci_set_bit(OCF_READ_BUFFER_SIZE, ocf_mask); + hci_set_bit(OCF_READ_COUNTRY_CODE, ocf_mask); + hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); + + printf("OGF_INFO_PARAM: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); - printf("OGF_INFO_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", - ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + /* OGF_STATUS_PARAM */ + memset(ocf_mask, 0, sizeof(ocf_mask)); + hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); + hci_set_bit(OCF_READ_LINK_QUALITY, ocf_mask); + hci_set_bit(OCF_READ_RSSI, ocf_mask); + hci_set_bit(OCF_READ_AFH_MAP, ocf_mask); + hci_set_bit(OCF_READ_CLOCK, ocf_mask); - /* OGF_INFO_PARAM */ - memset((void *) ocf_mask, 0, sizeof(ocf_mask)); - hci_set_bit(OCF_READ_FAILED_CONTACT_COUNTER, ocf_mask); - hci_set_bit(OCF_RESET_FAILED_CONTACT_COUNTER, ocf_mask); - hci_set_bit(OCF_READ_LINK_QUALITY, ocf_mask); - hci_set_bit(OCF_READ_RSSI, ocf_mask); - - printf("OGF_STATUS_PARAM: { 0x%x, 0x%x, 0x%x, 0x%x}\n", - ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); + printf("OGF_STATUS_PARAM: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); return 0; } -- cgit From 2ed8bc58caa1e27dffad6766a59f8f9f0930dc08 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Sep 2005 04:10:59 +0000 Subject: Don't forget the command for reading the extended inquiry response --- tools/hcisecfilter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 02d0d554..5827f143 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -124,6 +124,7 @@ int main(void) hci_set_bit(OCF_READ_INQUIRY_MODE, ocf_mask); hci_set_bit(OCF_READ_PAGE_SCAN_TYPE, ocf_mask); hci_set_bit(OCF_READ_AFH_MODE, ocf_mask); + //hci_set_bit(OCF_READ_EXT_INQUIRY_RESPONSE, ocf_mask); printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); -- cgit From e116bfb4f0192a6e54a71dfb0b2f3b63849e1524 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 00:03:53 +0000 Subject: Add support for PSKEY_ANA_FREQ and PSKEY_ANA_FTRIM --- tools/csr.h | 4 +++- tools/pskey.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/csr.h b/tools/csr.h index acb30641..95b5c63d 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -65,7 +65,9 @@ #define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ #define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab #define CSR_PSKEY_UART_BAUDRATE 0x01be -#define CSR_PSKEY_HOST_INTERFACE 0x01f9 +#define CSR_PSKEY_ANA_FTRIM 0x01f6 /* uint16 */ +#define CSR_PSKEY_HOST_INTERFACE 0x01f9 /* uint16 */ +#define CSR_PSKEY_ANA_FREQ 0x01fe /* uint16 */ #define CSR_PSKEY_USB_VENDOR_ID 0x02be #define CSR_PSKEY_USB_PRODUCT_ID 0x02bf #define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb diff --git a/tools/pskey.c b/tools/pskey.c index 9a4dd547..030a6a43 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -123,6 +123,8 @@ static struct { { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, + { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, "anafreq" }, + { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, "anaftrim" }, { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, -- cgit From b42672cbb91ea35268da5f0f385f539f133b2a0e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 00:09:39 +0000 Subject: Add PSKEY_ANA_FREQ and PSKEY_ANA_FTRIM translations --- tools/csr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 1f1ab229..5932c822 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -412,8 +412,12 @@ char *csr_pskeytostr(uint16_t pskey) return "Map SCO over PCM"; case CSR_PSKEY_UART_BAUDRATE: return "UART Baud rate"; + case CSR_PSKEY_ANA_FTRIM: + return "Crystal frequency trim"; case CSR_PSKEY_HOST_INTERFACE: return "Host interface"; + case CSR_PSKEY_ANA_FREQ: + return "Crystal frequency"; case CSR_PSKEY_USB_VENDOR_ID: return "USB vendor identifier"; case CSR_PSKEY_USB_PRODUCT_ID: -- cgit From 7eaf5aa39ab4592548baeffaca65f0e490e036b1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 00:34:21 +0000 Subject: Add support for transient persistent storage values --- tools/csr.c | 15 ++++++++------- tools/csr.h | 6 +++--- tools/hciconfig.c | 2 +- tools/pskey.c | 20 ++++++++++++++------ 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 5932c822..39706623 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -598,13 +598,13 @@ int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *val return 0; } -int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length) +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, pskey & 0xff, pskey >> 8, (length / 2) & 0xff, (length / 2) >> 8, - 0x00, 0x00, 0x00, 0x00 }; + store & 0xff, store >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; struct hci_request rq; @@ -640,11 +640,12 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *val return 0; } -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value) +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value) { unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, - pskey & 0xff, pskey >> 8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; + pskey & 0xff, pskey >> 8, 0x01, 0x00, + store & 0xff, store >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; struct hci_request rq; @@ -680,12 +681,12 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *val return 0; } -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value) +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value) { unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, - pskey & 0xff, pskey >> 8, 0x01, 0x00, 0x00, 0x00, - value & 0xff, value >> 8 }; + pskey & 0xff, pskey >> 8, 0x01, 0x00, + store & 0xff, store >> 8, value & 0xff, value >> 8 }; unsigned char cp[254], rp[254]; struct hci_request rq; diff --git a/tools/csr.h b/tools/csr.h index 95b5c63d..dc5e1029 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -81,6 +81,6 @@ int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); -int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint8_t *value, uint16_t length); -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t *value); -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t value); +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value); +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 0d13542d..2a352e85 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -1225,7 +1225,7 @@ static void print_rev_csr(int dd, uint16_t rev) if (!csr_read_varid_uint16(dd, 3, CSR_VARID_MAX_CRYPT_KEY_LENGTH, &maxkeylen)) printf("\tMax key size: %d bit\n", maxkeylen * 8); - if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, &mapsco)) + if (!csr_read_pskey_uint16(dd, 4, CSR_PSKEY_HOSTIO_MAP_SCO_PCM, 0x0000, &mapsco)) printf("\tSCO mapping: %s\n", mapsco ? "PCM" : "HCI"); } diff --git a/tools/pskey.c b/tools/pskey.c index 030a6a43..0180be59 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -47,6 +47,8 @@ #define CSR_TYPE_UINT8 2 #define CSR_TYPE_UINT16 3 +static int transient = 0; + static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { uint16_t value; @@ -67,7 +69,8 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) else value = atoi(argv[0]); - err = csr_write_pskey_uint16(dd, 0x4711, pskey, value); + err = csr_write_pskey_uint16(dd, 0x4711, pskey, + transient ? 0x0008 : 0x0000, value); return err; } @@ -88,7 +91,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) } if (type != CSR_TYPE_ARRAY) { - err = csr_read_pskey_uint16(dd, 0x4711, pskey, &value); + err = csr_read_pskey_uint16(dd, 0x4711, pskey, 0x0000, &value); if (err < 0) return err; @@ -97,7 +100,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) size = 8; - err = csr_read_pskey_complex(dd, 0x4711, pskey, array, size); + err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); if (err < 0) return err; @@ -138,7 +141,7 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [value]\n\n"); + "\tpskey [-i ] [-t] [value]\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -153,8 +156,9 @@ static void usage(void) } static struct option main_options[] = { - { "help", 0, 0, 'h' }, { "device", 1, 0, 'i' }, + { "transient", 0, 0, 't' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -164,7 +168,7 @@ int main(int argc, char *argv[]) struct hci_version ver; int i, err, dd, opt, dev = 0; - while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:th", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -174,6 +178,10 @@ int main(int argc, char *argv[]) } break; + case 't': + transient = 1; + break; + case 'h': default: usage(); -- cgit From 0f29ca5cf9885ba0b22db226c73c09478470c097 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 00:47:42 +0000 Subject: Add optional warm reset of the device --- tools/pskey.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tools/pskey.c b/tools/pskey.c index 0180be59..0c06e9ef 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -141,7 +141,7 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [-t] [value]\n\n"); + "\tpskey [-i ] [-r] [-t] [value]\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -157,6 +157,7 @@ static void usage(void) static struct option main_options[] = { { "device", 1, 0, 'i' }, + { "reset", 0, 0, 'r' }, { "transient", 0, 0, 't' }, { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } @@ -166,9 +167,9 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0; + int i, err, dd, opt, dev = 0, reset = 0; - while ((opt=getopt_long(argc, argv, "+i:th", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rth", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -178,6 +179,10 @@ int main(int argc, char *argv[]) } break; + case 'r': + reset = 1; + break; + case 't': transient = 1; break; @@ -229,10 +234,14 @@ int main(int argc, char *argv[]) if (strcasecmp(storage[i].str, argv[0])) continue; - if (argc > 1) + if (argc > 1) { err = write_pskey(dd, storage[i].pskey, storage[i].type, argc - 1, argv + 1); - else + + if (reset) + csr_write_varid_valueless(dd, 0x0000, + CSR_VARID_WARM_RESET); + } else err = read_pskey(dd, storage[i].pskey, storage[i].type); hci_close_dev(dd); -- cgit From 92510c33c1ab156ced109ae1652248ef08beabe8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 01:23:19 +0000 Subject: Add check for Filesystem in Userspace (FUSE) --- acinclude.m4 | 122 ++++++++++++++++++++++++++++++++++++++--------------------- configure.in | 3 +- 2 files changed, 81 insertions(+), 44 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 4d49dc81..9b38c25a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -134,6 +134,85 @@ AC_DEFUN([AC_PATH_OPENOBEX], [ AC_SUBST(OPENOBEX_LIBS) ]) +AC_DEFUN([AC_PATH_DBUS], [ + dbus_prefix=${prefix} + + AC_ARG_WITH(dbus, AC_HELP_STRING([--with-dbus=DIR], [D-BUS library is installed in DIR]), [ + if (test "${withval}" != "yes"); then + dbus_prefix=${withval} + fi + ]) + + ac_save_CPPFLAGS=$CPPFLAGS + ac_save_LDFLAGS=$LDFLAGS + + DBUS_CFLAGS="-DDBUS_API_SUBJECT_TO_CHANGE" + test -d "${dbus_prefix}/include/dbus-1.0" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/include/dbus-1.0" + if (test "${prefix}" = "${bluez_prefix}"); then + test -d "${libdir}/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${libdir}/dbus-1.0/include" + else + test -d "${dbus_prefix}/lib64/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib64/dbus-1.0/include" + test -d "${dbus_prefix}/lib/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib/dbus-1.0/include" + fi + + CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS" + AC_CHECK_HEADER(dbus/dbus.h, dbus_found=yes, dbus_found=no) + + DBUS_LIBS="" + if (test "${prefix}" = "${dbus_prefix}"); then + test -d "${libdir}" && DBUS_LIBS="$DBUS_LIBS -L${libdir}" + else + test -d "${dbus_prefix}/lib64" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib64" + test -d "${dbus_prefix}/lib" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib" + fi + + LDFLAGS="$LDFLAGS $DBUS_LIBS" + AC_CHECK_LIB(dbus-1, dbus_error_init, DBUS_LIBS="$DBUS_LIBS -ldbus-1", dbus_found=no) + AC_CHECK_LIB(dbus-1, dbus_message_iter_get_basic, AC_DEFINE(HAVE_DBUS_MESSAGE_ITER_GET_BASIC, 1, [Define to 1 if you have the dbus_message_iter_get_basic() function.])) + + CPPFLAGS=$ac_save_CPPFLAGS + LDFLAGS=$ac_save_LDFLAGS + + AC_SUBST(DBUS_CFLAGS) + AC_SUBST(DBUS_LIBS) +]) + +AC_DEFUN([AC_PATH_FUSE], [ + fuse_prefix=${prefix} + + AC_ARG_WITH(fuse, AC_HELP_STRING([--with-fuse=DIR], [FUSE library is installed in DIR]), [ + if (test "${withval}" != "yes"); then + fuse_prefix=${withval} + fi + ]) + + ac_save_CPPFLAGS=$CPPFLAGS + ac_save_LDFLAGS=$LDFLAGS + + FUSE_CFLAGS="" + test -d "${fuse_prefix}/include" && FUSE_CFLAGS="$FUSE_CFLAGS -I${fuse_prefix}/include" + + CPPFLAGS="$CPPFLAGS $FUSE_CFLAGS" + AC_CHECK_HEADER(fuse.h, fuse_found=yes, fuse_found=no) + + FUSE_LIBS="" + if (test "${prefix}" = "${fuse_prefix}"); then + test -d "${libdir}" && FUSE_LIBS="$FUSE_LIBS -L${libdir}" + else + test -d "${fuse_prefix}/lib64" && FUSE_LIBS="$FUSE_LIBS -L${fuse_prefix}/lib64" + test -d "${fuse_prefix}/lib" && FUSE_LIBS="$FUSE_LIBS -L${fuse_prefix}/lib" + fi + + LDFLAGS="$LDFLAGS $FUSE_LIBS" + AC_CHECK_LIB(fuse, fuse_main, FUSE_LIBS="$FUSE_LIBS -lfuse", fuse_found=no) + + CPPFLAGS=$ac_save_CPPFLAGS + LDFLAGS=$ac_save_LDFLAGS + + AC_SUBST(FUSE_CFLAGS) + AC_SUBST(FUSE_LIBS) +]) + AC_DEFUN([AC_PATH_ALSA], [ alsa_prefix=${prefix} @@ -210,49 +289,6 @@ AC_DEFUN([AC_PATH_USB], [ AC_SUBST(USB_LIBS) ]) -AC_DEFUN([AC_PATH_DBUS], [ - dbus_prefix=${prefix} - - AC_ARG_WITH(dbus, AC_HELP_STRING([--with-dbus=DIR], [D-BUS library is installed in DIR]), [ - if (test "${withval}" != "yes"); then - dbus_prefix=${withval} - fi - ]) - - ac_save_CPPFLAGS=$CPPFLAGS - ac_save_LDFLAGS=$LDFLAGS - - DBUS_CFLAGS="-DDBUS_API_SUBJECT_TO_CHANGE" - test -d "${dbus_prefix}/include/dbus-1.0" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/include/dbus-1.0" - if (test "${prefix}" = "${bluez_prefix}"); then - test -d "${libdir}/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${libdir}/dbus-1.0/include" - else - test -d "${dbus_prefix}/lib64/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib64/dbus-1.0/include" - test -d "${dbus_prefix}/lib/dbus-1.0/include" && DBUS_CFLAGS="$DBUS_CFLAGS -I${dbus_prefix}/lib/dbus-1.0/include" - fi - - CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS" - AC_CHECK_HEADER(dbus/dbus.h, dbus_found=yes, dbus_found=no) - - DBUS_LIBS="" - if (test "${prefix}" = "${dbus_prefix}"); then - test -d "${libdir}" && DBUS_LIBS="$DBUS_LIBS -L${libdir}" - else - test -d "${dbus_prefix}/lib64" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib64" - test -d "${dbus_prefix}/lib" && DBUS_LIBS="$DBUS_LIBS -L${dbus_prefix}/lib" - fi - - LDFLAGS="$LDFLAGS $DBUS_LIBS" - AC_CHECK_LIB(dbus-1, dbus_error_init, DBUS_LIBS="$DBUS_LIBS -ldbus-1", dbus_found=no) - AC_CHECK_LIB(dbus-1, dbus_message_iter_get_basic, AC_DEFINE(HAVE_DBUS_MESSAGE_ITER_GET_BASIC, 1, [Define to 1 if you have the dbus_message_iter_get_basic() function.])) - - CPPFLAGS=$ac_save_CPPFLAGS - LDFLAGS=$ac_save_LDFLAGS - - AC_SUBST(DBUS_CFLAGS) - AC_SUBST(DBUS_LIBS) -]) - AC_DEFUN([AC_ARG_BLUEZ], [ debug_enable=no pie_enable=no diff --git a/configure.in b/configure.in index 18690966..107ce98f 100644 --- a/configure.in +++ b/configure.in @@ -28,9 +28,10 @@ AC_PROG_LIBTOOL AC_PATH_BLUEZ AC_PATH_OPENOBEX +AC_PATH_DBUS +AC_PATH_FUSE AC_PATH_ALSA AC_PATH_USB -AC_PATH_DBUS AC_ARG_BLUEZ -- cgit From b4b75b29434226f97505afa14a9b8838d9b93f61 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 09:44:19 +0000 Subject: Fix infinite loops and false positive matches --- common/textfile.c | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/common/textfile.c b/common/textfile.c index 095e0355..f15d439c 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -113,6 +113,17 @@ static inline int write_key_value(int fd, char *key, char *value) return err; } +static inline char *find_key(char *map, char *key, size_t len) +{ + char *off = strstr(map, key); + + while (off && ((off > map && *(off - 1) != '\r' && + *(off - 1) != '\n') || *(off + len) != ' ')) + off = strstr(off + len, key); + + return off; +} + int textfile_put(char *pathname, char *key, char *value) { struct stat st; @@ -148,7 +159,7 @@ int textfile_put(char *pathname, char *key, char *value) goto unlock; } - off = strstr(map, key); + off = find_key(map, key, strlen(key)); if (!off) { munmap(map, size); pos = lseek(fd, size, SEEK_SET); @@ -156,18 +167,6 @@ int textfile_put(char *pathname, char *key, char *value) goto unlock; } - if (off > map) { - while (*(off - 1) != '\r' && *(off - 1) != '\n') { - off = strstr(off, key); - if (!off) { - munmap(map, size); - pos = lseek(fd, size, SEEK_SET); - err = write_key_value(fd, key, value); - goto unlock; - } - } - } - base = off - map; end = strpbrk(off, "\r\n"); @@ -254,29 +253,19 @@ char *textfile_get(char *pathname, char *key) goto unlock; } - off = strstr(map, key); + len = strlen(key); + off = find_key(map, key, len); if (!off) { err = EILSEQ; goto unmap; } - if (off > map) { - while (*(off - 1) != '\r' && *(off - 1) != '\n') { - off = strstr(off, key); - if (!off) { - err = EILSEQ; - goto unmap; - } - } - } - end = strpbrk(off, "\r\n"); if (!end) { err = EILSEQ; goto unmap; } - len = strlen(key); str = malloc(end - off - len); if (!str) { err = EILSEQ; -- cgit From 64a05a4438eb8c1258aabcd5864cf9f9c5ff2d07 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 09:56:03 +0000 Subject: The Filesystem in Userspace needs -D_FILE_OFFSET_BITS=64 --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 9b38c25a..e305b6b0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -189,7 +189,7 @@ AC_DEFUN([AC_PATH_FUSE], [ ac_save_CPPFLAGS=$CPPFLAGS ac_save_LDFLAGS=$LDFLAGS - FUSE_CFLAGS="" + FUSE_CFLAGS="-D_FILE_OFFSET_BITS=64" test -d "${fuse_prefix}/include" && FUSE_CFLAGS="$FUSE_CFLAGS -I${fuse_prefix}/include" CPPFLAGS="$CPPFLAGS $FUSE_CFLAGS" -- cgit From 51cf782b65ab5f022e725faf9c78907fd8fade46 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 10:25:38 +0000 Subject: Add support for the Filesystem in Userspace (FUSE) --- Makefile.am | 2 +- acinclude.m4 | 21 ++++++++---- configure.in | 2 +- fuse/Makefile.am | 14 ++++++++ fuse/main.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 fuse/Makefile.am create mode 100644 fuse/main.c diff --git a/Makefile.am b/Makefile.am index a0042ed8..17766626 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,7 @@ # SUBDIRS = common daemon tools rfcomm hcid sdpd dund pand hidd \ - cups alsa test scripts pcmcia extra + cups fuse alsa test scripts pcmcia extra MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in config.sub config.guess \ diff --git a/acinclude.m4 b/acinclude.m4 index e305b6b0..9f6779a9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -292,9 +292,10 @@ AC_DEFUN([AC_PATH_USB], [ AC_DEFUN([AC_ARG_BLUEZ], [ debug_enable=no pie_enable=no + dbus_enable=${dbus_found} obex_enable=${openobex_found} + fuse_enable=no alsa_enable=no - dbus_enable=${dbus_found} test_enable=no cups_enable=no pcmcia_enable=no @@ -315,9 +316,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ ]) AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], [enable all extra options below]), [ + dbus_enable=${enableval} obex_enable=${enableval} + fuse_enable=${enableval} alsa_enable=${enableval} - dbus_enable=${enableval} test_enable=${enableval} cups_enable=${enableval} pcmcia_enable=${enableval} @@ -330,16 +332,20 @@ AC_DEFUN([AC_ARG_BLUEZ], [ bluepin_enable=${enableval} ]) + AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ + dbus_enable=${enableval} + ]) + AC_ARG_ENABLE(obex, AC_HELP_STRING([--enable-obex], [enable OBEX support]), [ obex_enable=${enableval} ]) - AC_ARG_ENABLE(alsa, AC_HELP_STRING([--enable-alsa], [enable ALSA support]), [ - alsa_enable=${enableval} + AC_ARG_ENABLE(fuse, AC_HELP_STRING([--enable-fuse], [enable FUSE support]), [ + fuse_enable=${enableval} ]) - AC_ARG_ENABLE(dbus, AC_HELP_STRING([--enable-dbus], [enable D-BUS support]), [ - dbus_enable=${enableval} + AC_ARG_ENABLE(alsa, AC_HELP_STRING([--enable-alsa], [enable ALSA support]), [ + alsa_enable=${enableval} ]) AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test], [install test programs]), [ @@ -391,9 +397,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ LDFLAGS="$LDFLAGS -pie" fi + AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes" && test "${dbus_found}" = "yes") AM_CONDITIONAL(OBEX, test "${obex_enable}" = "yes" && test "${openobex_found}" = "yes") + AM_CONDITIONAL(FUSE, test "${fuse_enable}" = "yes" && test "${openobex_found}" = "yes" && test "${fuse_found}" = "yes") AM_CONDITIONAL(ALSA, test "${alsa_enable}" = "yes" && test "${alsa_found}" = "yes") - AM_CONDITIONAL(DBUS, test "${dbus_enable}" = "yes" && test "${dbus_found}" = "yes") AM_CONDITIONAL(TEST, test "${test_enable}" = "yes") AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") AM_CONDITIONAL(PCMCIA, test "${pcmcia_enable}" = "yes") diff --git a/configure.in b/configure.in index 107ce98f..abe93832 100644 --- a/configure.in +++ b/configure.in @@ -35,4 +35,4 @@ AC_PATH_USB AC_ARG_BLUEZ -AC_OUTPUT(Makefile common/Makefile daemon/Makefile tools/Makefile rfcomm/Makefile hcid/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) +AC_OUTPUT(Makefile common/Makefile daemon/Makefile tools/Makefile rfcomm/Makefile hcid/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile fuse/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile) diff --git a/fuse/Makefile.am b/fuse/Makefile.am new file mode 100644 index 00000000..ba504834 --- /dev/null +++ b/fuse/Makefile.am @@ -0,0 +1,14 @@ +# +# $Id$ +# + +if FUSE +noinst_PROGRAMS = btfs + +btfs_SOURCES = main.c +btfs_LDADD = @FUSE_LIBS@ @OPENOBEX_LIBS@ @BLUEZ_LIBS@ + +AM_CFLAGS = @BLUEZ_CFLAGS@ @OPENOBEX_CFLAGS@ @FUSE_CFLAGS@ +endif + +MAINTAINERCLEANFILES = Makefile.in diff --git a/fuse/main.c b/fuse/main.c new file mode 100644 index 00000000..7cd57123 --- /dev/null +++ b/fuse/main.c @@ -0,0 +1,102 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include + +static int btfs_getattr(const char *path, struct stat *stbuf) +{ + int err = 0; + + memset(stbuf, 0, sizeof(struct stat)); + + if (!strcmp(path, "/")) { + stbuf->st_mode = S_IFDIR | 0755; + stbuf->st_nlink = 2; + } else if (!strcmp(path, "/test")) { + stbuf->st_mode = S_IFREG | 0444; + stbuf->st_nlink = 1; + stbuf->st_size = strlen("/test"); + } else + err = -ENOENT; + + return err; +} + +static int btfs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler) +{ + if (strcmp(path, "/")) + return -ENOENT; + + filler(h, ".", 0); + filler(h, "..", 0); + filler(h, "test", 0); + + return 0; +} + +static int btfs_open(const char *path, int flags) +{ + if (strcmp(path, "/test")) + return -ENOENT; + + if ((flags & 3) != O_RDONLY) + return -EACCES; + + return 0; +} + +static int btfs_read(const char *path, char *buf, size_t size, off_t offset) +{ + if (strcmp(path, "/test")) + return -ENOENT; + + memcpy(buf, "Test" + offset, size); + + return size; +} + +static struct fuse_operations btfs_ops = { + .getattr = btfs_getattr, + .getdir = btfs_getdir, + .open = btfs_open, + .read = btfs_read, +}; + +int main(int argc, char *argv[]) +{ + return fuse_main(argc, argv, &btfs_ops); +} -- cgit From 26410165076fc1bcbffef6f46c1843bf861b2e9c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 10:57:55 +0000 Subject: Update changelog and bump version number --- ChangeLog | 13 +++++++++++++ configure.in | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 7ff90c84..c75057be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +ver 2.21: + Move create_dirs() and create_file() into the textfile library. + Let textfile_put() also replace the last key value pair. + Fix memory leaks with textfile_get() usage. + Fix infinite loops and false positive matches. + Don't retrieve stored link keys for RAW devices. + Document the putkey and delkey commands. + Show supported commands also in clear text. + Support volatile changes of the BD_ADDR for CSR chips. + + Note: + This version needs at least bluez-libs-2.21 + ver 2.20: Add support for extended inquiry response. Add support for HotSync service record. diff --git a/configure.in b/configure.in index abe93832..ac0c8834 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.20) +AM_INIT_AUTOMAKE(bluez-utils, 2.21) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From c38d98180b8d4bf18c54266a4b91a974f38dc5c0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 12 Sep 2005 22:40:09 +0000 Subject: Remove D-Bus 0.23 support --- acinclude.m4 | 2 +- hcid/dbus.c | 60 +----------------------------------------------------------- 2 files changed, 2 insertions(+), 60 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 9f6779a9..43b2d8b2 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -168,7 +168,7 @@ AC_DEFUN([AC_PATH_DBUS], [ LDFLAGS="$LDFLAGS $DBUS_LIBS" AC_CHECK_LIB(dbus-1, dbus_error_init, DBUS_LIBS="$DBUS_LIBS -ldbus-1", dbus_found=no) - AC_CHECK_LIB(dbus-1, dbus_message_iter_get_basic, AC_DEFINE(HAVE_DBUS_MESSAGE_ITER_GET_BASIC, 1, [Define to 1 if you have the dbus_message_iter_get_basic() function.])) + AC_CHECK_LIB(dbus-1, dbus_message_iter_get_basic, dummy=yes, dbus_found=no) CPPFLAGS=$ac_save_CPPFLAGS LDFLAGS=$ac_save_LDFLAGS diff --git a/hcid/dbus.c b/hcid/dbus.c index 5ffa97e2..2f66eae9 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -83,12 +83,7 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) if (type != DBUS_TYPE_STRING) goto error; -#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_iter_get_basic(&iter, &pin); -#else - pin = dbus_message_iter_get_string(&iter); -#endif - len = strlen(pin); memset(&pr, 0, sizeof(pr)); @@ -116,13 +111,9 @@ static void free_pin_req(void *req) void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) { DBusMessage *message; -#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC - uint8_t *addr = (uint8_t *) &ci->bdaddr; -#else - DBusMessageIter iter; -#endif DBusPendingCall *pending = NULL; struct pin_request *req; + uint8_t *addr = (uint8_t *) &ci->bdaddr; message = dbus_message_new_method_call(SERVICE_NAME, PATH_NAME, INTERFACE_NAME, REQUEST_NAME); @@ -135,17 +126,9 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) req->dev = dev; bacpy(&req->bda, &ci->bdaddr); -#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &ci->out, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, sizeof(bdaddr_t), DBUS_TYPE_INVALID); -#else - dbus_message_append_iter_init(message, &iter); - - dbus_message_iter_append_boolean(&iter, ci->out); - dbus_message_iter_append_byte_array(&iter, - (unsigned char *) &ci->bdaddr, sizeof(ci->bdaddr)); -#endif if (dbus_connection_send_with_reply(connection, message, &pending, TIMEOUT) == FALSE) { @@ -171,9 +154,6 @@ failed: void hcid_dbus_inquiry_start(bdaddr_t *local) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_ITER_GET_BASIC - DBusMessageIter iter; -#endif char *local_addr; bdaddr_t tmp; @@ -186,15 +166,9 @@ void hcid_dbus_inquiry_start(bdaddr_t *local) goto failed; } -#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, DBUS_TYPE_STRING, &local_addr, DBUS_TYPE_INVALID); -#else - dbus_message_append_iter_init(message, &iter); - - dbus_message_iter_append_string(&iter, local_addr); -#endif if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS inquiry start message"); @@ -214,9 +188,6 @@ failed: void hcid_dbus_inquiry_complete(bdaddr_t *local) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_ITER_GET_BASIC - DBusMessageIter iter; -#endif char *local_addr; bdaddr_t tmp; @@ -229,15 +200,9 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local) goto failed; } -#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, DBUS_TYPE_STRING, &local_addr, DBUS_TYPE_INVALID); -#else - dbus_message_append_iter_init(message, &iter); - - dbus_message_iter_append_string(&iter, local_addr); -#endif if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS inquiry complete message"); @@ -257,9 +222,6 @@ failed: void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_ITER_GET_BASIC - DBusMessageIter iter; -#endif char *local_addr, *peer_addr; bdaddr_t tmp; @@ -273,21 +235,12 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i goto failed; } -#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, DBUS_TYPE_STRING, &local_addr, DBUS_TYPE_STRING, &peer_addr, DBUS_TYPE_UINT32, &class, DBUS_TYPE_INT32, &rssi, DBUS_TYPE_INVALID); -#else - dbus_message_append_iter_init(message, &iter); - - dbus_message_iter_append_string(&iter, local_addr); - dbus_message_iter_append_string(&iter, peer_addr); - dbus_message_iter_append_uint32(&iter, class); - dbus_message_iter_append_int32(&iter, rssi); -#endif if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS inquiry result message"); @@ -308,9 +261,6 @@ failed: void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) { DBusMessage *message; -#ifndef HAVE_DBUS_MESSAGE_ITER_GET_BASIC - DBusMessageIter iter; -#endif char *local_addr, *peer_addr; bdaddr_t tmp; @@ -324,19 +274,11 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) goto failed; } -#ifdef HAVE_DBUS_MESSAGE_ITER_GET_BASIC dbus_message_append_args(message, DBUS_TYPE_STRING, &local_addr, DBUS_TYPE_STRING, &peer_addr, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); -#else - dbus_message_append_iter_init(message, &iter); - - dbus_message_iter_append_string(&iter, local_addr); - dbus_message_iter_append_string(&iter, peer_addr); - dbus_message_iter_append_string(&iter, name); -#endif if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS remote name message"); -- cgit From d83a07e5e8cef7c6a9af50e64ee5a8c9aa1ff069 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Sep 2005 03:20:14 +0000 Subject: Update PSKEY definitions --- tools/csr.c | 2 ++ tools/csr.h | 17 +++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 39706623..801652a1 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -408,6 +408,8 @@ char *csr_pskeytostr(uint16_t pskey) return "The HCI and LMP version reported locally"; case CSR_PSKEY_LMP_REMOTE_VERSION: return "The LMP version reported remotely"; + case CSR_PSKEY_HOSTIO_USE_HCI_EXTN: + return "Use hci_extn to route non-hci channels"; case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; case CSR_PSKEY_UART_BAUDRATE: diff --git a/tools/csr.h b/tools/csr.h index dc5e1029..1d9a18c2 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -59,19 +59,20 @@ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ #define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xFE8f, 0xF99B, 0x8000 } */ -#define CSR_PSKEY_ENC_KEY_LMIN 0x00da -#define CSR_PSKEY_ENC_KEY_LMAX 0x00db +#define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ +#define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ #define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ #define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ -#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab -#define CSR_PSKEY_UART_BAUDRATE 0x01be +#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN 0x01a5 /* bool (uint16) */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab /* bool (uint16) */ +#define CSR_PSKEY_UART_BAUDRATE 0x01be /* uint16 */ #define CSR_PSKEY_ANA_FTRIM 0x01f6 /* uint16 */ #define CSR_PSKEY_HOST_INTERFACE 0x01f9 /* uint16 */ #define CSR_PSKEY_ANA_FREQ 0x01fe /* uint16 */ -#define CSR_PSKEY_USB_VENDOR_ID 0x02be -#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf -#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb -#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd +#define CSR_PSKEY_USB_VENDOR_ID 0x02be /* uint16 */ +#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf /* uint16 */ +#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb /* uint16 */ +#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd /* int16 */ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); -- cgit From 12bc903cff57bed548080354159c0841cc20650b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Sep 2005 03:23:55 +0000 Subject: Support HOSTIO_USE_HCI_EXTN setting --- tools/pskey.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/pskey.c b/tools/pskey.c index 0c06e9ef..f8d93042 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -123,6 +123,7 @@ static struct { { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, + { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, "hciextn" }, { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, -- cgit From 0c9289ad794b5fa0d3117824f61a585d820e4f42 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 15 Sep 2005 08:07:53 +0000 Subject: Extend reply_handler_function() function --- hcid/dbus.c | 64 +++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 2f66eae9..df520316 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -68,39 +68,49 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) pin_code_reply_cp pr; DBusMessage *message; DBusMessageIter iter; - int type; + int arg_type; + int msg_type; size_t len; char *pin; - + const char *error_msg; + message = dbus_pending_call_steal_reply(call); - - if (dbus_message_is_error(message, WRONG_ARGS_ERROR)) - goto error; - - dbus_message_iter_init(message, &iter); - - type = dbus_message_iter_get_arg_type(&iter); - if (type != DBUS_TYPE_STRING) - goto error; - - dbus_message_iter_get_basic(&iter, &pin); - len = strlen(pin); - - memset(&pr, 0, sizeof(pr)); - bacpy(&pr.bdaddr, &req->bda); - memcpy(pr.pin_code, pin, len); - pr.pin_len = len; - hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, + + if (message) { + msg_type = dbus_message_get_type(message); + dbus_message_iter_init(message, &iter); + + if (msg_type == DBUS_MESSAGE_TYPE_ERROR) { + dbus_message_iter_get_basic(&iter, &error_msg); + + /* handling WRONG_ARGS_ERROR, DBUS_ERROR_NO_REPLY, DBUS_ERROR_SERVICE_UNKNOWN */ + syslog(LOG_ERR, "%s: %s", dbus_message_get_error_name(message), error_msg); + hci_send_cmd(req->dev, OGF_LINK_CTL, + OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); + } else { + /* check signature */ + arg_type = dbus_message_iter_get_arg_type(&iter); + if (arg_type != DBUS_TYPE_STRING) { + syslog(LOG_ERR, "Wrong reply signature: expected PIN"); + hci_send_cmd(req->dev, OGF_LINK_CTL, + OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); + } else { + dbus_message_iter_get_basic(&iter, &pin); + len = strlen(pin); + + memset(&pr, 0, sizeof(pr)); + bacpy(&pr.bdaddr, &req->bda); + memcpy(pr.pin_code, pin, len); + pr.pin_len = len; + hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); + } + } - dbus_message_unref(message); - dbus_pending_call_unref(call); - - return; + dbus_message_unref(message); + } -error: - hci_send_cmd(req->dev, OGF_LINK_CTL, - OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); + dbus_pending_call_unref(call); } static void free_pin_req(void *req) -- cgit From fad20a44db8a86d6687c6c57e3f7e18a5320c95e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 16 Sep 2005 04:18:46 +0000 Subject: Fix wrong UUID-128 for the PalmOS id record --- tools/sdptool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index fd824c2c..6c07cfab 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2197,7 +2197,7 @@ static int add_palmos(sdp_session_t *session, svc_info_t *si) root = sdp_list_append(NULL, &root_uuid); sdp_set_browse_groups(&record, root); - sdp_uuid128_create(&svclass_uuid, (void *) hotsync_uuid); + sdp_uuid128_create(&svclass_uuid, (void *) palmos_uuid); svclass = sdp_list_append(NULL, &svclass_uuid); sdp_set_service_classes(&record, svclass); -- cgit From c30cad7c8395eec65221edd4d835c5a4b7a2dde1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 Sep 2005 13:04:58 +0000 Subject: Add more build ids for Unified 20e and Unified 21a firmwares --- tools/csr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 801652a1..abf1150b 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -280,6 +280,10 @@ static struct { { 2244, "Unified 18e" }, { 2258, "Unified 20d" }, { 2259, "Unified 20d" }, + { 2361, "Unified 20e" }, + { 2362, "Unified 20e" }, + { 2423, "Unified 21a" }, + { 2424, "Unified 21a" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From 0113203bf3424c0645046b962d81fe85ede308f1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 Sep 2005 13:53:39 +0000 Subject: Update the hcid.8 and hcid.conf.5 manual pages --- hcid/hcid.8 | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- hcid/hcid.conf.5 | 16 ++++++++++++++-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/hcid/hcid.8 b/hcid/hcid.8 index 2ef8ed31..767fc2ed 100644 --- a/hcid/hcid.8 +++ b/hcid/hcid.8 @@ -21,6 +21,9 @@ itself does not accept many command\-line options, as most of its configuration is done in the .B hcid.conf file, which has its own man page. +.B hcid +can also provide a number of services via the D-BUS message bus +system. .SH "OPTIONS" .TP .B \-n @@ -33,7 +36,57 @@ Use alternate configuration file instead of /etc/bluetooth/hcid.conf .I /etc/bluetooth/hcid.conf Default location of the global configuration file. +.TP +.I /var/lib/bluetooth/nn:nn:nn:nn:nn:nn/linkkeys +Default location for link keys of paired devices. The directory +\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP +is the address of the local device. The file is line separated, with +the following columns separated by whitespace: + +\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP Remote device address. + +\fInnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn\fP Link key. + +\fIn\fP Link type integer. + +.TP +.I /var/lib/bluetooth/nn:nn:nn:nn:nn:nn/names +Default location for the device name cache. The directory +\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP +is the address of the local device. The file is line separated, with +the following columns separated by whitespace: + +\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP Remote device address. + +\fIname\fP Remote device name, terminated with newline. + +.TP +.I /var/lib/bluetooth/nn:nn:nn:nn:nn:nn/features +Default location for the features cache. The directory +\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP +is the address of the local device. The file is line separated, with +the following columns separated by whitespace: + +\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP Remote device address. + +\fInnnnnnnnnnnnnnnn\fP Remote device LMP features coded as an 8 byte bitfield. + +.TP +.I /var/lib/bluetooth/nn:nn:nn:nn:nn:nn/manufacturers +Default location for the manufacturers cache. The directory +\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP +is the address of the local device. The file is line separated, with +the following columns separated by whitespace: + +\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP\fB:\fP\fInn\fP Remote device address. + +\fIn\fP Remote device manufacturer integer. + +\fIn\fP Remote device LMP version integer. + +\fIn\fP Remote device LMP sub-version integer. + .SH "SEE ALSO" \fBhcid.conf\fR(5) .SH "AUTHOR" -This manual page was written by Philipp Matthias Hahn. +This manual page was written by Philipp Matthias Hahn and Fredrik Noring. diff --git a/hcid/hcid.conf.5 b/hcid/hcid.conf.5 index d110e2a7..a5d82417 100644 --- a/hcid/hcid.conf.5 +++ b/hcid/hcid.conf.5 @@ -57,12 +57,18 @@ Or, when no PIN is available: ERR +.TP +\fBdbus_pin_helper\fP + +Declaring this parameter enables the D-BUS message bus system for PIN +requests. + .TP \fBsecurity\fP none|auto|user \fInone\fP means the security manager is disabled. \fIauto\fP uses -local PIN for incoming connections. \fIuser\fP always asks the user -for a PIN. +local PIN, by default from /etc/bluetooth/pin, for incoming +connections. \fIuser\fP always asks the user for a PIN. .SH "DEVICE SECTION" Parameters within a device section with no specifier, the default @@ -230,5 +236,11 @@ You can check the Bluetooth specification version 1.2 Volume 2, Part B section 6 .I /etc/bluetooth/hcid.conf Default location of the global configuration file. +.TP +.I /etc/bluetooth/pin +Default location of local PIN file, used for incoming connections in +security mode \fIauto\fP. The file contains the PIN code terminated by +newline. + .SH "AUTHOR" This manual page was written by Edouard Lafargue, Fredrik Noring and Maxim Krasnyansky. -- cgit From c5d50b815bb5a30ad1d9b8f59fa33115513845e1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 22 Sep 2005 12:09:16 +0000 Subject: Fix memory alignment problem --- hcid/dbus.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index df520316..39daf783 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -124,6 +124,7 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) DBusPendingCall *pending = NULL; struct pin_request *req; uint8_t *addr = (uint8_t *) &ci->bdaddr; + dbus_bool_t out = ci->out; message = dbus_message_new_method_call(SERVICE_NAME, PATH_NAME, INTERFACE_NAME, REQUEST_NAME); @@ -136,7 +137,7 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) req->dev = dev; bacpy(&req->bda, &ci->bdaddr); - dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &ci->out, + dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &out, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, sizeof(bdaddr_t), DBUS_TYPE_INVALID); @@ -233,6 +234,8 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i { DBusMessage *message; char *local_addr, *peer_addr; + dbus_uint32_t tmp_class = class; + dbus_int32_t tmp_rssi = rssi; bdaddr_t tmp; baswap(&tmp, local); local_addr = batostr(&tmp); @@ -248,8 +251,8 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i dbus_message_append_args(message, DBUS_TYPE_STRING, &local_addr, DBUS_TYPE_STRING, &peer_addr, - DBUS_TYPE_UINT32, &class, - DBUS_TYPE_INT32, &rssi, + DBUS_TYPE_UINT32, &tmp_class, + DBUS_TYPE_INT32, &tmp_rssi, DBUS_TYPE_INVALID); if (dbus_connection_send(connection, message, NULL) == FALSE) { -- cgit From ca1b11b40db46287fc63024d5bb824d9695c1b67 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Sep 2005 11:43:37 +0000 Subject: Include the stdint.h header file --- tools/csrinit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/csrinit.c b/tools/csrinit.c index 07310175..5d939539 100644 --- a/tools/csrinit.c +++ b/tools/csrinit.c @@ -32,6 +32,7 @@ #include #include +#include #include #include -- cgit From d577091a3632210b7c5d8a07bc7698097f0042a6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Sep 2005 15:19:14 +0000 Subject: Show the OUI and include a manual page for the bdaddr utility --- test/Makefile.am | 8 +++++++- test/bdaddr.8 | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/bdaddr.c | 27 ++++++++++++++++++++++--- 3 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 test/bdaddr.8 diff --git a/test/Makefile.am b/test/Makefile.am index bf41fb03..8ee5ed06 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -17,11 +17,17 @@ attest_LDADD = @BLUEZ_LIBS@ hstest_LDADD = @BLUEZ_LIBS@ +bdaddr_SOURCES = bdaddr.c $(top_builddir)/tools/oui.h $(top_builddir)/tools/oui.c + bdaddr_LDADD = @BLUEZ_LIBS@ +noinst_MANS = bdaddr.8 + AM_CFLAGS = @BLUEZ_CFLAGS@ endif -EXTRA_DIST = hsplay hsmicro +INCLUDES = -I$(top_srcdir)/tools + +EXTRA_DIST = hsplay hsmicro bdaddr.8 MAINTAINERCLEANFILES = Makefile.in diff --git a/test/bdaddr.8 b/test/bdaddr.8 new file mode 100644 index 00000000..623a1401 --- /dev/null +++ b/test/bdaddr.8 @@ -0,0 +1,61 @@ +.TH BDADDR 8 "Sep 27 2005" BlueZ "Linux System Administration" +.SH NAME +bdaddr \- Utility for changing the Bluetooth device address +.SH SYNOPSIS +.B bdaddr +.br +.B bdaddr -h +.br +.B bdaddr [-i ] [-r] [-t] [new bdaddr] + +.SH DESCRIPTION +.LP +.B +bdaddr +is used to query or set the local Bluetooth device address (BD_ADDR). If run with no arguments, +.B +bdaddr +prints the chip manufacturer's name, and the current BD_ADDR. If the IEEE OUI index file "oui.txt" is installed on the system, +the BD_ADDR owner will be displayed. If the optional +[new bdaddr] argument is given, the device will be reprogrammed with that address. This can either be permanent or temporary, as specified +by the -t flag. In both cases, the device must be reset before the new address will become active. This can be done +with a 'soft' reset by specifying the -r flag, or a 'hard' reset by removing and replugging the device. +A 'hard' reset will cause the address to revert to the current non-volatile value. +.PP +.B +bdaddr +uses manufacturer specific commands to set the address, and is therefore device specific. For this reason, not all devices are supported, and not all +options are supported on all devices. +Current supported manufacturers are: +.B Ericsson, Cambridge Silicon Radio (CSR) +and +.B Zeevo + +.SH OPTIONS +.TP +.BI -h +Gives a list of possible commands. +.TP +.BI -i\ +Specify a particular device to operate on. If not specified, default is the first available device. +.TP +.BI -r +Reset device and make new BD_ADDR active. +.B +CSR +devices only. +.TP +.BI -t +Temporary change. Do not write to non-volatile memory. +.B +CSR +devices only. +.SH FILES +.TP +.I +/usr/share/misc/oui.txt +IEEE Organizationally Unique Identifier master file. Manually update from: http://standards.ieee.org/regauth/oui/oui.txt +.SH AUTHORS +Written by Marcel Holtmann , +man page by Adam Laurie +.PP diff --git a/test/bdaddr.c b/test/bdaddr.c index 57d9b005..92b43de8 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -41,6 +41,8 @@ #include #include +#include "oui.h" + static int transient = 0; #define OCF_ERICSSON_WRITE_BD_ADDR 0x000d @@ -246,7 +248,7 @@ int main(int argc, char *argv[]) struct hci_dev_info di; struct hci_version ver; bdaddr_t bdaddr; - char addr[18]; + char addr[18], oui[9], *comp; int i, dd, opt, dev = 0, reset = 0; bacpy(&bdaddr, BDADDR_ANY); @@ -314,8 +316,17 @@ int main(int argc, char *argv[]) printf("Manufacturer: %s (%d)\n", bt_compidtostr(ver.manufacturer), ver.manufacturer); + ba2oui(&bdaddr, oui); + comp = ouitocomp(oui); + ba2str(&bdaddr, addr); - printf("Device address: %s\n", addr); + printf("Device address: %s", addr); + + if (comp) { + printf(" (%s)\n", comp); + free(comp); + } else + printf("\n"); if (argc < 1) { hci_close_dev(dd); @@ -330,8 +341,18 @@ int main(int argc, char *argv[]) for (i = 0; vendor[i].compid != 65535; i++) if (ver.manufacturer == vendor[i].compid) { + ba2oui(&bdaddr, oui); + comp = ouitocomp(oui); + ba2str(&bdaddr, addr); - printf("New BD address: %s\n\n", addr); + printf("New BD address: %s", addr); + + if (comp) { + printf(" (%s)\n\n", comp); + free(comp); + } else + printf("\n\n"); + if (vendor[i].write_bd_addr(dd, &bdaddr) < 0) { fprintf(stderr, "Can't write new address\n"); -- cgit From 4e44a8510e66998d0df1c257014945535d1d847c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 28 Sep 2005 16:22:58 +0000 Subject: Add build ids for new sniffer firmwares --- tools/csr.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index abf1150b..250700d9 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -342,6 +342,12 @@ static struct { { 2032, "Sniff 44 (2005-04-18)" }, { 2033, "Sniff 44 (2005-04-18)" }, { 2034, "Sniff 44 (2005-04-18)" }, + { 2288, "Sniff 45 (2005-07-08)" }, + { 2289, "Sniff 45 (2005-07-08)" }, + { 2290, "Sniff 45 (2005-07-08)" }, + { 2388, "Sniff 46 (2005-08-17)" }, + { 2389, "Sniff 46 (2005-08-17)" }, + { 2390, "Sniff 46 (2005-08-17)" }, { 0, } }; -- cgit From f1407f1eff7f904defca54b598bad95bff108fde Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Sep 2005 10:50:26 +0000 Subject: Add support for the extended inquiry response commands --- tools/hciconfig.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 2a352e85..1bf7438b 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -915,6 +915,48 @@ static void cmd_inq_mode(int ctl, int hdev, char *opt) } } +static void cmd_inq_data(int ctl, int hdev, char *opt) +{ + int i, dd; + + dd = hci_open_dev(hdev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + if (opt) { + uint8_t fec = 0, data[248]; + + memset(data, 0, sizeof(data)); + data[0] = strlen(opt) + 1; + data[1] = 0x09; + memcpy(data + 2, opt, strlen(opt)); + + if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) { + fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + } else { + uint8_t fec, data[240]; + + if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) < 0) { + fprintf(stderr, "Can't read extended inquiry response on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + exit(1); + } + + print_dev_hdr(&di); + printf("\tFEC: %d\n\t", fec); + for (i = 0; i < 240; i++) + printf("%02x%s%s", data[i], (i + 1) % 8 ? "" : " ", + (i + 1) % 16 ? " " : "\n\t"); + printf("\n"); + } +} + static void cmd_inq_type(int ctl, int hdev, char *opt) { int dd; @@ -1382,8 +1424,9 @@ static struct { { "class", cmd_class, "[class]", "Get/Set class of device" }, { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, - { "inqmode", cmd_inq_mode, "[mode]", "Get/set inquiry mode" }, - { "inqtype", cmd_inq_type, "[type]", "Get/set inquiry scan type" }, + { "inqmode", cmd_inq_mode, "[mode]", "Get/Set inquiry mode" }, + { "inqdata", cmd_inq_data, "[name]", "Get/Set inquiry data (device name)" }, + { "inqtype", cmd_inq_type, "[type]", "Get/Set inquiry scan type" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, { "pageto", cmd_page_to, "[to]", "Get/Set page timeout" }, -- cgit From 8b530335eac02fdb11c449068eb0732fb45bfa93 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Sep 2005 11:12:26 +0000 Subject: Update for the extended inquiry response command --- tools/hciconfig.8 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 53c60526..0547ae3a 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -133,6 +133,12 @@ With no prints out the current inquiry mode. Otherwise, sets inquiry mode to .IR mode . .TP +.BI inqdata " [name]" +With no +.IR name , +prints out the current inquiry data. Otherwise, sets inquiry data to +.IR name . +.TP .BI inqtype " [type]" With no .IR type , -- cgit From bf1758786cd88dbf3ae3d113f7fce95c43ee71eb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Sep 2005 11:13:25 +0000 Subject: Add support for inquiry access codes --- tools/hcitool.c | 57 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 2865ec42..1804d9fd 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -323,6 +323,7 @@ static struct option inq_options[] = { { "help", 0, 0, 'h' }, { "length", 1, 0, 'l' }, { "numrsp", 1, 0, 'n' }, + { "iac", 1, 0, 'i' }, { "flush", 0, 0, 'f' }, { 0, 0, 0, 0 } }; @@ -331,14 +332,16 @@ static char *inq_help = "Usage:\n" "\tinq [--length=N] maximum inquiry duration in 1.28 s units\n" "\t [--numrsp=N] specify maximum number of inquiry responses\n" + "\t [--iac=lap] specify the inquiry access code\n" "\t [--flush] flush the inquiry cache\n"; static void cmd_inq(int dev_id, int argc, char **argv) { - int num_rsp, length, flags; inquiry_info *info = NULL; + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; + int num_rsp, length, flags; char addr[18]; - int i, opt; + int i, l, opt; length = 8; /* ~10 seconds */ num_rsp = 0; @@ -354,6 +357,17 @@ static void cmd_inq(int dev_id, int argc, char **argv) num_rsp = atoi(optarg); break; + case 'i': + l = strtoul(optarg, 0, 16); + if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + break; + case 'f': flags |= IREQ_CACHE_FLUSH; break; @@ -365,7 +379,7 @@ static void cmd_inq(int dev_id, int argc, char **argv) } printf("Inquiring ...\n"); - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); if (num_rsp < 0) { perror("Inquiry failed."); exit(1); @@ -389,22 +403,24 @@ static struct option scan_options[] = { { "help", 0, 0, 'h' }, { "length", 1, 0, 'l' }, { "numrsp", 1, 0, 'n' }, + { "iac", 1, 0, 'i' }, { "flush", 0, 0, 'f' }, - { "class", 0, 0, 'c' }, - { "info", 0, 0, 'i' }, - { "oui", 0, 0, 'o' }, - { "all", 0, 0, 'a' }, - { "ext", 0, 0, 'a' }, + { "class", 0, 0, 'C' }, + { "info", 0, 0, 'I' }, + { "oui", 0, 0, 'O' }, + { "all", 0, 0, 'A' }, + { "ext", 0, 0, 'A' }, { 0, 0, 0, 0 } }; static char *scan_help = "Usage:\n" - "\tscan [--length=N] [--numrsp=N] [--flush] [--class] [--info] [--oui]\n"; + "\tscan [--length=N] [--numrsp=N] [--iac=lap] [--flush] [--class] [--info] [--oui]\n"; static void cmd_scan(int dev_id, int argc, char **argv) { inquiry_info *info = NULL; + uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; int num_rsp, length, flags; uint8_t cls[3], features[8]; uint16_t handle; @@ -413,7 +429,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) struct hci_dev_info di; struct hci_conn_info_req *cr; int extcls = 0, extinf = 0, extoui = 0; - int i, n, opt, dd, cc, nc; + int i, n, l, opt, dd, cc, nc; length = 8; /* ~10 seconds */ num_rsp = 0; @@ -429,23 +445,34 @@ static void cmd_scan(int dev_id, int argc, char **argv) num_rsp = atoi(optarg); break; + case 'i': + l = strtoul(optarg, 0, 16); + if (l < 0x9e8b00 || l > 0x9e8b3f) { + printf("Invalid access code 0x%x\n", l); + exit(1); + } + lap[0] = (l & 0xff); + lap[1] = (l >> 8) & 0xff; + lap[2] = (l >> 16) & 0xff; + break; + case 'f': flags |= IREQ_CACHE_FLUSH; break; - case 'c': + case 'C': extcls = 1; break; - case 'i': + case 'I': extinf = 1; break; - case 'o': + case 'O': extoui = 1; break; - case 'a': + case 'A': extcls = 1; extinf = 1; extoui = 1; @@ -471,7 +498,7 @@ static void cmd_scan(int dev_id, int argc, char **argv) } printf("Scanning ...\n"); - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + num_rsp = hci_inquiry(dev_id, length, num_rsp, lap, &info, flags); if (num_rsp < 0) { perror("Inquiry failed"); exit(1); -- cgit From 3e077cde783d52817e9934681699c51994ba2031 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 30 Sep 2005 13:05:09 +0000 Subject: Add manual page for bccmd utility --- tools/Makefile.am | 4 +++- tools/bccmd.8 | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 tools/bccmd.8 diff --git a/tools/Makefile.am b/tools/Makefile.am index 3a018bb7..8a2241c6 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -85,6 +85,8 @@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ $(avctrl_manfiles) $(hid2hci_manfiles) $(csrinit_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 csrinit.8 dfutool.1 example.psr +noinst_MANS = bccmd.8 + +EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 csrinit.8 dfutool.1 bccmd.8 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/bccmd.8 b/tools/bccmd.8 new file mode 100644 index 00000000..a51be28e --- /dev/null +++ b/tools/bccmd.8 @@ -0,0 +1,55 @@ +.TH BCCMD 8 "Sep 30 2005" BlueZ "Linux System Administration" +.SH NAME +bccmd \- Utility for the CSR BCCMD interface +.SH SYNOPSIS +.B bccmd +.br +.B bccmd [-i ] +.br + +.SH DESCRIPTION +.LP +.B +bccmd +issues BlueCore commands to +.B +Cambridge Silicon Radio +devices. If run without the argument, a short help page will be diaplayed. +.PP + +.SH OPTIONS +.TP +.BI -i\ +Specify a particular device to operate on. If not specified, default is the first available device. +.SH COMMANDS +.TP +.BI keylen\ +Get current crypt key length +.TP +.BI clock +Get local Bluetooth clock +.TP +.BI rand +Get random number +.TP +.BI panicarg +Get panic code argument +.TP +.BI faultarg +Get fault code argument +.TP +.BI coldreset +Perform cold reset +.TP +.BI warmreset +Perform warm reset +.TP +.BI disabletx +Disable TX on the device +.TP +.BI enabletx +Enable TX on the device +.SH AUTHORS +Written by Marcel Holtmann , +man page by Adam Laurie +.PP -- cgit From 34e266aaa88d0ff1e5930946d96783420c232895 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Oct 2005 22:15:21 +0000 Subject: Add basic rough version of the D-Bus support --- hcid/Makefile.am | 4 +- hcid/dbus.c | 977 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- hcid/dbus.h | 180 ++++++++++ hcid/hcid.h | 35 ++ hcid/main.c | 14 + 5 files changed, 1182 insertions(+), 28 deletions(-) create mode 100644 hcid/dbus.h diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 875de7cd..7f235c73 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -13,7 +13,7 @@ state_DATA = sbin_PROGRAMS = hcid if DBUS -dbus_hcid_sources = dbus.c +dbus_hcid_sources = dbus.h dbus.c dbus_hcid_libs = @DBUS_LIBS@ dbus_hcid_cflags = -DENABLE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE else @@ -35,7 +35,7 @@ AM_YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.c +EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.h dbus.c MAINTAINERCLEANFILES = Makefile.in diff --git a/hcid/dbus.c b/hcid/dbus.c index 39daf783..36fd476c 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -33,6 +33,10 @@ #endif #include +#include +#include +#include +#include #include #include @@ -45,23 +49,187 @@ #include "glib-ectomy.h" #include "hcid.h" +#include "dbus.h" static DBusConnection *connection; +static int num_adapters = 0; #define TIMEOUT (30 * 1000) /* 30 seconds */ +#define BLUETOOTH_DEVICE_NAME_LEN (18) +#define BLUETOOTH_DEVICE_ADDR_LEN (18) +#define MAX_PATH_LENGTH (64) -#define SERVICE_NAME "org.bluez.PinAgent" -#define INTERFACE_NAME SERVICE_NAME -#define REQUEST_NAME "PinRequest" -#define PATH_NAME "/org/bluez/PinAgent" - -#define WRONG_ARGS_ERROR "org.bluez.Error.WrongArgs" +#define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent" +#define PINAGENT_INTERFACE PINAGENT_SERVICE_NAME +#define PIN_REQUEST "PinRequest" +#define PINAGENT_PATH BASE_PATH "/PinAgent" struct pin_request { int dev; bdaddr_t bda; }; +typedef DBusMessage* (service_handler_func_t)(DBusMessage *, void *); + +struct service_data { + const char *name; + service_handler_func_t *handler_func; + const char *signature; +}; + +typedef int register_function_t(DBusConnection *conn, int dft_reg, uint16_t id); +typedef int unregister_function_t(DBusConnection *conn, int unreg_dft, uint16_t id); + +const struct service_data *get_hci_table(void); + +static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id); +static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t id); + +typedef const struct service_data *get_svc_table_func_t(void); + +struct profile_obj_path_data { + const char *name; + int status; /* 1:active 0:disabled */ + int dft_reg; /* dft path registered */ + register_function_t *reg_func; + unregister_function_t *unreg_func; + get_svc_table_func_t *get_svc_table; /* return the service table */ +}; + +/* + * D-Bus error messages functions and declarations. + * This section should be moved to a common file + * in the future + * + */ +typedef struct { + uint32_t code; + const char *str; +}bluez_error_t; + +static const bluez_error_t error_array[] = { + { BLUEZ_EDBUS_UNKNOWN_METHOD, "Method not found" }, + { BLUEZ_EDBUS_WRONG_SIGNATURE, "Wrong method signature" }, + { BLUEZ_EDBUS_WRONG_PARAM, "Invalid parameters" }, + { BLUEZ_EDBUS_RECORD_NOT_FOUND, "No record found" }, + { BLUEZ_EDBUS_NO_MEM, "No memory" }, + { BLUEZ_EDBUS_CONN_NOT_FOUND, "Connection not found" }, + { BLUEZ_EDBUS_UNKNOWN_PATH, "Device path is not registered" }, + { 0, NULL } +}; + +static const char *bluez_dbus_error_to_str(const uint32_t ecode) +{ + const bluez_error_t *ptr; + uint32_t raw_code = 0; + + if (ecode & BLUEZ_ESYSTEM_OFFSET) { + /* System error */ + raw_code = (!BLUEZ_ESYSTEM_OFFSET) & ecode; + syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, strerror(raw_code)); + return strerror(raw_code); + } else if (ecode & BLUEZ_EDBUS_OFFSET) { + /* D-Bus error */ + for (ptr = error_array; ptr->code; ptr++) { + if (ptr->code == ecode) { + syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str); + return ptr->str; + } + } + } + + return NULL; +} + +static DBusMessage *bluez_new_failure_msg(DBusMessage *msg, const uint32_t ecode) +{ + DBusMessageIter iter; + DBusMessage *reply = NULL; + const char *error_msg = NULL; + + error_msg = bluez_dbus_error_to_str(ecode); + + if (error_msg) { + reply = dbus_message_new_error(msg, ERROR_INTERFACE, error_msg); + + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32 ,&ecode); + } + + return reply; +} + +/* + * Object path register/unregister functions + * + */ +static struct profile_obj_path_data obj_path_table[] = { + { BLUEZ_HCI, 1, 0, hci_dbus_reg_obj_path, hci_dbus_unreg_obj_path, get_hci_table }, + /* add other profiles here */ + { NULL, 0, 0, NULL, NULL, NULL } +}; + +/* + * Device Message handler functions object table declaration + */ +static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void *data); + +static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data); +static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data); + +static const DBusObjectPathVTable obj_vtable = { + NULL, + &msg_func, + NULL, + NULL, + NULL, + NULL +}; + +/* + * Service provided under the path DEVICE_PATH + * TODO add the handlers + */ +static const struct service_data dev_services[] = { + { DEV_UP, handle_not_implemented_req, DEV_UP_SIGNATURE }, + { DEV_DOWN, handle_not_implemented_req, DEV_DOWN_SIGNATURE }, + { DEV_RESET, handle_not_implemented_req, DEV_RESET_SIGNATURE }, + { DEV_SET_PROPERTY, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE }, + { DEV_GET_PROPERTY, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { NULL, NULL, NULL} +}; + +/* + * Manager Message handler functions object table declaration + * + */ +static const struct service_data mgr_services[] = { + { MGR_GET_DEV, handle_get_devices_req, MGR_GET_DEV_SIGNATURE }, + { MGR_INIT, handle_not_implemented_req, NULL }, + { MGR_ENABLE, handle_not_implemented_req, NULL }, + { MGR_DISABLE, handle_not_implemented_req, NULL }, + { NULL, handle_not_implemented_req, NULL } +}; + +/* + * HCI Manager Message handler functions object table declaration + * + */ +static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *msg, void *data); + +static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data); +static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data); +static DBusMessage* handle_inq_req(DBusMessage *msg, void *data); +static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data); + +static const struct service_data hci_services[] = { + { HCI_PERIODIC_INQ, handle_periodic_inq_req, HCI_PERIODIC_INQ_SIGNATURE }, + { HCI_CANCEL_PERIODIC_INQ, handle_cancel_periodic_inq_req, HCI_CANCEL_PERIODIC_INQ_SIGNATURE }, + { HCI_ROLE_SWITCH, handle_role_switch_req, HCI_ROLE_SWITCH_SIGNATURE }, + { HCI_INQ, handle_inq_req, HCI_INQ_SIGNATURE }, + { NULL, NULL, NULL } +}; + static void reply_handler_function(DBusPendingCall *call, void *user_data) { struct pin_request *req = (struct pin_request *) user_data; @@ -73,9 +241,9 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) size_t len; char *pin; const char *error_msg; - + message = dbus_pending_call_steal_reply(call); - + if (message) { msg_type = dbus_message_get_type(message); dbus_message_iter_init(message, &iter); @@ -105,7 +273,7 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); } - } + } dbus_message_unref(message); } @@ -126,8 +294,8 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) uint8_t *addr = (uint8_t *) &ci->bdaddr; dbus_bool_t out = ci->out; - message = dbus_message_new_method_call(SERVICE_NAME, PATH_NAME, - INTERFACE_NAME, REQUEST_NAME); + message = dbus_message_new_method_call(PINAGENT_SERVICE_NAME, PINAGENT_PATH, + PINAGENT_INTERFACE, PIN_REQUEST); if (message == NULL) { syslog(LOG_ERR, "Couldn't allocate D-BUS message"); goto failed; @@ -165,13 +333,13 @@ failed: void hcid_dbus_inquiry_start(bdaddr_t *local) { DBusMessage *message; - char *local_addr; + char *local_addr; bdaddr_t tmp; baswap(&tmp, local); local_addr = batostr(&tmp); - message = dbus_message_new_signal("/org/bluez/DevAgent", - "org.bluez.DevAgent", "InquiryStart"); + message = dbus_message_new_signal(BLUEZ_HCI_PATH, + BLUEZ_HCI_INTERFACE, BLUEZ_HCI_INQ_START); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry start message"); goto failed; @@ -204,8 +372,8 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local) baswap(&tmp, local); local_addr = batostr(&tmp); - message = dbus_message_new_signal("/org/bluez/DevAgent", - "org.bluez.DevAgent", "InquiryComplete"); + message = dbus_message_new_signal(BLUEZ_HCI_PATH, + BLUEZ_HCI_INTERFACE, BLUEZ_HCI_INQ_COMPLETE); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); goto failed; @@ -241,8 +409,8 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i baswap(&tmp, local); local_addr = batostr(&tmp); baswap(&tmp, peer); peer_addr = batostr(&tmp); - message = dbus_message_new_signal("/org/bluez/DevAgent", - "org.bluez.DevAgent", "InquiryResult"); + message = dbus_message_new_signal(BLUEZ_HCI_PATH, + BLUEZ_HCI_INTERFACE, BLUEZ_HCI_INQ_RESULT); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry result message"); goto failed; @@ -280,8 +448,8 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) baswap(&tmp, local); local_addr = batostr(&tmp); baswap(&tmp, peer); peer_addr = batostr(&tmp); - message = dbus_message_new_signal("/org/bluez/DevAgent", - "org.bluez.DevAgent", "RemoteName"); + message = dbus_message_new_signal(BLUEZ_HCI_PATH, + BLUEZ_HCI_INTERFACE, BLUEZ_HCI_REMOTE_NAME); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; @@ -376,8 +544,7 @@ static void remove_watch(DBusWatch *watch, void *data) static void watch_toggled(DBusWatch *watch, void *data) { /* Because we just exit on OOM, enable/disable is - * no different from add/remove - */ + * no different from add/remove */ if (dbus_watch_get_enabled(watch)) add_watch(watch, data); else @@ -387,19 +554,777 @@ static void watch_toggled(DBusWatch *watch, void *data) gboolean hcid_dbus_init(void) { DBusError error; + uint16_t *dev_path_id = (uint16_t *) malloc(1); + uint16_t *mgr_path_id = (uint16_t *) malloc(1); dbus_error_init(&error); connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); - if (connection == NULL) { - fprintf(stderr, "Failed to open connection to system message bus: %s\n", - error.message); + + if (dbus_error_is_set(&error)) { + syslog(LOG_ERR, "Can't open system message bus connection: %s\n", + error.message); dbus_error_free(&error); return FALSE; } + dbus_bus_request_name(connection, BASE_INTERFACE, + DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &error); + + if (dbus_error_is_set(&error)) { + syslog(LOG_ERR,"Can't get system message bus name: %s\n", + error.message); + dbus_error_free(&error); + return FALSE; + } + + if (!dev_path_id) + return FALSE; + + *dev_path_id = DEVICE_PATH_ID; + + if (!dbus_connection_register_object_path(connection, DEVICE_PATH, + &obj_vtable, dev_path_id)) { + syslog(LOG_ERR, "Can't register %s object", DEVICE_PATH); + return FALSE; + } + + syslog(LOG_INFO,"Registered %s object", DEVICE_PATH); + + if (!mgr_path_id) + goto done; + + *mgr_path_id = MANAGER_PATH_ID; + + if (!dbus_connection_register_fallback(connection, MANAGER_PATH, + &obj_vtable, mgr_path_id)) { + syslog(LOG_ERR, "Can't register %s object", MANAGER_PATH); + return FALSE; + } + + syslog(LOG_INFO, "Registered %s object", MANAGER_PATH); + +done: + if (!dbus_connection_add_filter(connection, hci_signal_filter, NULL, NULL)) { + syslog(LOG_ERR, "Can't add new HCI filter"); + return FALSE; + } + dbus_connection_set_watch_functions(connection, - add_watch, remove_watch, watch_toggled, NULL, NULL); + add_watch, remove_watch, watch_toggled, NULL, NULL); + + return TRUE; +} + +void hcid_dbus_exit(void) +{ + char path[MAX_PATH_LENGTH]; + char fst_parent[] = MANAGER_PATH; + char snd_parent[MAX_PATH_LENGTH]; + char **fst_level = NULL; + char **snd_level = NULL; + char *ptr1; + char *ptr2; + uint16_t *data = NULL; + + if (!connection) + return; + + if (dbus_connection_get_object_path_data(connection, + DEVICE_PATH, (void *) &data)) { + if (data) { + free(data); + data = NULL; + } + } + + if (!dbus_connection_unregister_object_path(connection, DEVICE_PATH)) + syslog(LOG_ERR, "Can't unregister %s object", DEVICE_PATH); + else + syslog(LOG_INFO, "Unregistered %s object", DEVICE_PATH); + + if (dbus_connection_get_object_path_data(connection, + MANAGER_PATH, (void*) &data)) { + if (data) { + free(data); + data = NULL; + } + } + + if (!dbus_connection_unregister_object_path(connection, MANAGER_PATH)) + syslog(LOG_ERR, "Can't unregister %s object", MANAGER_PATH); + else + syslog(LOG_INFO, "Unregistered %s object", MANAGER_PATH); + + dbus_connection_list_registered(connection, fst_parent, &fst_level); + + for (; *fst_level; fst_level++) { + ptr1 = *fst_level; + sprintf(snd_parent, "%s/%s", fst_parent, ptr1); + + dbus_connection_list_registered(connection, snd_parent, &snd_level); + + if (!(*snd_level)) { + sprintf(path, "%s/%s", MANAGER_PATH, ptr1); + + syslog(LOG_INFO, "Unregistered %s object", path); + + if (dbus_connection_get_object_path_data(connection, + path, (void*) &data)) { + if (data) { + free(data); + data = NULL; + } + } + + if (!dbus_connection_unregister_object_path(connection, path)) + syslog(LOG_ERR, "Can't unregister %s object", path); + + continue; + } + + for (; *snd_level; snd_level++) { + ptr2 = *snd_level; + sprintf(path, "%s/%s/%s", MANAGER_PATH, ptr1, ptr2); + + syslog(LOG_INFO, "Unregistered %s object", path); + + if (dbus_connection_get_object_path_data(connection, + path, (void*) &data)) { + if (data) { + free(data); + data = NULL; + } + } + + if (!dbus_connection_unregister_object_path(connection, path)) + syslog(LOG_ERR, "Can't unregister %s object", path); + } + + if (*snd_level) + dbus_free_string_array(snd_level); + } + + if (*fst_level) + dbus_free_string_array(fst_level); +} + +gboolean hcid_dbus_register_device(uint16_t id) +{ + struct profile_obj_path_data *ptr = obj_path_table; + int ret = -1; + + if (!connection) + return FALSE; + + for (; ptr->name; ptr++) { + ret = ptr->reg_func(connection, ptr->dft_reg, id); + ptr->dft_reg = 1; + } + + if (!ret) + num_adapters++; + + return TRUE; +} + +gboolean hcid_dbus_unregister_device(uint16_t id) +{ + struct profile_obj_path_data *ptr = obj_path_table; + int dft_unreg = 0; + + if (!connection) + return FALSE; + + for (; ptr->name; ptr++) { + dft_unreg = (num_adapters > 1) ? 0 : 1; + num_adapters--; + ptr->unreg_func(connection, dft_unreg, id); + + if (dft_unreg ) + ptr->dft_reg = 0; + } return TRUE; } + +/* + * @brief HCI object path register function + * Detailed description: function responsible for register a new hci + * D-Bus path. If necessary the default path must be registered too. + * @param conn D-Bus connection + * @param dft_reg register the default path(0 or !0) + * @param id hci device identification + * @return (0-Success/-1 failure) + */ +static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) +{ + char path[MAX_PATH_LENGTH]; + uint16_t *ptr_id = (uint16_t*)malloc(1); + uint16_t *ptr_id_dft; + + /* register the default path*/ + if (!dft_reg) { + ptr_id_dft = (uint16_t*)malloc(1); + *ptr_id_dft = DEFAULT_DEVICE_PATH_ID; + sprintf(path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); + + syslog(LOG_INFO, "registering dft path:%s - id:%d", path, DEFAULT_DEVICE_PATH_ID); + + if (!dbus_connection_register_object_path(conn, path, &obj_vtable, ptr_id_dft)) { + syslog(LOG_ERR,"DBUS failed to register %s object", path); + /* ignore, the default path was already registered */ + } + } + + *ptr_id = id; + + /* register the default path*/ + sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); + + syslog(LOG_INFO, "registering - path:%s - id:%d",path, id); + + if (!dbus_connection_register_object_path(conn, path, &obj_vtable, ptr_id)) { + syslog(LOG_ERR,"DBUS failed to register %s object", path); + /* ignore, the path was already registered */ + } + + return 0; +} + +/* + * @brief HCI object path unregister function + * Detailed description: function responsible for unregister HCI D-Bus + * path for a detached hci device. If necessary the default path must + * be registered too. + * @param conn D-Bus connection + * @param unreg_dft register the default path(0 or !0) + * @param id hci device identification + * @return (0-Success/-1 failure) + */ +static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t id) +{ + int ret = 0; + char path[MAX_PATH_LENGTH]; + char dft_path[MAX_PATH_LENGTH]; + uint16_t *data; + + if (unreg_dft) { + sprintf(dft_path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); + syslog(LOG_INFO, "%s - unregistering dft:%s", __PRETTY_FUNCTION__, dft_path); + if (!dbus_connection_unregister_object_path (connection, dft_path)) { + syslog(LOG_ERR,"DBUS failed to unregister %s object", dft_path); + ret = -1; + } else { + if (dbus_connection_get_object_path_data(conn, dft_path, (void *) &data)) { + if (data) { + free(data); + data = NULL; + } + } + } + } + + sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); + syslog(LOG_INFO, "%s - unregistering spec:%s", __PRETTY_FUNCTION__, path); + if (!dbus_connection_unregister_object_path (connection, path)) { + syslog(LOG_ERR,"DBUS failed to unregister %s object", path); + ret = -1; + } else { + if (dbus_connection_get_object_path_data(conn, path, (void *) &data)) { + if (data) { + free(data); + data = NULL; + } + } + } + + return ret; +} + +const struct service_data *get_hci_table(void) +{ + return hci_services; +} + +/***************************************************************** + * + * Section reserved to HCI Manaher D-Bus message handlers + * + *****************************************************************/ + +static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *msg, void *data) +{ + DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + const char *iface; + const char *method; + + if (!msg || !conn) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (dbus_message_get_type (msg) != DBUS_MESSAGE_TYPE_SIGNAL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + iface = dbus_message_get_interface(msg); + method = dbus_message_get_member(msg); + + if (strcmp(iface, DBUS_INTERFACE_LOCAL) == 0) { + if (strcmp(method, "Disconnected") == 0) + ret = DBUS_HANDLER_RESULT_HANDLED; + } else if (strcmp(iface, DBUS_INTERFACE_DBUS) == 0) { + if (strcmp(method, "NameOwnerChanged") == 0) + ret = DBUS_HANDLER_RESULT_HANDLED; + + if (strcmp(method, "NameAcquired") == 0) + ret = DBUS_HANDLER_RESULT_HANDLED; + } + + return ret; +} +/* + * There is only one message handler function for all object paths + * + */ + +static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void *data) +{ + const struct service_data *ptr_handlers = NULL; + DBusMessage *reply = NULL; + int type; + const char *iface; + const char *method; + const char *signature; + const char *path; + const char *rel_path; + const char *tmp_iface = NULL; + const uint16_t *udata = (uint16_t *) data; + uint32_t result = BLUEZ_EDBUS_UNKNOWN_METHOD; + DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + uint8_t found = 0; + + path = dbus_message_get_path(msg); + type = dbus_message_get_type(msg); + iface = dbus_message_get_interface(msg); + method = dbus_message_get_member (msg); + signature = dbus_message_get_signature(msg); + + syslog (LOG_INFO, "%s - path:%s, udata:0x%X", __PRETTY_FUNCTION__, path, *udata); + + if (strcmp(path, DEVICE_PATH) == 0) { + ptr_handlers = dev_services; + tmp_iface = DEVICE_INTERFACE; + found = 1; + } else { + if (strcmp(path, MANAGER_PATH) > 0) { + /* it is device specific path */ + if ( *udata == MANAGER_PATH_ID ) { + /* fallback handling. The child path IS NOT registered */ + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_UNKNOWN_PATH); + ret = DBUS_HANDLER_RESULT_HANDLED; + } else { + const struct profile_obj_path_data *mgr_child = obj_path_table; + rel_path = strrchr(path,'/'); + rel_path++; + + if (rel_path) { + for ( ;mgr_child->name; mgr_child++) { + if (strcmp(mgr_child->name, rel_path) == 0) { + ptr_handlers = mgr_child->get_svc_table(); + found = 1; + } + } + + tmp_iface = MANAGER_INTERFACE; + } + } + } else { + /* it's the manager path */ + ptr_handlers = mgr_services; + tmp_iface = MANAGER_INTERFACE; + found = 1; + } + } + + if (found && (type == DBUS_MESSAGE_TYPE_METHOD_CALL) && + (strcmp(iface, tmp_iface) == 0) && (method != NULL)) { + + for (; ptr_handlers->name; ptr_handlers++) { + if (strcmp(method, ptr_handlers->name) == 0) { + /* resetting unknown method. It's possible handle method overload */ + result = BLUEZ_EDBUS_WRONG_SIGNATURE; + if (strcmp(ptr_handlers->signature, signature) == 0) { + if (ptr_handlers->handler_func) { + reply = (ptr_handlers->handler_func)(msg, data); + result = 0; /* resetting wrong signature*/ + } else + syslog(LOG_INFO, "Service not implemented"); + + break; + } + + } + } + + if (result) { + reply = bluez_new_failure_msg(msg, result); + } + + /* send an error or the success reply*/ + if (reply) { + if (!dbus_connection_send (conn, reply, NULL)) { + syslog(LOG_ERR, "%s line:%d Can't send reply message!", + __PRETTY_FUNCTION__, __LINE__) ; + } + dbus_message_unref (reply); + } + + ret = DBUS_HANDLER_RESULT_HANDLED; + } + return ret; +} + +static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) +{ + write_inquiry_mode_cp inq_mode; + periodic_inquiry_cp inq_param; + DBusMessageIter iter; + DBusMessage *reply = NULL; + const uint16_t *udata = (uint16_t *) data; + uint8_t length; + uint8_t max_period; + uint8_t min_period; + int sock = -1; + int dev_id = -1; + + if (*udata == DEFAULT_DEVICE_PATH_ID) { + if ((dev_id = hci_get_route(NULL)) < 0) { + syslog(LOG_ERR, "Bluetooth device is not available"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + + } + } else + dev_id = *udata; + + if ((sock = hci_open_dev(dev_id)) < 0) { + syslog(LOG_ERR, "HCI device open failed"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &length); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &min_period); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &max_period); + + if ((length >= min_period) || (min_period >= max_period)) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); + goto failed; + } + + inq_param.num_rsp = 100; + inq_param.length = length; + + inq_param.max_period = max_period; + inq_param.min_period = min_period; + + /* General/Unlimited Inquiry Access Code (GIAC) */ + inq_param.lap[0] = 0x33; + inq_param.lap[1] = 0x8b; + inq_param.lap[2] = 0x9e; + + inq_mode.mode = 1; //INQUIRY_WITH_RSSI; + + if (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, + WRITE_INQUIRY_MODE_CP_SIZE, &inq_mode) < 0) { + syslog(LOG_ERR, "Can't set inquiry mode:%s.", strerror(errno)); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (hci_send_cmd(sock, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, + PERIODIC_INQUIRY_CP_SIZE, &inq_param) < 0) { + syslog(LOG_ERR, "Can't send HCI commands:%s.", strerror(errno)); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } else { + uint8_t result = 0; + /* return TRUE to indicate that operation was completed */ + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE ,&result); + } + +failed: + if (sock > 0) + close(sock); + + return reply; +} + +static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) +{ + DBusMessageIter iter; + DBusMessage *reply = NULL; + const uint16_t *udata = (uint16_t *)data; + int sock = -1; + int dev_id = -1; + + if (*udata == DEFAULT_DEVICE_PATH_ID) { + if ((dev_id = hci_get_route(NULL)) < 0) { + syslog(LOG_ERR, "Bluetooth device is not available"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + } else + dev_id = *udata; + + if ((sock = hci_open_dev(dev_id)) < 0) { + syslog(LOG_ERR, "HCI device open failed"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + + if (hci_send_cmd(sock, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY, 0 , NULL) < 0) { + syslog(LOG_ERR, "Send hci command failed."); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + } else { + uint8_t result = 0; + /* return TRUE to indicate that operation was completed */ + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE ,&result); + } + +failed: + if (sock > 0) + close(sock); + + return reply; +} + +static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) +{ + char addr[18]; + const char array_sig[] = HCI_INQ_REPLY_SIGNATURE; + DBusMessageIter iter; + DBusMessageIter array_iter; + DBusMessageIter struct_iter; + DBusMessage *reply = NULL; + inquiry_info *info = NULL; + const uint16_t *udata = (uint16_t *)data; + const char *paddr = addr; + int dev_id = -1; + int i; + uint32_t class = 0; + uint16_t clock_offset; + uint16_t flags; + int8_t length; + int8_t num_rsp; + + if (*udata == DEFAULT_DEVICE_PATH_ID) { + if ((dev_id = hci_get_route(NULL)) < 0) { + syslog(LOG_ERR, "Bluetooth device is not available"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + } else + dev_id = *udata; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &length); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &num_rsp); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &flags); + + if ((length <= 0) || (num_rsp <= 0)) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); + goto failed; + } + + num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); + + if (num_rsp < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + } else { + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); + + for (i = 0; i < num_rsp; i++) { + ba2str(&(info+i)->bdaddr, addr); + + clock_offset = btohs((info+i)->clock_offset); + /* only 3 bytes are used */ + memcpy(&class, (info+i)->dev_class, 3); + + dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING , &paddr); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32 , &class); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT16 , &clock_offset); + dbus_message_iter_close_container(&array_iter, &struct_iter); + } + + dbus_message_iter_close_container(&iter, &array_iter); + } + +failed: + if(info) + bt_free(info); + + return NULL; +} + +static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) +{ + DBusMessageIter iter; + DBusMessage *reply = NULL; + char *str_bdaddr = NULL; + const uint16_t *udata = (uint16_t *)data; + bdaddr_t bdaddr; + uint8_t role; + int dev_id = -1; + int sock = -1; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &str_bdaddr); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &role); + + str2ba(str_bdaddr, &bdaddr); + + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + + if (dev_id < 0) { + syslog(LOG_ERR, "Bluetooth device failed\n"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + + if (*udata != DEFAULT_DEVICE_PATH_ID && *udata != dev_id) { + syslog(LOG_ERR, "Connection not found\n"); + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); + goto failed; + } + + sock = hci_open_dev(dev_id); + + if (sock < 0) { + syslog(LOG_ERR, "HCI device open failed\n"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + + if (hci_switch_role(sock, &bdaddr, role, 10000) < 0) { + syslog(LOG_ERR, "Switch role request failed\n"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + } else { + uint8_t result = 0; + /* return TRUE to indicate that operation was completed */ + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE, &result); + } + +failed: + return reply; +} + +/***************************************************************** + * + * Section reserved to Device D-Bus message handlers + * + *****************************************************************/ + +static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) +{ + DBusMessageIter iter; + DBusMessageIter array_iter; + DBusMessageIter struct_iter; + DBusMessage *reply = NULL; + + struct hci_dev_list_req *dl = NULL; + struct hci_dev_req *dr = NULL; + struct hci_dev_info di; + int i; + int sock = -1; + + char aname[BLUETOOTH_DEVICE_NAME_LEN]; + char aaddr[BLUETOOTH_DEVICE_ADDR_LEN]; + char *paddr = aaddr; + char *pname = aname; + const char array_sig[] = HCI_DEVICE_STRUCT_SIGNATURE; + + /* Create and bind HCI socket */ + if ((sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { + syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); + + if (!dl) { + syslog(LOG_ERR, "Can't allocate memory"); + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); + goto failed; + } + + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(sock, HCIGETDEVLIST, (void *) dl) < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + /* active bluetooth adapter found */ + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); + dr = dl->dev_req; + + for (i = 0; i < dl->dev_num; i++, dr++) { + if (hci_test_bit(HCI_UP, &dr->dev_opt)) { + memset(&di, 0 , sizeof(struct hci_dev_info)); + di.dev_id = dr->dev_id; + + if (!ioctl(sock, HCIGETDEVINFO, (void *) &di)) { + strcpy(aname, di.name); + ba2str(&di.bdaddr, aaddr); + dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, + &struct_iter); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING ,&pname); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING ,&paddr); + + dbus_message_iter_close_container(&array_iter, &struct_iter); + } + } + } + + dbus_message_iter_close_container(&iter, &array_iter); + +failed: + if (dl) + free(dl); + + if (sock > 0) + close (sock); + + return reply; +} + +static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data) +{ + const char *path = dbus_message_get_path(msg); + const char *iface = dbus_message_get_interface(msg); + const char *method = dbus_message_get_member(msg); + + syslog(LOG_INFO, "Not Implemented - path %s iface %s method %s", + path, iface, method); + + return NULL; +} diff --git a/hcid/dbus.h b/hcid/dbus.h new file mode 100644 index 00000000..585739ce --- /dev/null +++ b/hcid/dbus.h @@ -0,0 +1,180 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id$ + */ + +#define __END_SIG__ DBUS_TYPE_INVALID_AS_STRING + +#define BASE_PATH "/org/bluez" +#define BASE_INTERFACE "org.bluez" + +#define DEVICE_PATH BASE_PATH "/Device" +#define DEVICE_INTERFACE BASE_INTERFACE ".Device" + +#define MANAGER_PATH BASE_PATH "/Manager" +#define MANAGER_INTERFACE BASE_INTERFACE ".Manager" + +#define ERROR_INTERFACE BASE_INTERFACE ".Error" + +#define ERROR_UNKNOWN_HCI_COMMAND 0x01 +#define ERROR_UNKNOWN_CONNECTION_IDENTIFIER 0x02 +#define ERROR_HARDWARE_FAILURE 0x03 +#define ERROR_PAGE_TIMEOUT 0x04 +#define ERROR_AUTHENTICATION_FAILURE 0x05 +#define ERROR_PIN_OR_KEY_MISSING 0x06 +#define ERROR_MEMORY_CAPACITY_EXCEEDED 0x07 +#define ERROR_CONNECTION_TIMEOUT 0x08 +#define ERROR_CONNECTION_LIMIT_EXCEEDED 0x09 +#define ERROR_SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED 0x0a +#define ERROR_ACL_CONNECTION_ALREADY_EXISTS 0x0b +#define ERROR_COMMAND_DISALLOWED 0x0c +#define ERROR_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES 0x0d +#define ERROR_CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS 0x0e +#define ERROR_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BDADDR 0x0f +#define ERROR_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED 0x10 +#define ERROR_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE 0x11 +#define ERROR_INVALID_HCI_COMMAND_PARAMETERS 0x12 +#define ERROR_REMOTE_USER_TERMINATED_CONNECTION 0x13 +#define ERROR_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO 0x14 + +#define DEFAULT_DEVICE_PATH_ID (0xFFFF) +#define MANAGER_PATH_ID (0xFFFE) +#define DEVICE_PATH_ID (0xFFFD) + +#define HCI_DEFAULT_DEVICE_NAME "default" +#define HCI_DEVICE_NAME "hci" + +/*======================================================================== + BlueZ D-Bus Device service definitions "/org/bluez/Device" + *========================================================================*/ +#define DEV_UP "Up" +#define DEV_DOWN "Down" +#define DEV_RESET "Reset" +#define DEV_SET_PROPERTY "SetProperty" +#define DEV_GET_PROPERTY "GetProperty" + +#define DEV_UP_SIGNATURE __END_SIG__ +#define DEV_DOWN_SIGNATURE __END_SIG__ +#define DEV_RESET_SIGNATURE __END_SIG__ +#define DEV_SET_PROPERTY_SIGNATURE __END_SIG__ +#define DEV_GET_PROPERTY_SIGNATURE __END_SIG__ + +/*======================================================================== + BlueZ D-Bus Manager service definitions "/org/bluez/Manager" + *========================================================================*/ + + /* ===== Manager definitions, services under DEVICE_PATH ===== */ +#define MGR_GET_DEV "DeviceList" +#define MGR_INIT "Init" + +/* Enable/Disable services controller, pan, serial, ... */ +#define MGR_ENABLE "Enable" +#define MGR_DISABLE "Disable" + +//signatures +#define MGR_GET_DEV_SIGNATURE __END_SIG__ + +/* yya(ss)*/ +#define MGR_GET_DEV_REPLY_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_ARRAY_AS_STRING\ + HCI_DEVICE_STRUCT_SIGNATURE\ + __END_SIG__ + +/* ===== HCI definitions ===== */ +#define BLUEZ_HCI "Controller" +#define BLUEZ_HCI_PATH MANAGER_PATH "/" BLUEZ_HCI +#define BLUEZ_HCI_INTERFACE MANAGER_INTERFACE "." BLUEZ_HCI + +//HCI signals +#define BLUEZ_HCI_INQ_START "InquiryStart" +#define BLUEZ_HCI_INQ_COMPLETE "InquiryComplete" +#define BLUEZ_HCI_INQ_RESULT "InquiryResult" +#define BLUEZ_HCI_REMOTE_NAME "RemoteName" + +//HCI Provided services +#define HCI_PERIODIC_INQ "PeriodicInquiry" +#define HCI_CANCEL_PERIODIC_INQ "CancelPeriodic" +#define HCI_INQ "Inquiry" +#define HCI_ROLE_SWITCH "RoleSwitch" + + +#define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + __END_SIG__ + +#define HCI_CANCEL_PERIODIC_INQ_SIGNATURE __END_SIG__ + +#define HCI_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_UINT16_AS_STRING\ + __END_SIG__ + +#define HCI_ROLE_SWITCH_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + __END_SIG__ + +#define HCI_DEVICE_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING\ + DBUS_TYPE_STRING_AS_STRING\ + DBUS_TYPE_STRING_AS_STRING\ + DBUS_STRUCT_END_CHAR_AS_STRING + +#define HCI_INQ_REPLY_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING\ + DBUS_TYPE_STRING_AS_STRING\ + DBUS_TYPE_UINT32_AS_STRING\ + DBUS_TYPE_UINT16_AS_STRING\ + DBUS_STRUCT_END_CHAR_AS_STRING\ + __END_SIG__ + +/* BLUEZ_DBUS_ERROR + * EFailed error messages signature is : su + * Where the first argument is a string(error message description), + * the last is a uint32 that contains the error class(system, dbus or hci). */ + +/* Error code offsets */ +#define BLUEZ_EBT_OFFSET (0x00000000) /* see Bluetooth error code */ +#define BLUEZ_EBT_EXT_OFFSET (0x00000100) +#define BLUEZ_EDBUS_OFFSET (0x00010000) +#define BLUEZ_ESYSTEM_OFFSET (0x00020000) +#define BLUEZ_EFUTURE_OFFSET (0x00040000) + +/* D-Bus error code, class BLUEZ_EDBUS_OFFSET */ +#define BLUEZ_EDBUS_UNKNOWN_METHOD (0x01 + BLUEZ_EDBUS_OFFSET) +#define BLUEZ_EDBUS_WRONG_SIGNATURE (0x02 + BLUEZ_EDBUS_OFFSET) +#define BLUEZ_EDBUS_WRONG_PARAM (0x03 + BLUEZ_EDBUS_OFFSET) +#define BLUEZ_EDBUS_RECORD_NOT_FOUND (0x04 + BLUEZ_EDBUS_OFFSET) +#define BLUEZ_EDBUS_NO_MEM (0x05 + BLUEZ_EDBUS_OFFSET) +#define BLUEZ_EDBUS_CONN_NOT_FOUND (0x06 + BLUEZ_EDBUS_OFFSET) +#define BLUEZ_EDBUS_UNKNOWN_PATH (0x07 + BLUEZ_EDBUS_OFFSET) + +/* D-Bus error code, class BLUEZ_ESYSTEM_OFFSET */ +#define BLUEZ_ESYSTEM_ENODEV (ENODEV + BLUEZ_ESYSTEM_OFFSET) + +/* BLUEZ_DBUS_ERR_NO_MEMORY */ +#define BLUEZ_DBUS_ERR_NO_MEMORY_STR "No memory" diff --git a/hcid/hcid.h b/hcid/hcid.h index 39b2cd09..d407c4c7 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -28,7 +28,9 @@ * $Id$ */ +#include #include +#include #include #include @@ -122,6 +124,9 @@ void toggle_pairing(int enable); #ifdef ENABLE_DBUS gboolean hcid_dbus_init(void); +void hcid_dbus_exit(void); +gboolean hcid_dbus_register_device(uint16_t id); +gboolean hcid_dbus_unregister_device(uint16_t id); void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); void hcid_dbus_inquiry_start(bdaddr_t *local); void hcid_dbus_inquiry_complete(bdaddr_t *local); @@ -145,3 +150,33 @@ int write_features_info(bdaddr_t *local, bdaddr_t *peer, unsigned char *features int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, int type); int read_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key); int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin); + +static inline int find_conn(int dd, int dev_id, long arg) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + int i; + + cl = malloc(10 * sizeof(*ci) + sizeof(*cl)); + if (!cl) { + syslog(LOG_ERR, "Can't allocate memory"); + return 0; + } + + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(dd, HCIGETCONNLIST, (void *) cl)) { + syslog(LOG_ERR, "Can't get connection list"); + return 0; + } + + for (i = 0; i < cl->conn_num; i++, ci++) + if (!bacmp((bdaddr_t *) arg, &ci->bdaddr)) + return 1; + + free(cl); + + return 0; +} diff --git a/hcid/main.c b/hcid/main.c index ecfc7db6..b6891ee4 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -375,6 +375,10 @@ static void init_all_devices(int ctl) if (hcid.security && hci_test_bit(HCI_UP, &dr->dev_opt)) start_security_manager(dr->dev_id); + +#ifdef ENABLE_DBUS + hcid_dbus_register_device(dr->dev_id); +#endif } free(dl); @@ -438,12 +442,18 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si) configure_device(sd->dev_id); if (hcid.security) start_security_manager(sd->dev_id); +#ifdef ENABLE_DBUS + hcid_dbus_register_device(sd->dev_id); +#endif break; case HCI_DEV_DOWN: syslog(LOG_INFO, "HCI dev %d down", sd->dev_id); if (hcid.security) stop_security_manager(sd->dev_id); +#ifdef ENABLE_DBUS + hcid_dbus_unregister_device(sd->dev_id); +#endif break; } } @@ -628,6 +638,10 @@ int main(int argc, char *argv[], char *env[]) free_device_opts(); +#ifdef ENABLE_DBUS + hcid_dbus_exit(); +#endif + syslog(LOG_INFO, "Exit."); return 0; } -- cgit From 1cc1c3615786c2f871044eaa471c7554bb2df3d2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Oct 2005 22:17:14 +0000 Subject: Add D-Bus security configuration --- hcid/Makefile.am | 2 +- hcid/dbus.conf | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 hcid/dbus.conf diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 7f235c73..f195c152 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -35,7 +35,7 @@ AM_YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.h dbus.c +EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.h dbus.c dbus.conf MAINTAINERCLEANFILES = Makefile.in diff --git a/hcid/dbus.conf b/hcid/dbus.conf new file mode 100644 index 00000000..af3c49e7 --- /dev/null +++ b/hcid/dbus.conf @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + -- cgit From c8d9c22613a80a77150f65ac6bdc753d5a1a3e68 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Oct 2005 22:45:43 +0000 Subject: Add compile time buffer checks (FORTIFY SOURCE) --- acinclude.m4 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/acinclude.m4 b/acinclude.m4 index 43b2d8b2..0d41c225 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -290,6 +290,7 @@ AC_DEFUN([AC_PATH_USB], [ ]) AC_DEFUN([AC_ARG_BLUEZ], [ + fortify_enable=yes debug_enable=no pie_enable=no dbus_enable=${dbus_found} @@ -307,6 +308,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ bcm203x_enable=no bluepin_enable=yes + AC_ARG_ENABLE(fortify, AC_HELP_STRING([--disable-fortify], [disable compile time buffer checks]), [ + fortify_enable=${enableval} + ]) + AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable compiling with debugging information]), [ debug_enable=${enableval} ]) @@ -388,6 +393,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ bluepin_enable=${enableval} ]) + if (test "${fortify_enable}" = "yes"); then + CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" + fi + if (test "${debug_enable}" = "yes" && test "${ac_cv_prog_cc_g}" = "yes"); then CFLAGS="$CFLAGS -g" fi -- cgit From f3249c39a30c3ebbb427e05976a143ae9db51082 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Oct 2005 23:16:54 +0000 Subject: Add compile script --- compile | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100755 compile diff --git a/compile b/compile new file mode 100755 index 00000000..28d79b54 --- /dev/null +++ b/compile @@ -0,0 +1,7 @@ +#! /bin/sh +./configure --enable-maintainer-mode --enable-all --disable-pcmcia --disable-initscripts --disable-bluepin && make && \ + sudo cp hcid/hcid /usr/sbin && \ + sudo cp sdpd/sdpd /usr/sbin && \ + sudo cp tools/hciconfig /usr/sbin && \ + sudo cp tools/hcitool /usr/bin && \ + sudo cp tools/sdptool /usr/bin -- cgit From 731a901de3a73233b3b51be71296b6658a6f91dd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Oct 2005 23:26:04 +0000 Subject: Set D-Bus system configuration directory --- hcid/Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hcid/Makefile.am b/hcid/Makefile.am index f195c152..b20432f3 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -10,6 +10,10 @@ statedir = $(localstatedir)/lib/bluetooth state_DATA = +if DBUS +dbusdir = $(sysconfdir)/dbus-1/system.d +endif + sbin_PROGRAMS = hcid if DBUS -- cgit From 66605acd2f237c337169ea975b399784ffa76788 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Oct 2005 23:31:29 +0000 Subject: Install D-Bus security configuration --- hcid/Makefile.am | 4 +++- hcid/bluez-hcid.conf | 24 ++++++++++++++++++++++++ hcid/dbus.conf | 24 ------------------------ 3 files changed, 27 insertions(+), 25 deletions(-) create mode 100644 hcid/bluez-hcid.conf delete mode 100644 hcid/dbus.conf diff --git a/hcid/Makefile.am b/hcid/Makefile.am index b20432f3..b616cbfc 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -12,6 +12,8 @@ state_DATA = if DBUS dbusdir = $(sysconfdir)/dbus-1/system.d + +dbus_DATA = bluez-hcid.conf endif sbin_PROGRAMS = hcid @@ -39,7 +41,7 @@ AM_YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.h dbus.c dbus.conf +EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.h dbus.c bluez-hcid.conf MAINTAINERCLEANFILES = Makefile.in diff --git a/hcid/bluez-hcid.conf b/hcid/bluez-hcid.conf new file mode 100644 index 00000000..af3c49e7 --- /dev/null +++ b/hcid/bluez-hcid.conf @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/hcid/dbus.conf b/hcid/dbus.conf deleted file mode 100644 index af3c49e7..00000000 --- a/hcid/dbus.conf +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -- cgit From 3b01d3c5e0457009c0bdc683d9e8adab29d20fe1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 10 Oct 2005 08:22:59 +0000 Subject: Add address change support for Texas Instruments chips --- test/bdaddr.8 | 31 +++++++++++++++++++------------ test/bdaddr.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/test/bdaddr.8 b/test/bdaddr.8 index 623a1401..dbc2099e 100644 --- a/test/bdaddr.8 +++ b/test/bdaddr.8 @@ -12,23 +12,28 @@ bdaddr \- Utility for changing the Bluetooth device address .LP .B bdaddr -is used to query or set the local Bluetooth device address (BD_ADDR). If run with no arguments, +is used to query or set the local Bluetooth device address (BD_ADDR). If run +with no arguments, .B bdaddr -prints the chip manufacturer's name, and the current BD_ADDR. If the IEEE OUI index file "oui.txt" is installed on the system, -the BD_ADDR owner will be displayed. If the optional -[new bdaddr] argument is given, the device will be reprogrammed with that address. This can either be permanent or temporary, as specified -by the -t flag. In both cases, the device must be reset before the new address will become active. This can be done -with a 'soft' reset by specifying the -r flag, or a 'hard' reset by removing and replugging the device. -A 'hard' reset will cause the address to revert to the current non-volatile value. +prints the chip manufacturer's name, and the current BD_ADDR. If the IEEE OUI +index file "oui.txt" is installed on the system, the BD_ADDR owner will be +displayed. If the optional [new bdaddr] argument is given, the device will be +reprogrammed with that address. This can either be permanent or temporary, as +specified by the -t flag. In both cases, the device must be reset before the +new address will become active. This can be done with a 'soft' reset by +specifying the -r flag, or a 'hard' reset by removing and replugging the +device. A 'hard' reset will cause the address to revert to the current +non-volatile value. .PP .B bdaddr -uses manufacturer specific commands to set the address, and is therefore device specific. For this reason, not all devices are supported, and not all +uses manufacturer specific commands to set the address, and is therefore +device specific. For this reason, not all devices are supported, and not all options are supported on all devices. Current supported manufacturers are: -.B Ericsson, Cambridge Silicon Radio (CSR) -and +.B Ericsson, Cambridge Silicon Radio (CSR), Texas Instruments (TI) +and .B Zeevo .SH OPTIONS @@ -37,7 +42,8 @@ and Gives a list of possible commands. .TP .BI -i\ -Specify a particular device to operate on. If not specified, default is the first available device. +Specify a particular device to operate on. If not specified, default is the +first available device. .TP .BI -r Reset device and make new BD_ADDR active. @@ -54,7 +60,8 @@ devices only. .TP .I /usr/share/misc/oui.txt -IEEE Organizationally Unique Identifier master file. Manually update from: http://standards.ieee.org/regauth/oui/oui.txt +IEEE Organizationally Unique Identifier master file. +Manually update from: http://standards.ieee.org/regauth/oui/oui.txt .SH AUTHORS Written by Marcel Holtmann , man page by Adam Laurie diff --git a/test/bdaddr.c b/test/bdaddr.c index 92b43de8..ac382e57 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -189,6 +189,34 @@ static int csr_reset_device(int dd) return 0; } +#define OCF_TI_WRITE_BD_ADDR 0x0006 +typedef struct { + bdaddr_t bdaddr; +} __attribute__ ((packed)) ti_write_bd_addr_cp; +#define TI_WRITE_BD_ADDR_CP_SIZE 6 + +static int ti_write_bd_addr(int dd, bdaddr_t *bdaddr) +{ + struct hci_request rq; + ti_write_bd_addr_cp cp; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_TI_WRITE_BD_ADDR; + rq.cparam = &cp; + rq.clen = TI_WRITE_BD_ADDR_CP_SIZE; + rq.rparam = NULL; + rq.rlen = 0; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + return 0; +} + #define OCF_ZEEVO_WRITE_BD_ADDR 0x0001 typedef struct { bdaddr_t bdaddr; @@ -224,6 +252,7 @@ static struct { } vendor[] = { { 0, ericsson_write_bd_addr, NULL }, { 10, csr_write_bd_addr, csr_reset_device }, + { 13, ti_write_bd_addr, NULL, }, { 18, zeevo_write_bd_addr, NULL }, { 65535, NULL, NULL }, }; -- cgit From abebc092a001a169868c7eff59242c88a8e92b2b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 10 Oct 2005 20:46:55 +0000 Subject: Update and cleanup D-Bus support --- hcid/dbus.c | 117 ++++++++++++------------------------------------------------ 1 file changed, 23 insertions(+), 94 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 36fd476c..d76da4cd 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -178,12 +178,8 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data); static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data); static const DBusObjectPathVTable obj_vtable = { - NULL, - &msg_func, - NULL, - NULL, - NULL, - NULL + .message_function = &msg_func, + .unregister_function = NULL }; /* @@ -554,8 +550,6 @@ static void watch_toggled(DBusWatch *watch, void *data) gboolean hcid_dbus_init(void) { DBusError error; - uint16_t *dev_path_id = (uint16_t *) malloc(1); - uint16_t *mgr_path_id = (uint16_t *) malloc(1); dbus_error_init(&error); @@ -578,33 +572,22 @@ gboolean hcid_dbus_init(void) return FALSE; } - if (!dev_path_id) - return FALSE; - - *dev_path_id = DEVICE_PATH_ID; - if (!dbus_connection_register_object_path(connection, DEVICE_PATH, - &obj_vtable, dev_path_id)) { + &obj_vtable, (void *)DEVICE_PATH_ID)) { syslog(LOG_ERR, "Can't register %s object", DEVICE_PATH); return FALSE; } syslog(LOG_INFO,"Registered %s object", DEVICE_PATH); - if (!mgr_path_id) - goto done; - - *mgr_path_id = MANAGER_PATH_ID; - if (!dbus_connection_register_fallback(connection, MANAGER_PATH, - &obj_vtable, mgr_path_id)) { + &obj_vtable, (void *)MANAGER_PATH_ID)) { syslog(LOG_ERR, "Can't register %s object", MANAGER_PATH); return FALSE; } syslog(LOG_INFO, "Registered %s object", MANAGER_PATH); -done: if (!dbus_connection_add_filter(connection, hci_signal_filter, NULL, NULL)) { syslog(LOG_ERR, "Can't add new HCI filter"); return FALSE; @@ -625,35 +608,18 @@ void hcid_dbus_exit(void) char **snd_level = NULL; char *ptr1; char *ptr2; - uint16_t *data = NULL; if (!connection) return; - if (dbus_connection_get_object_path_data(connection, - DEVICE_PATH, (void *) &data)) { - if (data) { - free(data); - data = NULL; - } - } - if (!dbus_connection_unregister_object_path(connection, DEVICE_PATH)) syslog(LOG_ERR, "Can't unregister %s object", DEVICE_PATH); else syslog(LOG_INFO, "Unregistered %s object", DEVICE_PATH); - if (dbus_connection_get_object_path_data(connection, - MANAGER_PATH, (void*) &data)) { - if (data) { - free(data); - data = NULL; - } - } - if (!dbus_connection_unregister_object_path(connection, MANAGER_PATH)) syslog(LOG_ERR, "Can't unregister %s object", MANAGER_PATH); - else + else syslog(LOG_INFO, "Unregistered %s object", MANAGER_PATH); dbus_connection_list_registered(connection, fst_parent, &fst_level); @@ -669,14 +635,6 @@ void hcid_dbus_exit(void) syslog(LOG_INFO, "Unregistered %s object", path); - if (dbus_connection_get_object_path_data(connection, - path, (void*) &data)) { - if (data) { - free(data); - data = NULL; - } - } - if (!dbus_connection_unregister_object_path(connection, path)) syslog(LOG_ERR, "Can't unregister %s object", path); @@ -689,14 +647,6 @@ void hcid_dbus_exit(void) syslog(LOG_INFO, "Unregistered %s object", path); - if (dbus_connection_get_object_path_data(connection, - path, (void*) &data)) { - if (data) { - free(data); - data = NULL; - } - } - if (!dbus_connection_unregister_object_path(connection, path)) syslog(LOG_ERR, "Can't unregister %s object", path); } @@ -760,31 +710,25 @@ gboolean hcid_dbus_unregister_device(uint16_t id) static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) { char path[MAX_PATH_LENGTH]; - uint16_t *ptr_id = (uint16_t*)malloc(1); - uint16_t *ptr_id_dft; /* register the default path*/ if (!dft_reg) { - ptr_id_dft = (uint16_t*)malloc(1); - *ptr_id_dft = DEFAULT_DEVICE_PATH_ID; sprintf(path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); syslog(LOG_INFO, "registering dft path:%s - id:%d", path, DEFAULT_DEVICE_PATH_ID); - if (!dbus_connection_register_object_path(conn, path, &obj_vtable, ptr_id_dft)) { + if (!dbus_connection_register_object_path(conn, path, &obj_vtable, (void *)DEFAULT_DEVICE_PATH_ID)) { syslog(LOG_ERR,"DBUS failed to register %s object", path); /* ignore, the default path was already registered */ } } - *ptr_id = id; - /* register the default path*/ sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); syslog(LOG_INFO, "registering - path:%s - id:%d",path, id); - if (!dbus_connection_register_object_path(conn, path, &obj_vtable, ptr_id)) { + if (!dbus_connection_register_object_path(conn, path, &obj_vtable, (void *)((uint32_t)id))) { syslog(LOG_ERR,"DBUS failed to register %s object", path); /* ignore, the path was already registered */ } @@ -807,7 +751,6 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t int ret = 0; char path[MAX_PATH_LENGTH]; char dft_path[MAX_PATH_LENGTH]; - uint16_t *data; if (unreg_dft) { sprintf(dft_path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); @@ -815,13 +758,6 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t if (!dbus_connection_unregister_object_path (connection, dft_path)) { syslog(LOG_ERR,"DBUS failed to unregister %s object", dft_path); ret = -1; - } else { - if (dbus_connection_get_object_path_data(conn, dft_path, (void *) &data)) { - if (data) { - free(data); - data = NULL; - } - } } } @@ -830,13 +766,6 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t if (!dbus_connection_unregister_object_path (connection, path)) { syslog(LOG_ERR,"DBUS failed to unregister %s object", path); ret = -1; - } else { - if (dbus_connection_get_object_path_data(conn, path, (void *) &data)) { - if (data) { - free(data); - data = NULL; - } - } } return ret; @@ -897,7 +826,7 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * const char *path; const char *rel_path; const char *tmp_iface = NULL; - const uint16_t *udata = (uint16_t *) data; + const uint32_t udata = (uint32_t) data; uint32_t result = BLUEZ_EDBUS_UNKNOWN_METHOD; DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; uint8_t found = 0; @@ -908,7 +837,7 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * method = dbus_message_get_member (msg); signature = dbus_message_get_signature(msg); - syslog (LOG_INFO, "%s - path:%s, udata:0x%X", __PRETTY_FUNCTION__, path, *udata); + syslog (LOG_INFO, "%s - path:%s, udata:0x%X", __PRETTY_FUNCTION__, path, udata); if (strcmp(path, DEVICE_PATH) == 0) { ptr_handlers = dev_services; @@ -917,7 +846,7 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * } else { if (strcmp(path, MANAGER_PATH) > 0) { /* it is device specific path */ - if ( *udata == MANAGER_PATH_ID ) { + if ( udata == MANAGER_PATH_ID ) { /* fallback handling. The child path IS NOT registered */ reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_UNKNOWN_PATH); ret = DBUS_HANDLER_RESULT_HANDLED; @@ -989,14 +918,14 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) periodic_inquiry_cp inq_param; DBusMessageIter iter; DBusMessage *reply = NULL; - const uint16_t *udata = (uint16_t *) data; + uint32_t udata = (uint32_t) data; uint8_t length; uint8_t max_period; uint8_t min_period; int sock = -1; int dev_id = -1; - if (*udata == DEFAULT_DEVICE_PATH_ID) { + if (udata == DEFAULT_DEVICE_PATH_ID) { if ((dev_id = hci_get_route(NULL)) < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); @@ -1004,7 +933,7 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) } } else - dev_id = *udata; + dev_id = udata; if ((sock = hci_open_dev(dev_id)) < 0) { syslog(LOG_ERR, "HCI device open failed"); @@ -1068,18 +997,18 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) { DBusMessageIter iter; DBusMessage *reply = NULL; - const uint16_t *udata = (uint16_t *)data; + uint32_t udata = (uint32_t) data; int sock = -1; int dev_id = -1; - if (*udata == DEFAULT_DEVICE_PATH_ID) { + if (udata == DEFAULT_DEVICE_PATH_ID) { if ((dev_id = hci_get_route(NULL)) < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } } else - dev_id = *udata; + dev_id = udata; if ((sock = hci_open_dev(dev_id)) < 0) { syslog(LOG_ERR, "HCI device open failed"); @@ -1114,7 +1043,7 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) DBusMessageIter struct_iter; DBusMessage *reply = NULL; inquiry_info *info = NULL; - const uint16_t *udata = (uint16_t *)data; + uint32_t udata = (uint32_t) data; const char *paddr = addr; int dev_id = -1; int i; @@ -1124,14 +1053,14 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) int8_t length; int8_t num_rsp; - if (*udata == DEFAULT_DEVICE_PATH_ID) { + if (udata == DEFAULT_DEVICE_PATH_ID) { if ((dev_id = hci_get_route(NULL)) < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } } else - dev_id = *udata; + dev_id = udata; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &length); @@ -1183,7 +1112,7 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) DBusMessageIter iter; DBusMessage *reply = NULL; char *str_bdaddr = NULL; - const uint16_t *udata = (uint16_t *)data; + const uint32_t udata = (uint32_t) data; bdaddr_t bdaddr; uint8_t role; int dev_id = -1; @@ -1204,7 +1133,7 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) goto failed; } - if (*udata != DEFAULT_DEVICE_PATH_ID && *udata != dev_id) { + if (udata != DEFAULT_DEVICE_PATH_ID && udata != dev_id) { syslog(LOG_ERR, "Connection not found\n"); reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; @@ -1276,7 +1205,7 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(sock, HCIGETDEVLIST, (void *) dl) < 0) { + if (ioctl(sock, HCIGETDEVLIST, dl) < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1292,7 +1221,7 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) memset(&di, 0 , sizeof(struct hci_dev_info)); di.dev_id = dr->dev_id; - if (!ioctl(sock, HCIGETDEVINFO, (void *) &di)) { + if (!ioctl(sock, HCIGETDEVINFO, &di)) { strcpy(aname, di.name); ba2str(&di.bdaddr, aaddr); dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, -- cgit From eb882ca6b4cf6fd8ccf8d20ac2a49c34615d2586 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Oct 2005 10:13:10 +0000 Subject: Use long instead of int for the watch id --- hcid/dbus.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index d76da4cd..fec9d278 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -507,7 +507,7 @@ dbus_bool_t add_watch(DBusWatch *watch, void *data) { GIOCondition cond = G_IO_HUP | G_IO_ERR; GIOChannel *io; - guint id; + gulong id; int fd, flags; if (!dbus_watch_get_enabled(watch)) @@ -520,7 +520,7 @@ dbus_bool_t add_watch(DBusWatch *watch, void *data) if (flags & DBUS_WATCH_READABLE) cond |= G_IO_IN; if (flags & DBUS_WATCH_WRITABLE) cond |= G_IO_OUT; - id = g_io_add_watch(io, cond, watch_func, watch); + id = (gulong) g_io_add_watch(io, cond, watch_func, watch); dbus_watch_set_data(watch, (void *) id, NULL); @@ -529,12 +529,12 @@ dbus_bool_t add_watch(DBusWatch *watch, void *data) static void remove_watch(DBusWatch *watch, void *data) { - guint id = (guint) dbus_watch_get_data(watch); + gulong id = (gulong) dbus_watch_get_data(watch); dbus_watch_set_data(watch, NULL, NULL); if (id) - g_io_remove_watch(id); + g_io_remove_watch((guint) id); } static void watch_toggled(DBusWatch *watch, void *data) @@ -717,7 +717,7 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) syslog(LOG_INFO, "registering dft path:%s - id:%d", path, DEFAULT_DEVICE_PATH_ID); - if (!dbus_connection_register_object_path(conn, path, &obj_vtable, (void *)DEFAULT_DEVICE_PATH_ID)) { + if (!dbus_connection_register_object_path(conn, path, &obj_vtable, (void *) DEFAULT_DEVICE_PATH_ID)) { syslog(LOG_ERR,"DBUS failed to register %s object", path); /* ignore, the default path was already registered */ } @@ -728,7 +728,7 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) syslog(LOG_INFO, "registering - path:%s - id:%d",path, id); - if (!dbus_connection_register_object_path(conn, path, &obj_vtable, (void *)((uint32_t)id))) { + if (!dbus_connection_register_object_path(conn, path, &obj_vtable, (void *) ((long) id))) { syslog(LOG_ERR,"DBUS failed to register %s object", path); /* ignore, the path was already registered */ } @@ -826,7 +826,7 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * const char *path; const char *rel_path; const char *tmp_iface = NULL; - const uint32_t udata = (uint32_t) data; + long udata = (long) data; uint32_t result = BLUEZ_EDBUS_UNKNOWN_METHOD; DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; uint8_t found = 0; @@ -837,7 +837,7 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * method = dbus_message_get_member (msg); signature = dbus_message_get_signature(msg); - syslog (LOG_INFO, "%s - path:%s, udata:0x%X", __PRETTY_FUNCTION__, path, udata); + syslog (LOG_INFO, "%s - path:%s, udata:0x%X", __PRETTY_FUNCTION__, path, (guint) udata); if (strcmp(path, DEVICE_PATH) == 0) { ptr_handlers = dev_services; @@ -918,7 +918,7 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) periodic_inquiry_cp inq_param; DBusMessageIter iter; DBusMessage *reply = NULL; - uint32_t udata = (uint32_t) data; + long udata = (long) data; uint8_t length; uint8_t max_period; uint8_t min_period; @@ -933,7 +933,7 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) } } else - dev_id = udata; + dev_id = (int) udata; if ((sock = hci_open_dev(dev_id)) < 0) { syslog(LOG_ERR, "HCI device open failed"); @@ -997,7 +997,7 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) { DBusMessageIter iter; DBusMessage *reply = NULL; - uint32_t udata = (uint32_t) data; + long udata = (long) data; int sock = -1; int dev_id = -1; @@ -1008,7 +1008,7 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) goto failed; } } else - dev_id = udata; + dev_id = (int) udata; if ((sock = hci_open_dev(dev_id)) < 0) { syslog(LOG_ERR, "HCI device open failed"); @@ -1043,7 +1043,7 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) DBusMessageIter struct_iter; DBusMessage *reply = NULL; inquiry_info *info = NULL; - uint32_t udata = (uint32_t) data; + long udata = (long) data; const char *paddr = addr; int dev_id = -1; int i; @@ -1060,7 +1060,7 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) goto failed; } } else - dev_id = udata; + dev_id = (int) udata; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &length); @@ -1112,7 +1112,7 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) DBusMessageIter iter; DBusMessage *reply = NULL; char *str_bdaddr = NULL; - const uint32_t udata = (uint32_t) data; + long udata = (long) data; bdaddr_t bdaddr; uint8_t role; int dev_id = -1; -- cgit From af1ee190718a073e2b291151903478cf82f5bf14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 11 Oct 2005 22:45:38 +0000 Subject: Allocate the watch private data --- hcid/dbus.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 23 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index fec9d278..50e95318 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -77,6 +77,10 @@ struct service_data { const char *signature; }; +struct hci_dbus_data { + uint16_t id; +}; + typedef int register_function_t(DBusConnection *conn, int dft_reg, uint16_t id); typedef int unregister_function_t(DBusConnection *conn, int unreg_dft, uint16_t id); @@ -507,12 +511,16 @@ dbus_bool_t add_watch(DBusWatch *watch, void *data) { GIOCondition cond = G_IO_HUP | G_IO_ERR; GIOChannel *io; - gulong id; + guint *id; int fd, flags; if (!dbus_watch_get_enabled(watch)) return TRUE; + id = malloc(sizeof(guint)); + if (id == NULL) + return FALSE; + fd = dbus_watch_get_fd(watch); io = g_io_channel_unix_new(fd); flags = dbus_watch_get_flags(watch); @@ -520,21 +528,23 @@ dbus_bool_t add_watch(DBusWatch *watch, void *data) if (flags & DBUS_WATCH_READABLE) cond |= G_IO_IN; if (flags & DBUS_WATCH_WRITABLE) cond |= G_IO_OUT; - id = (gulong) g_io_add_watch(io, cond, watch_func, watch); + *id = g_io_add_watch(io, cond, watch_func, watch); - dbus_watch_set_data(watch, (void *) id, NULL); + dbus_watch_set_data(watch, id, NULL); return TRUE; } static void remove_watch(DBusWatch *watch, void *data) { - gulong id = (gulong) dbus_watch_get_data(watch); + guint *id = dbus_watch_get_data(watch); dbus_watch_set_data(watch, NULL, NULL); - if (id) - g_io_remove_watch((guint) id); + if (id) { + g_io_remove_watch(*id); + free(id); + } } static void watch_toggled(DBusWatch *watch, void *data) @@ -549,6 +559,7 @@ static void watch_toggled(DBusWatch *watch, void *data) gboolean hcid_dbus_init(void) { + struct hci_dbus_data *data; DBusError error; dbus_error_init(&error); @@ -572,16 +583,28 @@ gboolean hcid_dbus_init(void) return FALSE; } + data = malloc(sizeof(struct hci_dbus_data)); + if (data == NULL) + return FALSE; + + data->id = DEVICE_PATH_ID; + if (!dbus_connection_register_object_path(connection, DEVICE_PATH, - &obj_vtable, (void *)DEVICE_PATH_ID)) { + &obj_vtable, data)) { syslog(LOG_ERR, "Can't register %s object", DEVICE_PATH); return FALSE; } syslog(LOG_INFO,"Registered %s object", DEVICE_PATH); + data = malloc(sizeof(struct hci_dbus_data)); + if (data == NULL) + return FALSE; + + data->id = MANAGER_PATH_ID; + if (!dbus_connection_register_fallback(connection, MANAGER_PATH, - &obj_vtable, (void *)MANAGER_PATH_ID)) { + &obj_vtable, data)) { syslog(LOG_ERR, "Can't register %s object", MANAGER_PATH); return FALSE; } @@ -608,15 +631,32 @@ void hcid_dbus_exit(void) char **snd_level = NULL; char *ptr1; char *ptr2; + void *data = NULL; if (!connection) return; + if (dbus_connection_get_object_path_data(connection, + DEVICE_PATH, &data)) { + if (data) { + free(data); + data = NULL; + } + } + if (!dbus_connection_unregister_object_path(connection, DEVICE_PATH)) syslog(LOG_ERR, "Can't unregister %s object", DEVICE_PATH); else syslog(LOG_INFO, "Unregistered %s object", DEVICE_PATH); + if (dbus_connection_get_object_path_data(connection, + MANAGER_PATH, &data)) { + if (data) { + free(data); + data = NULL; + } + } + if (!dbus_connection_unregister_object_path(connection, MANAGER_PATH)) syslog(LOG_ERR, "Can't unregister %s object", MANAGER_PATH); else @@ -635,6 +675,14 @@ void hcid_dbus_exit(void) syslog(LOG_INFO, "Unregistered %s object", path); + if (dbus_connection_get_object_path_data(connection, + path, &data)) { + if (data) { + free(data); + data = NULL; + } + } + if (!dbus_connection_unregister_object_path(connection, path)) syslog(LOG_ERR, "Can't unregister %s object", path); @@ -647,6 +695,14 @@ void hcid_dbus_exit(void) syslog(LOG_INFO, "Unregistered %s object", path); + if (dbus_connection_get_object_path_data(connection, + path, &data)) { + if (data) { + free(data); + data = NULL; + } + } + if (!dbus_connection_unregister_object_path(connection, path)) syslog(LOG_ERR, "Can't unregister %s object", path); } @@ -709,6 +765,7 @@ gboolean hcid_dbus_unregister_device(uint16_t id) */ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) { + struct hci_dbus_data *data; char path[MAX_PATH_LENGTH]; /* register the default path*/ @@ -723,12 +780,18 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) } } + data = malloc(sizeof(struct hci_dbus_data)); + if (data == NULL) + return -1; + + data->id = id; + /* register the default path*/ sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); syslog(LOG_INFO, "registering - path:%s - id:%d",path, id); - if (!dbus_connection_register_object_path(conn, path, &obj_vtable, (void *) ((long) id))) { + if (!dbus_connection_register_object_path(conn, path, &obj_vtable, data)) { syslog(LOG_ERR,"DBUS failed to register %s object", path); /* ignore, the path was already registered */ } @@ -751,6 +814,7 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t int ret = 0; char path[MAX_PATH_LENGTH]; char dft_path[MAX_PATH_LENGTH]; + void *data = NULL; if (unreg_dft) { sprintf(dft_path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); @@ -758,6 +822,13 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t if (!dbus_connection_unregister_object_path (connection, dft_path)) { syslog(LOG_ERR,"DBUS failed to unregister %s object", dft_path); ret = -1; + } else { + if (dbus_connection_get_object_path_data(conn, dft_path, &data)) { + if (data) { + free(data); + data = NULL; + } + } } } @@ -766,6 +837,13 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t if (!dbus_connection_unregister_object_path (connection, path)) { syslog(LOG_ERR,"DBUS failed to unregister %s object", path); ret = -1; + } else { + if (dbus_connection_get_object_path_data(conn, path, &data)) { + if (data) { + free(data); + data = NULL; + } + } } return ret; @@ -826,7 +904,7 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * const char *path; const char *rel_path; const char *tmp_iface = NULL; - long udata = (long) data; + struct hci_dbus_data *dbus_data = data; uint32_t result = BLUEZ_EDBUS_UNKNOWN_METHOD; DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; uint8_t found = 0; @@ -837,7 +915,7 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * method = dbus_message_get_member (msg); signature = dbus_message_get_signature(msg); - syslog (LOG_INFO, "%s - path:%s, udata:0x%X", __PRETTY_FUNCTION__, path, (guint) udata); + syslog (LOG_INFO, "%s - path:%s, id:0x%X", __PRETTY_FUNCTION__, path, dbus_data->id); if (strcmp(path, DEVICE_PATH) == 0) { ptr_handlers = dev_services; @@ -846,7 +924,7 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * } else { if (strcmp(path, MANAGER_PATH) > 0) { /* it is device specific path */ - if ( udata == MANAGER_PATH_ID ) { + if ( dbus_data->id == MANAGER_PATH_ID ) { /* fallback handling. The child path IS NOT registered */ reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_UNKNOWN_PATH); ret = DBUS_HANDLER_RESULT_HANDLED; @@ -918,14 +996,14 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) periodic_inquiry_cp inq_param; DBusMessageIter iter; DBusMessage *reply = NULL; - long udata = (long) data; + struct hci_dbus_data *dbus_data = data; uint8_t length; uint8_t max_period; uint8_t min_period; int sock = -1; int dev_id = -1; - if (udata == DEFAULT_DEVICE_PATH_ID) { + if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { if ((dev_id = hci_get_route(NULL)) < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); @@ -933,7 +1011,7 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) } } else - dev_id = (int) udata; + dev_id = dbus_data->id; if ((sock = hci_open_dev(dev_id)) < 0) { syslog(LOG_ERR, "HCI device open failed"); @@ -997,18 +1075,18 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) { DBusMessageIter iter; DBusMessage *reply = NULL; - long udata = (long) data; + struct hci_dbus_data *dbus_data = data; int sock = -1; int dev_id = -1; - if (udata == DEFAULT_DEVICE_PATH_ID) { + if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { if ((dev_id = hci_get_route(NULL)) < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } } else - dev_id = (int) udata; + dev_id = dbus_data->id; if ((sock = hci_open_dev(dev_id)) < 0) { syslog(LOG_ERR, "HCI device open failed"); @@ -1043,7 +1121,7 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) DBusMessageIter struct_iter; DBusMessage *reply = NULL; inquiry_info *info = NULL; - long udata = (long) data; + struct hci_dbus_data *dbus_data = data; const char *paddr = addr; int dev_id = -1; int i; @@ -1053,14 +1131,14 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) int8_t length; int8_t num_rsp; - if (udata == DEFAULT_DEVICE_PATH_ID) { + if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { if ((dev_id = hci_get_route(NULL)) < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } } else - dev_id = (int) udata; + dev_id = dbus_data->id; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &length); @@ -1112,7 +1190,7 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) DBusMessageIter iter; DBusMessage *reply = NULL; char *str_bdaddr = NULL; - long udata = (long) data; + struct hci_dbus_data *dbus_data = data; bdaddr_t bdaddr; uint8_t role; int dev_id = -1; @@ -1133,7 +1211,7 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) goto failed; } - if (udata != DEFAULT_DEVICE_PATH_ID && udata != dev_id) { + if (dbus_data->id != DEFAULT_DEVICE_PATH_ID && dbus_data->id != dev_id) { syslog(LOG_ERR, "Connection not found\n"); reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; -- cgit From caab20b1789e6f38531897dad0c72833c67bf960 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Oct 2005 09:33:13 +0000 Subject: Fix a segmentation fault for hci_dbus_data allocation --- hcid/dbus.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 50e95318..9f06f928 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -774,7 +774,13 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) syslog(LOG_INFO, "registering dft path:%s - id:%d", path, DEFAULT_DEVICE_PATH_ID); - if (!dbus_connection_register_object_path(conn, path, &obj_vtable, (void *) DEFAULT_DEVICE_PATH_ID)) { + data = malloc(sizeof(struct hci_dbus_data)); + if (data == NULL) + return -1; + + data->id = DEFAULT_DEVICE_PATH_ID; + + if (!dbus_connection_register_object_path(conn, path, &obj_vtable, data)) { syslog(LOG_ERR,"DBUS failed to register %s object", path); /* ignore, the default path was already registered */ } -- cgit From 84741f3be42dddc9fe2545048011a0042a5c5be0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Oct 2005 09:36:00 +0000 Subject: Add remote name and connection listing support --- hcid/dbus.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- hcid/dbus.h | 17 +++++++ 2 files changed, 159 insertions(+), 10 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 9f06f928..76540a7a 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -58,6 +58,8 @@ static int num_adapters = 0; #define BLUETOOTH_DEVICE_NAME_LEN (18) #define BLUETOOTH_DEVICE_ADDR_LEN (18) #define MAX_PATH_LENGTH (64) +#define READ_REMOTE_NAME_TIMEOUT (25000) +#define MAX_CONN_NUMBER (10) #define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent" #define PINAGENT_INTERFACE PINAGENT_SERVICE_NAME @@ -129,7 +131,7 @@ static const char *bluez_dbus_error_to_str(const uint32_t ecode) if (ecode & BLUEZ_ESYSTEM_OFFSET) { /* System error */ - raw_code = (!BLUEZ_ESYSTEM_OFFSET) & ecode; + raw_code = (~BLUEZ_ESYSTEM_OFFSET) & ecode; syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, strerror(raw_code)); return strerror(raw_code); } else if (ecode & BLUEZ_EDBUS_OFFSET) { @@ -221,12 +223,16 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data); static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data); static DBusMessage* handle_inq_req(DBusMessage *msg, void *data); static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data); +static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data); +static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data); static const struct service_data hci_services[] = { { HCI_PERIODIC_INQ, handle_periodic_inq_req, HCI_PERIODIC_INQ_SIGNATURE }, { HCI_CANCEL_PERIODIC_INQ, handle_cancel_periodic_inq_req, HCI_CANCEL_PERIODIC_INQ_SIGNATURE }, { HCI_ROLE_SWITCH, handle_role_switch_req, HCI_ROLE_SWITCH_SIGNATURE }, { HCI_INQ, handle_inq_req, HCI_INQ_SIGNATURE }, + { HCI_REMOTE_NAME, handle_remote_name_req, HCI_REMOTE_NAME_SIGNATURE }, + { HCI_CONNECTIONS, handle_display_conn_req, HCI_CONNECTIONS_SIGNATURE }, { NULL, NULL, NULL } }; @@ -982,17 +988,17 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * reply = bluez_new_failure_msg(msg, result); } - /* send an error or the success reply*/ - if (reply) { - if (!dbus_connection_send (conn, reply, NULL)) { - syslog(LOG_ERR, "%s line:%d Can't send reply message!", - __PRETTY_FUNCTION__, __LINE__) ; - } - dbus_message_unref (reply); - } - ret = DBUS_HANDLER_RESULT_HANDLED; } + + /* send an error or the success reply*/ + if (reply) { + if (!dbus_connection_send (conn, reply, NULL)) { + syslog(LOG_ERR, "Can't send reply message!") ; + } + dbus_message_unref (reply); + } + return ret; } @@ -1246,6 +1252,132 @@ failed: return reply; } +static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) +{ + char name[64]; + const char *pname = name; + DBusMessageIter iter; + DBusMessage *reply = NULL; + struct hci_dbus_data *dbus_data = data; + int dev_id = -1; + int dd = -1; + const char *str_bdaddr; + bdaddr_t bdaddr; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &str_bdaddr); + + str2ba(str_bdaddr, &bdaddr); + + if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { + if ((dev_id = hci_get_route(&bdaddr)) < 0) { + syslog(LOG_ERR, "Bluetooth device is not available"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + } else { + dev_id = dbus_data->id; + } + + if ((dd = hci_open_dev(dev_id)) > 0) { + + if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, READ_REMOTE_NAME_TIMEOUT) ==0) { + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &pname); + syslog(LOG_INFO, "Remote Name: %s", pname); + } else { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + } + } else { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + } + + if (dd > 0) + close (dd); + +failed: + return reply; +} + +static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) +{ + struct hci_conn_list_req *cl = NULL; + struct hci_conn_info *ci = NULL; + DBusMessage *reply = NULL; + DBusMessageIter iter; + DBusMessageIter array_iter; + DBusMessageIter struct_iter; + char addr[18]; + const char array_sig[] = HCI_CONN_INFO_STRUCT_SIGNATURE; + const char *paddr = addr; + struct hci_dbus_data *dbus_data = data; + int i; + int dev_id = -1; + int sk; + + if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { + if ((dev_id = hci_get_route(NULL)) < 0) { + syslog(LOG_ERR, "Bluetooth device is not available"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + } else { + dev_id = dbus_data->id; + } + + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + + if (sk < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (!(cl = malloc(MAX_CONN_NUMBER * sizeof(*ci) + sizeof(*cl)))) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); + goto failed; + } + + cl->dev_id = dev_id; + cl->conn_num = MAX_CONN_NUMBER; + ci = cl->conn_info; + + if (ioctl(sk, HCIGETCONNLIST, (void *) cl)) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); + + for (i = 0; i < cl->conn_num; i++, ci++) { + ba2str(&ci->bdaddr, addr); + + dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT16 ,&(ci->handle)); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING ,&paddr); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BYTE ,&(ci->type)); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_BYTE ,&(ci->out)); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT16 ,&(ci->state)); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32 ,&(ci->link_mode)); + dbus_message_iter_close_container(&array_iter, &struct_iter); + } + + dbus_message_iter_close_container(&iter, &array_iter); +failed: + + if (sk > 0) + close (sk); + + if (cl) + free (cl); + + return reply; +} + + + /***************************************************************** * * Section reserved to Device D-Bus message handlers diff --git a/hcid/dbus.h b/hcid/dbus.h index 585739ce..f47ea5f1 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -122,6 +122,8 @@ #define HCI_CANCEL_PERIODIC_INQ "CancelPeriodic" #define HCI_INQ "Inquiry" #define HCI_ROLE_SWITCH "RoleSwitch" +#define HCI_REMOTE_NAME "RemoteName" +#define HCI_CONNECTIONS "Connections" #define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ @@ -139,6 +141,21 @@ #define HCI_ROLE_SWITCH_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ DBUS_TYPE_BYTE_AS_STRING\ __END_SIG__ + +#define HCI_REMOTE_NAME_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ + __END_SIG__ + +#define HCI_CONNECTIONS_SIGNATURE __END_SIG__ + +#define HCI_CONN_INFO_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING\ + DBUS_TYPE_UINT16_AS_STRING\ + DBUS_TYPE_STRING_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_UINT16_AS_STRING\ + DBUS_TYPE_UINT32_AS_STRING\ + DBUS_STRUCT_END_CHAR_AS_STRING\ + __END_SIG__ #define HCI_DEVICE_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING\ DBUS_TYPE_STRING_AS_STRING\ -- cgit From ca80acc8cde450cb3a89f3aa18a89b7d925f3d77 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Oct 2005 22:47:50 +0000 Subject: Set object path of D-Bus signals according to the local device id --- hcid/dbus.c | 68 ++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 76540a7a..b65a4717 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -338,23 +338,29 @@ failed: void hcid_dbus_inquiry_start(bdaddr_t *local) { - DBusMessage *message; + DBusMessage *message = NULL; + char path[MAX_PATH_LENGTH]; char *local_addr; bdaddr_t tmp; + int id; baswap(&tmp, local); local_addr = batostr(&tmp); - message = dbus_message_new_signal(BLUEZ_HCI_PATH, + id = hci_devid(local_addr); + if (id < 0) { + syslog(LOG_ERR, "No matching device id for %s", local_addr); + goto failed; + } + + snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + + message = dbus_message_new_signal(path, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_INQ_START); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry start message"); goto failed; } - dbus_message_append_args(message, - DBUS_TYPE_STRING, &local_addr, - DBUS_TYPE_INVALID); - if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS inquiry start message"); goto failed; @@ -372,23 +378,29 @@ failed: void hcid_dbus_inquiry_complete(bdaddr_t *local) { - DBusMessage *message; + DBusMessage *message = NULL; + char path[MAX_PATH_LENGTH]; char *local_addr; bdaddr_t tmp; + int id; baswap(&tmp, local); local_addr = batostr(&tmp); - message = dbus_message_new_signal(BLUEZ_HCI_PATH, + id = hci_devid(local_addr); + if (id < 0) { + syslog(LOG_ERR, "No matching device id for %s", local_addr); + goto failed; + } + + snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + + message = dbus_message_new_signal(path, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_INQ_COMPLETE); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); goto failed; } - dbus_message_append_args(message, - DBUS_TYPE_STRING, &local_addr, - DBUS_TYPE_INVALID); - if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS inquiry complete message"); goto failed; @@ -406,16 +418,26 @@ failed: void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) { - DBusMessage *message; + DBusMessage *message = NULL; + char path[MAX_PATH_LENGTH]; char *local_addr, *peer_addr; dbus_uint32_t tmp_class = class; dbus_int32_t tmp_rssi = rssi; bdaddr_t tmp; + int id; baswap(&tmp, local); local_addr = batostr(&tmp); baswap(&tmp, peer); peer_addr = batostr(&tmp); - message = dbus_message_new_signal(BLUEZ_HCI_PATH, + id = hci_devid(local_addr); + if (id < 0) { + syslog(LOG_ERR, "No matching device id for %s", local_addr); + goto failed; + } + + snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + + message = dbus_message_new_signal(path, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_INQ_RESULT); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry result message"); @@ -423,7 +445,6 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i } dbus_message_append_args(message, - DBUS_TYPE_STRING, &local_addr, DBUS_TYPE_STRING, &peer_addr, DBUS_TYPE_UINT32, &tmp_class, DBUS_TYPE_INT32, &tmp_rssi, @@ -447,14 +468,24 @@ failed: void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) { - DBusMessage *message; + DBusMessage *message = NULL; + char path[MAX_PATH_LENGTH]; char *local_addr, *peer_addr; bdaddr_t tmp; + int id; baswap(&tmp, local); local_addr = batostr(&tmp); baswap(&tmp, peer); peer_addr = batostr(&tmp); - message = dbus_message_new_signal(BLUEZ_HCI_PATH, + id = hci_devid(local_addr); + if (id < 0) { + syslog(LOG_ERR, "No matching device id for %s", local_addr); + goto failed; + } + + snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + + message = dbus_message_new_signal(path, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_REMOTE_NAME); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); @@ -462,7 +493,6 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) } dbus_message_append_args(message, - DBUS_TYPE_STRING, &local_addr, DBUS_TYPE_STRING, &peer_addr, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); @@ -1314,7 +1344,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) struct hci_dbus_data *dbus_data = data; int i; int dev_id = -1; - int sk; + int sk = -1; if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { if ((dev_id = hci_get_route(NULL)) < 0) { -- cgit From 3533b6f9df09ff5b9864356f852b8381daf98cbc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 17 Oct 2005 09:29:44 +0000 Subject: Some cleanups --- hcid/dbus.c | 103 ++++++++++++++++++++++++++---------------------------------- 1 file changed, 45 insertions(+), 58 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index b65a4717..579ff6b6 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -120,7 +120,7 @@ static const bluez_error_t error_array[] = { { BLUEZ_EDBUS_RECORD_NOT_FOUND, "No record found" }, { BLUEZ_EDBUS_NO_MEM, "No memory" }, { BLUEZ_EDBUS_CONN_NOT_FOUND, "Connection not found" }, - { BLUEZ_EDBUS_UNKNOWN_PATH, "Device path is not registered" }, + { BLUEZ_EDBUS_UNKNOWN_PATH, "Device path is not registered" }, { 0, NULL } }; @@ -271,7 +271,7 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) } else { dbus_message_iter_get_basic(&iter, &pin); len = strlen(pin); - + memset(&pr, 0, sizeof(pr)); bacpy(&pr.bdaddr, &req->bda); memcpy(pr.pin_code, pin, len); @@ -631,8 +631,6 @@ gboolean hcid_dbus_init(void) return FALSE; } - syslog(LOG_INFO,"Registered %s object", DEVICE_PATH); - data = malloc(sizeof(struct hci_dbus_data)); if (data == NULL) return FALSE; @@ -645,8 +643,6 @@ gboolean hcid_dbus_init(void) return FALSE; } - syslog(LOG_INFO, "Registered %s object", MANAGER_PATH); - if (!dbus_connection_add_filter(connection, hci_signal_filter, NULL, NULL)) { syslog(LOG_ERR, "Can't add new HCI filter"); return FALSE; @@ -673,7 +669,7 @@ void hcid_dbus_exit(void) return; if (dbus_connection_get_object_path_data(connection, - DEVICE_PATH, &data)) { + DEVICE_PATH, &data)) { if (data) { free(data); data = NULL; @@ -682,11 +678,9 @@ void hcid_dbus_exit(void) if (!dbus_connection_unregister_object_path(connection, DEVICE_PATH)) syslog(LOG_ERR, "Can't unregister %s object", DEVICE_PATH); - else - syslog(LOG_INFO, "Unregistered %s object", DEVICE_PATH); if (dbus_connection_get_object_path_data(connection, - MANAGER_PATH, &data)) { + MANAGER_PATH, &data)) { if (data) { free(data); data = NULL; @@ -695,60 +689,56 @@ void hcid_dbus_exit(void) if (!dbus_connection_unregister_object_path(connection, MANAGER_PATH)) syslog(LOG_ERR, "Can't unregister %s object", MANAGER_PATH); - else - syslog(LOG_INFO, "Unregistered %s object", MANAGER_PATH); - - dbus_connection_list_registered(connection, fst_parent, &fst_level); - for (; *fst_level; fst_level++) { - ptr1 = *fst_level; - sprintf(snd_parent, "%s/%s", fst_parent, ptr1); + if (dbus_connection_list_registered(connection, fst_parent, &fst_level)) { - dbus_connection_list_registered(connection, snd_parent, &snd_level); + for (; *fst_level; fst_level++) { + ptr1 = *fst_level; + sprintf(snd_parent, "%s/%s", fst_parent, ptr1); - if (!(*snd_level)) { - sprintf(path, "%s/%s", MANAGER_PATH, ptr1); + if (dbus_connection_list_registered(connection, snd_parent, &snd_level)) { - syslog(LOG_INFO, "Unregistered %s object", path); + if (!(*snd_level)) { + sprintf(path, "%s/%s", MANAGER_PATH, ptr1); - if (dbus_connection_get_object_path_data(connection, + if (dbus_connection_get_object_path_data(connection, path, &data)) { - if (data) { - free(data); - data = NULL; - } - } - - if (!dbus_connection_unregister_object_path(connection, path)) - syslog(LOG_ERR, "Can't unregister %s object", path); + if (data) { + free(data); + data = NULL; + } + } - continue; - } + if (!dbus_connection_unregister_object_path(connection, path)) + syslog(LOG_ERR, "Can't unregister %s object", path); - for (; *snd_level; snd_level++) { - ptr2 = *snd_level; - sprintf(path, "%s/%s/%s", MANAGER_PATH, ptr1, ptr2); + continue; + } - syslog(LOG_INFO, "Unregistered %s object", path); + for (; *snd_level; snd_level++) { + ptr2 = *snd_level; + sprintf(path, "%s/%s/%s", MANAGER_PATH, ptr1, ptr2); - if (dbus_connection_get_object_path_data(connection, + if (dbus_connection_get_object_path_data(connection, path, &data)) { - if (data) { - free(data); - data = NULL; + if (data) { + free(data); + data = NULL; + } + } + + if (!dbus_connection_unregister_object_path(connection, path)) + syslog(LOG_ERR, "Can't unregister %s object", path); } - } - if (!dbus_connection_unregister_object_path(connection, path)) - syslog(LOG_ERR, "Can't unregister %s object", path); + if (*snd_level) + dbus_free_string_array(snd_level); + } } - if (*snd_level) - dbus_free_string_array(snd_level); + if (*fst_level) + dbus_free_string_array(fst_level); } - - if (*fst_level) - dbus_free_string_array(fst_level); } gboolean hcid_dbus_register_device(uint16_t id) @@ -806,9 +796,8 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) /* register the default path*/ if (!dft_reg) { - sprintf(path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); - syslog(LOG_INFO, "registering dft path:%s - id:%d", path, DEFAULT_DEVICE_PATH_ID); + sprintf(path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); data = malloc(sizeof(struct hci_dbus_data)); if (data == NULL) @@ -831,8 +820,6 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) /* register the default path*/ sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); - syslog(LOG_INFO, "registering - path:%s - id:%d",path, id); - if (!dbus_connection_register_object_path(conn, path, &obj_vtable, data)) { syslog(LOG_ERR,"DBUS failed to register %s object", path); /* ignore, the path was already registered */ @@ -859,8 +846,9 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t void *data = NULL; if (unreg_dft) { + sprintf(dft_path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); - syslog(LOG_INFO, "%s - unregistering dft:%s", __PRETTY_FUNCTION__, dft_path); + if (!dbus_connection_unregister_object_path (connection, dft_path)) { syslog(LOG_ERR,"DBUS failed to unregister %s object", dft_path); ret = -1; @@ -875,7 +863,7 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t } sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); - syslog(LOG_INFO, "%s - unregistering spec:%s", __PRETTY_FUNCTION__, path); + if (!dbus_connection_unregister_object_path (connection, path)) { syslog(LOG_ERR,"DBUS failed to unregister %s object", path); ret = -1; @@ -1305,7 +1293,7 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } - } else { + } else { dev_id = dbus_data->id; } @@ -1315,7 +1303,6 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) reply = dbus_message_new_method_return(msg); dbus_message_iter_init_append(reply, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &pname); - syslog(LOG_INFO, "Remote Name: %s", pname); } else { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); } @@ -1352,7 +1339,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } - } else { + } else { dev_id = dbus_data->id; } @@ -1410,7 +1397,7 @@ failed: /***************************************************************** * - * Section reserved to Device D-Bus message handlers + * Section reserved to Manager D-Bus message handlers * *****************************************************************/ -- cgit From d4e297cbb9e30d7f6048becfbfcc0937ffd7b0ef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Oct 2005 17:29:47 +0000 Subject: Implement non-blocking inquiry method --- hcid/dbus.c | 67 ++++++++++++++++++++++++++----------------------------------- hcid/dbus.h | 1 - 2 files changed, 29 insertions(+), 39 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 579ff6b6..1edfc56a 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -1144,20 +1144,12 @@ failed: static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) { - char addr[18]; - const char array_sig[] = HCI_INQ_REPLY_SIGNATURE; DBusMessageIter iter; - DBusMessageIter array_iter; - DBusMessageIter struct_iter; DBusMessage *reply = NULL; - inquiry_info *info = NULL; + inquiry_cp cp; + struct hci_request rq; struct hci_dbus_data *dbus_data = data; - const char *paddr = addr; - int dev_id = -1; - int i; - uint32_t class = 0; - uint16_t clock_offset; - uint16_t flags; + int dev_id = -1, dd = -1; int8_t length; int8_t num_rsp; @@ -1174,45 +1166,44 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) dbus_message_iter_get_basic(&iter, &length); dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &num_rsp); - dbus_message_iter_next(&iter); - dbus_message_iter_get_basic(&iter, &flags); if ((length <= 0) || (num_rsp <= 0)) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); goto failed; } - num_rsp = hci_inquiry(dev_id, length, num_rsp, NULL, &info, flags); - - if (num_rsp < 0) { + dd = hci_open_dev(dev_id); + if (dd < 0) { + syslog(LOG_ERR, "Unable to open device %d: %s", dev_id, strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); - } else { - reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); - - for (i = 0; i < num_rsp; i++) { - ba2str(&(info+i)->bdaddr, addr); - - clock_offset = btohs((info+i)->clock_offset); - /* only 3 bytes are used */ - memcpy(&class, (info+i)->dev_class, 3); - - dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); - dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING , &paddr); - dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32 , &class); - dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT16 , &clock_offset); - dbus_message_iter_close_container(&array_iter, &struct_iter); - } + goto failed; + } - dbus_message_iter_close_container(&iter, &array_iter); + cp.lap[0] = 0x33; + cp.lap[1] = 0x8b; + cp.lap[2] = 0x9e; + cp.length = length; + cp.num_rsp = num_rsp; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_INQUIRY; + rq.cparam = &cp; + rq.clen = INQUIRY_CP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, "Unable to start inquiry: %s", strerror(errno)); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; } + + reply = dbus_message_new_method_return(msg); failed: - if(info) - bt_free(info); + if (dd >= 0) + hci_close_dev(dd); - return NULL; + return reply; } static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) diff --git a/hcid/dbus.h b/hcid/dbus.h index f47ea5f1..c11f1a95 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -135,7 +135,6 @@ #define HCI_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ DBUS_TYPE_BYTE_AS_STRING\ - DBUS_TYPE_UINT16_AS_STRING\ __END_SIG__ #define HCI_ROLE_SWITCH_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ -- cgit From a6d4f9cdc6a4d189120dbffeba96a79f72a77c91 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Oct 2005 17:31:32 +0000 Subject: Add signals for added and removed devices --- hcid/dbus.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hcid/dbus.h | 7 ++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 1edfc56a..d0e61768 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -743,7 +743,11 @@ void hcid_dbus_exit(void) gboolean hcid_dbus_register_device(uint16_t id) { + char dev[BLUETOOTH_DEVICE_NAME_LEN]; struct profile_obj_path_data *ptr = obj_path_table; + DBusMessage *message = NULL; + const char *pdev = dev; + DBusMessageIter iter; int ret = -1; if (!connection) @@ -757,12 +761,43 @@ gboolean hcid_dbus_register_device(uint16_t id) if (!ret) num_adapters++; + + message = dbus_message_new_signal(BLUEZ_HCI_PATH, + BLUEZ_HCI_INTERFACE, BLUEZ_HCI_DEV_ADDED); + + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); + goto failed; + } + + sprintf(dev, "hci%d", id); + + dbus_message_iter_init_append(message, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING ,&pdev); + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS added device message"); + goto failed; + } + + dbus_connection_flush(connection); + +failed: + /* if the signal can't be sent ignore the error */ + + if (message) + dbus_message_unref(message); + return TRUE; } gboolean hcid_dbus_unregister_device(uint16_t id) { + char dev[BLUETOOTH_DEVICE_NAME_LEN]; struct profile_obj_path_data *ptr = obj_path_table; + DBusMessage *message = NULL; + const char *pdev = dev; + DBusMessageIter iter; int dft_unreg = 0; if (!connection) @@ -777,6 +812,33 @@ gboolean hcid_dbus_unregister_device(uint16_t id) ptr->dft_reg = 0; } + + message = dbus_message_new_signal(BLUEZ_HCI_PATH, + BLUEZ_HCI_INTERFACE, BLUEZ_HCI_DEV_REMOVED); + + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS device removed message"); + goto failed; + } + + sprintf(dev, "hci%d", id); + + dbus_message_iter_init_append(message, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING ,&pdev); + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS removed device message"); + goto failed; + } + + dbus_connection_flush(connection); + +failed: + /* if the signal can't be sent ignore the error */ + + if (message) + dbus_message_unref(message); + return TRUE; } diff --git a/hcid/dbus.h b/hcid/dbus.h index c11f1a95..faa19ea4 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -111,12 +111,16 @@ #define BLUEZ_HCI_PATH MANAGER_PATH "/" BLUEZ_HCI #define BLUEZ_HCI_INTERFACE MANAGER_INTERFACE "." BLUEZ_HCI -//HCI signals +//Device based HCI signals #define BLUEZ_HCI_INQ_START "InquiryStart" #define BLUEZ_HCI_INQ_COMPLETE "InquiryComplete" #define BLUEZ_HCI_INQ_RESULT "InquiryResult" #define BLUEZ_HCI_REMOTE_NAME "RemoteName" +//HCI signals sent in the BLUEZ_HCI_PATH +#define BLUEZ_HCI_DEV_ADDED "DeviceAdded" +#define BLUEZ_HCI_DEV_REMOVED "DeviceRemoved" + //HCI Provided services #define HCI_PERIODIC_INQ "PeriodicInquiry" #define HCI_CANCEL_PERIODIC_INQ "CancelPeriodic" @@ -168,6 +172,7 @@ DBUS_STRUCT_END_CHAR_AS_STRING\ __END_SIG__ + /* BLUEZ_DBUS_ERROR * EFailed error messages signature is : su * Where the first argument is a string(error message description), -- cgit From 5b90831adf64b3461986e52afe608b8917f389c9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 19 Oct 2005 10:51:58 +0000 Subject: Add command for device discovery --- tools/avctrl.8 | 1 + tools/avctrl.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/tools/avctrl.8 b/tools/avctrl.8 index f791cf9e..7c3759d6 100644 --- a/tools/avctrl.8 +++ b/tools/avctrl.8 @@ -23,6 +23,7 @@ avctrl \- Bluetooth Audio/Video control utility [ .I options ] + .SH DESCRIPTION .B avctrl is used to control the Audio/Video dongles. diff --git a/tools/avctrl.c b/tools/avctrl.c index 14d42e4a..03b54117 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -66,7 +66,7 @@ struct device_info; struct device_id { uint16_t vendor; uint16_t product; - int (*func)(struct device_info *dev); + int (*func)(struct device_info *dev, int argc, char *argv[]); }; struct device_info { @@ -80,12 +80,23 @@ struct device_info { #define SWITCH_TO_DFU 0x04 #define READ_CODEC 0x05 -static int dongle_csr(struct device_info *devinfo) +static int dongle_csr(struct device_info *devinfo, int argc, char *argv[]) { char buf[8]; struct usb_dev_handle *udev; int err, intf = 2; + memset(buf, 0, sizeof(buf)); + + if (!strncasecmp(argv[0], "discover", 4)) + buf[0] = DISCOVER; + else if (!strncasecmp(argv[0], "switch", 3)) + buf[0] = SWITCH_TO_DFU; + else if (!strncasecmp(argv[0], "dfu", 3)) + buf[0] = SWITCH_TO_DFU; + else + return -EINVAL; + udev = usb_open(devinfo->dev); if (!udev) return -errno; @@ -96,9 +107,6 @@ static int dongle_csr(struct device_info *devinfo) return err; } - memset(buf, 0, sizeof(buf)); - buf[0] = SWITCH_TO_DFU; - err = usb_control_msg(udev, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, HID_REQ_SET_REPORT, 0x03 << 8, intf, buf, sizeof(buf), 10000); @@ -166,13 +174,18 @@ static void usage(void) printf("avctrl - Bluetooth Audio/Video control utility\n\n"); printf("Usage:\n" - "\tavctrl [options]\n" + "\tavctrl [options] \n" "\n"); printf("Options:\n" "\t-h, --help Display help\n" "\t-q, --quiet Don't display any messages\n" "\n"); + + printf("Commands:\n" + "\tdiscover Simulate pressing the discover button\n" + "\tswitch Switch the dongle to DFU mode\n" + "\n"); } static struct option main_options[] = { @@ -203,6 +216,11 @@ int main(int argc, char *argv[]) argv += optind; optind = 0; + if (argc < 1) { + usage(); + exit(1); + } + usb_init(); num = find_devices(dev, sizeof(dev) / sizeof(dev[0])); @@ -214,15 +232,17 @@ int main(int argc, char *argv[]) for (i = 0; i < num; i++) { struct device_id *id = dev[i].id; + int err; if (!quiet) - printf("Switching device %04x:%04x ", + printf("Selecting device %04x:%04x ", id->vendor, id->product); fflush(stdout); - if (id->func(&dev[i]) < 0) { + err = id->func(&dev[i], argc, argv); + if (err < 0) { if (!quiet) - printf("failed (%s)\n", strerror(errno)); + printf("failed (%s)\n", strerror(-err)); } else { if (!quiet) printf("was successful\n"); -- cgit From 857e77d98e66a8835b0040becd5d62790aeaa696 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 19 Oct 2005 10:52:45 +0000 Subject: Update the coding style for some functions --- hcid/dbus.c | 85 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index d0e61768..60958f3b 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -761,7 +761,6 @@ gboolean hcid_dbus_register_device(uint16_t id) if (!ret) num_adapters++; - message = dbus_message_new_signal(BLUEZ_HCI_PATH, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_DEV_ADDED); @@ -812,7 +811,6 @@ gboolean hcid_dbus_unregister_device(uint16_t id) ptr->dft_reg = 0; } - message = dbus_message_new_signal(BLUEZ_HCI_PATH, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_DEV_REMOVED); @@ -1070,15 +1068,15 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * ret = DBUS_HANDLER_RESULT_HANDLED; } - + /* send an error or the success reply*/ if (reply) { - if (!dbus_connection_send (conn, reply, NULL)) { + if (!dbus_connection_send (conn, reply, NULL)) { syslog(LOG_ERR, "Can't send reply message!") ; } dbus_message_unref (reply); } - + return ret; } @@ -1252,13 +1250,13 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) rq.ocf = OCF_INQUIRY; rq.cparam = &cp; rq.clen = INQUIRY_CP_SIZE; - + if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to start inquiry: %s", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } - + reply = dbus_message_new_method_return(msg); failed: @@ -1301,7 +1299,6 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) } sock = hci_open_dev(dev_id); - if (sock < 0) { syslog(LOG_ERR, "HCI device open failed\n"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); @@ -1334,10 +1331,10 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) int dd = -1; const char *str_bdaddr; bdaddr_t bdaddr; - + dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &str_bdaddr); - + str2ba(str_bdaddr, &bdaddr); if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { @@ -1350,8 +1347,8 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) dev_id = dbus_data->id; } - if ((dd = hci_open_dev(dev_id)) > 0) { - + dd = hci_open_dev(dev_id); + if (dd >= 0) { if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, READ_REMOTE_NAME_TIMEOUT) ==0) { reply = dbus_message_new_method_return(msg); dbus_message_iter_init_append(reply, &iter); @@ -1362,9 +1359,9 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) } else { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); } - + if (dd > 0) - close (dd); + close(dd); failed: return reply; @@ -1397,13 +1394,13 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) } sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (sk < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } - if (!(cl = malloc(MAX_CONN_NUMBER * sizeof(*ci) + sizeof(*cl)))) { + cl = malloc(MAX_CONN_NUMBER * sizeof(*ci) + sizeof(*cl)); + if (!cl) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); goto failed; } @@ -1412,7 +1409,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) cl->conn_num = MAX_CONN_NUMBER; ci = cl->conn_info; - if (ioctl(sk, HCIGETCONNLIST, (void *) cl)) { + if (ioctl(sk, HCIGETCONNLIST, (void *) cl) < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1420,7 +1417,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) reply = dbus_message_new_method_return(msg); dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); - + for (i = 0; i < cl->conn_num; i++, ci++) { ba2str(&ci->bdaddr, addr); @@ -1433,21 +1430,19 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32 ,&(ci->link_mode)); dbus_message_iter_close_container(&array_iter, &struct_iter); } - + dbus_message_iter_close_container(&iter, &array_iter); -failed: +failed: if (sk > 0) - close (sk); + close(sk); if (cl) - free (cl); - + free(cl); + return reply; } - - /***************************************************************** * * Section reserved to Manager D-Bus message handlers @@ -1474,14 +1469,14 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) const char array_sig[] = HCI_DEVICE_STRUCT_SIGNATURE; /* Create and bind HCI socket */ - if ((sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) { + sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sock < 0) { syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); - if (!dl) { syslog(LOG_ERR, "Can't allocate memory"); reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); @@ -1503,21 +1498,25 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) dr = dl->dev_req; for (i = 0; i < dl->dev_num; i++, dr++) { - if (hci_test_bit(HCI_UP, &dr->dev_opt)) { - memset(&di, 0 , sizeof(struct hci_dev_info)); - di.dev_id = dr->dev_id; - - if (!ioctl(sock, HCIGETDEVINFO, &di)) { - strcpy(aname, di.name); - ba2str(&di.bdaddr, aaddr); - dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, - &struct_iter); - dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING ,&pname); - dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING ,&paddr); - - dbus_message_iter_close_container(&array_iter, &struct_iter); - } - } + if (!hci_test_bit(HCI_UP, &dr->dev_opt)) + continue; + + memset(&di, 0 , sizeof(struct hci_dev_info)); + di.dev_id = dr->dev_id; + + if (ioctl(sock, HCIGETDEVINFO, &di) < 0) + continue; + + strcpy(aname, di.name); + ba2str(&di.bdaddr, aaddr); + + dbus_message_iter_open_container(&array_iter, + DBUS_TYPE_STRUCT, NULL, &struct_iter); + + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &pname); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &paddr); + + dbus_message_iter_close_container(&array_iter, &struct_iter); } dbus_message_iter_close_container(&iter, &array_iter); @@ -1527,7 +1526,7 @@ failed: free(dl); if (sock > 0) - close (sock); + close(sock); return reply; } -- cgit From 97a6bcbbe32c89438f4f54e47b376c75e2949763 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 21 Oct 2005 11:44:26 +0000 Subject: Allow clear text IAC values --- tools/hciconfig.c | 11 ++++++++--- tools/hcitool.c | 13 +++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 1bf7438b..f85f5272 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -158,7 +159,11 @@ static void cmd_iac(int ctl, int hdev, char *opt) if (opt) { int l = strtoul(opt, 0, 16); uint8_t lap[3]; - if (l < 0x9e8b00 || l > 0x9e8b3f) { + if (!strcasecmp(opt, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(opt, "liac")) { + l = 0x9e8b00; + } else if (l < 0x9e8b00 || l > 0x9e8b3f) { printf("Invalid access code 0x%x\n", l); exit(1); } @@ -182,8 +187,8 @@ static void cmd_iac(int ctl, int hdev, char *opt) for (i = 0; i < n; i++) { printf("0x"); for (j = 3; j--; ) - printf("%02x", lap[j + 3*i]); - if (i < n-1) + printf("%02x", lap[j + 3 * i]); + if (i < n - 1) printf(", "); } printf("\n"); diff --git a/tools/hcitool.c b/tools/hcitool.c index 1804d9fd..75b09b77 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -359,7 +360,11 @@ static void cmd_inq(int dev_id, int argc, char **argv) case 'i': l = strtoul(optarg, 0, 16); - if (l < 0x9e8b00 || l > 0x9e8b3f) { + if (!strcasecmp(optarg, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(optarg, "liac")) { + l = 0x9e8b00; + } if (l < 0x9e8b00 || l > 0x9e8b3f) { printf("Invalid access code 0x%x\n", l); exit(1); } @@ -447,7 +452,11 @@ static void cmd_scan(int dev_id, int argc, char **argv) case 'i': l = strtoul(optarg, 0, 16); - if (l < 0x9e8b00 || l > 0x9e8b3f) { + if (!strcasecmp(optarg, "giac")) { + l = 0x9e8b33; + } else if (!strcasecmp(optarg, "liac")) { + l = 0x9e8b00; + } else if (l < 0x9e8b00 || l > 0x9e8b3f) { printf("Invalid access code 0x%x\n", l); exit(1); } -- cgit From d2506e5078e02804484d5e416e23a49fb646151b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Oct 2005 12:56:13 +0000 Subject: Make the remote name resolve non-blocking --- hcid/dbus.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++-------- hcid/dbus.h | 1 + hcid/hcid.h | 2 ++ hcid/security.c | 18 +++++----- 4 files changed, 104 insertions(+), 25 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 60958f3b..59d45634 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -513,6 +513,53 @@ failed: return; } +void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status) +{ + DBusMessage *message = NULL; + char path[MAX_PATH_LENGTH]; + char *local_addr, *peer_addr; + bdaddr_t tmp; + int id; + + baswap(&tmp, local); local_addr = batostr(&tmp); + baswap(&tmp, peer); peer_addr = batostr(&tmp); + + id = hci_devid(local_addr); + if (id < 0) { + syslog(LOG_ERR, "No matching device id for %s", local_addr); + goto failed; + } + + snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + + message = dbus_message_new_signal(path, + BLUEZ_HCI_INTERFACE, BLUEZ_HCI_REMOTE_NAME_FAILED); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); + goto failed; + } + + dbus_message_append_args(message, + DBUS_TYPE_STRING, &peer_addr, + DBUS_TYPE_BYTE, &status, + DBUS_TYPE_INVALID); + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS remote name message"); + goto failed; + } + + dbus_connection_flush(connection); + +failed: + dbus_message_unref(message); + + bt_free(local_addr); + bt_free(peer_addr); + + return; +} + void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) { } @@ -1207,6 +1254,7 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) DBusMessageIter iter; DBusMessage *reply = NULL; inquiry_cp cp; + evt_cmd_status rp; struct hci_request rq; struct hci_dbus_data *dbus_data = data; int dev_id = -1, dd = -1; @@ -1250,6 +1298,9 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) rq.ocf = OCF_INQUIRY; rq.cparam = &cp; rq.clen = INQUIRY_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CMD_STATUS_SIZE; + rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to start inquiry: %s", strerror(errno)); @@ -1257,6 +1308,12 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) goto failed; } + if (rp.status) { + syslog(LOG_ERR, "Inquiry command failed with status 0x%02X", rp.status); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + EIO); + goto failed; + } + reply = dbus_message_new_method_return(msg); failed: @@ -1322,8 +1379,6 @@ failed: static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) { - char name[64]; - const char *pname = name; DBusMessageIter iter; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; @@ -1331,6 +1386,9 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) int dd = -1; const char *str_bdaddr; bdaddr_t bdaddr; + struct hci_request rq; + remote_name_req_cp cp; + evt_cmd_status rp; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &str_bdaddr); @@ -1343,27 +1401,47 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } - } else { + } else dev_id = dbus_data->id; - } dd = hci_open_dev(dev_id); - if (dd >= 0) { - if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, READ_REMOTE_NAME_TIMEOUT) ==0) { - reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &pname); - } else { - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); - } - } else { + if (dd < 0) { + syslog(LOG_ERR, "Unable to open device %d: %s", dev_id, strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + memset(&cp, 0, sizeof(cp)); + cp.bdaddr = bdaddr; + cp.pscan_rep_mode = 0x01; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_REMOTE_NAME_REQ; + rq.cparam = &cp; + rq.clen = REMOTE_NAME_REQ_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CMD_STATUS_SIZE; + rq.event = EVT_CMD_STATUS; + + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, "Unable to send remote name request: %s", strerror(errno)); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; } - if (dd > 0) - close(dd); + if (rp.status) { + syslog(LOG_ERR, "Remote name command failed with status 0x%02X", rp.status); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + EIO); + goto failed; + } + + reply = dbus_message_new_method_return(msg); failed: + if (dd >= 0) + hci_close_dev(dd); + return reply; } diff --git a/hcid/dbus.h b/hcid/dbus.h index faa19ea4..8ba4af91 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -116,6 +116,7 @@ #define BLUEZ_HCI_INQ_COMPLETE "InquiryComplete" #define BLUEZ_HCI_INQ_RESULT "InquiryResult" #define BLUEZ_HCI_REMOTE_NAME "RemoteName" +#define BLUEZ_HCI_REMOTE_NAME_FAILED "RemoteNameFailed" //HCI signals sent in the BLUEZ_HCI_PATH #define BLUEZ_HCI_DEV_ADDED "DeviceAdded" diff --git a/hcid/hcid.h b/hcid/hcid.h index d407c4c7..048a0aed 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -132,6 +132,7 @@ void hcid_dbus_inquiry_start(bdaddr_t *local); void hcid_dbus_inquiry_complete(bdaddr_t *local); void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi); void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name); +void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status); void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer); void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason); #else @@ -139,6 +140,7 @@ static inline void hcid_dbus_inquiry_start(bdaddr_t *local) {} static inline void hcid_dbus_inquiry_complete(bdaddr_t *local) {} static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) {} static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) {} +static inline void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status) {} static inline void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) {} static inline void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) {} #endif diff --git a/hcid/security.c b/hcid/security.c index eb50ee32..f53d33d1 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -496,20 +496,18 @@ static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr) static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr) { evt_remote_name_req_complete *evt = ptr; - char name[249]; bdaddr_t dba; - if (evt->status) - return; - - memset(name, 0, sizeof(name)); - memcpy(name, evt->name, 248); - bacpy(&dba, &evt->bdaddr); - hcid_dbus_remote_name(sba, &dba, name); - - write_device_name(sba, &dba, name); + if (!evt->status) { + char name[249]; + memset(name, 0, sizeof(name)); + memcpy(name, evt->name, 248); + write_device_name(sba, &dba, name); + hcid_dbus_remote_name(sba, &dba, name); + } else + hcid_dbus_remote_name_failed(sba, &dba, evt->status); } static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr) -- cgit From d1e2c347489fd60b211069497e770b63a1bb0430 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Oct 2005 13:02:40 +0000 Subject: Add support for authentication over D-Bus --- hcid/dbus.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ hcid/dbus.h | 4 +++ 2 files changed, 102 insertions(+), 11 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 59d45634..8cd0a28a 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -225,6 +225,7 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data); static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data); static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data); static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data); +static DBusMessage* handle_auth_req(DBusMessage *msg, void *data); static const struct service_data hci_services[] = { { HCI_PERIODIC_INQ, handle_periodic_inq_req, HCI_PERIODIC_INQ_SIGNATURE }, @@ -233,6 +234,7 @@ static const struct service_data hci_services[] = { { HCI_INQ, handle_inq_req, HCI_INQ_SIGNATURE }, { HCI_REMOTE_NAME, handle_remote_name_req, HCI_REMOTE_NAME_SIGNATURE }, { HCI_CONNECTIONS, handle_display_conn_req, HCI_CONNECTIONS_SIGNATURE }, + { HCI_AUTHENTICATE, handle_auth_req, HCI_AUTHENTICATE_SIGNATURE }, { NULL, NULL, NULL } }; @@ -1150,7 +1152,8 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) } else dev_id = dbus_data->id; - if ((sock = hci_open_dev(dev_id)) < 0) { + sock = hci_open_dev(dev_id); + if (sock < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; @@ -1163,9 +1166,9 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &max_period); - if ((length >= min_period) || (min_period >= max_period)) { - reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); - goto failed; + if (length >= min_period || min_period >= max_period) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); + goto failed; } inq_param.num_rsp = 100; @@ -1182,14 +1185,14 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) inq_mode.mode = 1; //INQUIRY_WITH_RSSI; if (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, - WRITE_INQUIRY_MODE_CP_SIZE, &inq_mode) < 0) { + WRITE_INQUIRY_MODE_CP_SIZE, &inq_mode) < 0) { syslog(LOG_ERR, "Can't set inquiry mode:%s.", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (hci_send_cmd(sock, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, - PERIODIC_INQUIRY_CP_SIZE, &inq_param) < 0) { + PERIODIC_INQUIRY_CP_SIZE, &inq_param) < 0) { syslog(LOG_ERR, "Can't send HCI commands:%s.", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; @@ -1243,7 +1246,7 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) } failed: - if (sock > 0) + if (sock >= 0) close(sock); return reply; @@ -1512,7 +1515,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) dbus_message_iter_close_container(&iter, &array_iter); failed: - if (sk > 0) + if (sk >= 0) close(sk); if (cl) @@ -1521,6 +1524,90 @@ failed: return reply; } +static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) +{ + struct hci_request rq; + auth_requested_cp cp; + evt_cmd_status rp; + DBusMessageIter iter; + DBusMessage *reply = NULL; + char *str_bdaddr = NULL; + struct hci_dbus_data *dbus_data = data; + struct hci_conn_info_req *cr = NULL; + bdaddr_t bdaddr; + int dev_id = -1; + int sock = -1; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &str_bdaddr); + str2ba(str_bdaddr, &bdaddr); + + dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); + + if (dev_id < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); + goto failed; + } + + if (dbus_data->id != DEFAULT_DEVICE_PATH_ID && dbus_data->id != dev_id) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); + goto failed; + } + + sock = hci_open_dev(dev_id); + if (sock < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + + cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); + if (!cr) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); + goto failed; + } + + bacpy(&cr->bdaddr, &bdaddr); + cr->type = ACL_LINK; + + if (ioctl(sock, HCIGETCONNINFO, (unsigned long) cr) < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + memset(&cp, 0, sizeof(cp)); + cp.handle = cr->conn_info->handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_AUTH_REQUESTED; + rq.cparam = &cp; + rq.clen = AUTH_REQUESTED_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CMD_STATUS_SIZE; + rq.event = EVT_CMD_STATUS; + + if (hci_send_req(sock, &rq, 25000) < 0) { + syslog(LOG_ERR, "Unable to send authentication request: %s", strerror(errno)); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (rp.status) { + syslog(LOG_ERR, "Authentication command failed with status 0x%02X", rp.status); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + EIO); + goto failed; + } + +failed: + if (sock >= 0) + close(sock); + + if (cr) + free(cr); + + return reply; +} + /***************************************************************** * * Section reserved to Manager D-Bus message handlers @@ -1600,12 +1687,12 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) dbus_message_iter_close_container(&iter, &array_iter); failed: + if (sock >= 0) + close(sock); + if (dl) free(dl); - if (sock > 0) - close(sock); - return reply; } diff --git a/hcid/dbus.h b/hcid/dbus.h index 8ba4af91..5cbf74ae 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -129,6 +129,7 @@ #define HCI_ROLE_SWITCH "RoleSwitch" #define HCI_REMOTE_NAME "RemoteName" #define HCI_CONNECTIONS "Connections" +#define HCI_AUTHENTICATE "Authenticate" #define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ @@ -173,6 +174,9 @@ DBUS_STRUCT_END_CHAR_AS_STRING\ __END_SIG__ +#define HCI_AUTHENTICATE_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ + __END_SIG__ + /* BLUEZ_DBUS_ERROR * EFailed error messages signature is : su -- cgit From 93bb0c7373ea0cb22d4c655717f72fc4c126b073 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Oct 2005 13:03:41 +0000 Subject: Add support for HCI errors --- hcid/dbus.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- hcid/dbus.h | 21 ------------------- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 8cd0a28a..8205b066 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -113,7 +113,7 @@ typedef struct { const char *str; }bluez_error_t; -static const bluez_error_t error_array[] = { +static const bluez_error_t dbus_error_array[] = { { BLUEZ_EDBUS_UNKNOWN_METHOD, "Method not found" }, { BLUEZ_EDBUS_WRONG_SIGNATURE, "Wrong method signature" }, { BLUEZ_EDBUS_WRONG_PARAM, "Invalid parameters" }, @@ -121,9 +121,64 @@ static const bluez_error_t error_array[] = { { BLUEZ_EDBUS_NO_MEM, "No memory" }, { BLUEZ_EDBUS_CONN_NOT_FOUND, "Connection not found" }, { BLUEZ_EDBUS_UNKNOWN_PATH, "Device path is not registered" }, - { 0, NULL } + { 0, NULL } }; +static const bluez_error_t hci_error_array[] = { + { HCI_UNKNOWN_COMMAND, "Unknown HCI Command" }, + { HCI_NO_CONNECTION, "Unknown Connection Identifier" }, + { HCI_HARDWARE_FAILURE, "Hardware Failure" }, + { HCI_PAGE_TIMEOUT, "Page Timeout" }, + { HCI_AUTHENTICATION_FAILURE, "Authentication Failure" }, + { HCI_PIN_OR_KEY_MISSING, "PIN Missing" }, + { HCI_MEMORY_FULL, "Memory Capacity Exceeded" }, + { HCI_CONNECTION_TIMEOUT, "Connection Timeout" }, + { HCI_MAX_NUMBER_OF_CONNECTIONS, "Connection Limit Exceeded" }, + { HCI_MAX_NUMBER_OF_SCO_CONNECTIONS, "Synchronous Connection Limit To A Device Exceeded" }, + { HCI_ACL_CONNECTION_EXISTS, "ACL Connection Already Exists" }, + { HCI_COMMAND_DISALLOWED, "Command Disallowed" }, + { HCI_REJECTED_LIMITED_RESOURCES, "Connection Rejected due to Limited Resources" }, + { HCI_REJECTED_SECURITY, "Connection Rejected Due To Security Reasons" }, + { HCI_REJECTED_PERSONAL, "Connection Rejected due to Unacceptable BD_ADDR" }, + { HCI_HOST_TIMEOUT, "Connection Accept Timeout Exceeded" }, + { HCI_UNSUPPORTED_FEATURE, "Unsupported Feature or Parameter Value" }, + { HCI_INVALID_PARAMETERS, "Invalid HCI Command Parameters" }, + { HCI_OE_USER_ENDED_CONNECTION, "Remote User Terminated Connection" }, + { HCI_OE_LOW_RESOURCES, "Remote Device Terminated Connection due to Low Resources" }, + { HCI_OE_POWER_OFF, "Remote Device Terminated Connection due to Power Off" }, + { HCI_CONNECTION_TERMINATED, "Connection Terminated By Local Host" }, + { HCI_REPEATED_ATTEMPTS, "Repeated Attempts" }, + { HCI_PAIRING_NOT_ALLOWED, "Pairing Not Allowed" }, + { HCI_UNKNOWN_LMP_PDU, "Unknown LMP PDU" }, + { HCI_UNSUPPORTED_REMOTE_FEATURE, "Unsupported Remote Feature" }, + { HCI_SCO_OFFSET_REJECTED, "SCO Offset Rejected" }, + { HCI_SCO_INTERVAL_REJECTED, "SCO Interval Rejected" }, + { HCI_AIR_MODE_REJECTED, "SCO Air Mode Rejected" }, + { HCI_INVALID_LMP_PARAMETERS, "Invalid LMP Parameters" }, + { HCI_UNSPECIFIED_ERROR, "Unspecified Error" }, + { HCI_UNSUPPORTED_LMP_PARAMETER_VALUE, "Unsupported LMP Parameter Value" }, + { HCI_ROLE_CHANGE_NOT_ALLOWED, "Role Change Not Allowed" }, + { HCI_LMP_RESPONSE_TIMEOUT, "LMP Response Timeout" }, + { HCI_LMP_ERROR_TRANSACTION_COLLISION, "LMP Error Transaction Collision" }, + { HCI_LMP_PDU_NOT_ALLOWED, "LMP PDU Not Allowed" }, + { HCI_ENCRYPTION_MODE_NOT_ACCEPTED, "Encryption Mode Not Acceptable" }, + { HCI_UNIT_LINK_KEY_USED, "Link Key Can Not be Changed" }, + { HCI_QOS_NOT_SUPPORTED, "Requested QoS Not Supported" }, + { HCI_INSTANT_PASSED, "Instant Passed" }, + { HCI_PAIRING_NOT_SUPPORTED, "Pairing With Unit Key Not Supported" }, + { HCI_TRANSACTION_COLLISION, "Different Transaction Collision" }, + { HCI_QOS_UNACCEPTABLE_PARAMETER, "QoS Unacceptable Parameter" }, + { HCI_QOS_REJECTED, "QoS Rejected" }, + { HCI_CLASSIFICATION_NOT_SUPPORTED, "Channel Classification Not Supported" }, + { HCI_INSUFFICIENT_SECURITY, "Insufficient Security" }, + { HCI_PARAMETER_OUT_OF_RANGE, "Parameter Out Of Mandatory Range" }, + { HCI_ROLE_SWITCH_PENDING, "Role Switch Pending" }, + { HCI_SLOT_VIOLATION, "Reserved Slot Violation" }, + { HCI_ROLE_SWITCH_FAILED, "Role Switch Failed" }, + { 0, NULL }, +}; + + static const char *bluez_dbus_error_to_str(const uint32_t ecode) { const bluez_error_t *ptr; @@ -136,7 +191,15 @@ static const char *bluez_dbus_error_to_str(const uint32_t ecode) return strerror(raw_code); } else if (ecode & BLUEZ_EDBUS_OFFSET) { /* D-Bus error */ - for (ptr = error_array; ptr->code; ptr++) { + for (ptr = dbus_error_array; ptr->code; ptr++) { + if (ptr->code == ecode) { + syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str); + return ptr->str; + } + } + } else { + /* BLUEZ_EBT_OFFSET - Bluetooth HCI errors */ + for (ptr = hci_error_array; ptr->code; ptr++) { if (ptr->code == ecode) { syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str); return ptr->str; diff --git a/hcid/dbus.h b/hcid/dbus.h index 5cbf74ae..b12934b3 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -41,27 +41,6 @@ #define ERROR_INTERFACE BASE_INTERFACE ".Error" -#define ERROR_UNKNOWN_HCI_COMMAND 0x01 -#define ERROR_UNKNOWN_CONNECTION_IDENTIFIER 0x02 -#define ERROR_HARDWARE_FAILURE 0x03 -#define ERROR_PAGE_TIMEOUT 0x04 -#define ERROR_AUTHENTICATION_FAILURE 0x05 -#define ERROR_PIN_OR_KEY_MISSING 0x06 -#define ERROR_MEMORY_CAPACITY_EXCEEDED 0x07 -#define ERROR_CONNECTION_TIMEOUT 0x08 -#define ERROR_CONNECTION_LIMIT_EXCEEDED 0x09 -#define ERROR_SYNCHRONOUS_CONNECTION_LIMIT_EXCEEDED 0x0a -#define ERROR_ACL_CONNECTION_ALREADY_EXISTS 0x0b -#define ERROR_COMMAND_DISALLOWED 0x0c -#define ERROR_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES 0x0d -#define ERROR_CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS 0x0e -#define ERROR_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BDADDR 0x0f -#define ERROR_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED 0x10 -#define ERROR_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE 0x11 -#define ERROR_INVALID_HCI_COMMAND_PARAMETERS 0x12 -#define ERROR_REMOTE_USER_TERMINATED_CONNECTION 0x13 -#define ERROR_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO 0x14 - #define DEFAULT_DEVICE_PATH_ID (0xFFFF) #define MANAGER_PATH_ID (0xFFFE) #define DEVICE_PATH_ID (0xFFFD) -- cgit From 6ebb0299dc72b9b6141be5f2712b1319eb0ac1c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Oct 2005 21:25:02 +0000 Subject: Remove unecessary checks for rp.status --- hcid/dbus.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 8205b066..8f0217ec 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -1374,12 +1374,6 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) goto failed; } - if (rp.status) { - syslog(LOG_ERR, "Inquiry command failed with status 0x%02X", rp.status); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + EIO); - goto failed; - } - reply = dbus_message_new_method_return(msg); failed: @@ -1496,12 +1490,6 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) goto failed; } - if (rp.status) { - syslog(LOG_ERR, "Remote name command failed with status 0x%02X", rp.status); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + EIO); - goto failed; - } - reply = dbus_message_new_method_return(msg); failed: @@ -1655,12 +1643,6 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) goto failed; } - if (rp.status) { - syslog(LOG_ERR, "Authentication command failed with status 0x%02X", rp.status); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + EIO); - goto failed; - } - failed: if (sock >= 0) close(sock); -- cgit From 55b5343679121898bbc999c38a670c444f602e17 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Oct 2005 21:27:41 +0000 Subject: Add support for inquiry cancel functionality --- hcid/dbus.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ hcid/dbus.h | 5 ++++- hcid/security.c | 12 ++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 8f0217ec..ce6f4e70 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -285,6 +285,7 @@ static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *m static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data); static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data); static DBusMessage* handle_inq_req(DBusMessage *msg, void *data); +static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data); static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data); static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data); static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data); @@ -295,6 +296,7 @@ static const struct service_data hci_services[] = { { HCI_CANCEL_PERIODIC_INQ, handle_cancel_periodic_inq_req, HCI_CANCEL_PERIODIC_INQ_SIGNATURE }, { HCI_ROLE_SWITCH, handle_role_switch_req, HCI_ROLE_SWITCH_SIGNATURE }, { HCI_INQ, handle_inq_req, HCI_INQ_SIGNATURE }, + { HCI_CANCEL_INQ, handle_cancel_inq_req, HCI_CANCEL_INQ_SIGNATURE }, { HCI_REMOTE_NAME, handle_remote_name_req, HCI_REMOTE_NAME_SIGNATURE }, { HCI_CONNECTIONS, handle_display_conn_req, HCI_CONNECTIONS_SIGNATURE }, { HCI_AUTHENTICATE, handle_auth_req, HCI_AUTHENTICATE_SIGNATURE }, @@ -1383,6 +1385,48 @@ failed: return reply; } +static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data) +{ + DBusMessage *reply = NULL; + struct hci_request rq; + struct hci_dbus_data *dbus_data = data; + int dev_id = -1, dd = -1; + + if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { + if ((dev_id = hci_get_route(NULL)) < 0) { + syslog(LOG_ERR, "Bluetooth device is not available"); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + } else + dev_id = dbus_data->id; + + dd = hci_open_dev(dev_id); + if (dd < 0) { + syslog(LOG_ERR, "Unable to open device %d: %s", dev_id, strerror(errno)); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_INQUIRY_CANCEL; + + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, "Unable to cancel inquiry: %s", strerror(errno)); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + reply = dbus_message_new_method_return(msg); + +failed: + if (dd >= 0) + hci_close_dev(dd); + + return reply; +} + static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) { DBusMessageIter iter; diff --git a/hcid/dbus.h b/hcid/dbus.h index b12934b3..0e18aea3 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -105,10 +105,11 @@ #define HCI_PERIODIC_INQ "PeriodicInquiry" #define HCI_CANCEL_PERIODIC_INQ "CancelPeriodic" #define HCI_INQ "Inquiry" +#define HCI_CANCEL_INQ "CancelInquiry" #define HCI_ROLE_SWITCH "RoleSwitch" #define HCI_REMOTE_NAME "RemoteName" #define HCI_CONNECTIONS "Connections" -#define HCI_AUTHENTICATE "Authenticate" +#define HCI_AUTHENTICATE "Authenticate" #define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ @@ -122,6 +123,8 @@ DBUS_TYPE_BYTE_AS_STRING\ __END_SIG__ +#define HCI_CANCEL_INQ_SIGNATURE __END_SIG__ + #define HCI_ROLE_SWITCH_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ DBUS_TYPE_BYTE_AS_STRING\ __END_SIG__ diff --git a/hcid/security.c b/hcid/security.c index f53d33d1..670f8dde 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -493,6 +493,14 @@ static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr) hcid_dbus_inquiry_start(sba); } +static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr) +{ + evt_cmd_complete *evt = ptr; + + if (evt->opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL)) + hcid_dbus_inquiry_complete(sba); +} + static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr) { evt_remote_name_req_complete *evt = ptr; @@ -679,6 +687,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer cmd_status(dev, &di->bdaddr, ptr); break; + case EVT_CMD_COMPLETE: + cmd_complete(dev, &di->bdaddr, ptr); + break; + case EVT_REMOTE_NAME_REQ_COMPLETE: remote_name_information(dev, &di->bdaddr, ptr); break; -- cgit From a8f6c4d67b3f06165e27570ffeecea464fbe877c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Oct 2005 22:25:31 +0000 Subject: Add support for writing complex PS keys --- tools/csr.c | 59 ++++++++++++++++++++--------------------------------------- tools/csr.h | 1 + 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 250700d9..e600cec7 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -463,7 +463,7 @@ int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid) case CSR_VARID_WARM_HALT: return hci_send_cmd(dd, OGF_VENDOR_CMD, 0x00, sizeof(cmd) + 1, cp); } - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = 0x00; @@ -630,7 +630,7 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto rq.ocf = 0x00; rq.event = EVT_VENDOR; rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; + rq.clen = sizeof(cmd) + length - 1; rq.rparam = rp; rq.rlen = sizeof(rp); @@ -652,11 +652,12 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto return 0; } -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value) +int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length) { - unsigned char cmd[] = { 0x00, 0x00, 0x09, 0x00, + unsigned char cmd[] = { 0x02, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, - pskey & 0xff, pskey >> 8, 0x01, 0x00, + pskey & 0xff, pskey >> 8, + (length / 2) & 0xff, (length / 2) >> 8, store & 0xff, store >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; @@ -666,12 +667,14 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stor cp[0] = 0xc2; memcpy(cp + 1, cmd, sizeof(cmd)); + memcpy(cp + 17, value, length); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_VENDOR_CMD; rq.ocf = 0x00; rq.event = EVT_VENDOR; rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; + rq.clen = sizeof(cmd) + length - 1; rq.rparam = rp; rq.rlen = sizeof(rp); @@ -688,46 +691,24 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stor return -1; } - *value = rp[17] + (rp[18] << 8); - return 0; } -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value) +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value) { - unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, - seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, - pskey & 0xff, pskey >> 8, 0x01, 0x00, - store & 0xff, store >> 8, value & 0xff, value >> 8 }; - - unsigned char cp[254], rp[254]; - struct hci_request rq; + uint8_t array[2] = { 0x00, 0x00 }; + int err; - memset(&cp, 0, sizeof(cp)); - cp[0] = 0xc2; - memcpy(cp + 1, cmd, sizeof(cmd)); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = 0x00; - rq.event = EVT_VENDOR; - rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; - rq.rparam = rp; - rq.rlen = sizeof(rp); + err = csr_read_pskey_complex(dd, seqnum, pskey, store, array, 2); - if (hci_send_req(dd, &rq, 2000) < 0) - return -1; + *value = array[0] + (array[1] << 8); - if (rp[0] != 0xc2) { - errno = EIO; - return -1; - } + return err; +} - if ((rp[9] + (rp[10] << 8)) != 0) { - errno = ENXIO; - return -1; - } +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value) +{ + uint8_t array[2] = { value & 0xff, value >> 8 }; - return 0; + return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 2); } diff --git a/tools/csr.h b/tools/csr.h index 1d9a18c2..7d928d13 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -83,5 +83,6 @@ int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *val int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); +int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); -- cgit From b8857295f260fba3aa0e977cddfeb5e38d79298b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Oct 2005 22:26:59 +0000 Subject: Add support for changing the feature bits --- tools/pskey.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/tools/pskey.c b/tools/pskey.c index f8d93042..45c53b32 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -51,26 +51,50 @@ static int transient = 0; static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { + uint8_t array[64]; uint16_t value; - int err; + int i, err, size = sizeof(array); - if (type != CSR_TYPE_UINT8 && type != CSR_TYPE_UINT16) { + memset(array, 0, sizeof(array)); + + if (type != CSR_TYPE_ARRAY && + type != CSR_TYPE_UINT8 && + type != CSR_TYPE_UINT16) { errno = EFAULT; return -1; } - if (argc != 1) { - errno = E2BIG; - return -1; - } + if (type != CSR_TYPE_ARRAY) { + if (argc != 1) { + errno = E2BIG; + return -1; + } - if (!strncasecmp(argv[0], "0x", 2)) - value = strtol(argv[0] + 2, NULL, 16); - else - value = atoi(argv[0]); + if (!strncasecmp(argv[0], "0x", 2)) + value = strtol(argv[0] + 2, NULL, 16); + else + value = atoi(argv[0]); - err = csr_write_pskey_uint16(dd, 0x4711, pskey, + err = csr_write_pskey_uint16(dd, 0x4711, pskey, transient ? 0x0008 : 0x0000, value); + } else { + if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) + size = 8; + + if (argc != size) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < size; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i] = strtol(argv[i] + 2, NULL, 16); + else + array[i] = atoi(argv[i]); + + err = csr_write_pskey_complex(dd, 0x4711, pskey, + transient ? 0x0008 : 0x0000, array, size); + } return err; } @@ -239,7 +263,7 @@ int main(int argc, char *argv[]) err = write_pskey(dd, storage[i].pskey, storage[i].type, argc - 1, argv + 1); - if (reset) + if (!err && reset) csr_write_varid_valueless(dd, 0x0000, CSR_VARID_WARM_RESET); } else -- cgit From 50f6d576076b6692f8aa391bf56fdb0922ad4072 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 11:03:37 +0000 Subject: Add EVT_CMD_COMPLETE to the filter --- hcid/security.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hcid/security.c b/hcid/security.c index 670f8dde..0bcb8d38 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -775,6 +775,7 @@ void start_security_manager(int hdev) hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_CMD_STATUS, &flt); + hci_filter_set_event(EVT_CMD_COMPLETE, &flt); hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); -- cgit From 807ca2230559ac939c8b481a9fcfe337a6707b3d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 20:26:25 +0000 Subject: Add the local supported commands PSKEY --- tools/csr.c | 2 ++ tools/csr.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/csr.c b/tools/csr.c index e600cec7..5a08d51f 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -414,6 +414,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Maximum encryption key length"; case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: return "Local supported features block"; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return "Local supported commands"; case CSR_PSKEY_HCI_LMP_LOCAL_VERSION: return "The HCI and LMP version reported locally"; case CSR_PSKEY_LMP_REMOTE_VERSION: diff --git a/tools/csr.h b/tools/csr.h index 7d928d13..e6c2acad 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -58,9 +58,10 @@ #define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ -#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xFE8f, 0xF99B, 0x8000 } */ #define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ #define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ +#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 } */ +#define CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS 0x0106 /* uint16[] = { 0xffff, 0x03ff, 0xfffe, 0xffff, 0xffff, 0xffff, 0x0ff3, 0xfff8, 0x003f } */ #define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ #define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ #define CSR_PSKEY_HOSTIO_USE_HCI_EXTN 0x01a5 /* bool (uint16) */ -- cgit From a9e2212be2ea550a0421610c97cdce775e98ac62 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 20:27:03 +0000 Subject: Add support for the local supported commands --- tools/pskey.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/pskey.c b/tools/pskey.c index 45c53b32..b4a6a3f5 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -78,8 +78,14 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) err = csr_write_pskey_uint16(dd, 0x4711, pskey, transient ? 0x0008 : 0x0000, value); } else { - if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) + switch (pskey) { + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: size = 8; + break; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + size = 18; + break; + } if (argc != size) { errno = EINVAL; @@ -121,8 +127,14 @@ static int read_pskey(int dd, uint16_t pskey, int type) printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); } else { - if (pskey == CSR_PSKEY_LOCAL_SUPPORTED_FEATURES) + switch (pskey) { + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: size = 8; + break; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + size = 18; + break; + } err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); if (err < 0) @@ -145,6 +157,7 @@ static struct { { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, + { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, "commands" }, { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, "hciextn" }, -- cgit From 8a908f68a13c67fc1f0314957d91300d027213c6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 22:22:45 +0000 Subject: Add support for the Logitech diNovo Media Desktop Laser --- tools/hid2hci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 9a85c1fd..a5c2722c 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -226,6 +226,7 @@ static struct device_id device_list[] = { { HCI, 0x046d, 0xc703, switch_logitech }, { HCI, 0x046d, 0xc704, switch_logitech }, { HCI, 0x046d, 0xc705, switch_logitech }, + { HCI, 0x046d, 0x0b02, switch_logitech }, /* Logitech diNovo Media Desktop Laser */ { -1 } }; -- cgit From 3705606f41a7b9150a8ac66a9f83c4d534a95507 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 22:26:29 +0000 Subject: Add more BCCMD command ids and PS key values --- tools/csr.c | 6 +++++ tools/csr.h | 76 ++++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 5a08d51f..4ab38232 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -408,6 +408,12 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) char *csr_pskeytostr(uint16_t pskey) { switch (pskey) { + case CSR_PSKEY_BDADDR: + return "Bluetooth address"; + case CSR_PSKEY_COUNTRYCODE: + return "Country code"; + case CSR_PSKEY_CLASSOFDEVICE: + return "Class of device"; case CSR_PSKEY_ENC_KEY_LMIN: return "Minimum encryption key length"; case CSR_PSKEY_ENC_KEY_LMAX: diff --git a/tools/csr.h b/tools/csr.h index e6c2acad..ff2c6541 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -26,38 +26,52 @@ * $Id$ */ -#define CSR_VARID_BC01_STATUS 0x2801 /* uint16 */ -#define CSR_VARID_BUILDID 0x2819 /* uint16 */ -#define CSR_VARID_CHIPVER 0x281a /* uint16 */ -#define CSR_VARID_CHIPREV 0x281b /* uint16 */ -#define CSR_VARID_INTERFACE_VERSION 0x2825 /* uint16 */ -#define CSR_VARID_RAND 0x282a /* uint16 */ -#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c /* uint16 */ -#define CSR_VARID_CHIPANAREV 0x2836 /* uint16 */ -#define CSR_VARID_BUILDID_LOADER 0x2838 /* uint16 */ -#define CSR_VARID_BT_CLOCK 0x2c00 /* uint32 */ -#define CSR_VARID_CRYPT_KEY_LENGTH 0x3008 /* complex */ -#define CSR_VARID_PICONET_INSTANCE 0x3009 /* complex */ -#define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ -#define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ -#define CSR_VARID_COLD_RESET 0x4001 /* valueless */ -#define CSR_VARID_WARM_RESET 0x4002 /* valueless */ -#define CSR_VARID_COLD_HALT 0x4003 /* valueless */ -#define CSR_VARID_WARM_HALT 0x4004 /* valueless */ -#define CSR_VARID_INIT_BT_STACK 0x4005 /* valueless */ -#define CSR_VARID_ACTIVATE_BT_STACK 0x4006 /* valueless */ -#define CSR_VARID_ENABLE_TX 0x4007 /* valueless */ -#define CSR_VARID_DISABLE_TX 0x4008 /* valueless */ -#define CSR_VARID_RECAL 0x4009 /* valueless */ -#define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */ -#define CSR_VARID_MAP_SCO_PCM 0x481c /* uint16 */ -#define CSR_VARID_NO_VARIABLE 0x6000 /* valueless */ -#define CSR_VARID_CONFIG_UART 0x6802 /* uint16 */ -#define CSR_VARID_PANIC_ARG 0x6805 /* uint16 */ -#define CSR_VARID_FAULT_ARG 0x6806 /* uint16 */ -#define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ -#define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ +#define CSR_VARID_PS_CLR_ALL 0x000b /* valueless */ +#define CSR_VARID_PS_FACTORY_SET 0x000c /* valueless */ +#define CSR_VARID_PS_CLR_ALL_STORES 0x082d /* uint16 */ +#define CSR_VARID_BC01_STATUS 0x2801 /* uint16 */ +#define CSR_VARID_BUILDID 0x2819 /* uint16 */ +#define CSR_VARID_CHIPVER 0x281a /* uint16 */ +#define CSR_VARID_CHIPREV 0x281b /* uint16 */ +#define CSR_VARID_INTERFACE_VERSION 0x2825 /* uint16 */ +#define CSR_VARID_RAND 0x282a /* uint16 */ +#define CSR_VARID_MAX_CRYPT_KEY_LENGTH 0x282c /* uint16 */ +#define CSR_VARID_CHIPANAREV 0x2836 /* uint16 */ +#define CSR_VARID_BUILDID_LOADER 0x2838 /* uint16 */ +#define CSR_VARID_BT_CLOCK 0x2c00 /* uint32 */ +#define CSR_VARID_PS_NEXT 0x3005 /* complex */ +#define CSR_VARID_PS_SIZE 0x3006 /* complex */ +#define CSR_VARID_CRYPT_KEY_LENGTH 0x3008 /* complex */ +#define CSR_VARID_PICONET_INSTANCE 0x3009 /* complex */ +#define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ +#define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ +#define CSR_VARID_COLD_RESET 0x4001 /* valueless */ +#define CSR_VARID_WARM_RESET 0x4002 /* valueless */ +#define CSR_VARID_COLD_HALT 0x4003 /* valueless */ +#define CSR_VARID_WARM_HALT 0x4004 /* valueless */ +#define CSR_VARID_INIT_BT_STACK 0x4005 /* valueless */ +#define CSR_VARID_ACTIVATE_BT_STACK 0x4006 /* valueless */ +#define CSR_VARID_ENABLE_TX 0x4007 /* valueless */ +#define CSR_VARID_DISABLE_TX 0x4008 /* valueless */ +#define CSR_VARID_RECAL 0x4009 /* valueless */ +#define CSR_VARID_PS_FACTORY_RESTORE 0x400d /* valueless */ +#define CSR_VARID_PS_FACTORY_RESTORE_ALL 0x400e /* valueless */ +#define CSR_VARID_PS_DEFRAG_RESET 0x400f /* valueless */ +#define CSR_VARID_CANCEL_PAGE 0x4012 /* valueless */ +#define CSR_VARID_PS_CLR 0x4818 /* uint16 */ +#define CSR_VARID_MAP_SCO_PCM 0x481c /* uint16 */ +#define CSR_VARID_PS_CLR_STORES 0x500c /* complex */ +#define CSR_VARID_NO_VARIABLE 0x6000 /* valueless */ +#define CSR_VARID_CONFIG_UART 0x6802 /* uint16 */ +#define CSR_VARID_PANIC_ARG 0x6805 /* uint16 */ +#define CSR_VARID_FAULT_ARG 0x6806 /* uint16 */ +#define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ +#define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ +#define CSR_VARID_PS 0x7002 /* complex */ +#define CSR_PSKEY_BDADDR 0x0001 /* uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ +#define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ +#define CSR_PSKEY_CLASSOFDEVICE 0x0003 /* uint32 */ #define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ #define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ #define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 } */ -- cgit From 51a4c2e364b3096d945ac4a01e844ca5d1513f4a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 22:27:08 +0000 Subject: Add support for listing all available PS keys --- tools/pskey.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/tools/pskey.c b/tools/pskey.c index b4a6a3f5..24c0c4f2 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -179,7 +179,8 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [-r] [-t] [value]\n\n"); + "\tpskey [-i ] [-r] [-t] [value]\n" + "\tpskey [-i ] --list\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -197,6 +198,7 @@ static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, { "transient", 0, 0, 't' }, + { "list", 0, 0, 'l' }, { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -205,9 +207,9 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0, reset = 0; + int i, err, dd, opt, dev = 0, list = 0, reset = 0; - while ((opt=getopt_long(argc, argv, "+i:rth", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rtlh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -225,6 +227,10 @@ int main(int argc, char *argv[]) transient = 1; break; + case 'l': + list = 1; + break; + case 'h': default: usage(); @@ -236,7 +242,7 @@ int main(int argc, char *argv[]) argv += optind; optind = 0; - if (argc < 1) { + if (!list && argc < 1) { usage(); exit(1); } @@ -268,6 +274,44 @@ int main(int argc, char *argv[]) exit(1); } + if (list) { + uint8_t array[8]; + uint16_t length, seqnum = 0x0000, pskey = 0x0000; + int err; + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, sizeof(array)); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, sizeof(array)); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + + printf("0x%04x - %s (%d bytes)\n", pskey, + csr_pskeytostr(pskey), length * 2); + } + + hci_close_dev(dd); + exit(0); + } + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; -- cgit From 967b0ec7667fb6d3db632ce8ccc66668c060a1f0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 23:10:08 +0000 Subject: Add support for UINT32 PS keys --- tools/csr.c | 21 +++++++++++++++++++++ tools/csr.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 4ab38232..936a20f9 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -720,3 +720,24 @@ int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 2); } + +int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value) +{ + uint8_t array[4] = { 0x00, 0x00, 0x00, 0x00 }; + int err; + + err = csr_read_pskey_complex(dd, seqnum, pskey, store, array, 4); + + *value = ((array[0] + (array[1] << 8)) << 16) + + (array[2] + (array[3] << 8)); + + return err; +} + +int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value) +{ + uint8_t array[4] = { (value & 0xff0000) >> 16, value >> 24, + value & 0xff, (value & 0xff00) >> 8 }; + + return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 4); +} diff --git a/tools/csr.h b/tools/csr.h index ff2c6541..74c97c92 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -101,3 +101,5 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value); int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); +int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value); +int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value); -- cgit From d17f131aa94e5aa9e3bcfe391f033ada1bc855da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 23:10:53 +0000 Subject: Add PS keys for BD_ADDR, country code and class of device --- tools/pskey.c | 127 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 46 deletions(-) diff --git a/tools/pskey.c b/tools/pskey.c index 24c0c4f2..bf044dd3 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -46,25 +46,54 @@ #define CSR_TYPE_ARRAY 1 #define CSR_TYPE_UINT8 2 #define CSR_TYPE_UINT16 3 +#define CSR_TYPE_UINT32 4 static int transient = 0; +static int pskey_size(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_BDADDR: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return 18; + default: + return 64; + } +} + static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) { uint8_t array[64]; uint16_t value; + uint32_t val32; int i, err, size = sizeof(array); memset(array, 0, sizeof(array)); - if (type != CSR_TYPE_ARRAY && - type != CSR_TYPE_UINT8 && - type != CSR_TYPE_UINT16) { - errno = EFAULT; - return -1; - } + switch (type) { + case CSR_TYPE_ARRAY: + size = pskey_size(pskey); + + if (argc != size) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < size; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i] = strtol(argv[i] + 2, NULL, 16); + else + array[i] = atoi(argv[i]); + + err = csr_write_pskey_complex(dd, 0x4711, pskey, + transient ? 0x0008 : 0x0000, array, size); + break; - if (type != CSR_TYPE_ARRAY) { + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: if (argc != 1) { errno = E2BIG; return -1; @@ -77,29 +106,27 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) err = csr_write_pskey_uint16(dd, 0x4711, pskey, transient ? 0x0008 : 0x0000, value); - } else { - switch (pskey) { - case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: - size = 8; - break; - case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: - size = 18; - break; - } + break; - if (argc != size) { - errno = EINVAL; + case CSR_TYPE_UINT32: + if (argc != 1) { + errno = E2BIG; return -1; } - for (i = 0; i < size; i++) - if (!strncasecmp(argv[0], "0x", 2)) - array[i] = strtol(argv[i] + 2, NULL, 16); - else - array[i] = atoi(argv[i]); + if (!strncasecmp(argv[0], "0x", 2)) + val32 = strtol(argv[0] + 2, NULL, 16); + else + val32 = atoi(argv[0]); - err = csr_write_pskey_complex(dd, 0x4711, pskey, - transient ? 0x0008 : 0x0000, array, size); + err = csr_write_pskey_uint32(dd, 0x4711, pskey, + transient ? 0x0008 : 0x0000, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; } return err; @@ -109,41 +136,46 @@ static int read_pskey(int dd, uint16_t pskey, int type) { uint8_t array[64]; uint16_t value = 0; + uint32_t val32 = 0; int i, err, size = sizeof(array); memset(array, 0, sizeof(array)); - if (type != CSR_TYPE_ARRAY && - type != CSR_TYPE_UINT8 && - type != CSR_TYPE_UINT16) { - errno = EFAULT; - return -1; - } + switch (type) { + case CSR_TYPE_ARRAY: + size = pskey_size(pskey); - if (type != CSR_TYPE_ARRAY) { + err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); + if (err < 0) + return err; + + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < size; i++) + printf(" 0x%02x", array[i]); + printf("\n"); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: err = csr_read_pskey_uint16(dd, 0x4711, pskey, 0x0000, &value); if (err < 0) return err; printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); - } else { - switch (pskey) { - case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: - size = 8; - break; - case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: - size = 18; - break; - } + break; - err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); + case CSR_TYPE_UINT32: + err = csr_read_pskey_uint32(dd, 0x4711, pskey, 0x0000, &val32); if (err < 0) return err; - printf("%s:", csr_pskeytostr(pskey)); - for (i = 0; i < size; i++) - printf(" 0x%02x", array[i]); - printf("\n"); + printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; } return err; @@ -154,6 +186,9 @@ static struct { int type; char *str; } storage[] = { + { CSR_PSKEY_BDADDR, CSR_TYPE_ARRAY, "bdaddr" }, + { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, "country" }, + { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, "devclass" }, { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, -- cgit From 70d9cbea647199f8f76d0f6b467799c5bb7b95fb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 24 Oct 2005 23:19:09 +0000 Subject: Add more PS key definitions --- tools/csr.c | 10 ++++++++++ tools/csr.h | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 936a20f9..43ae25b0 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -414,6 +414,16 @@ char *csr_pskeytostr(uint16_t pskey) return "Country code"; case CSR_PSKEY_CLASSOFDEVICE: return "Class of device"; + case CSR_PSKEY_DEVICE_DRIFT: + return "Device drift"; + case CSR_PSKEY_DEVICE_JITTER: + return "Device jitter"; + case CSR_PSKEY_MAX_ACLS: + return "Maximum ACL links"; + case CSR_PSKEY_MAX_SCOS: + return "Maximum SCO links"; + case CSR_PSKEY_MAX_REMOTE_MASTERS: + return "Maximum remote masters"; case CSR_PSKEY_ENC_KEY_LMIN: return "Minimum encryption key length"; case CSR_PSKEY_ENC_KEY_LMAX: diff --git a/tools/csr.h b/tools/csr.h index 74c97c92..0f9859fa 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -72,6 +72,11 @@ #define CSR_PSKEY_BDADDR 0x0001 /* uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ #define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ #define CSR_PSKEY_CLASSOFDEVICE 0x0003 /* uint32 */ +#define CSR_PSKEY_DEVICE_DRIFT 0x0004 /* uint16 */ +#define CSR_PSKEY_DEVICE_JITTER 0x0005 /* uint16 */ +#define CSR_PSKEY_MAX_ACLS 0x000d /* uint16 */ +#define CSR_PSKEY_MAX_SCOS 0x000e /* uint16 */ +#define CSR_PSKEY_MAX_REMOTE_MASTERS 0x000f /* uint16 */ #define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ #define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ #define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 } */ -- cgit From fdb212e90ef47972b4d2d1745d6da7e927ab19ff Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 00:55:12 +0000 Subject: Update the list of PS keys --- tools/csr.c | 802 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 449 ++++++++++++++++++++++++++++++++-- 2 files changed, 1227 insertions(+), 24 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 43ae25b0..556f13cb 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -424,38 +424,840 @@ char *csr_pskeytostr(uint16_t pskey) return "Maximum SCO links"; case CSR_PSKEY_MAX_REMOTE_MASTERS: return "Maximum remote masters"; + case CSR_PSKEY_ENABLE_MASTERY_WITH_SLAVERY: + return "Support master and slave roles simultaneously"; + case CSR_PSKEY_H_HC_FC_MAX_ACL_PKT_LEN: + return "Maximum HCI ACL packet length"; + case CSR_PSKEY_H_HC_FC_MAX_SCO_PKT_LEN: + return "Maximum HCI SCO packet length"; + case CSR_PSKEY_H_HC_FC_MAX_ACL_PKTS: + return "Maximum number of HCI ACL packets"; + case CSR_PSKEY_H_HC_FC_MAX_SCO_PKTS: + return "Maximum number of HCI SCO packets"; + case CSR_PSKEY_LC_FC_BUFFER_LOW_WATER_MARK: + return "Flow control low water mark"; + case CSR_PSKEY_LC_MAX_TX_POWER: + return "Maximum transmit power"; + case CSR_PSKEY_TX_GAIN_RAMP: + return "Transmit gain ramp rate"; + case CSR_PSKEY_LC_PEER_POWER_PERIOD: + return "Peer transmit power control interval"; + case CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK: + return "Flow control pool low water mark"; + case CSR_PSKEY_LC_DEFAULT_TX_POWER: + return "Default transmit power"; + case CSR_PSKEY_LC_RSSI_GOLDEN_RANGE: + return "RSSI at bottom of golden receive range"; + case CSR_PSKEY_LC_COMBO_DISABLE_PIO_MASK: + return "Combo: PIO lines and logic to disable transmit"; + case CSR_PSKEY_LC_COMBO_PRIORITY_PIO_MASK: + return "Combo: priority activity PIO lines and logic"; + case CSR_PSKEY_LC_COMBO_DOT11_CHANNEL_PIO_BASE: + return "Combo: 802.11b channel number base PIO line"; + case CSR_PSKEY_LC_COMBO_DOT11_BLOCK_CHANNELS: + return "Combo: channels to block either side of 802.11b"; + case CSR_PSKEY_LC_MAX_TX_POWER_NO_RSSI: + return "Maximum transmit power when peer has no RSSI"; + case CSR_PSKEY_LC_CONNECTION_RX_WINDOW: + return "Receive window size during connections"; + case CSR_PSKEY_LC_COMBO_DOT11_TX_PROTECTION_MODE: + return "Combo: which TX packets shall we protect"; + case CSR_PSKEY_LC_ENHANCED_POWER_TABLE: + return "Radio power table"; + case CSR_PSKEY_LC_WIDEBAND_RSSI_CONFIG: + return "RSSI configuration for use with wideband RSSI"; + case CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_LEAD: + return "Combo: How much notice will we give the Combo Card"; + case CSR_PSKEY_BT_CLOCK_INIT: + return "Initial value of Bluetooth clock"; + case CSR_PSKEY_TX_MR_MOD_DELAY: + return "TX Mod delay"; + case CSR_PSKEY_RX_MR_SYNC_TIMING: + return "RX MR Sync Timing"; + case CSR_PSKEY_RX_MR_SYNC_CONFIG: + return "RX MR Sync Configuration"; + case CSR_PSKEY_LC_LOST_SYNC_SLOTS: + return "Time in ms for lost sync in low power modes"; + case CSR_PSKEY_RX_MR_SAMP_CONFIG: + return "RX MR Sync Configuration"; + case CSR_PSKEY_AGC_HYST_LEVELS: + return "AGC hysteresis levels"; + case CSR_PSKEY_RX_LEVEL_LOW_SIGNAL: + return "ANA_RX_LVL at low signal strengths"; + case CSR_PSKEY_AGC_IQ_LVL_VALUES: + return "ANA_IQ_LVL values for AGC algorithmn"; + case CSR_PSKEY_MR_FTRIM_OFFSET_12DB: + return "ANA_RX_FTRIM offset when using 12 dB IF atten "; + case CSR_PSKEY_MR_FTRIM_OFFSET_6DB: + return "ANA_RX_FTRIM offset when using 6 dB IF atten "; + case CSR_PSKEY_NO_CAL_ON_BOOT: + return "Do not calibrate radio on boot"; + case CSR_PSKEY_RSSI_HI_TARGET: + return "RSSI high target"; + case CSR_PSKEY_PREFERRED_MIN_ATTENUATION: + return "Preferred minimum attenuator setting"; + case CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_OVERRIDE: + return "Combo: Treat all packets as high priority"; + case CSR_PSKEY_LC_MULTISLOT_HOLDOFF: + return "Time till single slot packets are used for resync"; + case CSR_PSKEY_FREE_KEY_PIGEON_HOLE: + return "Link key store bitfield"; + case CSR_PSKEY_LINK_KEY_BD_ADDR0: + return "Bluetooth address + link key 0"; + case CSR_PSKEY_LINK_KEY_BD_ADDR1: + return "Bluetooth address + link key 1"; + case CSR_PSKEY_LINK_KEY_BD_ADDR2: + return "Bluetooth address + link key 2"; + case CSR_PSKEY_LINK_KEY_BD_ADDR3: + return "Bluetooth address + link key 3"; + case CSR_PSKEY_LINK_KEY_BD_ADDR4: + return "Bluetooth address + link key 4"; + case CSR_PSKEY_LINK_KEY_BD_ADDR5: + return "Bluetooth address + link key 5"; + case CSR_PSKEY_LINK_KEY_BD_ADDR6: + return "Bluetooth address + link key 6"; + case CSR_PSKEY_LINK_KEY_BD_ADDR7: + return "Bluetooth address + link key 7"; + case CSR_PSKEY_LINK_KEY_BD_ADDR8: + return "Bluetooth address + link key 8"; + case CSR_PSKEY_LINK_KEY_BD_ADDR9: + return "Bluetooth address + link key 9"; + case CSR_PSKEY_LINK_KEY_BD_ADDR10: + return "Bluetooth address + link key 10"; + case CSR_PSKEY_LINK_KEY_BD_ADDR11: + return "Bluetooth address + link key 11"; + case CSR_PSKEY_LINK_KEY_BD_ADDR12: + return "Bluetooth address + link key 12"; + case CSR_PSKEY_LINK_KEY_BD_ADDR13: + return "Bluetooth address + link key 13"; + case CSR_PSKEY_LINK_KEY_BD_ADDR14: + return "Bluetooth address + link key 14"; + case CSR_PSKEY_LINK_KEY_BD_ADDR15: + return "Bluetooth address + link key 15"; case CSR_PSKEY_ENC_KEY_LMIN: return "Minimum encryption key length"; case CSR_PSKEY_ENC_KEY_LMAX: return "Maximum encryption key length"; case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: return "Local supported features block"; + case CSR_PSKEY_LM_USE_UNIT_KEY: + return "Allow use of unit key for authentication?"; + case CSR_PSKEY_HCI_NOP_DISABLE: + return "Disable the HCI Command_Status event on boot"; + case CSR_PSKEY_LM_MAX_EVENT_FILTERS: + return "Maximum number of event filters"; + case CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE: + return "LM sends two LMP_accepted messages in test mode"; + case CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME: + return "Maximum time we hold a device around page"; + case CSR_PSKEY_AFH_ADAPTATION_RESPONSE_TIME: + return "LM period for AFH adaption"; + case CSR_PSKEY_AFH_OPTIONS: + return "Options to configure AFH"; + case CSR_PSKEY_AFH_RSSI_RUN_PERIOD: + return "AFH RSSI reading period"; + case CSR_PSKEY_AFH_REENABLE_CHANNEL_TIME: + return "AFH good channel adding time"; + case CSR_PSKEY_NO_DROP_ON_ACR_MS_FAIL: + return "Complete link if acr barge-in role switch refused"; + case CSR_PSKEY_MAX_PRIVATE_KEYS: + return "Max private link keys stored"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR0: + return "Bluetooth address + link key 0"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR1: + return "Bluetooth address + link key 1"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR2: + return "Bluetooth address + link key 2"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR3: + return "Bluetooth address + link key 3"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR4: + return "Bluetooth address + link key 4"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR5: + return "Bluetooth address + link key 5"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR6: + return "Bluetooth address + link key 6"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR7: + return "Bluetooth address + link key 7"; case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: return "Local supported commands"; + case CSR_PSKEY_LM_MAX_ABSENCE_INDEX: + return "Maximum absence index allowed"; + case CSR_PSKEY_DEVICE_NAME: + return "Local device's \"user friendly\" name"; + case CSR_PSKEY_AFH_RSSI_THRESHOLD: + return "AFH RSSI threshold"; + case CSR_PSKEY_LM_CASUAL_SCAN_INTERVAL: + return "Scan interval in slots for casual scanning"; + case CSR_PSKEY_AFH_MIN_MAP_CHANGE: + return "The minimum amount to change an AFH map by"; + case CSR_PSKEY_AFH_RSSI_LP_RUN_PERIOD: + return "AFH RSSI reading period when in low power mode"; case CSR_PSKEY_HCI_LMP_LOCAL_VERSION: return "The HCI and LMP version reported locally"; case CSR_PSKEY_LMP_REMOTE_VERSION: return "The LMP version reported remotely"; + case CSR_PSKEY_HOLD_ERROR_MESSAGE_NUMBER: + return "Maximum number of queued HCI Hardware Error Events"; + case CSR_PSKEY_DFU_ATTRIBUTES: + return "DFU attributes"; + case CSR_PSKEY_DFU_DETACH_TO: + return "DFU detach timeout"; + case CSR_PSKEY_DFU_TRANSFER_SIZE: + return "DFU transfer size"; + case CSR_PSKEY_DFU_ENABLE: + return "DFU enable"; + case CSR_PSKEY_DFU_LIN_REG_ENABLE: + return "Linear Regulator enabled at boot in DFU mode"; + case CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_MSB: + return "DFU encryption VM application public key MSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_LSB: + return "DFU encryption VM application public key LSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_M_DASH: + return "DFU encryption VM application M dash"; + case CSR_PSKEY_DFUENC_VMAPP_PK_R2N_MSB: + return "DFU encryption VM application public key R2N MSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_R2N_LSB: + return "DFU encryption VM application public key R2N LSB"; + case CSR_PSKEY_BCSP_LM_PS_BLOCK: + return "BCSP link establishment block"; + case CSR_PSKEY_HOSTIO_FC_PS_BLOCK: + return "HCI flow control block"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO0: + return "Host transport channel 0 settings (BCSP ACK"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO1: + return "Host transport channel 1 settings (BCSP-LE"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO2: + return "Host transport channel 2 settings (BCCMD"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO3: + return "Host transport channel 3 settings (HQ"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO4: + return "Host transport channel 4 settings (DM"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO5: + return "Host transport channel 5 settings (HCI CMD/EVT"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO6: + return "Host transport channel 6 settings (HCI ACL"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO7: + return "Host transport channel 7 settings (HCI SCO"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO8: + return "Host transport channel 8 settings (L2CAP"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO9: + return "Host transport channel 9 settings (RFCOMM"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO10: + return "Host transport channel 10 settings (SDP"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO11: + return "Host transport channel 11 settings (TEST"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO12: + return "Host transport channel 12 settings (DFU"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO13: + return "Host transport channel 13 settings (VM"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO14: + return "Host transport channel 14 settings"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO15: + return "Host transport channel 15 settings"; + case CSR_PSKEY_HOSTIO_UART_RESET_TIMEOUT: + return "UART reset counter timeout"; case CSR_PSKEY_HOSTIO_USE_HCI_EXTN: return "Use hci_extn to route non-hci channels"; + case CSR_PSKEY_HOSTIO_USE_HCI_EXTN_CCFC: + return "Use command-complete flow control for hci_extn"; + case CSR_PSKEY_HOSTIO_HCI_EXTN_PAYLOAD_SIZE: + return "Maximum hci_extn payload size"; + case CSR_PSKEY_BCSP_LM_CNF_CNT_LIMIT: + return "BCSP link establishment conf message count"; case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: return "Map SCO over PCM"; + case CSR_PSKEY_HOSTIO_AWKWARD_PCM_SYNC: + return "PCM interface synchronisation is difficult"; + case CSR_PSKEY_HOSTIO_BREAK_POLL_PERIOD: + return "Break poll period (microseconds"; + case CSR_PSKEY_HOSTIO_MIN_UART_HCI_SCO_SIZE: + return "Minimum SCO packet size sent to host over UART HCI"; + case CSR_PSKEY_HOSTIO_MAP_SCO_CODEC: + return "Map SCO over the built-in codec"; + case CSR_PSKEY_PCM_CVSD_TX_HI_FREQ_BOOST: + return "High frequency boost for PCM when transmitting CVSD"; + case CSR_PSKEY_PCM_CVSD_RX_HI_FREQ_BOOST: + return "High frequency boost for PCM when receiving CVSD"; + case CSR_PSKEY_PCM_CONFIG32: + return "PCM interface settings bitfields"; + case CSR_PSKEY_USE_OLD_BCSP_LE: + return "Use the old version of BCSP link establishment"; + case CSR_PSKEY_PCM_CVSD_USE_NEW_FILTER: + return "CVSD uses the new filter if available"; + case CSR_PSKEY_PCM_FORMAT: + return "PCM data format"; + case CSR_PSKEY_CODEC_OUT_GAIN: + return "Audio output gain when using built-in codec"; + case CSR_PSKEY_CODEC_IN_GAIN: + return "Audio input gain when using built-in codec"; + case CSR_PSKEY_CODEC_PIO: + return "PIO to enable when built-in codec is enabled"; + case CSR_PSKEY_PCM_LOW_JITTER_CONFIG: + return "PCM interface settings for low jitter master mode"; + case CSR_PSKEY_HOSTIO_SCO_PCM_THRESHOLDS: + return "Thresholds for SCO PCM buffers"; + case CSR_PSKEY_HOSTIO_SCO_HCI_THRESHOLDS: + return "Thresholds for SCO HCI buffers"; + case CSR_PSKEY_HOSTIO_MAP_SCO_PCM_SLOT: + return "Route SCO data to specified slot in pcm frame"; case CSR_PSKEY_UART_BAUDRATE: return "UART Baud rate"; + case CSR_PSKEY_UART_CONFIG_BCSP: + return "UART configuration when using BCSP"; + case CSR_PSKEY_UART_CONFIG_H4: + return "UART configuration when using H4"; + case CSR_PSKEY_UART_CONFIG_H5: + return "UART configuration when using H5"; + case CSR_PSKEY_UART_CONFIG_USR: + return "UART configuration when under VM control"; + case CSR_PSKEY_UART_TX_CRCS: + return "Use CRCs for BCSP or H5"; + case CSR_PSKEY_UART_ACK_TIMEOUT: + return "Acknowledgement timeout for BCSP and H5"; + case CSR_PSKEY_UART_TX_MAX_ATTEMPTS: + return "Max times to send reliable BCSP or H5 message"; + case CSR_PSKEY_UART_TX_WINDOW_SIZE: + return "Transmit window size for BCSP and H5"; + case CSR_PSKEY_UART_HOST_WAKE: + return "UART host wakeup"; + case CSR_PSKEY_HOSTIO_THROTTLE_TIMEOUT: + return "Host interface performance control."; + case CSR_PSKEY_PCM_ALWAYS_ENABLE: + return "PCM port is always enable when chip is running"; + case CSR_PSKEY_UART_HOST_WAKE_SIGNAL: + return "Signal to use for uart host wakeup protocol"; + case CSR_PSKEY_UART_CONFIG_H4DS: + return "UART configuration when using H4DS"; + case CSR_PSKEY_H4DS_WAKE_DURATION: + return "How long to spend waking the host when using H4DS"; + case CSR_PSKEY_H4DS_MAXWU: + return "Maximum number of H4DS Wake-Up messages to send"; + case CSR_PSKEY_H4DS_LE_TIMER_PERIOD: + return "H4DS Link Establishment Tsync and Tconf period"; + case CSR_PSKEY_H4DS_TWU_TIMER_PERIOD: + return "H4DS Twu timer period"; + case CSR_PSKEY_H4DS_UART_IDLE_TIMER_PERIOD: + return "H4DS Tuart_idle timer period"; case CSR_PSKEY_ANA_FTRIM: return "Crystal frequency trim"; + case CSR_PSKEY_WD_TIMEOUT: + return "Watchdog timeout (microseconds"; + case CSR_PSKEY_WD_PERIOD: + return "Watchdog period (microseconds"; case CSR_PSKEY_HOST_INTERFACE: return "Host interface"; + case CSR_PSKEY_HQ_HOST_TIMEOUT: + return "HQ host command timeout"; + case CSR_PSKEY_HQ_ACTIVE: + return "Enable host query task?"; + case CSR_PSKEY_BCCMD_SECURITY_ACTIVE: + return "Enable configuration security"; case CSR_PSKEY_ANA_FREQ: return "Crystal frequency"; + case CSR_PSKEY_PIO_PROTECT_MASK: + return "Access to PIO pins"; + case CSR_PSKEY_PMALLOC_SIZES: + return "pmalloc sizes array"; + case CSR_PSKEY_UART_BAUD_RATE: + return "UART Baud rate (pre 18"; + case CSR_PSKEY_UART_CONFIG: + return "UART configuration bitfield"; + case CSR_PSKEY_STUB: + return "Stub"; + case CSR_PSKEY_TXRX_PIO_CONTROL: + return "TX and RX PIO control"; + case CSR_PSKEY_ANA_RX_LEVEL: + return "ANA_RX_LVL register initial value"; + case CSR_PSKEY_ANA_RX_FTRIM: + return "ANA_RX_FTRIM register initial value"; + case CSR_PSKEY_PSBC_DATA_VERSION: + return "Persistent store version"; + case CSR_PSKEY_PCM0_ATTENUATION: + return "Volume control on PCM channel 0"; + case CSR_PSKEY_LO_LVL_MAX: + return "Maximum value of LO level control register"; + case CSR_PSKEY_LO_ADC_AMPL_MIN: + return "Minimum value of the LO amplitude measured on the ADC"; + case CSR_PSKEY_LO_ADC_AMPL_MAX: + return "Maximum value of the LO amplitude measured on the ADC"; + case CSR_PSKEY_IQ_TRIM_CHANNEL: + return "IQ calibration channel"; + case CSR_PSKEY_IQ_TRIM_GAIN: + return "IQ calibration gain"; + case CSR_PSKEY_TX_OFFSET_HALF_MHZ: + return "Transmit offset"; + case CSR_PSKEY_GBL_MISC_ENABLES: + return "Global miscellaneous hardware enables"; + case CSR_PSKEY_UART_SLEEP_TIMEOUT: + return "Time in ms to deep sleep if nothing received"; + case CSR_PSKEY_DEEP_SLEEP_STATE: + return "Deep sleep state usage"; + case CSR_PSKEY_IQ_ENABLE_PHASE_TRIM: + return "IQ phase enable"; + case CSR_PSKEY_HCI_HANDLE_FREEZE_PERIOD: + return "Time for which HCI handle is frozen after link removal"; + case CSR_PSKEY_MAX_FROZEN_HCI_HANDLES: + return "Maximum number of frozen HCI handles"; + case CSR_PSKEY_PAGETABLE_DESTRUCTION_DELAY: + return "Delay from freezing buf handle to deleting page table"; + case CSR_PSKEY_IQ_TRIM_PIO_SETTINGS: + return "IQ PIO settings"; + case CSR_PSKEY_USE_EXTERNAL_CLOCK: + return "Device uses an external clock"; + case CSR_PSKEY_DEEP_SLEEP_WAKE_CTS: + return "Exit deep sleep on CTS line activity"; + case CSR_PSKEY_FC_HC2H_FLUSH_DELAY: + return "Delay from disconnect to flushing HC->H FC tokens"; + case CSR_PSKEY_RX_HIGHSIDE: + return "Disable the HIGHSIDE bit in ANA_CONFIG"; + case CSR_PSKEY_TX_PRE_LVL: + return "TX pre-amplifier level"; + case CSR_PSKEY_RX_SINGLE_ENDED: + return "RX single ended"; + case CSR_PSKEY_TX_FILTER_CONFIG: + return "TX filter configuration"; + case CSR_PSKEY_CLOCK_REQUEST_ENABLE: + return "External clock request enable"; + case CSR_PSKEY_RX_MIN_ATTEN: + return "Minimum attenuation allowed for receiver"; + case CSR_PSKEY_XTAL_TARGET_AMPLITUDE: + return "Crystal target amplitude"; + case CSR_PSKEY_PCM_MIN_CPU_CLOCK: + return "Minimum CPU clock speed with PCM port running"; + case CSR_PSKEY_HOST_INTERFACE_PIO_USB: + return "USB host interface selection PIO line"; + case CSR_PSKEY_CPU_IDLE_MODE: + return "CPU idle mode when radio is active"; + case CSR_PSKEY_DEEP_SLEEP_CLEAR_RTS: + return "Deep sleep clears the UART RTS line"; + case CSR_PSKEY_RF_RESONANCE_TRIM: + return "Frequency trim for IQ and LNA resonant circuits"; + case CSR_PSKEY_DEEP_SLEEP_PIO_WAKE: + return "PIO line to wake the chip from deep sleep"; + case CSR_PSKEY_DRAIN_BORE_TIMERS: + return "Energy consumption measurement settings"; + case CSR_PSKEY_DRAIN_TX_POWER_BASE: + return "Energy consumption measurement settings"; + case CSR_PSKEY_MODULE_ID: + return "Module serial number"; + case CSR_PSKEY_MODULE_DESIGN: + return "Module design ID"; + case CSR_PSKEY_MODULE_SECURITY_CODE: + return "Module security code"; + case CSR_PSKEY_VM_DISABLE: + return "VM disable"; + case CSR_PSKEY_MOD_MANUF0: + return "Module manufactuer data 0"; + case CSR_PSKEY_MOD_MANUF1: + return "Module manufactuer data 1"; + case CSR_PSKEY_MOD_MANUF2: + return "Module manufactuer data 2"; + case CSR_PSKEY_MOD_MANUF3: + return "Module manufactuer data 3"; + case CSR_PSKEY_MOD_MANUF4: + return "Module manufactuer data 4"; + case CSR_PSKEY_MOD_MANUF5: + return "Module manufactuer data 5"; + case CSR_PSKEY_MOD_MANUF6: + return "Module manufactuer data 6"; + case CSR_PSKEY_MOD_MANUF7: + return "Module manufactuer data 7"; + case CSR_PSKEY_MOD_MANUF8: + return "Module manufactuer data 8"; + case CSR_PSKEY_MOD_MANUF9: + return "Module manufactuer data 9"; + case CSR_PSKEY_DUT_VM_DISABLE: + return "VM disable when entering radiotest modes"; + case CSR_PSKEY_USR0: + return "User configuration data 0"; + case CSR_PSKEY_USR1: + return "User configuration data 1"; + case CSR_PSKEY_USR2: + return "User configuration data 2"; + case CSR_PSKEY_USR3: + return "User configuration data 3"; + case CSR_PSKEY_USR4: + return "User configuration data 4"; + case CSR_PSKEY_USR5: + return "User configuration data 5"; + case CSR_PSKEY_USR6: + return "User configuration data 6"; + case CSR_PSKEY_USR7: + return "User configuration data 7"; + case CSR_PSKEY_USR8: + return "User configuration data 8"; + case CSR_PSKEY_USR9: + return "User configuration data 9"; + case CSR_PSKEY_USR10: + return "User configuration data 10"; + case CSR_PSKEY_USR11: + return "User configuration data 11"; + case CSR_PSKEY_USR12: + return "User configuration data 12"; + case CSR_PSKEY_USR13: + return "User configuration data 13"; + case CSR_PSKEY_USR14: + return "User configuration data 14"; + case CSR_PSKEY_USR15: + return "User configuration data 15"; + case CSR_PSKEY_USR16: + return "User configuration data 16"; + case CSR_PSKEY_USR17: + return "User configuration data 17"; + case CSR_PSKEY_USR18: + return "User configuration data 18"; + case CSR_PSKEY_USR19: + return "User configuration data 19"; + case CSR_PSKEY_USR20: + return "User configuration data 20"; + case CSR_PSKEY_USR21: + return "User configuration data 21"; + case CSR_PSKEY_USR22: + return "User configuration data 22"; + case CSR_PSKEY_USR23: + return "User configuration data 23"; + case CSR_PSKEY_USR24: + return "User configuration data 24"; + case CSR_PSKEY_USR25: + return "User configuration data 25"; + case CSR_PSKEY_USR26: + return "User configuration data 26"; + case CSR_PSKEY_USR27: + return "User configuration data 27"; + case CSR_PSKEY_USR28: + return "User configuration data 28"; + case CSR_PSKEY_USR29: + return "User configuration data 29"; + case CSR_PSKEY_USR30: + return "User configuration data 30"; + case CSR_PSKEY_USR31: + return "User configuration data 31"; + case CSR_PSKEY_USR32: + return "User configuration data 32"; + case CSR_PSKEY_USR33: + return "User configuration data 33"; + case CSR_PSKEY_USR34: + return "User configuration data 34"; + case CSR_PSKEY_USR35: + return "User configuration data 35"; + case CSR_PSKEY_USR36: + return "User configuration data 36"; + case CSR_PSKEY_USR37: + return "User configuration data 37"; + case CSR_PSKEY_USR38: + return "User configuration data 38"; + case CSR_PSKEY_USR39: + return "User configuration data 39"; + case CSR_PSKEY_USR40: + return "User configuration data 40"; + case CSR_PSKEY_USR41: + return "User configuration data 41"; + case CSR_PSKEY_USR42: + return "User configuration data 42"; + case CSR_PSKEY_USR43: + return "User configuration data 43"; + case CSR_PSKEY_USR44: + return "User configuration data 44"; + case CSR_PSKEY_USR45: + return "User configuration data 45"; + case CSR_PSKEY_USR46: + return "User configuration data 46"; + case CSR_PSKEY_USR47: + return "User configuration data 47"; + case CSR_PSKEY_USR48: + return "User configuration data 48"; + case CSR_PSKEY_USR49: + return "User configuration data 49"; + case CSR_PSKEY_USB_VERSION: + return "USB specification version number"; + case CSR_PSKEY_USB_DEVICE_CLASS_CODES: + return "USB device class codes"; case CSR_PSKEY_USB_VENDOR_ID: return "USB vendor identifier"; case CSR_PSKEY_USB_PRODUCT_ID: return "USB product identifier"; + case CSR_PSKEY_USB_MANUF_STRING: + return "USB manufacturer string"; + case CSR_PSKEY_USB_PRODUCT_STRING: + return "USB product string"; + case CSR_PSKEY_USB_SERIAL_NUMBER_STRING: + return "USB serial number string"; + case CSR_PSKEY_USB_CONFIG_STRING: + return "USB configuration string"; + case CSR_PSKEY_USB_ATTRIBUTES: + return "USB attributes bitmap"; + case CSR_PSKEY_USB_MAX_POWER: + return "USB device maximum power consumption"; + case CSR_PSKEY_USB_BT_IF_CLASS_CODES: + return "USB Bluetooth interface class codes"; + case CSR_PSKEY_USB_LANGID: + return "USB language strings supported"; + case CSR_PSKEY_USB_DFU_CLASS_CODES: + return "USB DFU class codes block"; case CSR_PSKEY_USB_DFU_PRODUCT_ID: return "USB DFU product ID"; + case CSR_PSKEY_USB_PIO_DETACH: + return "USB detach/attach PIO line"; + case CSR_PSKEY_USB_PIO_WAKEUP: + return "USB wakeup PIO line"; + case CSR_PSKEY_USB_PIO_PULLUP: + return "USB D+ pullup PIO line"; + case CSR_PSKEY_USB_PIO_VBUS: + return "USB VBus detection PIO Line"; + case CSR_PSKEY_USB_PIO_WAKE_TIMEOUT: + return "Timeout for assertion of USB PIO wake signal"; + case CSR_PSKEY_USB_PIO_RESUME: + return "PIO signal used in place of bus resume"; + case CSR_PSKEY_USB_BT_SCO_IF_CLASS_CODES: + return "USB Bluetooth SCO interface class codes"; + case CSR_PSKEY_USB_SUSPEND_PIO_LEVEL: + return "USB PIO levels to set when suspended"; + case CSR_PSKEY_USB_SUSPEND_PIO_DIR: + return "USB PIO I/O directions to set when suspended"; + case CSR_PSKEY_USB_SUSPEND_PIO_MASK: + return "USB PIO lines to be set forcibly in suspend"; + case CSR_PSKEY_USB_ENDPOINT_0_MAX_PACKET_SIZE: + return "The maxmimum packet size for USB endpoint 0"; + case CSR_PSKEY_USB_CONFIG: + return "USB config params for new chips (>bc2"; + case CSR_PSKEY_RADIOTEST_ATTEN_INIT: + return "Radio test initial attenuator"; + case CSR_PSKEY_RADIOTEST_FIRST_TRIM_TIME: + return "IQ first calibration period in test"; + case CSR_PSKEY_RADIOTEST_SUBSEQUENT_TRIM_TIME: + return "IQ subsequent calibration period in test"; + case CSR_PSKEY_RADIOTEST_LO_LVL_TRIM_ENABLE: + return "LO_LVL calibration enable"; + case CSR_PSKEY_RADIOTEST_DISABLE_MODULATION: + return "Disable modulation during radiotest transmissions"; + case CSR_PSKEY_RFCOMM_FCON_THRESHOLD: + return "RFCOMM aggregate flow control on threshold"; + case CSR_PSKEY_RFCOMM_FCOFF_THRESHOLD: + return "RFCOMM aggregate flow control off threshold"; + case CSR_PSKEY_IPV6_STATIC_ADDR: + return "Static IPv6 address"; + case CSR_PSKEY_IPV4_STATIC_ADDR: + return "Static IPv4 address"; + case CSR_PSKEY_IPV6_STATIC_PREFIX_LEN: + return "Static IPv6 prefix length"; + case CSR_PSKEY_IPV6_STATIC_ROUTER_ADDR: + return "Static IPv6 router address"; + case CSR_PSKEY_IPV4_STATIC_SUBNET_MASK: + return "Static IPv4 subnet mask"; + case CSR_PSKEY_IPV4_STATIC_ROUTER_ADDR: + return "Static IPv4 router address"; + case CSR_PSKEY_MDNS_NAME: + return "Multicast DNS name"; + case CSR_PSKEY_FIXED_PIN: + return "Fixed PIN"; + case CSR_PSKEY_MDNS_PORT: + return "Multicast DNS port"; + case CSR_PSKEY_MDNS_TTL: + return "Multicast DNS TTL"; + case CSR_PSKEY_MDNS_IPV4_ADDR: + return "Multicast DNS IPv4 address"; + case CSR_PSKEY_ARP_CACHE_TIMEOUT: + return "ARP cache timeout"; + case CSR_PSKEY_HFP_POWER_TABLE: + return "HFP power table"; + case CSR_PSKEY_DRAIN_BORE_TIMER_COUNTERS: + return "Energy consumption estimation timer counters"; + case CSR_PSKEY_DRAIN_BORE_COUNTERS: + return "Energy consumption estimation counters"; + case CSR_PSKEY_LOOP_FILTER_TRIM: + return "Trim value to optimise loop filter"; + case CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK: + return "Energy consumption estimation current peak"; + case CSR_PSKEY_FORCE_16MHZ_REF_PIO: + return "PIO line to force 16 MHz reference to be assumed"; + case CSR_PSKEY_CDMA_LO_REF_LIMITS: + return "Local oscillator frequency reference limits for CDMA"; + case CSR_PSKEY_CDMA_LO_ERROR_LIMITS: + return "Local oscillator frequency error limits for CDMA"; + case CSR_PSKEY_CLOCK_STARTUP_DELAY: + return "Clock startup delay in milliseconds"; + case CSR_PSKEY_DEEP_SLEEP_CORRECTION_FACTOR: + return "Deep sleep clock correction factor"; + case CSR_PSKEY_TEMPERATURE_CALIBRATION: + return "Temperature in deg C for a given internal setting"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA: + return "Temperature for given internal PA adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL: + return "Temperature for a given TX_PRE_LVL adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB: + return "Temperature for a given TX_BB adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_ANA_FTRIM: + return "Temperature for given crystal trim adjustment"; + case CSR_PSKEY_TEST_DELTA_OFFSET: + return "Frequency offset applied to synthesiser in test mode"; + case CSR_PSKEY_RX_DYNAMIC_LVL_OFFSET: + return "Receiver dynamic level offset depending on channel"; + case CSR_PSKEY_TEST_FORCE_OFFSET: + return "Force use of exact value in PSKEY_TEST_DELTA_OFFSET"; + case CSR_PSKEY_RF_TRAP_BAD_DIVISION_RATIOS: + return "Trap bad division ratios in radio frequency tables"; + case CSR_PSKEY_RADIOTEST_CDMA_LO_REF_LIMITS: + return "LO frequency reference limits for CDMA in radiotest"; case CSR_PSKEY_INITIAL_BOOTMODE: return "Initial device bootmode"; + case CSR_PSKEY_ONCHIP_HCI_CLIENT: + return "HCI traffic routed internally"; + case CSR_PSKEY_RX_ATTEN_BACKOFF: + return "Receiver attenuation back-off"; + case CSR_PSKEY_RX_ATTEN_UPDATE_RATE: + return "Receiver attenuation update rate"; + case CSR_PSKEY_SYNTH_TXRX_THRESHOLDS: + return "Local oscillator tuning voltage limits for tx and rx"; + case CSR_PSKEY_MIN_WAIT_STATES: + return "Flash wait state indicator"; + case CSR_PSKEY_RSSI_CORRECTION: + return "RSSI correction factor."; + case CSR_PSKEY_SCHED_THROTTLE_TIMEOUT: + return "Scheduler performance control."; + case CSR_PSKEY_DEEP_SLEEP_USE_EXTERNAL_CLOCK: + return "Deep sleep uses external 32 kHz clock source"; + case CSR_PSKEY_TRIM_RADIO_FILTERS: + return "Trim rx and tx radio filters if true."; + case CSR_PSKEY_TRANSMIT_OFFSET: + return "Transmit offset in units of 62.5 kHz"; + case CSR_PSKEY_USB_VM_CONTROL: + return "VM application will supply USB descriptors"; + case CSR_PSKEY_MR_ANA_RX_FTRIM: + return "Medium rate value for the ANA_RX_FTRIM register"; + case CSR_PSKEY_I2C_CONFIG: + return "I2C configuration"; + case CSR_PSKEY_MR_TX_FILTER_CONFIG: + return "TX filter configuration used for enhanced data rate"; + case CSR_PSKEY_MR_TX_CONFIG2: + return "TX filter configuration used for enhanced data rate"; + case CSR_PSKEY_USB_DONT_RESET_BOOTMODE_ON_HOST_RESET: + return "Don't reset bootmode if USB host resets"; + case CSR_PSKEY_LC_USE_THROTTLING: + return "Adjust packet selection on packet error rate"; + case CSR_PSKEY_CHARGER_TRIM: + return "Trim value for the current charger"; + case CSR_PSKEY_CLOCK_REQUEST_FEATURES: + return "Clock request is tristated if enabled"; + case CSR_PSKEY_TRANSMIT_OFFSET_CLASS1: + return "Transmit offset / 62.5 kHz for class 1 radios"; + case CSR_PSKEY_TX_AVOID_PA_CLASS1_PIO: + return "PIO line asserted in class1 operation to avoid PA"; + case CSR_PSKEY_MR_PIO_CONFIG: + return "PIO line asserted in class1 operation to avoid PA"; + case CSR_PSKEY_UART_CONFIG2: + return "The UART Sampling point"; + case CSR_PSKEY_CLASS1_IQ_LVL: + return "IQ demand level for class 1 power level"; + case CSR_PSKEY_CLASS1_TX_CONFIG2: + return "TX filter configuration used for class 1 tx power"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA_CLASS1: + return "Temperature for given internal PA adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_EXTERNAL_PA_CLASS1: + return "Temperature for given internal PA adjustment"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL_MR: + return "Temperature adjustment for TX_PRE_LVL in EDR"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_HEADER: + return "Temperature for a given TX_BB in EDR header"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_PAYLOAD: + return "Temperature for a given TX_BB in EDR payload"; + case CSR_PSKEY_RX_MR_EQ_TAPS: + return "Adjust receiver configuration for EDR"; + case CSR_PSKEY_TX_PRE_LVL_CLASS1: + return "TX pre-amplifier level in class 1 operation"; + case CSR_PSKEY_ANALOGUE_ATTENUATOR: + return "TX analogue attenuator setting"; + case CSR_PSKEY_MR_RX_FILTER_TRIM: + return "Trim for receiver used in EDR."; + case CSR_PSKEY_MR_RX_FILTER_RESPONSE: + return "Filter response for receiver used in EDR."; + case CSR_PSKEY_PIO_WAKEUP_STATE: + return "PIO deep sleep wake up state "; + case CSR_PSKEY_MR_TX_IF_ATTEN_OFF_TEMP: + return "TX IF atten off temperature when using EDR."; + case CSR_PSKEY_LO_DIV_LATCH_BYPASS: + return "Bypass latch for LO dividers"; + case CSR_PSKEY_LO_VCO_STANDBY: + return "Use standby mode for the LO VCO"; + case CSR_PSKEY_SLOW_CLOCK_FILTER_SHIFT: + return "Slow clock sampling filter constant"; + case CSR_PSKEY_SLOW_CLOCK_FILTER_DIVIDER: + return "Slow clock filter fractional threshold"; + case CSR_PSKEY_USB_ATTRIBUTES_POWER: + return "USB self powered"; + case CSR_PSKEY_USB_ATTRIBUTES_WAKEUP: + return "USB responds to wake-up"; + case CSR_PSKEY_DFU_ATTRIBUTES_MANIFESTATION_TOLERANT: + return "DFU manifestation tolerant"; + case CSR_PSKEY_DFU_ATTRIBUTES_CAN_UPLOAD: + return "DFU can upload"; + case CSR_PSKEY_DFU_ATTRIBUTES_CAN_DOWNLOAD: + return "DFU can download"; + case CSR_PSKEY_UART_CONFIG_STOP_BITS: + return "UART: stop bits"; + case CSR_PSKEY_UART_CONFIG_PARITY_BIT: + return "UART: parity bit"; + case CSR_PSKEY_UART_CONFIG_FLOW_CTRL_EN: + return "UART: hardware flow control"; + case CSR_PSKEY_UART_CONFIG_RTS_AUTO_EN: + return "UART: RTS auto-enabled"; + case CSR_PSKEY_UART_CONFIG_RTS: + return "UART: RTS asserted"; + case CSR_PSKEY_UART_CONFIG_TX_ZERO_EN: + return "UART: TX zero enable"; + case CSR_PSKEY_UART_CONFIG_NON_BCSP_EN: + return "UART: enable BCSP-specific hardware"; + case CSR_PSKEY_UART_CONFIG_RX_RATE_DELAY: + return "UART: RX rate delay"; + case CSR_PSKEY_UART_SEQ_TIMEOUT: + return "UART: BCSP ack timeout"; + case CSR_PSKEY_UART_SEQ_RETRIES: + return "UART: retry limit in sequencing layer"; + case CSR_PSKEY_UART_SEQ_WINSIZE: + return "UART: BCSP transmit window size"; + case CSR_PSKEY_UART_USE_CRC_ON_TX: + return "UART: use BCSP CRCs"; + case CSR_PSKEY_UART_HOST_INITIAL_STATE: + return "UART: initial host state"; + case CSR_PSKEY_UART_HOST_ATTENTION_SPAN: + return "UART: host attention span"; + case CSR_PSKEY_UART_HOST_WAKEUP_TIME: + return "UART: host wakeup time"; + case CSR_PSKEY_UART_HOST_WAKEUP_WAIT: + return "UART: host wakeup wait"; + case CSR_PSKEY_BCSP_LM_MODE: + return "BCSP link establishment mode"; + case CSR_PSKEY_BCSP_LM_SYNC_RETRIES: + return "BCSP link establishment sync retries"; + case CSR_PSKEY_BCSP_LM_TSHY: + return "BCSP link establishment Tshy"; + case CSR_PSKEY_UART_DFU_CONFIG_STOP_BITS: + return "DFU mode UART: stop bits"; + case CSR_PSKEY_UART_DFU_CONFIG_PARITY_BIT: + return "DFU mode UART: parity bit"; + case CSR_PSKEY_UART_DFU_CONFIG_FLOW_CTRL_EN: + return "DFU mode UART: hardware flow control"; + case CSR_PSKEY_UART_DFU_CONFIG_RTS_AUTO_EN: + return "DFU mode UART: RTS auto-enabled"; + case CSR_PSKEY_UART_DFU_CONFIG_RTS: + return "DFU mode UART: RTS asserted"; + case CSR_PSKEY_UART_DFU_CONFIG_TX_ZERO_EN: + return "DFU mode UART: TX zero enable"; + case CSR_PSKEY_UART_DFU_CONFIG_NON_BCSP_EN: + return "DFU mode UART: enable BCSP-specific hardware"; + case CSR_PSKEY_UART_DFU_CONFIG_RX_RATE_DELAY: + return "DFU mode UART: RX rate delay"; + case CSR_PSKEY_AMUX_AIO0: + return "Multiplexer for AIO 0"; + case CSR_PSKEY_AMUX_AIO1: + return "Multiplexer for AIO 1"; + case CSR_PSKEY_AMUX_AIO2: + return "Multiplexer for AIO 2"; + case CSR_PSKEY_AMUX_AIO3: + return "Multiplexer for AIO 3"; + case CSR_PSKEY_LOCAL_NAME_SIMPLIFIED: + return "Local Name (simplified"; + case CSR_PSKEY_EXTENDED_STUB: + return "Extended stub"; default: return "Unknown"; } diff --git a/tools/csr.h b/tools/csr.h index 0f9859fa..319c863e 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -69,30 +69,431 @@ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ #define CSR_VARID_PS 0x7002 /* complex */ -#define CSR_PSKEY_BDADDR 0x0001 /* uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ -#define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ -#define CSR_PSKEY_CLASSOFDEVICE 0x0003 /* uint32 */ -#define CSR_PSKEY_DEVICE_DRIFT 0x0004 /* uint16 */ -#define CSR_PSKEY_DEVICE_JITTER 0x0005 /* uint16 */ -#define CSR_PSKEY_MAX_ACLS 0x000d /* uint16 */ -#define CSR_PSKEY_MAX_SCOS 0x000e /* uint16 */ -#define CSR_PSKEY_MAX_REMOTE_MASTERS 0x000f /* uint16 */ -#define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ -#define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ -#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 } */ -#define CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS 0x0106 /* uint16[] = { 0xffff, 0x03ff, 0xfffe, 0xffff, 0xffff, 0xffff, 0x0ff3, 0xfff8, 0x003f } */ -#define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ -#define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ -#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN 0x01a5 /* bool (uint16) */ -#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab /* bool (uint16) */ -#define CSR_PSKEY_UART_BAUDRATE 0x01be /* uint16 */ -#define CSR_PSKEY_ANA_FTRIM 0x01f6 /* uint16 */ -#define CSR_PSKEY_HOST_INTERFACE 0x01f9 /* uint16 */ -#define CSR_PSKEY_ANA_FREQ 0x01fe /* uint16 */ -#define CSR_PSKEY_USB_VENDOR_ID 0x02be /* uint16 */ -#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf /* uint16 */ -#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb /* uint16 */ -#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd /* int16 */ +#define CSR_PSKEY_BDADDR 0x0001 /* bdaddr / uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ +#define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ +#define CSR_PSKEY_CLASSOFDEVICE 0x0003 /* bdcod */ +#define CSR_PSKEY_DEVICE_DRIFT 0x0004 /* uint16 */ +#define CSR_PSKEY_DEVICE_JITTER 0x0005 /* uint16 */ +#define CSR_PSKEY_MAX_ACLS 0x000d /* uint16 */ +#define CSR_PSKEY_MAX_SCOS 0x000e /* uint16 */ +#define CSR_PSKEY_MAX_REMOTE_MASTERS 0x000f /* uint16 */ +#define CSR_PSKEY_ENABLE_MASTERY_WITH_SLAVERY 0x0010 /* bool */ +#define CSR_PSKEY_H_HC_FC_MAX_ACL_PKT_LEN 0x0011 /* uint16 */ +#define CSR_PSKEY_H_HC_FC_MAX_SCO_PKT_LEN 0x0012 /* uint8 */ +#define CSR_PSKEY_H_HC_FC_MAX_ACL_PKTS 0x0013 /* uint16 */ +#define CSR_PSKEY_H_HC_FC_MAX_SCO_PKTS 0x0014 /* uint16 */ +#define CSR_PSKEY_LC_FC_BUFFER_LOW_WATER_MARK 0x0015 /* lc_fc_lwm */ +#define CSR_PSKEY_LC_MAX_TX_POWER 0x0017 /* int16 */ +#define CSR_PSKEY_TX_GAIN_RAMP 0x001d /* uint16 */ +#define CSR_PSKEY_LC_PEER_POWER_PERIOD 0x001f /* TIME */ +#define CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK 0x0020 /* lc_fc_lwm */ +#define CSR_PSKEY_LC_DEFAULT_TX_POWER 0x0021 /* int16 */ +#define CSR_PSKEY_LC_RSSI_GOLDEN_RANGE 0x0022 /* uint8 */ +#define CSR_PSKEY_LC_COMBO_DISABLE_PIO_MASK 0x0028 /* uint16[] */ +#define CSR_PSKEY_LC_COMBO_PRIORITY_PIO_MASK 0x0029 /* uint16[] */ +#define CSR_PSKEY_LC_COMBO_DOT11_CHANNEL_PIO_BASE 0x002a /* uint16 */ +#define CSR_PSKEY_LC_COMBO_DOT11_BLOCK_CHANNELS 0x002b /* uint16 */ +#define CSR_PSKEY_LC_MAX_TX_POWER_NO_RSSI 0x002d /* int8 */ +#define CSR_PSKEY_LC_CONNECTION_RX_WINDOW 0x002e /* uint16 */ +#define CSR_PSKEY_LC_COMBO_DOT11_TX_PROTECTION_MODE 0x0030 /* uint16 */ +#define CSR_PSKEY_LC_ENHANCED_POWER_TABLE 0x0031 /* enhanced_power_setting[] */ +#define CSR_PSKEY_LC_WIDEBAND_RSSI_CONFIG 0x0032 /* wideband_rssi_config */ +#define CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_LEAD 0x0033 /* uint16 */ +#define CSR_PSKEY_BT_CLOCK_INIT 0x0034 /* uint32 */ +#define CSR_PSKEY_TX_MR_MOD_DELAY 0x0038 /* uint8 */ +#define CSR_PSKEY_RX_MR_SYNC_TIMING 0x0039 /* uint16 */ +#define CSR_PSKEY_RX_MR_SYNC_CONFIG 0x003a /* uint16 */ +#define CSR_PSKEY_LC_LOST_SYNC_SLOTS 0x003b /* uint16 */ +#define CSR_PSKEY_RX_MR_SAMP_CONFIG 0x003c /* uint16 */ +#define CSR_PSKEY_AGC_HYST_LEVELS 0x003d /* agc_hyst_config */ +#define CSR_PSKEY_RX_LEVEL_LOW_SIGNAL 0x003e /* uint16 */ +#define CSR_PSKEY_AGC_IQ_LVL_VALUES 0x003f /* IQ_LVL_VAL[] */ +#define CSR_PSKEY_MR_FTRIM_OFFSET_12DB 0x0040 /* uint16 */ +#define CSR_PSKEY_MR_FTRIM_OFFSET_6DB 0x0041 /* uint16 */ +#define CSR_PSKEY_NO_CAL_ON_BOOT 0x0042 /* bool */ +#define CSR_PSKEY_RSSI_HI_TARGET 0x0043 /* uint8 */ +#define CSR_PSKEY_PREFERRED_MIN_ATTENUATION 0x0044 /* uint8 */ +#define CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_OVERRIDE 0x0045 /* bool */ +#define CSR_PSKEY_LC_MULTISLOT_HOLDOFF 0x0047 /* TIME */ +#define CSR_PSKEY_FREE_KEY_PIGEON_HOLE 0x00c9 /* uint16 */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR0 0x00ca /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR1 0x00cb /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR2 0x00cc /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR3 0x00cd /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR4 0x00ce /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR5 0x00cf /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR6 0x00d0 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR7 0x00d1 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR8 0x00d2 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR9 0x00d3 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR10 0x00d4 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR11 0x00d5 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR12 0x00d6 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR13 0x00d7 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR14 0x00d8 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LINK_KEY_BD_ADDR15 0x00d9 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_ENC_KEY_LMIN 0x00da /* uint16 */ +#define CSR_PSKEY_ENC_KEY_LMAX 0x00db /* uint16 */ +#define CSR_PSKEY_LOCAL_SUPPORTED_FEATURES 0x00ef /* uint16[] = { 0xffff, 0xfe8f, 0xf99b, 0x8000 }*/ +#define CSR_PSKEY_LM_USE_UNIT_KEY 0x00f0 /* bool */ +#define CSR_PSKEY_HCI_NOP_DISABLE 0x00f2 /* bool */ +#define CSR_PSKEY_LM_MAX_EVENT_FILTERS 0x00f4 /* uint8 */ +#define CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE 0x00f6 /* bool */ +#define CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME 0x00f7 /* uint16 */ +#define CSR_PSKEY_AFH_ADAPTATION_RESPONSE_TIME 0x00f8 /* uint16 */ +#define CSR_PSKEY_AFH_OPTIONS 0x00f9 /* uint16 */ +#define CSR_PSKEY_AFH_RSSI_RUN_PERIOD 0x00fa /* uint16 */ +#define CSR_PSKEY_AFH_REENABLE_CHANNEL_TIME 0x00fb /* uint16 */ +#define CSR_PSKEY_NO_DROP_ON_ACR_MS_FAIL 0x00fc /* bool */ +#define CSR_PSKEY_MAX_PRIVATE_KEYS 0x00fd /* uint8 */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR0 0x00fe /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR1 0x00ff /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR2 0x0100 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR3 0x0101 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR4 0x0102 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR5 0x0103 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR6 0x0104 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR7 0x0105 /* LM_LINK_KEY_BD_ADDR_T */ +#define CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS 0x0106 /* uint16[] = { 0xffff, 0x03ff, 0xfffe, 0xffff, 0xffff, 0xffff, 0x0ff3, 0xfff8, 0x003f } */ +#define CSR_PSKEY_LM_MAX_ABSENCE_INDEX 0x0107 /* uint8 */ +#define CSR_PSKEY_DEVICE_NAME 0x0108 /* uint16[] */ +#define CSR_PSKEY_AFH_RSSI_THRESHOLD 0x0109 /* uint16 */ +#define CSR_PSKEY_LM_CASUAL_SCAN_INTERVAL 0x010a /* uint16 */ +#define CSR_PSKEY_AFH_MIN_MAP_CHANGE 0x010b /* uint16[] */ +#define CSR_PSKEY_AFH_RSSI_LP_RUN_PERIOD 0x010c /* uint16 */ +#define CSR_PSKEY_HCI_LMP_LOCAL_VERSION 0x010d /* uint16 */ +#define CSR_PSKEY_LMP_REMOTE_VERSION 0x010e /* uint8 */ +#define CSR_PSKEY_HOLD_ERROR_MESSAGE_NUMBER 0x0113 /* uint16 */ +#define CSR_PSKEY_DFU_ATTRIBUTES 0x0136 /* uint8 */ +#define CSR_PSKEY_DFU_DETACH_TO 0x0137 /* uint16 */ +#define CSR_PSKEY_DFU_TRANSFER_SIZE 0x0138 /* uint16 */ +#define CSR_PSKEY_DFU_ENABLE 0x0139 /* bool */ +#define CSR_PSKEY_DFU_LIN_REG_ENABLE 0x013a /* bool */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_MSB 0x015e /* uint16[] */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_LSB 0x015f /* uint16[] */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_M_DASH 0x0160 /* uint16 */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_R2N_MSB 0x0161 /* uint16[] */ +#define CSR_PSKEY_DFUENC_VMAPP_PK_R2N_LSB 0x0162 /* uint16[] */ +#define CSR_PSKEY_BCSP_LM_PS_BLOCK 0x0192 /* BCSP_LM_PS_BLOCK */ +#define CSR_PSKEY_HOSTIO_FC_PS_BLOCK 0x0193 /* HOSTIO_FC_PS_BLOCK */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO0 0x0194 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO1 0x0195 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO2 0x0196 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO3 0x0197 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO4 0x0198 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO5 0x0199 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO6 0x019a /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO7 0x019b /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO8 0x019c /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO9 0x019d /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO10 0x019e /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO11 0x019f /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO12 0x01a0 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO13 0x01a1 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO14 0x01a2 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_PROTOCOL_INFO15 0x01a3 /* PROTOCOL_INFO */ +#define CSR_PSKEY_HOSTIO_UART_RESET_TIMEOUT 0x01a4 /* TIME */ +#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN 0x01a5 /* bool */ +#define CSR_PSKEY_HOSTIO_USE_HCI_EXTN_CCFC 0x01a6 /* bool */ +#define CSR_PSKEY_HOSTIO_HCI_EXTN_PAYLOAD_SIZE 0x01a7 /* uint16 */ +#define CSR_PSKEY_BCSP_LM_CNF_CNT_LIMIT 0x01aa /* uint16 */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM 0x01ab /* bool */ +#define CSR_PSKEY_HOSTIO_AWKWARD_PCM_SYNC 0x01ac /* bool */ +#define CSR_PSKEY_HOSTIO_BREAK_POLL_PERIOD 0x01ad /* TIME */ +#define CSR_PSKEY_HOSTIO_MIN_UART_HCI_SCO_SIZE 0x01ae /* uint16 */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_CODEC 0x01b0 /* bool */ +#define CSR_PSKEY_PCM_CVSD_TX_HI_FREQ_BOOST 0x01b1 /* uint16 */ +#define CSR_PSKEY_PCM_CVSD_RX_HI_FREQ_BOOST 0x01b2 /* uint16 */ +#define CSR_PSKEY_PCM_CONFIG32 0x01b3 /* uint32 */ +#define CSR_PSKEY_USE_OLD_BCSP_LE 0x01b4 /* uint16 */ +#define CSR_PSKEY_PCM_CVSD_USE_NEW_FILTER 0x01b5 /* bool */ +#define CSR_PSKEY_PCM_FORMAT 0x01b6 /* uint16 */ +#define CSR_PSKEY_CODEC_OUT_GAIN 0x01b7 /* uint16 */ +#define CSR_PSKEY_CODEC_IN_GAIN 0x01b8 /* uint16 */ +#define CSR_PSKEY_CODEC_PIO 0x01b9 /* uint16 */ +#define CSR_PSKEY_PCM_LOW_JITTER_CONFIG 0x01ba /* uint32 */ +#define CSR_PSKEY_HOSTIO_SCO_PCM_THRESHOLDS 0x01bb /* uint16[] */ +#define CSR_PSKEY_HOSTIO_SCO_HCI_THRESHOLDS 0x01bc /* uint16[] */ +#define CSR_PSKEY_HOSTIO_MAP_SCO_PCM_SLOT 0x01bd /* uint16 */ +#define CSR_PSKEY_UART_BAUDRATE 0x01be /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_BCSP 0x01bf /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_H4 0x01c0 /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_H5 0x01c1 /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_USR 0x01c2 /* uint16 */ +#define CSR_PSKEY_UART_TX_CRCS 0x01c3 /* bool */ +#define CSR_PSKEY_UART_ACK_TIMEOUT 0x01c4 /* uint16 */ +#define CSR_PSKEY_UART_TX_MAX_ATTEMPTS 0x01c5 /* uint16 */ +#define CSR_PSKEY_UART_TX_WINDOW_SIZE 0x01c6 /* uint16 */ +#define CSR_PSKEY_UART_HOST_WAKE 0x01c7 /* uint16[] */ +#define CSR_PSKEY_HOSTIO_THROTTLE_TIMEOUT 0x01c8 /* TIME */ +#define CSR_PSKEY_PCM_ALWAYS_ENABLE 0x01c9 /* bool */ +#define CSR_PSKEY_UART_HOST_WAKE_SIGNAL 0x01ca /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_H4DS 0x01cb /* uint16 */ +#define CSR_PSKEY_H4DS_WAKE_DURATION 0x01cc /* uint16 */ +#define CSR_PSKEY_H4DS_MAXWU 0x01cd /* uint16 */ +#define CSR_PSKEY_H4DS_LE_TIMER_PERIOD 0x01cf /* uint16 */ +#define CSR_PSKEY_H4DS_TWU_TIMER_PERIOD 0x01d0 /* uint16 */ +#define CSR_PSKEY_H4DS_UART_IDLE_TIMER_PERIOD 0x01d1 /* uint16 */ +#define CSR_PSKEY_ANA_FTRIM 0x01f6 /* uint16 */ +#define CSR_PSKEY_WD_TIMEOUT 0x01f7 /* TIME */ +#define CSR_PSKEY_WD_PERIOD 0x01f8 /* TIME */ +#define CSR_PSKEY_HOST_INTERFACE 0x01f9 /* phys_bus */ +#define CSR_PSKEY_HQ_HOST_TIMEOUT 0x01fb /* TIME */ +#define CSR_PSKEY_HQ_ACTIVE 0x01fc /* bool */ +#define CSR_PSKEY_BCCMD_SECURITY_ACTIVE 0x01fd /* bool */ +#define CSR_PSKEY_ANA_FREQ 0x01fe /* uint16 */ +#define CSR_PSKEY_PIO_PROTECT_MASK 0x0202 /* uint16 */ +#define CSR_PSKEY_PMALLOC_SIZES 0x0203 /* uint16[] */ +#define CSR_PSKEY_UART_BAUD_RATE 0x0204 /* uint16 */ +#define CSR_PSKEY_UART_CONFIG 0x0205 /* uint16 */ +#define CSR_PSKEY_STUB 0x0207 /* uint16 */ +#define CSR_PSKEY_TXRX_PIO_CONTROL 0x0209 /* uint16 */ +#define CSR_PSKEY_ANA_RX_LEVEL 0x020b /* uint16 */ +#define CSR_PSKEY_ANA_RX_FTRIM 0x020c /* uint16 */ +#define CSR_PSKEY_PSBC_DATA_VERSION 0x020d /* uint16 */ +#define CSR_PSKEY_PCM0_ATTENUATION 0x020f /* uint16 */ +#define CSR_PSKEY_LO_LVL_MAX 0x0211 /* uint16 */ +#define CSR_PSKEY_LO_ADC_AMPL_MIN 0x0212 /* uint16 */ +#define CSR_PSKEY_LO_ADC_AMPL_MAX 0x0213 /* uint16 */ +#define CSR_PSKEY_IQ_TRIM_CHANNEL 0x0214 /* uint16 */ +#define CSR_PSKEY_IQ_TRIM_GAIN 0x0215 /* uint16 */ +#define CSR_PSKEY_TX_OFFSET_HALF_MHZ 0x0217 /* int16 */ +#define CSR_PSKEY_GBL_MISC_ENABLES 0x0221 /* uint16 */ +#define CSR_PSKEY_UART_SLEEP_TIMEOUT 0x0222 /* uint16 */ +#define CSR_PSKEY_DEEP_SLEEP_STATE 0x0229 /* deep_sleep_state */ +#define CSR_PSKEY_IQ_ENABLE_PHASE_TRIM 0x022d /* bool */ +#define CSR_PSKEY_HCI_HANDLE_FREEZE_PERIOD 0x0237 /* TIME */ +#define CSR_PSKEY_MAX_FROZEN_HCI_HANDLES 0x0238 /* uint16 */ +#define CSR_PSKEY_PAGETABLE_DESTRUCTION_DELAY 0x0239 /* TIME */ +#define CSR_PSKEY_IQ_TRIM_PIO_SETTINGS 0x023a /* uint8 */ +#define CSR_PSKEY_USE_EXTERNAL_CLOCK 0x023b /* bool */ +#define CSR_PSKEY_DEEP_SLEEP_WAKE_CTS 0x023c /* uint16 */ +#define CSR_PSKEY_FC_HC2H_FLUSH_DELAY 0x023d /* TIME */ +#define CSR_PSKEY_RX_HIGHSIDE 0x023e /* bool */ +#define CSR_PSKEY_TX_PRE_LVL 0x0240 /* uint8 */ +#define CSR_PSKEY_RX_SINGLE_ENDED 0x0242 /* bool */ +#define CSR_PSKEY_TX_FILTER_CONFIG 0x0243 /* uint32 */ +#define CSR_PSKEY_CLOCK_REQUEST_ENABLE 0x0246 /* uint16 */ +#define CSR_PSKEY_RX_MIN_ATTEN 0x0249 /* uint16 */ +#define CSR_PSKEY_XTAL_TARGET_AMPLITUDE 0x024b /* uint8 */ +#define CSR_PSKEY_PCM_MIN_CPU_CLOCK 0x024d /* uint16 */ +#define CSR_PSKEY_HOST_INTERFACE_PIO_USB 0x0250 /* uint16 */ +#define CSR_PSKEY_CPU_IDLE_MODE 0x0251 /* cpu_idle_mode */ +#define CSR_PSKEY_DEEP_SLEEP_CLEAR_RTS 0x0252 /* bool */ +#define CSR_PSKEY_RF_RESONANCE_TRIM 0x0254 /* uint16 */ +#define CSR_PSKEY_DEEP_SLEEP_PIO_WAKE 0x0255 /* uint16 */ +#define CSR_PSKEY_DRAIN_BORE_TIMERS 0x0256 /* uint32[] */ +#define CSR_PSKEY_DRAIN_TX_POWER_BASE 0x0257 /* uint16 */ +#define CSR_PSKEY_MODULE_ID 0x0259 /* uint32 */ +#define CSR_PSKEY_MODULE_DESIGN 0x025a /* uint16 */ +#define CSR_PSKEY_MODULE_SECURITY_CODE 0x025c /* uint16[] */ +#define CSR_PSKEY_VM_DISABLE 0x025d /* bool */ +#define CSR_PSKEY_MOD_MANUF0 0x025e /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF1 0x025f /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF2 0x0260 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF3 0x0261 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF4 0x0262 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF5 0x0263 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF6 0x0264 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF7 0x0265 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF8 0x0266 /* uint16[] */ +#define CSR_PSKEY_MOD_MANUF9 0x0267 /* uint16[] */ +#define CSR_PSKEY_DUT_VM_DISABLE 0x0268 /* bool */ +#define CSR_PSKEY_USR0 0x028a /* uint16[] */ +#define CSR_PSKEY_USR1 0x028b /* uint16[] */ +#define CSR_PSKEY_USR2 0x028c /* uint16[] */ +#define CSR_PSKEY_USR3 0x028d /* uint16[] */ +#define CSR_PSKEY_USR4 0x028e /* uint16[] */ +#define CSR_PSKEY_USR5 0x028f /* uint16[] */ +#define CSR_PSKEY_USR6 0x0290 /* uint16[] */ +#define CSR_PSKEY_USR7 0x0291 /* uint16[] */ +#define CSR_PSKEY_USR8 0x0292 /* uint16[] */ +#define CSR_PSKEY_USR9 0x0293 /* uint16[] */ +#define CSR_PSKEY_USR10 0x0294 /* uint16[] */ +#define CSR_PSKEY_USR11 0x0295 /* uint16[] */ +#define CSR_PSKEY_USR12 0x0296 /* uint16[] */ +#define CSR_PSKEY_USR13 0x0297 /* uint16[] */ +#define CSR_PSKEY_USR14 0x0298 /* uint16[] */ +#define CSR_PSKEY_USR15 0x0299 /* uint16[] */ +#define CSR_PSKEY_USR16 0x029a /* uint16[] */ +#define CSR_PSKEY_USR17 0x029b /* uint16[] */ +#define CSR_PSKEY_USR18 0x029c /* uint16[] */ +#define CSR_PSKEY_USR19 0x029d /* uint16[] */ +#define CSR_PSKEY_USR20 0x029e /* uint16[] */ +#define CSR_PSKEY_USR21 0x029f /* uint16[] */ +#define CSR_PSKEY_USR22 0x02a0 /* uint16[] */ +#define CSR_PSKEY_USR23 0x02a1 /* uint16[] */ +#define CSR_PSKEY_USR24 0x02a2 /* uint16[] */ +#define CSR_PSKEY_USR25 0x02a3 /* uint16[] */ +#define CSR_PSKEY_USR26 0x02a4 /* uint16[] */ +#define CSR_PSKEY_USR27 0x02a5 /* uint16[] */ +#define CSR_PSKEY_USR28 0x02a6 /* uint16[] */ +#define CSR_PSKEY_USR29 0x02a7 /* uint16[] */ +#define CSR_PSKEY_USR30 0x02a8 /* uint16[] */ +#define CSR_PSKEY_USR31 0x02a9 /* uint16[] */ +#define CSR_PSKEY_USR32 0x02aa /* uint16[] */ +#define CSR_PSKEY_USR33 0x02ab /* uint16[] */ +#define CSR_PSKEY_USR34 0x02ac /* uint16[] */ +#define CSR_PSKEY_USR35 0x02ad /* uint16[] */ +#define CSR_PSKEY_USR36 0x02ae /* uint16[] */ +#define CSR_PSKEY_USR37 0x02af /* uint16[] */ +#define CSR_PSKEY_USR38 0x02b0 /* uint16[] */ +#define CSR_PSKEY_USR39 0x02b1 /* uint16[] */ +#define CSR_PSKEY_USR40 0x02b2 /* uint16[] */ +#define CSR_PSKEY_USR41 0x02b3 /* uint16[] */ +#define CSR_PSKEY_USR42 0x02b4 /* uint16[] */ +#define CSR_PSKEY_USR43 0x02b5 /* uint16[] */ +#define CSR_PSKEY_USR44 0x02b6 /* uint16[] */ +#define CSR_PSKEY_USR45 0x02b7 /* uint16[] */ +#define CSR_PSKEY_USR46 0x02b8 /* uint16[] */ +#define CSR_PSKEY_USR47 0x02b9 /* uint16[] */ +#define CSR_PSKEY_USR48 0x02ba /* uint16[] */ +#define CSR_PSKEY_USR49 0x02bb /* uint16[] */ +#define CSR_PSKEY_USB_VERSION 0x02bc /* uint16 */ +#define CSR_PSKEY_USB_DEVICE_CLASS_CODES 0x02bd /* usbclass */ +#define CSR_PSKEY_USB_VENDOR_ID 0x02be /* uint16 */ +#define CSR_PSKEY_USB_PRODUCT_ID 0x02bf /* uint16 */ +#define CSR_PSKEY_USB_MANUF_STRING 0x02c1 /* unicodestring */ +#define CSR_PSKEY_USB_PRODUCT_STRING 0x02c2 /* unicodestring */ +#define CSR_PSKEY_USB_SERIAL_NUMBER_STRING 0x02c3 /* unicodestring */ +#define CSR_PSKEY_USB_CONFIG_STRING 0x02c4 /* unicodestring */ +#define CSR_PSKEY_USB_ATTRIBUTES 0x02c5 /* uint8 */ +#define CSR_PSKEY_USB_MAX_POWER 0x02c6 /* uint16 */ +#define CSR_PSKEY_USB_BT_IF_CLASS_CODES 0x02c7 /* usbclass */ +#define CSR_PSKEY_USB_LANGID 0x02c9 /* uint16 */ +#define CSR_PSKEY_USB_DFU_CLASS_CODES 0x02ca /* usbclass */ +#define CSR_PSKEY_USB_DFU_PRODUCT_ID 0x02cb /* uint16 */ +#define CSR_PSKEY_USB_PIO_DETACH 0x02ce /* uint16 */ +#define CSR_PSKEY_USB_PIO_WAKEUP 0x02cf /* uint16 */ +#define CSR_PSKEY_USB_PIO_PULLUP 0x02d0 /* uint16 */ +#define CSR_PSKEY_USB_PIO_VBUS 0x02d1 /* uint16 */ +#define CSR_PSKEY_USB_PIO_WAKE_TIMEOUT 0x02d2 /* uint16 */ +#define CSR_PSKEY_USB_PIO_RESUME 0x02d3 /* uint16 */ +#define CSR_PSKEY_USB_BT_SCO_IF_CLASS_CODES 0x02d4 /* usbclass */ +#define CSR_PSKEY_USB_SUSPEND_PIO_LEVEL 0x02d5 /* uint16 */ +#define CSR_PSKEY_USB_SUSPEND_PIO_DIR 0x02d6 /* uint16 */ +#define CSR_PSKEY_USB_SUSPEND_PIO_MASK 0x02d7 /* uint16 */ +#define CSR_PSKEY_USB_ENDPOINT_0_MAX_PACKET_SIZE 0x02d8 /* uint8 */ +#define CSR_PSKEY_USB_CONFIG 0x02d9 /* uint16 */ +#define CSR_PSKEY_RADIOTEST_ATTEN_INIT 0x0320 /* uint16 */ +#define CSR_PSKEY_RADIOTEST_FIRST_TRIM_TIME 0x0326 /* TIME */ +#define CSR_PSKEY_RADIOTEST_SUBSEQUENT_TRIM_TIME 0x0327 /* TIME */ +#define CSR_PSKEY_RADIOTEST_LO_LVL_TRIM_ENABLE 0x0328 /* bool */ +#define CSR_PSKEY_RADIOTEST_DISABLE_MODULATION 0x032c /* bool */ +#define CSR_PSKEY_RFCOMM_FCON_THRESHOLD 0x0352 /* uint16 */ +#define CSR_PSKEY_RFCOMM_FCOFF_THRESHOLD 0x0353 /* uint16 */ +#define CSR_PSKEY_IPV6_STATIC_ADDR 0x0354 /* uint16[] */ +#define CSR_PSKEY_IPV4_STATIC_ADDR 0x0355 /* uint32 */ +#define CSR_PSKEY_IPV6_STATIC_PREFIX_LEN 0x0356 /* uint8 */ +#define CSR_PSKEY_IPV6_STATIC_ROUTER_ADDR 0x0357 /* uint16[] */ +#define CSR_PSKEY_IPV4_STATIC_SUBNET_MASK 0x0358 /* uint32 */ +#define CSR_PSKEY_IPV4_STATIC_ROUTER_ADDR 0x0359 /* uint32 */ +#define CSR_PSKEY_MDNS_NAME 0x035a /* char[] */ +#define CSR_PSKEY_FIXED_PIN 0x035b /* uint8[] */ +#define CSR_PSKEY_MDNS_PORT 0x035c /* uint16 */ +#define CSR_PSKEY_MDNS_TTL 0x035d /* uint8 */ +#define CSR_PSKEY_MDNS_IPV4_ADDR 0x035e /* uint32 */ +#define CSR_PSKEY_ARP_CACHE_TIMEOUT 0x035f /* uint16 */ +#define CSR_PSKEY_HFP_POWER_TABLE 0x0360 /* uint16[] */ +#define CSR_PSKEY_DRAIN_BORE_TIMER_COUNTERS 0x03e7 /* uint32[] */ +#define CSR_PSKEY_DRAIN_BORE_COUNTERS 0x03e6 /* uint32[] */ +#define CSR_PSKEY_LOOP_FILTER_TRIM 0x03e4 /* uint16 */ +#define CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK 0x03e3 /* uint32[] */ +#define CSR_PSKEY_FORCE_16MHZ_REF_PIO 0x03e1 /* uint16 */ +#define CSR_PSKEY_CDMA_LO_REF_LIMITS 0x03df /* uint16 */ +#define CSR_PSKEY_CDMA_LO_ERROR_LIMITS 0x03de /* uint16 */ +#define CSR_PSKEY_CLOCK_STARTUP_DELAY 0x03dd /* uint16 */ +#define CSR_PSKEY_DEEP_SLEEP_CORRECTION_FACTOR 0x03dc /* int16 */ +#define CSR_PSKEY_TEMPERATURE_CALIBRATION 0x03db /* temperature_calibration */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA 0x03da /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL 0x03d9 /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB 0x03d8 /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_ANA_FTRIM 0x03d7 /* temperature_calibration[] */ +#define CSR_PSKEY_TEST_DELTA_OFFSET 0x03d6 /* uint16 */ +#define CSR_PSKEY_RX_DYNAMIC_LVL_OFFSET 0x03d4 /* uint16 */ +#define CSR_PSKEY_TEST_FORCE_OFFSET 0x03d3 /* bool */ +#define CSR_PSKEY_RF_TRAP_BAD_DIVISION_RATIOS 0x03cf /* uint16 */ +#define CSR_PSKEY_RADIOTEST_CDMA_LO_REF_LIMITS 0x03ce /* uint16 */ +#define CSR_PSKEY_INITIAL_BOOTMODE 0x03cd /* int16 */ +#define CSR_PSKEY_ONCHIP_HCI_CLIENT 0x03cc /* bool */ +#define CSR_PSKEY_RX_ATTEN_BACKOFF 0x03ca /* uint16 */ +#define CSR_PSKEY_RX_ATTEN_UPDATE_RATE 0x03c9 /* uint16 */ +#define CSR_PSKEY_SYNTH_TXRX_THRESHOLDS 0x03c7 /* uint16 */ +#define CSR_PSKEY_MIN_WAIT_STATES 0x03c6 /* uint16 */ +#define CSR_PSKEY_RSSI_CORRECTION 0x03c5 /* int8 */ +#define CSR_PSKEY_SCHED_THROTTLE_TIMEOUT 0x03c4 /* TIME */ +#define CSR_PSKEY_DEEP_SLEEP_USE_EXTERNAL_CLOCK 0x03c3 /* bool */ +#define CSR_PSKEY_TRIM_RADIO_FILTERS 0x03c2 /* uint16 */ +#define CSR_PSKEY_TRANSMIT_OFFSET 0x03c1 /* int16 */ +#define CSR_PSKEY_USB_VM_CONTROL 0x03c0 /* bool */ +#define CSR_PSKEY_MR_ANA_RX_FTRIM 0x03bf /* uint16 */ +#define CSR_PSKEY_I2C_CONFIG 0x03be /* uint16 */ +#define CSR_PSKEY_MR_TX_FILTER_CONFIG 0x03bb /* uint32 */ +#define CSR_PSKEY_MR_TX_CONFIG2 0x03ba /* uint16 */ +#define CSR_PSKEY_USB_DONT_RESET_BOOTMODE_ON_HOST_RESET 0x03b9 /* bool */ +#define CSR_PSKEY_LC_USE_THROTTLING 0x03b8 /* bool */ +#define CSR_PSKEY_CHARGER_TRIM 0x03b7 /* uint16 */ +#define CSR_PSKEY_CLOCK_REQUEST_FEATURES 0x03b6 /* uint16 */ +#define CSR_PSKEY_TRANSMIT_OFFSET_CLASS1 0x03b4 /* int16 */ +#define CSR_PSKEY_TX_AVOID_PA_CLASS1_PIO 0x03b3 /* uint16 */ +#define CSR_PSKEY_MR_PIO_CONFIG 0x03b2 /* uint16 */ +#define CSR_PSKEY_UART_CONFIG2 0x03b1 /* uint8 */ +#define CSR_PSKEY_CLASS1_IQ_LVL 0x03b0 /* uint16 */ +#define CSR_PSKEY_CLASS1_TX_CONFIG2 0x03af /* uint16 */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA_CLASS1 0x03ae /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_EXTERNAL_PA_CLASS1 0x03ad /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL_MR 0x03ac /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_HEADER 0x03ab /* temperature_calibration[] */ +#define CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_PAYLOAD 0x03aa /* temperature_calibration[] */ +#define CSR_PSKEY_RX_MR_EQ_TAPS 0x03a9 /* uint16[] */ +#define CSR_PSKEY_TX_PRE_LVL_CLASS1 0x03a8 /* uint8 */ +#define CSR_PSKEY_ANALOGUE_ATTENUATOR 0x03a7 /* bool */ +#define CSR_PSKEY_MR_RX_FILTER_TRIM 0x03a6 /* uint16 */ +#define CSR_PSKEY_MR_RX_FILTER_RESPONSE 0x03a5 /* int16[] */ +#define CSR_PSKEY_PIO_WAKEUP_STATE 0x039f /* uint16 */ +#define CSR_PSKEY_MR_TX_IF_ATTEN_OFF_TEMP 0x0394 /* int16 */ +#define CSR_PSKEY_LO_DIV_LATCH_BYPASS 0x0393 /* bool */ +#define CSR_PSKEY_LO_VCO_STANDBY 0x0392 /* bool */ +#define CSR_PSKEY_SLOW_CLOCK_FILTER_SHIFT 0x0391 /* uint16 */ +#define CSR_PSKEY_SLOW_CLOCK_FILTER_DIVIDER 0x0390 /* uint16 */ +#define CSR_PSKEY_USB_ATTRIBUTES_POWER 0x03f2 /* bool */ +#define CSR_PSKEY_USB_ATTRIBUTES_WAKEUP 0x03f3 /* bool */ +#define CSR_PSKEY_DFU_ATTRIBUTES_MANIFESTATION_TOLERANT 0x03f4 /* bool */ +#define CSR_PSKEY_DFU_ATTRIBUTES_CAN_UPLOAD 0x03f5 /* bool */ +#define CSR_PSKEY_DFU_ATTRIBUTES_CAN_DOWNLOAD 0x03f6 /* bool */ +#define CSR_PSKEY_UART_CONFIG_STOP_BITS 0x03fc /* bool */ +#define CSR_PSKEY_UART_CONFIG_PARITY_BIT 0x03fd /* uint16 */ +#define CSR_PSKEY_UART_CONFIG_FLOW_CTRL_EN 0x03fe /* bool */ +#define CSR_PSKEY_UART_CONFIG_RTS_AUTO_EN 0x03ff /* bool */ +#define CSR_PSKEY_UART_CONFIG_RTS 0x0400 /* bool */ +#define CSR_PSKEY_UART_CONFIG_TX_ZERO_EN 0x0401 /* bool */ +#define CSR_PSKEY_UART_CONFIG_NON_BCSP_EN 0x0402 /* bool */ +#define CSR_PSKEY_UART_CONFIG_RX_RATE_DELAY 0x0403 /* uint16 */ +#define CSR_PSKEY_UART_SEQ_TIMEOUT 0x0405 /* uint16 */ +#define CSR_PSKEY_UART_SEQ_RETRIES 0x0406 /* uint16 */ +#define CSR_PSKEY_UART_SEQ_WINSIZE 0x0407 /* uint16 */ +#define CSR_PSKEY_UART_USE_CRC_ON_TX 0x0408 /* bool */ +#define CSR_PSKEY_UART_HOST_INITIAL_STATE 0x0409 /* hwakeup_state */ +#define CSR_PSKEY_UART_HOST_ATTENTION_SPAN 0x040a /* uint16 */ +#define CSR_PSKEY_UART_HOST_WAKEUP_TIME 0x040b /* uint16 */ +#define CSR_PSKEY_UART_HOST_WAKEUP_WAIT 0x040c /* uint16 */ +#define CSR_PSKEY_BCSP_LM_MODE 0x0410 /* uint16 */ +#define CSR_PSKEY_BCSP_LM_SYNC_RETRIES 0x0411 /* uint16 */ +#define CSR_PSKEY_BCSP_LM_TSHY 0x0412 /* uint16 */ +#define CSR_PSKEY_UART_DFU_CONFIG_STOP_BITS 0x0417 /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_PARITY_BIT 0x0418 /* uint16 */ +#define CSR_PSKEY_UART_DFU_CONFIG_FLOW_CTRL_EN 0x0419 /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_RTS_AUTO_EN 0x041a /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_RTS 0x041b /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_TX_ZERO_EN 0x041c /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_NON_BCSP_EN 0x041d /* bool */ +#define CSR_PSKEY_UART_DFU_CONFIG_RX_RATE_DELAY 0x041e /* uint16 */ +#define CSR_PSKEY_AMUX_AIO0 0x041f /* ana_amux_sel */ +#define CSR_PSKEY_AMUX_AIO1 0x0420 /* ana_amux_sel */ +#define CSR_PSKEY_AMUX_AIO2 0x0421 /* ana_amux_sel */ +#define CSR_PSKEY_AMUX_AIO3 0x0422 /* ana_amux_sel */ +#define CSR_PSKEY_LOCAL_NAME_SIMPLIFIED 0x0423 /* local_name_complete */ +#define CSR_PSKEY_EXTENDED_STUB 0x2001 /* uint16 */ char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); -- cgit From b77c88f001624ea277b84c0521286490c0c60c46 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 01:55:04 +0000 Subject: Add build definition to string function --- tools/csr.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- tools/csr.h | 1 + 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 556f13cb..11068298 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -351,6 +351,112 @@ static struct { { 0, } }; +char *csr_builddeftostr(uint16_t def) +{ + switch (def) { + case 0x0000: + return "NONE"; + case 0x0001: + return "CHIP_BASE_BC01"; + case 0x0002: + return "CHIP_BASE_BC02"; + case 0x0003: + return "CHIP_BC01B"; + case 0x0004: + return "CHIP_BC02_EXTERNAL"; + case 0x0005: + return "BUILD_HCI"; + case 0x0006: + return "BUILD_RFCOMM"; + case 0x0007: + return "BT_VER_1_1"; + case 0x0008: + return "TRANSPORT_ALL"; + case 0x0009: + return "TRANSPORT_BCSP"; + case 0x000a: + return "TRANSPORT_H4"; + case 0x000b: + return "TRANSPORT_USB"; + case 0x000c: + return "MAX_CRYPT_KEY_LEN_56"; + case 0x000d: + return "MAX_CRYPT_KEY_LEN_128"; + case 0x000e: + return "TRANSPORT_USER"; + case 0x000f: + return "CHIP_BC02K"; + case 0x0010: + return "TRANSPORT_NONE"; + case 0x0012: + return "REQUIRE_8MBIT"; + case 0x0013: + return "RADIOTEST"; + case 0x0014: + return "RADIOTEST_LITE"; + case 0x0015: + return "INSTALL_FLASH"; + case 0x0016: + return "INSTALL_EEPROM"; + case 0x0017: + return "INSTALL_COMBO_DOT11"; + case 0x0018: + return "LOWPOWER_TX"; + case 0x0019: + return "TRANSPORT_TWUTL"; + case 0x001a: + return "COMPILER_GCC"; + case 0x001b: + return "CHIP_BC02C"; + case 0x001c: + return "CHIP_BC02T"; + case 0x001d: + return "CHIP_BASE_BC3"; + case 0x001e: + return "CHIP_BC3N"; + case 0x001f: + return "CHIP_BC3K"; + case 0x0020: + return "INSTALL_HCI_MODULE"; + case 0x0021: + return "INSTALL_L2CAP_MODULE"; + case 0x0022: + return "INSTALL_DM_MODULE"; + case 0x0023: + return "INSTALL_SDP_MODULE"; + case 0x0024: + return "INSTALL_RFCOMM_MODULE"; + case 0x0025: + return "INSTALL_HIDIO_MODULE"; + case 0x0026: + return "INSTALL_PAN_MODULE"; + case 0x0027: + return "INSTALL_IPV4_MODULE"; + case 0x0028: + return "INSTALL_IPV6_MODULE"; + case 0x0029: + return "INSTALL_TCP_MODULE"; + case 0x002a: + return "BT_VER_1_2"; + case 0x002b: + return "INSTALL_UDP_MODULE"; + case 0x002c: + return "REQUIRE_0_WAIT_STATES"; + case 0x002d: + return "CHIP_BC3_PADDYWACK"; + case 0x002e: + return "CHIP_BC4_COYOTE"; + case 0x002f: + return "CHIP_BC4_ODDJOB"; + case 0x0030: + return "TRANSPORT_H4DS"; + case 0x0031: + return "CHIP_BASE_BC4"; + default: + return "UNKNOWN"; + } +} + char *csr_buildidtostr(uint16_t id) { static char str[12]; @@ -370,10 +476,13 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev) case 0x00: return "BlueCore01a"; case 0x01: - if (rev == 0x64) + switch (rev) { + case 0x64: return "BlueCore01b (ES)"; - else + case 0x65: + default: return "BlueCore01b"; + } case 0x02: switch (rev) { case 0x89: diff --git a/tools/csr.h b/tools/csr.h index 319c863e..aead1f17 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -495,6 +495,7 @@ #define CSR_PSKEY_LOCAL_NAME_SIMPLIFIED 0x0423 /* local_name_complete */ #define CSR_PSKEY_EXTENDED_STUB 0x2001 /* uint16 */ +char *csr_builddeftostr(uint16_t def); char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); -- cgit From 7dbda16a2352e6c935c47b49ecca3336bdc2a5da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 01:55:51 +0000 Subject: Add support for reading the build definitions --- tools/bccmd.8 | 3 +++ tools/bccmd.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/tools/bccmd.8 b/tools/bccmd.8 index a51be28e..58e8814f 100644 --- a/tools/bccmd.8 +++ b/tools/bccmd.8 @@ -23,6 +23,9 @@ devices. If run without the argument, a short help page will be diapla Specify a particular device to operate on. If not specified, default is the first available device. .SH COMMANDS .TP +.BI builddef +Get build definitions +.TP .BI keylen\ Get current crypt key length .TP diff --git a/tools/bccmd.c b/tools/bccmd.c index e476165e..4d32c089 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -42,6 +42,41 @@ #include "csr.h" +static int cmd_builddef(int dd, int argc, char *argv[]) +{ + uint8_t buf[8]; + uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; + int err = 0; + + printf("Build definitions:"); + + while (1) { + memset(buf, 0, sizeof(buf)); + buf[0] = def & 0xff; + buf[1] = def >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_GET_NEXT_BUILDDEF, buf, sizeof(buf)); + if (err < 0) { + errno = -err; + break; + } + + nextdef = buf[2] | (buf[3] << 8); + + if (nextdef == 0x0000) + break; + + def = nextdef; + + printf(" %s (0x%02x)", csr_builddeftostr(def), def); + } + + printf("\n"); + + return err; +} + static int cmd_keylen(int dd, int argc, char *argv[]) { uint8_t buf[8]; @@ -171,6 +206,7 @@ static struct { char *arg; char *doc; } commands[] = { + { "builddef", cmd_builddef, "", "Get build definitions" }, { "keylen", cmd_keylen, "", "Get current crypt key length" }, { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { "rand", cmd_rand, "", "Get random number" }, -- cgit From ed31ef0927bc60f9ecb24c1733aabb8540adc72b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 01:59:11 +0000 Subject: Display one build definition per line --- tools/bccmd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/bccmd.c b/tools/bccmd.c index 4d32c089..18d38766 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -48,7 +48,7 @@ static int cmd_builddef(int dd, int argc, char *argv[]) uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; int err = 0; - printf("Build definitions:"); + printf("Build definitions:\n"); while (1) { memset(buf, 0, sizeof(buf)); @@ -69,11 +69,9 @@ static int cmd_builddef(int dd, int argc, char *argv[]) def = nextdef; - printf(" %s (0x%02x)", csr_builddeftostr(def), def); + printf("0x%04x - %s\n", def, csr_builddeftostr(def)); } - printf("\n"); - return err; } -- cgit From 4634453164622a49ee06f530ddf8a2a5b82edfec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 02:12:46 +0000 Subject: Update build ids --- tools/csr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 11068298..0470e5b2 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -262,6 +262,7 @@ static struct { { 1586, "HCI 18.2" }, { 1591, "HCI 18.2" }, { 1592, "HCI 18.2" }, + { 1593, "HCI 18.2.1" }, { 1733, "HCI 18.3" }, { 1734, "HCI 18.3" }, { 1735, "HCI 18.3" }, @@ -282,6 +283,8 @@ static struct { { 2259, "Unified 20d" }, { 2361, "Unified 20e" }, { 2362, "Unified 20e" }, + { 2386, "Unified 21a" }, + { 2387, "Unified 21a" }, { 2423, "Unified 21a" }, { 2424, "Unified 21a" }, { 195, "Sniff 1 (2001-11-27)" }, -- cgit From 403a8b252f7e27b97b4db18fbc31173d51f407c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 09:36:44 +0000 Subject: Add PS key to value transformation routine --- tools/csr.c | 858 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 859 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 0470e5b2..765a6d90 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -1375,6 +1375,864 @@ char *csr_pskeytostr(uint16_t pskey) } } +char *csr_pskeytoval(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_BDADDR: + return "BDADDR"; + case CSR_PSKEY_COUNTRYCODE: + return "COUNTRYCODE"; + case CSR_PSKEY_CLASSOFDEVICE: + return "CLASSOFDEVICE"; + case CSR_PSKEY_DEVICE_DRIFT: + return "DEVICE_DRIFT"; + case CSR_PSKEY_DEVICE_JITTER: + return "DEVICE_JITTER"; + case CSR_PSKEY_MAX_ACLS: + return "MAX_ACLS"; + case CSR_PSKEY_MAX_SCOS: + return "MAX_SCOS"; + case CSR_PSKEY_MAX_REMOTE_MASTERS: + return "MAX_REMOTE_MASTERS"; + case CSR_PSKEY_ENABLE_MASTERY_WITH_SLAVERY: + return "ENABLE_MASTERY_WITH_SLAVERY"; + case CSR_PSKEY_H_HC_FC_MAX_ACL_PKT_LEN: + return "H_HC_FC_MAX_ACL_PKT_LEN"; + case CSR_PSKEY_H_HC_FC_MAX_SCO_PKT_LEN: + return "H_HC_FC_MAX_SCO_PKT_LEN"; + case CSR_PSKEY_H_HC_FC_MAX_ACL_PKTS: + return "H_HC_FC_MAX_ACL_PKTS"; + case CSR_PSKEY_H_HC_FC_MAX_SCO_PKTS: + return "H_HC_FC_MAX_SCO_PKTS"; + case CSR_PSKEY_LC_FC_BUFFER_LOW_WATER_MARK: + return "LC_FC_BUFFER_LOW_WATER_MARK"; + case CSR_PSKEY_LC_MAX_TX_POWER: + return "LC_MAX_TX_POWER"; + case CSR_PSKEY_TX_GAIN_RAMP: + return "TX_GAIN_RAMP"; + case CSR_PSKEY_LC_PEER_POWER_PERIOD: + return "LC_PEER_POWER_PERIOD"; + case CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK: + return "LC_FC_POOLS_LOW_WATER_MARK"; + case CSR_PSKEY_LC_DEFAULT_TX_POWER: + return "LC_DEFAULT_TX_POWER"; + case CSR_PSKEY_LC_RSSI_GOLDEN_RANGE: + return "LC_RSSI_GOLDEN_RANGE"; + case CSR_PSKEY_LC_COMBO_DISABLE_PIO_MASK: + return "LC_COMBO_DISABLE_PIO_MASK"; + case CSR_PSKEY_LC_COMBO_PRIORITY_PIO_MASK: + return "LC_COMBO_PRIORITY_PIO_MASK"; + case CSR_PSKEY_LC_COMBO_DOT11_CHANNEL_PIO_BASE: + return "LC_COMBO_DOT11_CHANNEL_PIO_BASE"; + case CSR_PSKEY_LC_COMBO_DOT11_BLOCK_CHANNELS: + return "LC_COMBO_DOT11_BLOCK_CHANNELS"; + case CSR_PSKEY_LC_MAX_TX_POWER_NO_RSSI: + return "LC_MAX_TX_POWER_NO_RSSI"; + case CSR_PSKEY_LC_CONNECTION_RX_WINDOW: + return "LC_CONNECTION_RX_WINDOW"; + case CSR_PSKEY_LC_COMBO_DOT11_TX_PROTECTION_MODE: + return "LC_COMBO_DOT11_TX_PROTECTION_MODE"; + case CSR_PSKEY_LC_ENHANCED_POWER_TABLE: + return "LC_ENHANCED_POWER_TABLE"; + case CSR_PSKEY_LC_WIDEBAND_RSSI_CONFIG: + return "LC_WIDEBAND_RSSI_CONFIG"; + case CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_LEAD: + return "LC_COMBO_DOT11_PRIORITY_LEAD"; + case CSR_PSKEY_BT_CLOCK_INIT: + return "BT_CLOCK_INIT"; + case CSR_PSKEY_TX_MR_MOD_DELAY: + return "TX_MR_MOD_DELAY"; + case CSR_PSKEY_RX_MR_SYNC_TIMING: + return "RX_MR_SYNC_TIMING"; + case CSR_PSKEY_RX_MR_SYNC_CONFIG: + return "RX_MR_SYNC_CONFIG"; + case CSR_PSKEY_LC_LOST_SYNC_SLOTS: + return "LC_LOST_SYNC_SLOTS"; + case CSR_PSKEY_RX_MR_SAMP_CONFIG: + return "RX_MR_SAMP_CONFIG"; + case CSR_PSKEY_AGC_HYST_LEVELS: + return "AGC_HYST_LEVELS"; + case CSR_PSKEY_RX_LEVEL_LOW_SIGNAL: + return "RX_LEVEL_LOW_SIGNAL"; + case CSR_PSKEY_AGC_IQ_LVL_VALUES: + return "AGC_IQ_LVL_VALUES"; + case CSR_PSKEY_MR_FTRIM_OFFSET_12DB: + return "MR_FTRIM_OFFSET_12DB"; + case CSR_PSKEY_MR_FTRIM_OFFSET_6DB: + return "MR_FTRIM_OFFSET_6DB"; + case CSR_PSKEY_NO_CAL_ON_BOOT: + return "NO_CAL_ON_BOOT"; + case CSR_PSKEY_RSSI_HI_TARGET: + return "RSSI_HI_TARGET"; + case CSR_PSKEY_PREFERRED_MIN_ATTENUATION: + return "PREFERRED_MIN_ATTENUATION"; + case CSR_PSKEY_LC_COMBO_DOT11_PRIORITY_OVERRIDE: + return "LC_COMBO_DOT11_PRIORITY_OVERRIDE"; + case CSR_PSKEY_LC_MULTISLOT_HOLDOFF: + return "LC_MULTISLOT_HOLDOFF"; + case CSR_PSKEY_FREE_KEY_PIGEON_HOLE: + return "FREE_KEY_PIGEON_HOLE"; + case CSR_PSKEY_LINK_KEY_BD_ADDR0: + return "LINK_KEY_BD_ADDR0"; + case CSR_PSKEY_LINK_KEY_BD_ADDR1: + return "LINK_KEY_BD_ADDR1"; + case CSR_PSKEY_LINK_KEY_BD_ADDR2: + return "LINK_KEY_BD_ADDR2"; + case CSR_PSKEY_LINK_KEY_BD_ADDR3: + return "LINK_KEY_BD_ADDR3"; + case CSR_PSKEY_LINK_KEY_BD_ADDR4: + return "LINK_KEY_BD_ADDR4"; + case CSR_PSKEY_LINK_KEY_BD_ADDR5: + return "LINK_KEY_BD_ADDR5"; + case CSR_PSKEY_LINK_KEY_BD_ADDR6: + return "LINK_KEY_BD_ADDR6"; + case CSR_PSKEY_LINK_KEY_BD_ADDR7: + return "LINK_KEY_BD_ADDR7"; + case CSR_PSKEY_LINK_KEY_BD_ADDR8: + return "LINK_KEY_BD_ADDR8"; + case CSR_PSKEY_LINK_KEY_BD_ADDR9: + return "LINK_KEY_BD_ADDR9"; + case CSR_PSKEY_LINK_KEY_BD_ADDR10: + return "LINK_KEY_BD_ADDR10"; + case CSR_PSKEY_LINK_KEY_BD_ADDR11: + return "LINK_KEY_BD_ADDR11"; + case CSR_PSKEY_LINK_KEY_BD_ADDR12: + return "LINK_KEY_BD_ADDR12"; + case CSR_PSKEY_LINK_KEY_BD_ADDR13: + return "LINK_KEY_BD_ADDR13"; + case CSR_PSKEY_LINK_KEY_BD_ADDR14: + return "LINK_KEY_BD_ADDR14"; + case CSR_PSKEY_LINK_KEY_BD_ADDR15: + return "LINK_KEY_BD_ADDR15"; + case CSR_PSKEY_ENC_KEY_LMIN: + return "ENC_KEY_LMIN"; + case CSR_PSKEY_ENC_KEY_LMAX: + return "ENC_KEY_LMAX"; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return "LOCAL_SUPPORTED_FEATURES"; + case CSR_PSKEY_LM_USE_UNIT_KEY: + return "LM_USE_UNIT_KEY"; + case CSR_PSKEY_HCI_NOP_DISABLE: + return "HCI_NOP_DISABLE"; + case CSR_PSKEY_LM_MAX_EVENT_FILTERS: + return "LM_MAX_EVENT_FILTERS"; + case CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE: + return "LM_TEST_SEND_ACCEPTED_TWICE"; + case CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME: + return "LM_MAX_PAGE_HOLD_TIME"; + case CSR_PSKEY_AFH_ADAPTATION_RESPONSE_TIME: + return "AFH_ADAPTATION_RESPONSE_TIME"; + case CSR_PSKEY_AFH_OPTIONS: + return "AFH_OPTIONS"; + case CSR_PSKEY_AFH_RSSI_RUN_PERIOD: + return "AFH_RSSI_RUN_PERIOD"; + case CSR_PSKEY_AFH_REENABLE_CHANNEL_TIME: + return "AFH_REENABLE_CHANNEL_TIME"; + case CSR_PSKEY_NO_DROP_ON_ACR_MS_FAIL: + return "NO_DROP_ON_ACR_MS_FAIL"; + case CSR_PSKEY_MAX_PRIVATE_KEYS: + return "MAX_PRIVATE_KEYS"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR0: + return "PRIVATE_LINK_KEY_BD_ADDR0"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR1: + return "PRIVATE_LINK_KEY_BD_ADDR1"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR2: + return "PRIVATE_LINK_KEY_BD_ADDR2"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR3: + return "PRIVATE_LINK_KEY_BD_ADDR3"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR4: + return "PRIVATE_LINK_KEY_BD_ADDR4"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR5: + return "PRIVATE_LINK_KEY_BD_ADDR5"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR6: + return "PRIVATE_LINK_KEY_BD_ADDR6"; + case CSR_PSKEY_PRIVATE_LINK_KEY_BD_ADDR7: + return "PRIVATE_LINK_KEY_BD_ADDR7"; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return "LOCAL_SUPPORTED_COMMANDS"; + case CSR_PSKEY_LM_MAX_ABSENCE_INDEX: + return "LM_MAX_ABSENCE_INDEX"; + case CSR_PSKEY_DEVICE_NAME: + return "DEVICE_NAME"; + case CSR_PSKEY_AFH_RSSI_THRESHOLD: + return "AFH_RSSI_THRESHOLD"; + case CSR_PSKEY_LM_CASUAL_SCAN_INTERVAL: + return "LM_CASUAL_SCAN_INTERVAL"; + case CSR_PSKEY_AFH_MIN_MAP_CHANGE: + return "AFH_MIN_MAP_CHANGE"; + case CSR_PSKEY_AFH_RSSI_LP_RUN_PERIOD: + return "AFH_RSSI_LP_RUN_PERIOD"; + case CSR_PSKEY_HCI_LMP_LOCAL_VERSION: + return "HCI_LMP_LOCAL_VERSION"; + case CSR_PSKEY_LMP_REMOTE_VERSION: + return "LMP_REMOTE_VERSION"; + case CSR_PSKEY_HOLD_ERROR_MESSAGE_NUMBER: + return "HOLD_ERROR_MESSAGE_NUMBER"; + case CSR_PSKEY_DFU_ATTRIBUTES: + return "DFU_ATTRIBUTES"; + case CSR_PSKEY_DFU_DETACH_TO: + return "DFU_DETACH_TO"; + case CSR_PSKEY_DFU_TRANSFER_SIZE: + return "DFU_TRANSFER_SIZE"; + case CSR_PSKEY_DFU_ENABLE: + return "DFU_ENABLE"; + case CSR_PSKEY_DFU_LIN_REG_ENABLE: + return "DFU_LIN_REG_ENABLE"; + case CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_MSB: + return "DFUENC_VMAPP_PK_MODULUS_MSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_MODULUS_LSB: + return "DFUENC_VMAPP_PK_MODULUS_LSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_M_DASH: + return "DFUENC_VMAPP_PK_M_DASH"; + case CSR_PSKEY_DFUENC_VMAPP_PK_R2N_MSB: + return "DFUENC_VMAPP_PK_R2N_MSB"; + case CSR_PSKEY_DFUENC_VMAPP_PK_R2N_LSB: + return "DFUENC_VMAPP_PK_R2N_LSB"; + case CSR_PSKEY_BCSP_LM_PS_BLOCK: + return "BCSP_LM_PS_BLOCK"; + case CSR_PSKEY_HOSTIO_FC_PS_BLOCK: + return "HOSTIO_FC_PS_BLOCK"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO0: + return "HOSTIO_PROTOCOL_INFO0"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO1: + return "HOSTIO_PROTOCOL_INFO1"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO2: + return "HOSTIO_PROTOCOL_INFO2"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO3: + return "HOSTIO_PROTOCOL_INFO3"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO4: + return "HOSTIO_PROTOCOL_INFO4"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO5: + return "HOSTIO_PROTOCOL_INFO5"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO6: + return "HOSTIO_PROTOCOL_INFO6"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO7: + return "HOSTIO_PROTOCOL_INFO7"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO8: + return "HOSTIO_PROTOCOL_INFO8"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO9: + return "HOSTIO_PROTOCOL_INFO9"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO10: + return "HOSTIO_PROTOCOL_INFO10"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO11: + return "HOSTIO_PROTOCOL_INFO11"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO12: + return "HOSTIO_PROTOCOL_INFO12"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO13: + return "HOSTIO_PROTOCOL_INFO13"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO14: + return "HOSTIO_PROTOCOL_INFO14"; + case CSR_PSKEY_HOSTIO_PROTOCOL_INFO15: + return "HOSTIO_PROTOCOL_INFO15"; + case CSR_PSKEY_HOSTIO_UART_RESET_TIMEOUT: + return "HOSTIO_UART_RESET_TIMEOUT"; + case CSR_PSKEY_HOSTIO_USE_HCI_EXTN: + return "HOSTIO_USE_HCI_EXTN"; + case CSR_PSKEY_HOSTIO_USE_HCI_EXTN_CCFC: + return "HOSTIO_USE_HCI_EXTN_CCFC"; + case CSR_PSKEY_HOSTIO_HCI_EXTN_PAYLOAD_SIZE: + return "HOSTIO_HCI_EXTN_PAYLOAD_SIZE"; + case CSR_PSKEY_BCSP_LM_CNF_CNT_LIMIT: + return "BCSP_LM_CNF_CNT_LIMIT"; + case CSR_PSKEY_HOSTIO_MAP_SCO_PCM: + return "HOSTIO_MAP_SCO_PCM"; + case CSR_PSKEY_HOSTIO_AWKWARD_PCM_SYNC: + return "HOSTIO_AWKWARD_PCM_SYNC"; + case CSR_PSKEY_HOSTIO_BREAK_POLL_PERIOD: + return "HOSTIO_BREAK_POLL_PERIOD"; + case CSR_PSKEY_HOSTIO_MIN_UART_HCI_SCO_SIZE: + return "HOSTIO_MIN_UART_HCI_SCO_SIZE"; + case CSR_PSKEY_HOSTIO_MAP_SCO_CODEC: + return "HOSTIO_MAP_SCO_CODEC"; + case CSR_PSKEY_PCM_CVSD_TX_HI_FREQ_BOOST: + return "PCM_CVSD_TX_HI_FREQ_BOOST"; + case CSR_PSKEY_PCM_CVSD_RX_HI_FREQ_BOOST: + return "PCM_CVSD_RX_HI_FREQ_BOOST"; + case CSR_PSKEY_PCM_CONFIG32: + return "PCM_CONFIG32"; + case CSR_PSKEY_USE_OLD_BCSP_LE: + return "USE_OLD_BCSP_LE"; + case CSR_PSKEY_PCM_CVSD_USE_NEW_FILTER: + return "PCM_CVSD_USE_NEW_FILTER"; + case CSR_PSKEY_PCM_FORMAT: + return "PCM_FORMAT"; + case CSR_PSKEY_CODEC_OUT_GAIN: + return "CODEC_OUT_GAIN"; + case CSR_PSKEY_CODEC_IN_GAIN: + return "CODEC_IN_GAIN"; + case CSR_PSKEY_CODEC_PIO: + return "CODEC_PIO"; + case CSR_PSKEY_PCM_LOW_JITTER_CONFIG: + return "PCM_LOW_JITTER_CONFIG"; + case CSR_PSKEY_HOSTIO_SCO_PCM_THRESHOLDS: + return "HOSTIO_SCO_PCM_THRESHOLDS"; + case CSR_PSKEY_HOSTIO_SCO_HCI_THRESHOLDS: + return "HOSTIO_SCO_HCI_THRESHOLDS"; + case CSR_PSKEY_HOSTIO_MAP_SCO_PCM_SLOT: + return "HOSTIO_MAP_SCO_PCM_SLOT"; + case CSR_PSKEY_UART_BAUDRATE: + return "UART_BAUDRATE"; + case CSR_PSKEY_UART_CONFIG_BCSP: + return "UART_CONFIG_BCSP"; + case CSR_PSKEY_UART_CONFIG_H4: + return "UART_CONFIG_H4"; + case CSR_PSKEY_UART_CONFIG_H5: + return "UART_CONFIG_H5"; + case CSR_PSKEY_UART_CONFIG_USR: + return "UART_CONFIG_USR"; + case CSR_PSKEY_UART_TX_CRCS: + return "UART_TX_CRCS"; + case CSR_PSKEY_UART_ACK_TIMEOUT: + return "UART_ACK_TIMEOUT"; + case CSR_PSKEY_UART_TX_MAX_ATTEMPTS: + return "UART_TX_MAX_ATTEMPTS"; + case CSR_PSKEY_UART_TX_WINDOW_SIZE: + return "UART_TX_WINDOW_SIZE"; + case CSR_PSKEY_UART_HOST_WAKE: + return "UART_HOST_WAKE"; + case CSR_PSKEY_HOSTIO_THROTTLE_TIMEOUT: + return "HOSTIO_THROTTLE_TIMEOUT"; + case CSR_PSKEY_PCM_ALWAYS_ENABLE: + return "PCM_ALWAYS_ENABLE"; + case CSR_PSKEY_UART_HOST_WAKE_SIGNAL: + return "UART_HOST_WAKE_SIGNAL"; + case CSR_PSKEY_UART_CONFIG_H4DS: + return "UART_CONFIG_H4DS"; + case CSR_PSKEY_H4DS_WAKE_DURATION: + return "H4DS_WAKE_DURATION"; + case CSR_PSKEY_H4DS_MAXWU: + return "H4DS_MAXWU"; + case CSR_PSKEY_H4DS_LE_TIMER_PERIOD: + return "H4DS_LE_TIMER_PERIOD"; + case CSR_PSKEY_H4DS_TWU_TIMER_PERIOD: + return "H4DS_TWU_TIMER_PERIOD"; + case CSR_PSKEY_H4DS_UART_IDLE_TIMER_PERIOD: + return "H4DS_UART_IDLE_TIMER_PERIOD"; + case CSR_PSKEY_ANA_FTRIM: + return "ANA_FTRIM"; + case CSR_PSKEY_WD_TIMEOUT: + return "WD_TIMEOUT"; + case CSR_PSKEY_WD_PERIOD: + return "WD_PERIOD"; + case CSR_PSKEY_HOST_INTERFACE: + return "HOST_INTERFACE"; + case CSR_PSKEY_HQ_HOST_TIMEOUT: + return "HQ_HOST_TIMEOUT"; + case CSR_PSKEY_HQ_ACTIVE: + return "HQ_ACTIVE"; + case CSR_PSKEY_BCCMD_SECURITY_ACTIVE: + return "BCCMD_SECURITY_ACTIVE"; + case CSR_PSKEY_ANA_FREQ: + return "ANA_FREQ"; + case CSR_PSKEY_PIO_PROTECT_MASK: + return "PIO_PROTECT_MASK"; + case CSR_PSKEY_PMALLOC_SIZES: + return "PMALLOC_SIZES"; + case CSR_PSKEY_UART_BAUD_RATE: + return "UART_BAUD_RATE"; + case CSR_PSKEY_UART_CONFIG: + return "UART_CONFIG"; + case CSR_PSKEY_STUB: + return "STUB"; + case CSR_PSKEY_TXRX_PIO_CONTROL: + return "TXRX_PIO_CONTROL"; + case CSR_PSKEY_ANA_RX_LEVEL: + return "ANA_RX_LEVEL"; + case CSR_PSKEY_ANA_RX_FTRIM: + return "ANA_RX_FTRIM"; + case CSR_PSKEY_PSBC_DATA_VERSION: + return "PSBC_DATA_VERSION"; + case CSR_PSKEY_PCM0_ATTENUATION: + return "PCM0_ATTENUATION"; + case CSR_PSKEY_LO_LVL_MAX: + return "LO_LVL_MAX"; + case CSR_PSKEY_LO_ADC_AMPL_MIN: + return "LO_ADC_AMPL_MIN"; + case CSR_PSKEY_LO_ADC_AMPL_MAX: + return "LO_ADC_AMPL_MAX"; + case CSR_PSKEY_IQ_TRIM_CHANNEL: + return "IQ_TRIM_CHANNEL"; + case CSR_PSKEY_IQ_TRIM_GAIN: + return "IQ_TRIM_GAIN"; + case CSR_PSKEY_TX_OFFSET_HALF_MHZ: + return "TX_OFFSET_HALF_MHZ"; + case CSR_PSKEY_GBL_MISC_ENABLES: + return "GBL_MISC_ENABLES"; + case CSR_PSKEY_UART_SLEEP_TIMEOUT: + return "UART_SLEEP_TIMEOUT"; + case CSR_PSKEY_DEEP_SLEEP_STATE: + return "DEEP_SLEEP_STATE"; + case CSR_PSKEY_IQ_ENABLE_PHASE_TRIM: + return "IQ_ENABLE_PHASE_TRIM"; + case CSR_PSKEY_HCI_HANDLE_FREEZE_PERIOD: + return "HCI_HANDLE_FREEZE_PERIOD"; + case CSR_PSKEY_MAX_FROZEN_HCI_HANDLES: + return "MAX_FROZEN_HCI_HANDLES"; + case CSR_PSKEY_PAGETABLE_DESTRUCTION_DELAY: + return "PAGETABLE_DESTRUCTION_DELAY"; + case CSR_PSKEY_IQ_TRIM_PIO_SETTINGS: + return "IQ_TRIM_PIO_SETTINGS"; + case CSR_PSKEY_USE_EXTERNAL_CLOCK: + return "USE_EXTERNAL_CLOCK"; + case CSR_PSKEY_DEEP_SLEEP_WAKE_CTS: + return "DEEP_SLEEP_WAKE_CTS"; + case CSR_PSKEY_FC_HC2H_FLUSH_DELAY: + return "FC_HC2H_FLUSH_DELAY"; + case CSR_PSKEY_RX_HIGHSIDE: + return "RX_HIGHSIDE"; + case CSR_PSKEY_TX_PRE_LVL: + return "TX_PRE_LVL"; + case CSR_PSKEY_RX_SINGLE_ENDED: + return "RX_SINGLE_ENDED"; + case CSR_PSKEY_TX_FILTER_CONFIG: + return "TX_FILTER_CONFIG"; + case CSR_PSKEY_CLOCK_REQUEST_ENABLE: + return "CLOCK_REQUEST_ENABLE"; + case CSR_PSKEY_RX_MIN_ATTEN: + return "RX_MIN_ATTEN"; + case CSR_PSKEY_XTAL_TARGET_AMPLITUDE: + return "XTAL_TARGET_AMPLITUDE"; + case CSR_PSKEY_PCM_MIN_CPU_CLOCK: + return "PCM_MIN_CPU_CLOCK"; + case CSR_PSKEY_HOST_INTERFACE_PIO_USB: + return "HOST_INTERFACE_PIO_USB"; + case CSR_PSKEY_CPU_IDLE_MODE: + return "CPU_IDLE_MODE"; + case CSR_PSKEY_DEEP_SLEEP_CLEAR_RTS: + return "DEEP_SLEEP_CLEAR_RTS"; + case CSR_PSKEY_RF_RESONANCE_TRIM: + return "RF_RESONANCE_TRIM"; + case CSR_PSKEY_DEEP_SLEEP_PIO_WAKE: + return "DEEP_SLEEP_PIO_WAKE"; + case CSR_PSKEY_DRAIN_BORE_TIMERS: + return "DRAIN_BORE_TIMERS"; + case CSR_PSKEY_DRAIN_TX_POWER_BASE: + return "DRAIN_TX_POWER_BASE"; + case CSR_PSKEY_MODULE_ID: + return "MODULE_ID"; + case CSR_PSKEY_MODULE_DESIGN: + return "MODULE_DESIGN"; + case CSR_PSKEY_MODULE_SECURITY_CODE: + return "MODULE_SECURITY_CODE"; + case CSR_PSKEY_VM_DISABLE: + return "VM_DISABLE"; + case CSR_PSKEY_MOD_MANUF0: + return "MOD_MANUF0"; + case CSR_PSKEY_MOD_MANUF1: + return "MOD_MANUF1"; + case CSR_PSKEY_MOD_MANUF2: + return "MOD_MANUF2"; + case CSR_PSKEY_MOD_MANUF3: + return "MOD_MANUF3"; + case CSR_PSKEY_MOD_MANUF4: + return "MOD_MANUF4"; + case CSR_PSKEY_MOD_MANUF5: + return "MOD_MANUF5"; + case CSR_PSKEY_MOD_MANUF6: + return "MOD_MANUF6"; + case CSR_PSKEY_MOD_MANUF7: + return "MOD_MANUF7"; + case CSR_PSKEY_MOD_MANUF8: + return "MOD_MANUF8"; + case CSR_PSKEY_MOD_MANUF9: + return "MOD_MANUF9"; + case CSR_PSKEY_DUT_VM_DISABLE: + return "DUT_VM_DISABLE"; + case CSR_PSKEY_USR0: + return "USR0"; + case CSR_PSKEY_USR1: + return "USR1"; + case CSR_PSKEY_USR2: + return "USR2"; + case CSR_PSKEY_USR3: + return "USR3"; + case CSR_PSKEY_USR4: + return "USR4"; + case CSR_PSKEY_USR5: + return "USR5"; + case CSR_PSKEY_USR6: + return "USR6"; + case CSR_PSKEY_USR7: + return "USR7"; + case CSR_PSKEY_USR8: + return "USR8"; + case CSR_PSKEY_USR9: + return "USR9"; + case CSR_PSKEY_USR10: + return "USR10"; + case CSR_PSKEY_USR11: + return "USR11"; + case CSR_PSKEY_USR12: + return "USR12"; + case CSR_PSKEY_USR13: + return "USR13"; + case CSR_PSKEY_USR14: + return "USR14"; + case CSR_PSKEY_USR15: + return "USR15"; + case CSR_PSKEY_USR16: + return "USR16"; + case CSR_PSKEY_USR17: + return "USR17"; + case CSR_PSKEY_USR18: + return "USR18"; + case CSR_PSKEY_USR19: + return "USR19"; + case CSR_PSKEY_USR20: + return "USR20"; + case CSR_PSKEY_USR21: + return "USR21"; + case CSR_PSKEY_USR22: + return "USR22"; + case CSR_PSKEY_USR23: + return "USR23"; + case CSR_PSKEY_USR24: + return "USR24"; + case CSR_PSKEY_USR25: + return "USR25"; + case CSR_PSKEY_USR26: + return "USR26"; + case CSR_PSKEY_USR27: + return "USR27"; + case CSR_PSKEY_USR28: + return "USR28"; + case CSR_PSKEY_USR29: + return "USR29"; + case CSR_PSKEY_USR30: + return "USR30"; + case CSR_PSKEY_USR31: + return "USR31"; + case CSR_PSKEY_USR32: + return "USR32"; + case CSR_PSKEY_USR33: + return "USR33"; + case CSR_PSKEY_USR34: + return "USR34"; + case CSR_PSKEY_USR35: + return "USR35"; + case CSR_PSKEY_USR36: + return "USR36"; + case CSR_PSKEY_USR37: + return "USR37"; + case CSR_PSKEY_USR38: + return "USR38"; + case CSR_PSKEY_USR39: + return "USR39"; + case CSR_PSKEY_USR40: + return "USR40"; + case CSR_PSKEY_USR41: + return "USR41"; + case CSR_PSKEY_USR42: + return "USR42"; + case CSR_PSKEY_USR43: + return "USR43"; + case CSR_PSKEY_USR44: + return "USR44"; + case CSR_PSKEY_USR45: + return "USR45"; + case CSR_PSKEY_USR46: + return "USR46"; + case CSR_PSKEY_USR47: + return "USR47"; + case CSR_PSKEY_USR48: + return "USR48"; + case CSR_PSKEY_USR49: + return "USR49"; + case CSR_PSKEY_USB_VERSION: + return "USB_VERSION"; + case CSR_PSKEY_USB_DEVICE_CLASS_CODES: + return "USB_DEVICE_CLASS_CODES"; + case CSR_PSKEY_USB_VENDOR_ID: + return "USB_VENDOR_ID"; + case CSR_PSKEY_USB_PRODUCT_ID: + return "USB_PRODUCT_ID"; + case CSR_PSKEY_USB_MANUF_STRING: + return "USB_MANUF_STRING"; + case CSR_PSKEY_USB_PRODUCT_STRING: + return "USB_PRODUCT_STRING"; + case CSR_PSKEY_USB_SERIAL_NUMBER_STRING: + return "USB_SERIAL_NUMBER_STRING"; + case CSR_PSKEY_USB_CONFIG_STRING: + return "USB_CONFIG_STRING"; + case CSR_PSKEY_USB_ATTRIBUTES: + return "USB_ATTRIBUTES"; + case CSR_PSKEY_USB_MAX_POWER: + return "USB_MAX_POWER"; + case CSR_PSKEY_USB_BT_IF_CLASS_CODES: + return "USB_BT_IF_CLASS_CODES"; + case CSR_PSKEY_USB_LANGID: + return "USB_LANGID"; + case CSR_PSKEY_USB_DFU_CLASS_CODES: + return "USB_DFU_CLASS_CODES"; + case CSR_PSKEY_USB_DFU_PRODUCT_ID: + return "USB_DFU_PRODUCT_ID"; + case CSR_PSKEY_USB_PIO_DETACH: + return "USB_PIO_DETACH"; + case CSR_PSKEY_USB_PIO_WAKEUP: + return "USB_PIO_WAKEUP"; + case CSR_PSKEY_USB_PIO_PULLUP: + return "USB_PIO_PULLUP"; + case CSR_PSKEY_USB_PIO_VBUS: + return "USB_PIO_VBUS"; + case CSR_PSKEY_USB_PIO_WAKE_TIMEOUT: + return "USB_PIO_WAKE_TIMEOUT"; + case CSR_PSKEY_USB_PIO_RESUME: + return "USB_PIO_RESUME"; + case CSR_PSKEY_USB_BT_SCO_IF_CLASS_CODES: + return "USB_BT_SCO_IF_CLASS_CODES"; + case CSR_PSKEY_USB_SUSPEND_PIO_LEVEL: + return "USB_SUSPEND_PIO_LEVEL"; + case CSR_PSKEY_USB_SUSPEND_PIO_DIR: + return "USB_SUSPEND_PIO_DIR"; + case CSR_PSKEY_USB_SUSPEND_PIO_MASK: + return "USB_SUSPEND_PIO_MASK"; + case CSR_PSKEY_USB_ENDPOINT_0_MAX_PACKET_SIZE: + return "USB_ENDPOINT_0_MAX_PACKET_SIZE"; + case CSR_PSKEY_USB_CONFIG: + return "USB_CONFIG"; + case CSR_PSKEY_RADIOTEST_ATTEN_INIT: + return "RADIOTEST_ATTEN_INIT"; + case CSR_PSKEY_RADIOTEST_FIRST_TRIM_TIME: + return "RADIOTEST_FIRST_TRIM_TIME"; + case CSR_PSKEY_RADIOTEST_SUBSEQUENT_TRIM_TIME: + return "RADIOTEST_SUBSEQUENT_TRIM_TIME"; + case CSR_PSKEY_RADIOTEST_LO_LVL_TRIM_ENABLE: + return "RADIOTEST_LO_LVL_TRIM_ENABLE"; + case CSR_PSKEY_RADIOTEST_DISABLE_MODULATION: + return "RADIOTEST_DISABLE_MODULATION"; + case CSR_PSKEY_RFCOMM_FCON_THRESHOLD: + return "RFCOMM_FCON_THRESHOLD"; + case CSR_PSKEY_RFCOMM_FCOFF_THRESHOLD: + return "RFCOMM_FCOFF_THRESHOLD"; + case CSR_PSKEY_IPV6_STATIC_ADDR: + return "IPV6_STATIC_ADDR"; + case CSR_PSKEY_IPV4_STATIC_ADDR: + return "IPV4_STATIC_ADDR"; + case CSR_PSKEY_IPV6_STATIC_PREFIX_LEN: + return "IPV6_STATIC_PREFIX_LEN"; + case CSR_PSKEY_IPV6_STATIC_ROUTER_ADDR: + return "IPV6_STATIC_ROUTER_ADDR"; + case CSR_PSKEY_IPV4_STATIC_SUBNET_MASK: + return "IPV4_STATIC_SUBNET_MASK"; + case CSR_PSKEY_IPV4_STATIC_ROUTER_ADDR: + return "IPV4_STATIC_ROUTER_ADDR"; + case CSR_PSKEY_MDNS_NAME: + return "MDNS_NAME"; + case CSR_PSKEY_FIXED_PIN: + return "FIXED_PIN"; + case CSR_PSKEY_MDNS_PORT: + return "MDNS_PORT"; + case CSR_PSKEY_MDNS_TTL: + return "MDNS_TTL"; + case CSR_PSKEY_MDNS_IPV4_ADDR: + return "MDNS_IPV4_ADDR"; + case CSR_PSKEY_ARP_CACHE_TIMEOUT: + return "ARP_CACHE_TIMEOUT"; + case CSR_PSKEY_HFP_POWER_TABLE: + return "HFP_POWER_TABLE"; + case CSR_PSKEY_DRAIN_BORE_TIMER_COUNTERS: + return "DRAIN_BORE_TIMER_COUNTERS"; + case CSR_PSKEY_DRAIN_BORE_COUNTERS: + return "DRAIN_BORE_COUNTERS"; + case CSR_PSKEY_LOOP_FILTER_TRIM: + return "LOOP_FILTER_TRIM"; + case CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK: + return "DRAIN_BORE_CURRENT_PEAK"; + case CSR_PSKEY_FORCE_16MHZ_REF_PIO: + return "FORCE_16MHZ_REF_PIO"; + case CSR_PSKEY_CDMA_LO_REF_LIMITS: + return "CDMA_LO_REF_LIMITS"; + case CSR_PSKEY_CDMA_LO_ERROR_LIMITS: + return "CDMA_LO_ERROR_LIMITS"; + case CSR_PSKEY_CLOCK_STARTUP_DELAY: + return "CLOCK_STARTUP_DELAY"; + case CSR_PSKEY_DEEP_SLEEP_CORRECTION_FACTOR: + return "DEEP_SLEEP_CORRECTION_FACTOR"; + case CSR_PSKEY_TEMPERATURE_CALIBRATION: + return "TEMPERATURE_CALIBRATION"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA: + return "TEMPERATURE_VS_DELTA_INTERNAL_PA"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL: + return "TEMPERATURE_VS_DELTA_TX_PRE_LVL"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB: + return "TEMPERATURE_VS_DELTA_TX_BB"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_ANA_FTRIM: + return "TEMPERATURE_VS_DELTA_ANA_FTRIM"; + case CSR_PSKEY_TEST_DELTA_OFFSET: + return "TEST_DELTA_OFFSET"; + case CSR_PSKEY_RX_DYNAMIC_LVL_OFFSET: + return "RX_DYNAMIC_LVL_OFFSET"; + case CSR_PSKEY_TEST_FORCE_OFFSET: + return "TEST_FORCE_OFFSET"; + case CSR_PSKEY_RF_TRAP_BAD_DIVISION_RATIOS: + return "RF_TRAP_BAD_DIVISION_RATIOS"; + case CSR_PSKEY_RADIOTEST_CDMA_LO_REF_LIMITS: + return "RADIOTEST_CDMA_LO_REF_LIMITS"; + case CSR_PSKEY_INITIAL_BOOTMODE: + return "INITIAL_BOOTMODE"; + case CSR_PSKEY_ONCHIP_HCI_CLIENT: + return "ONCHIP_HCI_CLIENT"; + case CSR_PSKEY_RX_ATTEN_BACKOFF: + return "RX_ATTEN_BACKOFF"; + case CSR_PSKEY_RX_ATTEN_UPDATE_RATE: + return "RX_ATTEN_UPDATE_RATE"; + case CSR_PSKEY_SYNTH_TXRX_THRESHOLDS: + return "SYNTH_TXRX_THRESHOLDS"; + case CSR_PSKEY_MIN_WAIT_STATES: + return "MIN_WAIT_STATES"; + case CSR_PSKEY_RSSI_CORRECTION: + return "RSSI_CORRECTION"; + case CSR_PSKEY_SCHED_THROTTLE_TIMEOUT: + return "SCHED_THROTTLE_TIMEOUT"; + case CSR_PSKEY_DEEP_SLEEP_USE_EXTERNAL_CLOCK: + return "DEEP_SLEEP_USE_EXTERNAL_CLOCK"; + case CSR_PSKEY_TRIM_RADIO_FILTERS: + return "TRIM_RADIO_FILTERS"; + case CSR_PSKEY_TRANSMIT_OFFSET: + return "TRANSMIT_OFFSET"; + case CSR_PSKEY_USB_VM_CONTROL: + return "USB_VM_CONTROL"; + case CSR_PSKEY_MR_ANA_RX_FTRIM: + return "MR_ANA_RX_FTRIM"; + case CSR_PSKEY_I2C_CONFIG: + return "I2C_CONFIG"; + case CSR_PSKEY_MR_TX_FILTER_CONFIG: + return "MR_TX_FILTER_CONFIG"; + case CSR_PSKEY_MR_TX_CONFIG2: + return "MR_TX_CONFIG2"; + case CSR_PSKEY_USB_DONT_RESET_BOOTMODE_ON_HOST_RESET: + return "USB_DONT_RESET_BOOTMODE_ON_HOST_RESET"; + case CSR_PSKEY_LC_USE_THROTTLING: + return "LC_USE_THROTTLING"; + case CSR_PSKEY_CHARGER_TRIM: + return "CHARGER_TRIM"; + case CSR_PSKEY_CLOCK_REQUEST_FEATURES: + return "CLOCK_REQUEST_FEATURES"; + case CSR_PSKEY_TRANSMIT_OFFSET_CLASS1: + return "TRANSMIT_OFFSET_CLASS1"; + case CSR_PSKEY_TX_AVOID_PA_CLASS1_PIO: + return "TX_AVOID_PA_CLASS1_PIO"; + case CSR_PSKEY_MR_PIO_CONFIG: + return "MR_PIO_CONFIG"; + case CSR_PSKEY_UART_CONFIG2: + return "UART_CONFIG2"; + case CSR_PSKEY_CLASS1_IQ_LVL: + return "CLASS1_IQ_LVL"; + case CSR_PSKEY_CLASS1_TX_CONFIG2: + return "CLASS1_TX_CONFIG2"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_INTERNAL_PA_CLASS1: + return "TEMPERATURE_VS_DELTA_INTERNAL_PA_CLASS1"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_EXTERNAL_PA_CLASS1: + return "TEMPERATURE_VS_DELTA_EXTERNAL_PA_CLASS1"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_PRE_LVL_MR: + return "TEMPERATURE_VS_DELTA_TX_PRE_LVL_MR"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_HEADER: + return "TEMPERATURE_VS_DELTA_TX_BB_MR_HEADER"; + case CSR_PSKEY_TEMPERATURE_VS_DELTA_TX_BB_MR_PAYLOAD: + return "TEMPERATURE_VS_DELTA_TX_BB_MR_PAYLOAD"; + case CSR_PSKEY_RX_MR_EQ_TAPS: + return "RX_MR_EQ_TAPS"; + case CSR_PSKEY_TX_PRE_LVL_CLASS1: + return "TX_PRE_LVL_CLASS1"; + case CSR_PSKEY_ANALOGUE_ATTENUATOR: + return "ANALOGUE_ATTENUATOR"; + case CSR_PSKEY_MR_RX_FILTER_TRIM: + return "MR_RX_FILTER_TRIM"; + case CSR_PSKEY_MR_RX_FILTER_RESPONSE: + return "MR_RX_FILTER_RESPONSE"; + case CSR_PSKEY_PIO_WAKEUP_STATE: + return "PIO_WAKEUP_STATE"; + case CSR_PSKEY_MR_TX_IF_ATTEN_OFF_TEMP: + return "MR_TX_IF_ATTEN_OFF_TEMP"; + case CSR_PSKEY_LO_DIV_LATCH_BYPASS: + return "LO_DIV_LATCH_BYPASS"; + case CSR_PSKEY_LO_VCO_STANDBY: + return "LO_VCO_STANDBY"; + case CSR_PSKEY_SLOW_CLOCK_FILTER_SHIFT: + return "SLOW_CLOCK_FILTER_SHIFT"; + case CSR_PSKEY_SLOW_CLOCK_FILTER_DIVIDER: + return "SLOW_CLOCK_FILTER_DIVIDER"; + case CSR_PSKEY_USB_ATTRIBUTES_POWER: + return "USB_ATTRIBUTES_POWER"; + case CSR_PSKEY_USB_ATTRIBUTES_WAKEUP: + return "USB_ATTRIBUTES_WAKEUP"; + case CSR_PSKEY_DFU_ATTRIBUTES_MANIFESTATION_TOLERANT: + return "DFU_ATTRIBUTES_MANIFESTATION_TOLERANT"; + case CSR_PSKEY_DFU_ATTRIBUTES_CAN_UPLOAD: + return "DFU_ATTRIBUTES_CAN_UPLOAD"; + case CSR_PSKEY_DFU_ATTRIBUTES_CAN_DOWNLOAD: + return "DFU_ATTRIBUTES_CAN_DOWNLOAD"; + case CSR_PSKEY_UART_CONFIG_STOP_BITS: + return "UART_CONFIG_STOP_BITS"; + case CSR_PSKEY_UART_CONFIG_PARITY_BIT: + return "UART_CONFIG_PARITY_BIT"; + case CSR_PSKEY_UART_CONFIG_FLOW_CTRL_EN: + return "UART_CONFIG_FLOW_CTRL_EN"; + case CSR_PSKEY_UART_CONFIG_RTS_AUTO_EN: + return "UART_CONFIG_RTS_AUTO_EN"; + case CSR_PSKEY_UART_CONFIG_RTS: + return "UART_CONFIG_RTS"; + case CSR_PSKEY_UART_CONFIG_TX_ZERO_EN: + return "UART_CONFIG_TX_ZERO_EN"; + case CSR_PSKEY_UART_CONFIG_NON_BCSP_EN: + return "UART_CONFIG_NON_BCSP_EN"; + case CSR_PSKEY_UART_CONFIG_RX_RATE_DELAY: + return "UART_CONFIG_RX_RATE_DELAY"; + case CSR_PSKEY_UART_SEQ_TIMEOUT: + return "UART_SEQ_TIMEOUT"; + case CSR_PSKEY_UART_SEQ_RETRIES: + return "UART_SEQ_RETRIES"; + case CSR_PSKEY_UART_SEQ_WINSIZE: + return "UART_SEQ_WINSIZE"; + case CSR_PSKEY_UART_USE_CRC_ON_TX: + return "UART_USE_CRC_ON_TX"; + case CSR_PSKEY_UART_HOST_INITIAL_STATE: + return "UART_HOST_INITIAL_STATE"; + case CSR_PSKEY_UART_HOST_ATTENTION_SPAN: + return "UART_HOST_ATTENTION_SPAN"; + case CSR_PSKEY_UART_HOST_WAKEUP_TIME: + return "UART_HOST_WAKEUP_TIME"; + case CSR_PSKEY_UART_HOST_WAKEUP_WAIT: + return "UART_HOST_WAKEUP_WAIT"; + case CSR_PSKEY_BCSP_LM_MODE: + return "BCSP_LM_MODE"; + case CSR_PSKEY_BCSP_LM_SYNC_RETRIES: + return "BCSP_LM_SYNC_RETRIES"; + case CSR_PSKEY_BCSP_LM_TSHY: + return "BCSP_LM_TSHY"; + case CSR_PSKEY_UART_DFU_CONFIG_STOP_BITS: + return "UART_DFU_CONFIG_STOP_BITS"; + case CSR_PSKEY_UART_DFU_CONFIG_PARITY_BIT: + return "UART_DFU_CONFIG_PARITY_BIT"; + case CSR_PSKEY_UART_DFU_CONFIG_FLOW_CTRL_EN: + return "UART_DFU_CONFIG_FLOW_CTRL_EN"; + case CSR_PSKEY_UART_DFU_CONFIG_RTS_AUTO_EN: + return "UART_DFU_CONFIG_RTS_AUTO_EN"; + case CSR_PSKEY_UART_DFU_CONFIG_RTS: + return "UART_DFU_CONFIG_RTS"; + case CSR_PSKEY_UART_DFU_CONFIG_TX_ZERO_EN: + return "UART_DFU_CONFIG_TX_ZERO_EN"; + case CSR_PSKEY_UART_DFU_CONFIG_NON_BCSP_EN: + return "UART_DFU_CONFIG_NON_BCSP_EN"; + case CSR_PSKEY_UART_DFU_CONFIG_RX_RATE_DELAY: + return "UART_DFU_CONFIG_RX_RATE_DELAY"; + case CSR_PSKEY_AMUX_AIO0: + return "AMUX_AIO0"; + case CSR_PSKEY_AMUX_AIO1: + return "AMUX_AIO1"; + case CSR_PSKEY_AMUX_AIO2: + return "AMUX_AIO2"; + case CSR_PSKEY_AMUX_AIO3: + return "AMUX_AIO3"; + case CSR_PSKEY_LOCAL_NAME_SIMPLIFIED: + return "LOCAL_NAME_SIMPLIFIED"; + case CSR_PSKEY_EXTENDED_STUB: + return "EXTENDED_STUB"; + default: + return "UNKNOWN"; + } +} + int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid) { unsigned char cmd[] = { 0x02, 0x00, 0x09, 0x00, diff --git a/tools/csr.h b/tools/csr.h index aead1f17..e46b90ca 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -499,6 +499,7 @@ char *csr_builddeftostr(uint16_t def); char *csr_buildidtostr(uint16_t id); char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); +char *csr_pskeytoval(uint16_t pskey); int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); -- cgit From 0a403feb8c67b6c36c92711c6880598345ca78f2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Oct 2005 09:43:01 +0000 Subject: Add support for reading all available PS keys --- tools/pskey.c | 163 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 125 insertions(+), 38 deletions(-) diff --git a/tools/pskey.c b/tools/pskey.c index bf044dd3..b1f6a319 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -48,8 +48,107 @@ #define CSR_TYPE_UINT16 3 #define CSR_TYPE_UINT32 4 +enum { + NONE = 0, + LIST, + READ, +}; + static int transient = 0; +static int cmd_list(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t length, seqnum = 0x0000, pskey = 0x0000; + int err; + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, sizeof(array)); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, sizeof(array)); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + + printf("0x%04x - %s (%d bytes)\n", pskey, + csr_pskeytostr(pskey), length * 2); + } + + return 0; +} + +static int cmd_read(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t length, seqnum = 0x0000, pskey = 0x0000; + char *str, val[7]; + int i, err; + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, 8); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + continue; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, + 0x0000, array, length * 2); + if (err < 0) + continue; + + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", + str ? str : val, pskey); + for (i = 0; i < length; i++) + printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf("\n"); + } + + return 0; +} + static int pskey_size(uint16_t pskey) { switch (pskey) { @@ -215,7 +314,8 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" "\tpskey [-i ] [-r] [-t] [value]\n" - "\tpskey [-i ] --list\n\n"); + "\tpskey [-i ] --list\n" + "\tpskey [-i ] --read\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -233,7 +333,8 @@ static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, { "transient", 0, 0, 't' }, - { "list", 0, 0, 'l' }, + { "list", 0, 0, 'L' }, + { "read", 0, 0, 'R' }, { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -242,9 +343,9 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0, list = 0, reset = 0; + int i, err, dd, opt, dev = 0, reset = 0, mode = NONE; - while ((opt=getopt_long(argc, argv, "+i:rtlh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rtLRh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -262,8 +363,12 @@ int main(int argc, char *argv[]) transient = 1; break; - case 'l': - list = 1; + case 'L': + mode = LIST; + break; + + case 'R': + mode = READ; break; case 'h': @@ -277,7 +382,7 @@ int main(int argc, char *argv[]) argv += optind; optind = 0; - if (!list && argc < 1) { + if (mode == NONE && argc < 1) { usage(); exit(1); } @@ -309,42 +414,24 @@ int main(int argc, char *argv[]) exit(1); } - if (list) { - uint8_t array[8]; - uint16_t length, seqnum = 0x0000, pskey = 0x0000; - int err; - - while (1) { - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, sizeof(array)); - if (err < 0) - break; - - pskey = array[4] + (array[5] << 8); - if (pskey == 0x0000) - break; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, sizeof(array)); - if (err < 0) - continue; + if (mode > 0) { + switch (mode) { + case LIST: + err = cmd_list(dd, argc, argv); + break; - length = array[2] + (array[3] << 8); + case READ: + err = cmd_read(dd, argc, argv); + break; - printf("0x%04x - %s (%d bytes)\n", pskey, - csr_pskeytostr(pskey), length * 2); + default: + usage(); + err = -1; + break; } hci_close_dev(dd); - exit(0); + exit(err < 0 ? 1 : 0); } for (i = 0; storage[i].pskey; i++) { -- cgit From fdf8c10513c0f4d3eab0dc0c75c878825f35f979 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Oct 2005 21:51:04 +0000 Subject: Add support for the PSR file format --- tools/csr.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr.h | 5 ++ 2 files changed, 181 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 765a6d90..f02540a6 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -32,7 +32,13 @@ #include #include +#include +#include +#include +#include #include +#include +#include #include #include @@ -41,6 +47,15 @@ #include "csr.h" +struct psr_data { + uint16_t pskey; + uint8_t *value; + uint8_t size; + struct psr_data *next; +}; + +static struct psr_data *head = NULL, *tail = NULL; + static struct { uint16_t id; char *str; @@ -2523,3 +2538,164 @@ int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 4); } + +int psr_put(uint16_t pskey, uint8_t *value, uint16_t size) +{ + struct psr_data *item; + + item = malloc(sizeof(*item)); + if (!item) + return -ENOMEM; + + item->pskey = pskey; + + if (size > 0) { + item->value = malloc(size); + if (!item->value) { + free(item); + return -ENOMEM; + } + + memcpy(item->value, value, size); + item->size = size; + } else { + item->value = NULL; + item->size = 0; + } + + item->next = NULL; + + if (!head) + head = item; + else + tail->next = item; + + tail = item; + + return 0; +} + +int psr_get(uint16_t *pskey, uint8_t *value, uint16_t *size) +{ + struct psr_data *item = head; + + if (!head) + return -ENOENT; + + *pskey = item->pskey; + + if (item->value) { + if (value && item->size > 0) + memcpy(value, item->value, item->size); + free(item->value); + *size = item->size; + } else + *size = 0; + + if (head == tail) + tail = NULL; + + head = head->next; + free(item); + + return 0; +} + +static int parse_line(char *str) +{ + uint8_t array[256]; + uint16_t value, pskey, length = 0; + char *tmp, *end; + + pskey = strtol(str + 1, NULL, 16); + tmp = strstr(str, "=") + 1; + + while (1) { + value = strtol(tmp, &end, 16); + if (value == 0 && tmp == end) + break; + + array[length++] = value & 0xff; + array[length++] = value >> 8; + + tmp = end + 1; + } + + return psr_put(pskey, array, length); +} + +int psr_read(const char *filename) +{ + struct stat st; + char *str, *map, *off, *end; + int fd, err = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return fd; + + if (fstat(fd, &st) < 0) { + err = -errno; + goto close; + } + + map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) { + err = -errno; + goto close; + } + + off = map; + + while (1) { + end = strpbrk(off, "\r\n"); + if (!end) + break; + + str = malloc(end - off + 1); + if (!str) + break; + + memset(str, 0, end - off + 1); + strncpy(str, off, end - off); + if (*str == '&') + parse_line(str); + + free(str); + off = end + 1; + } + + munmap(map, st.st_size); + +close: + close(fd); + + return err; +} + +int psr_print(void) +{ + uint8_t array[256]; + uint16_t pskey, length; + char *str, val[7]; + int i; + + while (1) { + if (psr_get(&pskey, array, &length) < 0) + break; + + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", + str ? str : val, pskey); + for (i = 0; i < length / 2; i++) + printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf("\n"); + } + + return 0; +} diff --git a/tools/csr.h b/tools/csr.h index e46b90ca..fe46f4b4 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -511,3 +511,8 @@ int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stor int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value); int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value); + +int psr_put(uint16_t pskey, uint8_t *value, uint16_t size); +int psr_get(uint16_t *pskey, uint8_t *value, uint16_t *size); +int psr_read(const char *filename); +int psr_print(void); -- cgit From 5b06ecd76bbb760cdee2e7b9e36cc3202db2e5db Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 26 Oct 2005 22:40:59 +0000 Subject: Update bootstrap stuff --- bootstrap | 9 +++++++-- bootstrap-configure | 13 +++++++++++++ compile | 7 ------- 3 files changed, 20 insertions(+), 9 deletions(-) create mode 100755 bootstrap-configure delete mode 100755 compile diff --git a/bootstrap b/bootstrap index 199053bb..c838d5e2 100755 --- a/bootstrap +++ b/bootstrap @@ -1,2 +1,7 @@ -#! /bin/sh -aclocal && autoheader && libtoolize --copy --force && automake --add-missing --copy --ignore-deps && autoconf +#!/bin/sh + +aclocal && \ + autoheader && \ + libtoolize --copy --force && \ + automake --add-missing --copy && \ + autoconf diff --git a/bootstrap-configure b/bootstrap-configure new file mode 100755 index 00000000..76e6fce3 --- /dev/null +++ b/bootstrap-configure @@ -0,0 +1,13 @@ +#!/bin/sh + +./bootstrap && \ + ./configure --enable-maintainer-mode \ + --enable-debug \ + --prefix=/usr \ + --mandir=/usr/share/man \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --enable-all \ + --disable-pcmcia \ + --disable-initscripts \ + --disable-bluepin diff --git a/compile b/compile deleted file mode 100755 index 28d79b54..00000000 --- a/compile +++ /dev/null @@ -1,7 +0,0 @@ -#! /bin/sh -./configure --enable-maintainer-mode --enable-all --disable-pcmcia --disable-initscripts --disable-bluepin && make && \ - sudo cp hcid/hcid /usr/sbin && \ - sudo cp sdpd/sdpd /usr/sbin && \ - sudo cp tools/hciconfig /usr/sbin && \ - sudo cp tools/hcitool /usr/bin && \ - sudo cp tools/sdptool /usr/bin -- cgit From 7a58f1b38a86d30477048e84d979d627ebfec10b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Oct 2005 00:28:36 +0000 Subject: Add initial D-Bus device configuration support --- hcid/dbus.c | 133 ++++++++++++++++++++++++++++++++---------------------------- hcid/hcid.h | 2 + hcid/main.c | 13 +++++- 3 files changed, 85 insertions(+), 63 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index ce6f4e70..672e1263 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -52,7 +52,7 @@ #include "dbus.h" static DBusConnection *connection; -static int num_adapters = 0; +static int up_adapters = 0; #define TIMEOUT (30 * 1000) /* 30 seconds */ #define BLUETOOTH_DEVICE_NAME_LEN (18) @@ -359,6 +359,39 @@ static void free_pin_req(void *req) free(req); } +static gboolean register_dbus_path(char *path, uint16_t id) +{ + struct hci_dbus_data *data; + syslog(LOG_INFO,"Registering DBUS Path: %s", path); + data = malloc(sizeof(struct hci_dbus_data)); + if (data == NULL) { + syslog(LOG_ERR,"Failed to alloc memory to DBUS path register data (%s)", path); + return FALSE; + } + data->id = id; + + if (!dbus_connection_register_object_path(connection, path, &obj_vtable, data)) { + syslog(LOG_ERR,"DBUS failed to register %s object", path); + free(data); + return FALSE; + } + return TRUE; +} + +static gboolean unregister_dbus_path(char *path) +{ + void *data; + syslog(LOG_INFO,"Unregistering DBUS Path: %s", path); + if (dbus_connection_get_object_path_data(connection, path, &data) && data) + free(data); + + if (!dbus_connection_unregister_object_path (connection, path)) { + syslog(LOG_ERR,"DBUS failed to unregister %s object", path); + return FALSE; + } + return TRUE; +} + void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) { DBusMessage *message; @@ -739,7 +772,7 @@ gboolean hcid_dbus_init(void) data->id = DEVICE_PATH_ID; - if (!dbus_connection_register_object_path(connection, DEVICE_PATH, + if (!dbus_connection_register_fallback(connection, DEVICE_PATH, &obj_vtable, data)) { syslog(LOG_ERR, "Can't register %s object", DEVICE_PATH); return FALSE; @@ -855,7 +888,32 @@ void hcid_dbus_exit(void) } } -gboolean hcid_dbus_register_device(uint16_t id) +gboolean hcid_dbus_register_device(uint16_t id) +{ + char path[MAX_PATH_LENGTH+1]; + char dev[BLUETOOTH_DEVICE_NAME_LEN+1]; + const char *pdev = dev; + + snprintf(dev, BLUETOOTH_DEVICE_NAME_LEN, HCI_DEVICE_NAME "%d", id); + snprintf(path, MAX_PATH_LENGTH, "%s/%s", DEVICE_PATH, pdev); + + /* register the default path*/ + return register_dbus_path(path, id); +} + +gboolean hcid_dbus_unregister_device(uint16_t id) +{ + char dev[BLUETOOTH_DEVICE_NAME_LEN+1]; + char path[MAX_PATH_LENGTH+1]; + const char *pdev = dev; + + snprintf(dev, BLUETOOTH_DEVICE_NAME_LEN, HCI_DEVICE_NAME "%d", id); + snprintf(path, MAX_PATH_LENGTH, "%s/%s", DEVICE_PATH, pdev); + + return unregister_dbus_path(path); +} + +gboolean hcid_dbus_register_manager(uint16_t id) { char dev[BLUETOOTH_DEVICE_NAME_LEN]; struct profile_obj_path_data *ptr = obj_path_table; @@ -873,7 +931,7 @@ gboolean hcid_dbus_register_device(uint16_t id) } if (!ret) - num_adapters++; + up_adapters++; message = dbus_message_new_signal(BLUEZ_HCI_PATH, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_DEV_ADDED); @@ -883,7 +941,7 @@ gboolean hcid_dbus_register_device(uint16_t id) goto failed; } - sprintf(dev, "hci%d", id); + sprintf(dev, HCI_DEVICE_NAME "%d", id); dbus_message_iter_init_append(message, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING ,&pdev); @@ -904,7 +962,7 @@ failed: return TRUE; } -gboolean hcid_dbus_unregister_device(uint16_t id) +gboolean hcid_dbus_unregister_manager(uint16_t id) { char dev[BLUETOOTH_DEVICE_NAME_LEN]; struct profile_obj_path_data *ptr = obj_path_table; @@ -917,8 +975,8 @@ gboolean hcid_dbus_unregister_device(uint16_t id) return FALSE; for (; ptr->name; ptr++) { - dft_unreg = (num_adapters > 1) ? 0 : 1; - num_adapters--; + dft_unreg = (up_adapters > 1) ? 0 : 1; + up_adapters--; ptr->unreg_func(connection, dft_unreg, id); if (dft_unreg ) @@ -933,7 +991,7 @@ gboolean hcid_dbus_unregister_device(uint16_t id) goto failed; } - sprintf(dev, "hci%d", id); + sprintf(dev, HCI_DEVICE_NAME "%d", id); dbus_message_iter_init_append(message, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING ,&pdev); @@ -965,39 +1023,17 @@ failed: */ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) { - struct hci_dbus_data *data; char path[MAX_PATH_LENGTH]; /* register the default path*/ if (!dft_reg) { - sprintf(path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); - - data = malloc(sizeof(struct hci_dbus_data)); - if (data == NULL) - return -1; - - data->id = DEFAULT_DEVICE_PATH_ID; - - if (!dbus_connection_register_object_path(conn, path, &obj_vtable, data)) { - syslog(LOG_ERR,"DBUS failed to register %s object", path); - /* ignore, the default path was already registered */ - } + register_dbus_path(path, DEFAULT_DEVICE_PATH_ID); } - data = malloc(sizeof(struct hci_dbus_data)); - if (data == NULL) - return -1; - - data->id = id; - /* register the default path*/ sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); - - if (!dbus_connection_register_object_path(conn, path, &obj_vtable, data)) { - syslog(LOG_ERR,"DBUS failed to register %s object", path); - /* ignore, the path was already registered */ - } + register_dbus_path(path, id); return 0; } @@ -1016,39 +1052,14 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t { int ret = 0; char path[MAX_PATH_LENGTH]; - char dft_path[MAX_PATH_LENGTH]; - void *data = NULL; if (unreg_dft) { - - sprintf(dft_path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); - - if (!dbus_connection_unregister_object_path (connection, dft_path)) { - syslog(LOG_ERR,"DBUS failed to unregister %s object", dft_path); - ret = -1; - } else { - if (dbus_connection_get_object_path_data(conn, dft_path, &data)) { - if (data) { - free(data); - data = NULL; - } - } - } + sprintf(path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); + unregister_dbus_path(path); } sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); - - if (!dbus_connection_unregister_object_path (connection, path)) { - syslog(LOG_ERR,"DBUS failed to unregister %s object", path); - ret = -1; - } else { - if (dbus_connection_get_object_path_data(conn, path, &data)) { - if (data) { - free(data); - data = NULL; - } - } - } + unregister_dbus_path(path); return ret; } diff --git a/hcid/hcid.h b/hcid/hcid.h index 048a0aed..0e5a673e 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -126,7 +126,9 @@ void toggle_pairing(int enable); gboolean hcid_dbus_init(void); void hcid_dbus_exit(void); gboolean hcid_dbus_register_device(uint16_t id); +gboolean hcid_dbus_register_manager(uint16_t id); gboolean hcid_dbus_unregister_device(uint16_t id); +gboolean hcid_dbus_unregister_manager(uint16_t id); void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); void hcid_dbus_inquiry_start(bdaddr_t *local); void hcid_dbus_inquiry_complete(bdaddr_t *local); diff --git a/hcid/main.c b/hcid/main.c index b6891ee4..d3d285da 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -377,6 +377,9 @@ static void init_all_devices(int ctl) start_security_manager(dr->dev_id); #ifdef ENABLE_DBUS + if (hci_test_bit(HCI_UP, &dr->dev_opt)) + hcid_dbus_register_manager(dr->dev_id); + hcid_dbus_register_device(dr->dev_id); #endif } @@ -430,10 +433,16 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si) syslog(LOG_INFO, "HCI dev %d registered", sd->dev_id); if (hcid.auto_init) init_device(sd->dev_id); +#ifdef ENABLE_DBUS + hcid_dbus_register_device(sd->dev_id); +#endif break; case HCI_DEV_UNREG: syslog(LOG_INFO, "HCI dev %d unregistered", sd->dev_id); +#ifdef ENABLE_DBUS + hcid_dbus_unregister_device(sd->dev_id); +#endif break; case HCI_DEV_UP: @@ -443,7 +452,7 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si) if (hcid.security) start_security_manager(sd->dev_id); #ifdef ENABLE_DBUS - hcid_dbus_register_device(sd->dev_id); + hcid_dbus_register_manager(sd->dev_id); #endif break; @@ -452,7 +461,7 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si) if (hcid.security) stop_security_manager(sd->dev_id); #ifdef ENABLE_DBUS - hcid_dbus_unregister_device(sd->dev_id); + hcid_dbus_unregister_manager(sd->dev_id); #endif break; } -- cgit From 5b697fd220b762a6b6a2a62462d62910dffaeccd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Oct 2005 00:33:33 +0000 Subject: Cleanup the socket and device descriptor variable names --- hcid/dbus.c | 75 ++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 672e1263..b7271f0d 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -1215,11 +1215,12 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) uint8_t length; uint8_t max_period; uint8_t min_period; - int sock = -1; + int dd = -1; int dev_id = -1; if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - if ((dev_id = hci_get_route(NULL)) < 0) { + dev_id = hci_get_route(NULL); + if (dev_id < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; @@ -1228,8 +1229,8 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) } else dev_id = dbus_data->id; - sock = hci_open_dev(dev_id); - if (sock < 0) { + dd = hci_open_dev(dev_id); + if (dd < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; @@ -1260,14 +1261,14 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) inq_mode.mode = 1; //INQUIRY_WITH_RSSI; - if (hci_send_cmd(sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, + if (hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, WRITE_INQUIRY_MODE_CP_SIZE, &inq_mode) < 0) { syslog(LOG_ERR, "Can't set inquiry mode:%s.", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } - if (hci_send_cmd(sock, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, + if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, PERIODIC_INQUIRY_CP_SIZE, &inq_param) < 0) { syslog(LOG_ERR, "Can't send HCI commands:%s.", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); @@ -1281,8 +1282,8 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) } failed: - if (sock > 0) - close(sock); + if (dd >= 0) + close(dd); return reply; } @@ -1292,11 +1293,12 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) DBusMessageIter iter; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; - int sock = -1; + int dd = -1; int dev_id = -1; if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - if ((dev_id = hci_get_route(NULL)) < 0) { + dev_id = hci_get_route(NULL); + if (dev_id < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; @@ -1304,13 +1306,14 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) } else dev_id = dbus_data->id; - if ((sock = hci_open_dev(dev_id)) < 0) { + dd = hci_open_dev(dev_id); + if (dd < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } - if (hci_send_cmd(sock, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY, 0 , NULL) < 0) { + if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY, 0 , NULL) < 0) { syslog(LOG_ERR, "Send hci command failed."); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); } else { @@ -1322,8 +1325,8 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) } failed: - if (sock >= 0) - close(sock); + if (dd >= 0) + close(dd); return reply; } @@ -1447,7 +1450,7 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) bdaddr_t bdaddr; uint8_t role; int dev_id = -1; - int sock = -1; + int dd = -1; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &str_bdaddr); @@ -1470,14 +1473,14 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) goto failed; } - sock = hci_open_dev(dev_id); - if (sock < 0) { + dd = hci_open_dev(dev_id); + if (dd < 0) { syslog(LOG_ERR, "HCI device open failed\n"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } - if (hci_switch_role(sock, &bdaddr, role, 10000) < 0) { + if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) { syslog(LOG_ERR, "Switch role request failed\n"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); } else { @@ -1511,7 +1514,8 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) str2ba(str_bdaddr, &bdaddr); if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - if ((dev_id = hci_get_route(&bdaddr)) < 0) { + dev_id = hci_get_route(&bdaddr); + if (dev_id < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; @@ -1566,12 +1570,13 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) const char array_sig[] = HCI_CONN_INFO_STRUCT_SIGNATURE; const char *paddr = addr; struct hci_dbus_data *dbus_data = data; - int i; int dev_id = -1; int sk = -1; + int i; if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - if ((dev_id = hci_get_route(NULL)) < 0) { + dev_id = hci_get_route(NULL); + if (dev_id < 0) { syslog(LOG_ERR, "Bluetooth device is not available"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; @@ -1642,7 +1647,7 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) struct hci_conn_info_req *cr = NULL; bdaddr_t bdaddr; int dev_id = -1; - int sock = -1; + int dd = -1; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &str_bdaddr); @@ -1660,8 +1665,8 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) goto failed; } - sock = hci_open_dev(dev_id); - if (sock < 0) { + dd = hci_open_dev(dev_id); + if (dd < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } @@ -1675,7 +1680,7 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) bacpy(&cr->bdaddr, &bdaddr); cr->type = ACL_LINK; - if (ioctl(sock, HCIGETCONNINFO, (unsigned long) cr) < 0) { + if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1692,15 +1697,15 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) rq.rlen = EVT_CMD_STATUS_SIZE; rq.event = EVT_CMD_STATUS; - if (hci_send_req(sock, &rq, 25000) < 0) { + if (hci_send_req(dd, &rq, 25000) < 0) { syslog(LOG_ERR, "Unable to send authentication request: %s", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } failed: - if (sock >= 0) - close(sock); + if (dd >= 0) + close(dd); if (cr) free(cr); @@ -1724,8 +1729,8 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) struct hci_dev_list_req *dl = NULL; struct hci_dev_req *dr = NULL; struct hci_dev_info di; + int sk = -1; int i; - int sock = -1; char aname[BLUETOOTH_DEVICE_NAME_LEN]; char aaddr[BLUETOOTH_DEVICE_ADDR_LEN]; @@ -1734,8 +1739,8 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) const char array_sig[] = HCI_DEVICE_STRUCT_SIGNATURE; /* Create and bind HCI socket */ - sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (sock < 0) { + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) { syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; @@ -1751,7 +1756,7 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(sock, HCIGETDEVLIST, dl) < 0) { + if (ioctl(sk, HCIGETDEVLIST, dl) < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1769,7 +1774,7 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) memset(&di, 0 , sizeof(struct hci_dev_info)); di.dev_id = dr->dev_id; - if (ioctl(sock, HCIGETDEVINFO, &di) < 0) + if (ioctl(sk, HCIGETDEVINFO, &di) < 0) continue; strcpy(aname, di.name); @@ -1787,8 +1792,8 @@ static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) dbus_message_iter_close_container(&iter, &array_iter); failed: - if (sock >= 0) - close(sock); + if (sk >= 0) + close(sk); if (dl) free(dl); -- cgit From 11daf0ac507966ec3d29d3369a8a9be9ea3d1e90 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Oct 2005 17:08:13 +0000 Subject: Send signal for authentication complete events --- hcid/dbus.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- hcid/dbus.h | 1 + hcid/hcid.h | 2 ++ hcid/security.c | 16 ++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index b7271f0d..8c324bcd 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -668,6 +668,51 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) { } +void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status) +{ + DBusMessage *message = NULL; + char *local_addr, *peer_addr; + bdaddr_t tmp; + char path[MAX_PATH_LENGTH]; + int id; + + baswap(&tmp, local); local_addr = batostr(&tmp); + baswap(&tmp, peer); peer_addr = batostr(&tmp); + + id = hci_devid(local_addr); + if (id < 0) { + syslog(LOG_ERR, "No matching device id for %s", local_addr); + goto failed; + } + + snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + + message = dbus_message_new_signal(path, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_AUTH_COMPLETE); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); + goto failed; + } + + dbus_message_append_args(message, + DBUS_TYPE_STRING, &peer_addr, + DBUS_TYPE_BYTE, &status, + DBUS_TYPE_INVALID); + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS remote name message"); + goto failed; + } + + dbus_connection_flush(connection); + +failed: + if (message) + dbus_message_unref(message); + + bt_free(local_addr); + bt_free(peer_addr); +} + gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data) { DBusWatch *watch = (DBusWatch *) data; @@ -1697,7 +1742,7 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) rq.rlen = EVT_CMD_STATUS_SIZE; rq.event = EVT_CMD_STATUS; - if (hci_send_req(dd, &rq, 25000) < 0) { + if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to send authentication request: %s", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; diff --git a/hcid/dbus.h b/hcid/dbus.h index 0e18aea3..45ead04d 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -96,6 +96,7 @@ #define BLUEZ_HCI_INQ_RESULT "InquiryResult" #define BLUEZ_HCI_REMOTE_NAME "RemoteName" #define BLUEZ_HCI_REMOTE_NAME_FAILED "RemoteNameFailed" +#define BLUEZ_HCI_AUTH_COMPLETE "AuthenticationComplete" //HCI signals sent in the BLUEZ_HCI_PATH #define BLUEZ_HCI_DEV_ADDED "DeviceAdded" diff --git a/hcid/hcid.h b/hcid/hcid.h index 0e5a673e..e7dfeb82 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -137,6 +137,7 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name); void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status); void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer); void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason); +void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status); #else static inline void hcid_dbus_inquiry_start(bdaddr_t *local) {} static inline void hcid_dbus_inquiry_complete(bdaddr_t *local) {} @@ -145,6 +146,7 @@ static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char * static inline void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status) {} static inline void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) {} static inline void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) {} +static inline void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status) {} #endif int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); diff --git a/hcid/security.c b/hcid/security.c index 0bcb8d38..1c363906 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -644,6 +644,18 @@ static inline void disconn_complete(int dev, bdaddr_t *sba, void *ptr) hcid_dbus_disconn_complete(sba, &dba, evt->reason); } +static inline void auth_complete(int dev, bdaddr_t *sba, void *ptr) +{ + evt_auth_complete *evt = ptr; + bdaddr_t dba; + + if (get_bdaddr(dev, sba, evt->handle, &dba) < 0) + return; + + hcid_dbus_auth_complete(sba, &dba, evt->status); +} + + static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; @@ -726,6 +738,9 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer case EVT_DISCONN_COMPLETE: disconn_complete(dev, &di->bdaddr, ptr); break; + case EVT_AUTH_COMPLETE: + auth_complete(dev, &di->bdaddr, ptr); + break; } if (hci_test_bit(HCI_SECMGR, &di->flags)) @@ -789,6 +804,7 @@ void start_security_manager(int hdev) hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_CONN_COMPLETE, &flt); hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt); + hci_filter_set_event(EVT_AUTH_COMPLETE, &flt); if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { syslog(LOG_ERR, "Can't set filter on hci%d: %s (%d)", hdev, strerror(errno), errno); -- cgit From c9d47fdc3cc13c9a581701001de8bfdec47002ab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Oct 2005 20:40:02 +0000 Subject: Add build ids for the "marcel" specific firmware --- tools/csr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index f02540a6..41677d22 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -302,6 +302,9 @@ static struct { { 2387, "Unified 21a" }, { 2423, "Unified 21a" }, { 2424, "Unified 21a" }, + { 2526, "Marcel 1 (2005-09-26)" }, + { 2543, "Marcel 2 (2005-09-28)" }, + { 2622, "Marcel 3 (2005-10-27)" }, { 195, "Sniff 1 (2001-11-27)" }, { 220, "Sniff 2 (2002-01-03)" }, { 269, "Sniff 3 (2002-02-22)" }, -- cgit From dd3e8a6ab8938c4d8f62765e7c03a005807fbb64 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Oct 2005 22:49:49 +0000 Subject: Update security filter for Extended Inquiry Response (EIR) --- tools/hcisecfilter.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 5827f143..ce0082e9 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -69,7 +69,7 @@ int main(void) hci_set_bit(EVT_READ_REMOTE_EXT_FEATURES_COMPLETE, event_mask); hci_set_bit(EVT_SYNC_CONN_COMPLETE, event_mask); hci_set_bit(EVT_SYNC_CONN_CHANGED, event_mask); - //hci_set_bit(EVT_EXTENDED_INQUIRY_RESULT, event_mask); + hci_set_bit(EVT_EXTENDED_INQUIRY_RESULT, event_mask); printf("Event mask: { 0x%08x, 0x%08x }\n", event_mask[0], event_mask[1]); @@ -86,7 +86,7 @@ int main(void) hci_set_bit(OCF_READ_CLOCK_OFFSET, ocf_mask); hci_set_bit(OCF_READ_LMP_HANDLE, ocf_mask); - printf("OGF_LINK_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_LINK_CTL: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_LINK_POLICY */ @@ -95,7 +95,7 @@ int main(void) hci_set_bit(OCF_READ_LINK_POLICY, ocf_mask); hci_set_bit(OCF_READ_DEFAULT_LINK_POLICY, ocf_mask); - printf("OGF_LINK_POLICY: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_LINK_POLICY: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_HOST_CTL */ @@ -124,9 +124,9 @@ int main(void) hci_set_bit(OCF_READ_INQUIRY_MODE, ocf_mask); hci_set_bit(OCF_READ_PAGE_SCAN_TYPE, ocf_mask); hci_set_bit(OCF_READ_AFH_MODE, ocf_mask); - //hci_set_bit(OCF_READ_EXT_INQUIRY_RESPONSE, ocf_mask); + hci_set_bit(OCF_READ_EXT_INQUIRY_RESPONSE, ocf_mask); - printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_HOST_CTL: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_INFO_PARAM */ @@ -139,7 +139,7 @@ int main(void) hci_set_bit(OCF_READ_COUNTRY_CODE, ocf_mask); hci_set_bit(OCF_READ_BD_ADDR, ocf_mask); - printf("OGF_INFO_PARAM: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_INFO_PARAM: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); /* OGF_STATUS_PARAM */ @@ -150,7 +150,7 @@ int main(void) hci_set_bit(OCF_READ_AFH_MAP, ocf_mask); hci_set_bit(OCF_READ_CLOCK, ocf_mask); - printf("OGF_STATUS_PARAM: { 0x%08x, 0x%08x, 0x%04x, 0x%02x }\n", + printf("OGF_STATUS_PARAM: { 0x%08x, 0x%08x, 0x%06x, 0x%02x }\n", ocf_mask[0], ocf_mask[1], ocf_mask[2], ocf_mask[3]); return 0; -- cgit From 14e7b4e9a3c868b3bded7b08488aac89210984a6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 28 Oct 2005 13:55:29 +0000 Subject: Set inquiry mode only when its feature bit is present --- hcid/main.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/hcid/main.c b/hcid/main.c index d3d285da..ca123bb0 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -252,11 +252,25 @@ static void configure_device(int hdev) } /* Set inquiry mode */ - if ((device_opts->flags & (1 << HCID_SET_INQMODE)) && - (di.features[3] & LMP_RSSI_INQ)) { + if ((device_opts->flags & (1 << HCID_SET_INQMODE))) { write_inquiry_mode_cp cp; - cp.mode = device_opts->inqmode; + switch (device_opts->inqmode) { + case 2: + if (di.features[6] & LMP_EXT_INQ) { + cp.mode = 2; + break; + } + case 1: + if (di.features[3] & LMP_RSSI_INQ) { + cp.mode = 1; + break; + } + default: + cp.mode = 0; + break; + } + hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, WRITE_INQUIRY_MODE_CP_SIZE, &cp); } -- cgit From 973d77c73f3f110591e0dc8a57f3efe529aadebd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 18:06:39 +0000 Subject: Use snprintf() and remove unecessary byte parameters --- hcid/dbus.c | 52 ++++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 8c324bcd..e055b0c4 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -886,12 +886,12 @@ void hcid_dbus_exit(void) for (; *fst_level; fst_level++) { ptr1 = *fst_level; - sprintf(snd_parent, "%s/%s", fst_parent, ptr1); + snprintf(snd_parent, sizeof(snd_parent), "%s/%s", fst_parent, ptr1); if (dbus_connection_list_registered(connection, snd_parent, &snd_level)) { if (!(*snd_level)) { - sprintf(path, "%s/%s", MANAGER_PATH, ptr1); + snprintf(path, sizeof(path), "%s/%s", MANAGER_PATH, ptr1); if (dbus_connection_get_object_path_data(connection, path, &data)) { @@ -909,7 +909,7 @@ void hcid_dbus_exit(void) for (; *snd_level; snd_level++) { ptr2 = *snd_level; - sprintf(path, "%s/%s/%s", MANAGER_PATH, ptr1, ptr2); + snprintf(path, sizeof(path), "%s/%s/%s", MANAGER_PATH, ptr1, ptr2); if (dbus_connection_get_object_path_data(connection, path, &data)) { @@ -935,12 +935,12 @@ void hcid_dbus_exit(void) gboolean hcid_dbus_register_device(uint16_t id) { - char path[MAX_PATH_LENGTH+1]; - char dev[BLUETOOTH_DEVICE_NAME_LEN+1]; + char path[MAX_PATH_LENGTH]; + char dev[BLUETOOTH_DEVICE_NAME_LEN]; const char *pdev = dev; - snprintf(dev, BLUETOOTH_DEVICE_NAME_LEN, HCI_DEVICE_NAME "%d", id); - snprintf(path, MAX_PATH_LENGTH, "%s/%s", DEVICE_PATH, pdev); + snprintf(dev, sizeof(dev), HCI_DEVICE_NAME "%d", id); + snprintf(path, sizeof(path), "%s/%s", DEVICE_PATH, pdev); /* register the default path*/ return register_dbus_path(path, id); @@ -948,12 +948,12 @@ gboolean hcid_dbus_register_device(uint16_t id) gboolean hcid_dbus_unregister_device(uint16_t id) { - char dev[BLUETOOTH_DEVICE_NAME_LEN+1]; - char path[MAX_PATH_LENGTH+1]; + char dev[BLUETOOTH_DEVICE_NAME_LEN]; + char path[MAX_PATH_LENGTH]; const char *pdev = dev; - snprintf(dev, BLUETOOTH_DEVICE_NAME_LEN, HCI_DEVICE_NAME "%d", id); - snprintf(path, MAX_PATH_LENGTH, "%s/%s", DEVICE_PATH, pdev); + snprintf(dev, sizeof(dev), HCI_DEVICE_NAME "%d", id); + snprintf(path, sizeof(path), "%s/%s", DEVICE_PATH, pdev); return unregister_dbus_path(path); } @@ -986,7 +986,7 @@ gboolean hcid_dbus_register_manager(uint16_t id) goto failed; } - sprintf(dev, HCI_DEVICE_NAME "%d", id); + snprintf(dev, sizeof(dev), HCI_DEVICE_NAME "%d", id); dbus_message_iter_init_append(message, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING ,&pdev); @@ -1036,7 +1036,7 @@ gboolean hcid_dbus_unregister_manager(uint16_t id) goto failed; } - sprintf(dev, HCI_DEVICE_NAME "%d", id); + snprintf(dev, sizeof(dev), HCI_DEVICE_NAME "%d", id); dbus_message_iter_init_append(message, &iter); dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING ,&pdev); @@ -1072,12 +1072,12 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) /* register the default path*/ if (!dft_reg) { - sprintf(path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); register_dbus_path(path, DEFAULT_DEVICE_PATH_ID); } /* register the default path*/ - sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); register_dbus_path(path, id); return 0; @@ -1099,11 +1099,11 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t char path[MAX_PATH_LENGTH]; if (unreg_dft) { - sprintf(path, "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); unregister_dbus_path(path); } - sprintf(path, "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); unregister_dbus_path(path); return ret; @@ -1318,14 +1318,10 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) syslog(LOG_ERR, "Can't send HCI commands:%s.", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; - } else { - uint8_t result = 0; - /* return TRUE to indicate that operation was completed */ - reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE ,&result); } + reply = dbus_message_new_method_return(msg); + failed: if (dd >= 0) close(dd); @@ -1335,7 +1331,6 @@ failed: static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) { - DBusMessageIter iter; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; int dd = -1; @@ -1361,14 +1356,11 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY, 0 , NULL) < 0) { syslog(LOG_ERR, "Send hci command failed."); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); - } else { - uint8_t result = 0; - /* return TRUE to indicate that operation was completed */ - reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE ,&result); + goto failed; } + reply = dbus_message_new_method_return(msg); + failed: if (dd >= 0) close(dd); -- cgit From 52bd6030faf7f3448beadab2b9388e339de08811 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 19:00:56 +0000 Subject: Set local name for extended inquiry response --- hcid/main.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/hcid/main.c b/hcid/main.c index ca123bb0..8183f42c 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -225,11 +225,29 @@ static void configure_device(int hdev) /* Set device name */ if ((device_opts->flags & (1 << HCID_SET_NAME)) && device_opts->name) { change_local_name_cp cp; + write_ext_inquiry_response_cp ip; + uint8_t len; + memset(cp.name, 0, sizeof(cp.name)); expand_name((char *) cp.name, sizeof(cp.name), device_opts->name, hdev); + ip.fec = 0x00; + memset(ip.data, 0, sizeof(ip.data)); + len = strlen((char *) cp.name); + if (len > 48) { + len = 48; + ip.data[1] = 0x08; + } else + ip.data[1] = 0x09; + ip.data[0] = len + 1; + memcpy(ip.data + 2, cp.name, len); + hci_send_cmd(s, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME, CHANGE_LOCAL_NAME_CP_SIZE, &cp); + + if (di.features[6] & LMP_EXT_INQ) + hci_send_cmd(s, OGF_HOST_CTL, OCF_WRITE_EXT_INQUIRY_RESPONSE, + WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &ip); } /* Set device class */ -- cgit From b5b9479c9afc42666245261d5864f410c59a9ef2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 19:03:41 +0000 Subject: Update support for extended inquiry response --- tools/hciconfig.8 | 4 +-- tools/hciconfig.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 90 insertions(+), 14 deletions(-) diff --git a/tools/hciconfig.8 b/tools/hciconfig.8 index 0547ae3a..96990b06 100644 --- a/tools/hciconfig.8 +++ b/tools/hciconfig.8 @@ -133,11 +133,11 @@ With no prints out the current inquiry mode. Otherwise, sets inquiry mode to .IR mode . .TP -.BI inqdata " [name]" +.BI inqdata " [data]" With no .IR name , prints out the current inquiry data. Otherwise, sets inquiry data to -.IR name . +.IR data . .TP .BI inqtype " [type]" With no diff --git a/tools/hciconfig.c b/tools/hciconfig.c index f85f5272..7267d564 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -434,34 +434,66 @@ static void cmd_features(int ctl, int hdev, char *opt) static void cmd_name(int ctl, int hdev, char *opt) { - int s = hci_open_dev(hdev); + int dd; - if (s < 0) { + dd = hci_open_dev(hdev); + if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } + if (opt) { - if (hci_write_local_name(s, opt, 2000) < 0) { + uint8_t fec = 0, data[240]; + int len, eir = 0; + + if (di.features[6] & LMP_EXT_INQ) { + if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) == 0) + eir = 1; + } + + memset(data, 0, sizeof(data)); + len = strlen(opt); + if (len > 48) { + len = 48; + data[1] = 0x08; + } else + data[1] = 0x09; + data[0] = len + 1; + memcpy(data + 2, opt, len); + + if (hci_write_local_name(dd, opt, 2000) < 0) { fprintf(stderr, "Can't change local name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } + + if (eir) { + if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) { + fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n", + hdev, strerror(errno), errno); + } + } } else { char name[249]; int i; - if (hci_read_local_name(s, sizeof(name), name, 1000) < 0) { + + if (hci_read_local_name(dd, sizeof(name), name, 1000) < 0) { fprintf(stderr, "Can't read local name on hci%d: %s (%d)\n", hdev, strerror(errno), errno); exit(1); } + for (i = 0; i < 248 && name[i]; i++) if (!isprint(name[i])) name[i] = '.'; name[248] = '\0'; + print_dev_hdr(&di); printf("\tName: '%s'\n", name); } + + hci_close_dev(dd); } /* @@ -918,6 +950,8 @@ static void cmd_inq_mode(int ctl, int hdev, char *opt) break; } } + + hci_close_dev(dd); } static void cmd_inq_data(int ctl, int hdev, char *opt) @@ -932,12 +966,21 @@ static void cmd_inq_data(int ctl, int hdev, char *opt) } if (opt) { - uint8_t fec = 0, data[248]; + uint8_t fec = 0, data[240]; + char tmp[3]; + int i, size; memset(data, 0, sizeof(data)); - data[0] = strlen(opt) + 1; - data[1] = 0x09; - memcpy(data + 2, opt, strlen(opt)); + + memset(tmp, 0, sizeof(tmp)); + size = (strlen(opt) + 1) / 2; + if (size > 240) + size = 240; + + for (i = 0; i < size; i++) { + memcpy(tmp, opt + (i * 2), 2); + data[i] = strtol(tmp, NULL, 16); + } if (hci_write_ext_inquiry_response(dd, fec, data, 2000) < 0) { fprintf(stderr, "Can't set extended inquiry response on hci%d: %s (%d)\n", @@ -945,7 +988,8 @@ static void cmd_inq_data(int ctl, int hdev, char *opt) exit(1); } } else { - uint8_t fec, data[240]; + uint8_t fec, data[240], len, type, *ptr; + char *str; if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) < 0) { fprintf(stderr, "Can't read extended inquiry response on hci%d: %s (%d)\n", @@ -954,12 +998,42 @@ static void cmd_inq_data(int ctl, int hdev, char *opt) } print_dev_hdr(&di); - printf("\tFEC: %d\n\t", fec); + printf("\tFEC %s\n\t\t", fec ? "enabled" : "disabled"); for (i = 0; i < 240; i++) printf("%02x%s%s", data[i], (i + 1) % 8 ? "" : " ", - (i + 1) % 16 ? " " : "\n\t"); + (i + 1) % 16 ? " " : (i < 239 ? "\n\t\t" : "\n")); + + ptr = data; + while (*ptr) { + len = *ptr++; + type = *ptr++; + switch (type) { + case 0x08: + case 0x09: + str = malloc(len); + if (str) { + snprintf(str, len, "%s", ptr); + for (i = 0; i < len - 1; i++) + if (!isprint(str[i])) + str[i] = '.'; + printf("\t%s local name: \'%s\'\n", + type == 0x08 ? "Shortened" : "Complete", str); + free(str); + } + break; + default: + printf("\tUnknown type 0x%02x with %d bytes data\n", + type, len - 1); + break; + } + + ptr += (len - 1); + } + printf("\n"); } + + hci_close_dev(dd); } static void cmd_inq_type(int ctl, int hdev, char *opt) @@ -994,6 +1068,8 @@ static void cmd_inq_type(int ctl, int hdev, char *opt) printf("\tInquiry scan type: %s\n", type == 1 ? "Interlaced Inquiry Scan" : "Standard Inquiry Scan"); } + + hci_close_dev(dd); } static void cmd_inq_parms(int ctl, int hdev, char *opt) @@ -1430,7 +1506,7 @@ static struct { { "voice", cmd_voice, "[voice]", "Get/Set voice setting" }, { "iac", cmd_iac, "[iac]", "Get/Set inquiry access code" }, { "inqmode", cmd_inq_mode, "[mode]", "Get/Set inquiry mode" }, - { "inqdata", cmd_inq_data, "[name]", "Get/Set inquiry data (device name)" }, + { "inqdata", cmd_inq_data, "[data]", "Get/Set inquiry data" }, { "inqtype", cmd_inq_type, "[type]", "Get/Set inquiry scan type" }, { "inqparms", cmd_inq_parms, "[win:int]", "Get/Set inquiry scan window and interval" }, { "pageparms", cmd_page_parms, "[win:int]", "Get/Set page scan window and interval" }, -- cgit From 632a9432774ff3a0c6e556e8f32a565b38890767 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 22:36:31 +0000 Subject: Big cleanup of CVS relics --- AUTHORS | 39 +++++++------------------------- COPYING | 6 ++--- INSTALL | 61 ++++++++++++++++++++++++++++---------------------- Makefile.am | 3 --- README | 9 +++++--- acinclude.m4 | 6 +---- alsa/Makefile.am | 3 --- alsa/pcm_a2dp.c | 2 +- alsa/sbc.c | 2 +- alsa/sbc.h | 2 +- bootstrap-configure | 4 ++++ common/Makefile.am | 3 --- common/test_textfile.c | 25 +++++++++------------ common/textfile.c | 25 +++++++++------------ common/textfile.h | 25 +++++++++------------ configure.in | 4 ---- cups/Makefile.am | 3 --- cups/hcrp.c | 27 +++++++++------------- cups/main.c | 35 +++++++++++++---------------- cups/sdp.c | 27 +++++++++------------- cups/spp.c | 27 +++++++++------------- daemon/Makefile.am | 3 --- daemon/main.c | 2 +- dund/Makefile.am | 3 --- dund/dun.c | 35 +++++++++++++---------------- dund/dund.h | 25 +++++++++------------ dund/lib.h | 30 +++++++++---------------- dund/main.c | 31 +++++++++++-------------- dund/msdun.c | 31 +++++++++++-------------- dund/sdp.c | 27 +++++++++------------- extra/Makefile.am | 3 --- extra/bcm203x.c | 27 +++++++++------------- fuse/Makefile.am | 3 --- fuse/main.c | 25 +++++++++------------ hcid/Makefile.am | 3 --- hcid/dbus.c | 31 ++++++++++--------------- hcid/dbus.h | 31 ++++++++++--------------- hcid/hcid.conf | 2 -- hcid/hcid.h | 25 +++++++++------------ hcid/kword.c | 26 +++++++++------------ hcid/kword.h | 25 +++++++++------------ hcid/lexer.l | 27 ++++++++++------------ hcid/lib.c | 34 +++++++++++++--------------- hcid/lib.h | 25 +++++++++------------ hcid/main.c | 38 +++++++++++++------------------ hcid/parser.y | 26 +++++++++------------ hcid/security.c | 25 +++++++++------------ hcid/storage.c | 29 +++++++++--------------- hidd/Makefile.am | 3 --- hidd/hidd.h | 27 +++++++++------------- hidd/main.c | 27 +++++++++------------- hidd/sdp.c | 27 +++++++++------------- pand/Makefile.am | 3 --- pand/bnep.c | 36 +++++++++++++---------------- pand/main.c | 38 +++++++++++++------------------ pand/pand.h | 27 +++++++++------------- pand/sdp.c | 29 ++++++++++-------------- pcmcia/Makefile.am | 3 --- pcmcia/bluetooth | 4 ---- rfcomm/Makefile.am | 3 --- rfcomm/kword.c | 28 ++++++++++------------- rfcomm/kword.h | 27 +++++++++------------- rfcomm/lexer.l | 28 ++++++++++------------- rfcomm/main.c | 33 ++++++++++++--------------- rfcomm/parser.y | 30 +++++++++++-------------- rfcomm/rfcomm.conf | 2 -- scripts/Makefile.am | 3 --- scripts/create_dev | 2 -- sdpd/Makefile.am | 3 --- sdpd/cstate.c | 28 ++++++++++------------- sdpd/main.c | 37 +++++++++++++----------------- sdpd/request.c | 31 ++++++++++++------------- sdpd/sdpd.h | 32 +++++++++----------------- sdpd/service.c | 31 ++++++++++++------------- sdpd/servicedb.c | 28 ++++++++++------------- test/Makefile.am | 3 --- test/attest.c | 25 +++++++++------------ test/bdaddr.c | 25 +++++++++------------ test/hstest.c | 27 +++++++++------------- test/l2test.c | 25 +++++++++------------ test/rctest.c | 25 +++++++++------------ test/scotest.c | 25 +++++++++------------ tools/Makefile.am | 3 --- tools/avctrl.c | 25 +++++++++------------ tools/bccmd.c | 25 +++++++++------------ tools/ciptool.c | 27 +++++++++------------- tools/csr.c | 25 +++++++++------------ tools/csr.h | 25 +++++++++------------ tools/csrinit.c | 25 +++++++++------------ tools/dfu.c | 17 +++++++------- tools/dfu.h | 17 +++++++------- tools/dfutool.c | 17 +++++++------- tools/hciattach.c | 27 +++++++++------------- tools/hciconfig.c | 25 +++++++++------------ tools/hcisecfilter.c | 25 +++++++++------------ tools/hcitool.c | 25 +++++++++------------ tools/hid2hci.c | 27 +++++++++------------- tools/l2ping.c | 25 +++++++++------------ tools/oui.c | 25 +++++++++------------ tools/oui.h | 25 +++++++++------------ tools/ppporc.c | 27 +++++++++------------- tools/pskey.c | 25 +++++++++------------ tools/sdptool.c | 25 +++++++++------------ 103 files changed, 857 insertions(+), 1285 deletions(-) diff --git a/AUTHORS b/AUTHORS index 1c4fa22e..b92f0a55 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,39 +1,16 @@ Maxim Krasnyansky - Original author. - Marcel Holtmann - Primary maintainer. - Various patches, fixes and other contributions. - RFCOMM configuration utility. - -Ilguiz Latypov - Patches. Suggestions. - -Jan Beutel - Documentation maintainer. - BlueZ HowTo. - +Stephen Crane Jean Tourrilhes - CSR and BrainBoxes specific UART initialization. - -Thomas Moser - Silicon Wave UART initialization. - +Jan Beutel +Ilguiz Latypov +Thomas Moser Nils Faerber - Man pages. - Martin Leopold - Various patches and fixes. - -Stephen Crane - Support for human readable class of device display. - SDP server and sdptool fixes. - Wolfgang Heidrich - Support for displaying link quality (hcitool). - Fabrizio Gennari - Support for link supervision timeout (hcitool). - +Brad Midgley +Henryk Ploetz Philip Blundell - D-Bus PIN helper support. +Claudio Takahasi +Johan Hedberg diff --git a/COPYING b/COPYING index d60c31a9..3912109b 100644 --- a/COPYING +++ b/COPYING @@ -2,7 +2,7 @@ Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + 51 Franklin St, 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. @@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. @@ -313,7 +313,7 @@ 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 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. diff --git a/INSTALL b/INSTALL index 54caf7c1..56b077d6 100644 --- a/INSTALL +++ b/INSTALL @@ -1,13 +1,16 @@ -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software -Foundation, Inc. +Installation Instructions +************************* - This file is free documentation; the Free Software Foundation gives +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== - These are generic installation instructions. +These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -67,9 +70,9 @@ The simplest way to compile this package is: Compilers and Options ===================== - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here @@ -82,7 +85,7 @@ is an example: Compiling For Multiple Architectures ==================================== - You can compile the package for more than one kind of computer at the +You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the @@ -99,19 +102,19 @@ for another architecture. Installation Names ================== - By default, `make install' will install the package's files in +By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. +option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. +give `configure' the option `--exec-prefix=PREFIX', the package will +use PREFIX as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular +options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. @@ -122,7 +125,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= - Some packages pay attention to `--enable-FEATURE' options to +Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The @@ -137,11 +140,11 @@ you can use the `configure' options `--x-includes=DIR' and Specifying the System Type ========================== - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of machine the package -will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints -a message saying it cannot guess the machine type, give it the +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: @@ -167,9 +170,9 @@ eventually be run) with `--host=TYPE'. Sharing Defaults ================ - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. @@ -178,7 +181,7 @@ A warning: not all `configure' scripts look for a site script. Defining Variables ================== - Variables not defined in a site shell script can be set in the +Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set @@ -186,14 +189,18 @@ them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc -will cause the specified gcc to be used as the C compiler (unless it is -overridden in the site shell script). +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. `configure' Invocation ====================== - `configure' recognizes the following options to control how it -operates. +`configure' recognizes the following options to control how it operates. `--help' `-h' diff --git a/Makefile.am b/Makefile.am index 17766626..657fc219 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# SUBDIRS = common daemon tools rfcomm hcid sdpd dund pand hidd \ cups fuse alsa test scripts pcmcia extra diff --git a/README b/README index 98ad8551..0ae4eb5f 100644 --- a/README +++ b/README @@ -1,4 +1,5 @@ BlueZ - Bluetooth protocol stack for Linux +****************************************** Copyright (C) 2000-2001 Qualcomm Incorporated Copyright (C) 2002-2003 Maxim Krasnyansky @@ -7,7 +8,8 @@ Copyright (C) 2002-2005 Marcel Holtmann Bluetooth utilities -1. Compilation and installation +Compilation and installation +============================ In order to compile Bluetooth utilities you need following software packages: - Linux Bluetooth protocol stack (BlueZ) @@ -23,10 +25,11 @@ To configure run: Configure automatically searches for all required components and packages. To compile and install run: - make install + make && make install -2. Information +Information +=========== Mailing lists: bluez-users@lists.sf.net - BlueZ general questions and discussions diff --git a/acinclude.m4 b/acinclude.m4 index 0d41c225..8b8b4f06 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,7 +1,3 @@ -dnl -dnl $Id$ -dnl - AC_DEFUN([AC_PROG_CC_PIE], [ AC_CACHE_CHECK([whether ${CC-cc} accepts -fPIE], ac_cv_prog_cc_pie, [ echo 'void f(){}' > conftest.c @@ -15,7 +11,7 @@ AC_DEFUN([AC_PROG_CC_PIE], [ ]) AC_DEFUN([AC_INIT_BLUEZ], [ - AC_PREFIX_DEFAULT(/usr) + AC_PREFIX_DEFAULT(/usr/local) if (test "${CFLAGS}" = ""); then CFLAGS="-Wall -O2" diff --git a/alsa/Makefile.am b/alsa/Makefile.am index e0c3168e..63458cd9 100644 --- a/alsa/Makefile.am +++ b/alsa/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# if ALSA alsadir = $(libdir)/alsa-lib diff --git a/alsa/pcm_a2dp.c b/alsa/pcm_a2dp.c index e2f8bde4..6bd4d721 100644 --- a/alsa/pcm_a2dp.c +++ b/alsa/pcm_a2dp.c @@ -17,7 +17,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ diff --git a/alsa/sbc.c b/alsa/sbc.c index 3eda2910..9b9df4dd 100644 --- a/alsa/sbc.c +++ b/alsa/sbc.c @@ -18,7 +18,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ diff --git a/alsa/sbc.h b/alsa/sbc.h index f0c6c09d..ae1896ff 100644 --- a/alsa/sbc.h +++ b/alsa/sbc.h @@ -18,7 +18,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ diff --git a/bootstrap-configure b/bootstrap-configure index 76e6fce3..ad595294 100755 --- a/bootstrap-configure +++ b/bootstrap-configure @@ -1,5 +1,9 @@ #!/bin/sh +if [ -f config.status ]; then + make maintainer-clean +fi + ./bootstrap && \ ./configure --enable-maintainer-mode \ --enable-debug \ diff --git a/common/Makefile.am b/common/Makefile.am index 3cc9318d..71592813 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# noinst_LIBRARIES = libtextfile.a diff --git a/common/test_textfile.c b/common/test_textfile.c index 5a783d20..1c6be660 100644 --- a/common/test_textfile.c +++ b/common/test_textfile.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/common/textfile.c b/common/textfile.c index f15d439c..dd77980c 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/common/textfile.h b/common/textfile.h index bd7c7470..4f428ad0 100644 --- a/common/textfile.h +++ b/common/textfile.h @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ int create_dirs(char *filename, mode_t mode); diff --git a/configure.in b/configure.in index ac0c8834..977a04ef 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,3 @@ -dnl -dnl $Id$ -dnl - AC_PREREQ(2.50) AC_INIT() diff --git a/cups/Makefile.am b/cups/Makefile.am index ea4aa876..0d97b41e 100644 --- a/cups/Makefile.am +++ b/cups/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# if CUPS cupsdir = $(libdir)/cups/backend diff --git a/cups/hcrp.c b/cups/hcrp.c index c8c26f92..2ee0e16c 100644 --- a/cups/hcrp.c +++ b/cups/hcrp.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/cups/main.c b/cups/main.c index a8a01d4c..dce6145b 100644 --- a/cups/main.c +++ b/cups/main.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -43,11 +38,11 @@ #include #include -int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel); -int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm); +extern int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel); +extern int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm); -int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies); -int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies); +extern int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies); +extern int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies); /* * Usage: printer-uri job-id user title copies options [file] diff --git a/cups/sdp.c b/cups/sdp.c index c636f7d2..8d856499 100644 --- a/cups/sdp.c +++ b/cups/sdp.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/cups/spp.c b/cups/spp.c index ec8fcdd5..3f3f1431 100644 --- a/cups/spp.c +++ b/cups/spp.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 9eacf7da..de94dc0f 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# if DBUS noinst_PROGRAMS = bluetoothd diff --git a/daemon/main.c b/daemon/main.c index df39a66c..8d8c2099 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -17,7 +17,7 @@ * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ diff --git a/dund/Makefile.am b/dund/Makefile.am index 236decc6..84e3a150 100644 --- a/dund/Makefile.am +++ b/dund/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# bin_PROGRAMS = dund diff --git a/dund/dun.c b/dund/dun.c index d5724cfb..3de858d9 100644 --- a/dund/dun.c +++ b/dund/dun.c @@ -7,45 +7,40 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H #include #endif -#include -#include #include #include +#include #include +#include +#include #include #include -#include #include -#include #include #include -#include #include +#include +#include #include diff --git a/dund/dund.h b/dund/dund.h index f2a9b026..7ed9e23e 100644 --- a/dund/dund.h +++ b/dund/dund.h @@ -7,24 +7,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ /* DUN scripts & commands */ diff --git a/dund/lib.h b/dund/lib.h index c9b0f0a4..9d66bdb1 100644 --- a/dund/lib.h +++ b/dund/lib.h @@ -7,29 +7,21 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ -#ifndef _DUND_LIB_H -#define _DUND_LIB_H - #include #include #include @@ -94,5 +86,3 @@ static inline int write_n(int fd, char *buf, int len) } int ms_dun(int fd, int server, int timeo); - -#endif /* _DUND_LIB_H */ diff --git a/dund/main.c b/dund/main.c index e58e382b..32b7351a 100644 --- a/dund/main.c +++ b/dund/main.c @@ -7,24 +7,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -32,13 +27,13 @@ #endif #include +#include +#include +#include #include #include -#include -#include #include #include -#include #include #include diff --git a/dund/msdun.c b/dund/msdun.c index f035971b..cba1bbfe 100644 --- a/dund/msdun.c +++ b/dund/msdun.c @@ -7,24 +7,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -32,11 +27,11 @@ #endif #include -#include -#include -#include #include #include +#include +#include +#include #include #include #include diff --git a/dund/sdp.c b/dund/sdp.c index 74cafb55..54b40ca2 100644 --- a/dund/sdp.c +++ b/dund/sdp.c @@ -7,24 +7,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -33,9 +28,9 @@ #include #include +#include #include #include -#include #include #include #include diff --git a/extra/Makefile.am b/extra/Makefile.am index 7ce141c0..c5e53d9a 100644 --- a/extra/Makefile.am +++ b/extra/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# datafiles = bcm203x.usermap diff --git a/extra/bcm203x.c b/extra/bcm203x.c index 5990ae8c..135d003f 100644 --- a/extra/bcm203x.c +++ b/extra/bcm203x.c @@ -3,28 +3,23 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2001-2002 Maxim Krasnyansky - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/fuse/Makefile.am b/fuse/Makefile.am index ba504834..1fd42311 100644 --- a/fuse/Makefile.am +++ b/fuse/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# if FUSE noinst_PROGRAMS = btfs diff --git a/fuse/main.c b/fuse/main.c index 7cd57123..46bc4c25 100644 --- a/fuse/main.c +++ b/fuse/main.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/hcid/Makefile.am b/hcid/Makefile.am index b616cbfc..e82a4263 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# confdir = $(sysconfdir)/bluetooth diff --git a/hcid/dbus.c b/hcid/dbus.c index e055b0c4..6fa9f121 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -2,30 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2000-2001 Qualcomm Incorporated - * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2004-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -36,9 +29,9 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/hcid/dbus.h b/hcid/dbus.h index 45ead04d..8ba45517 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -2,32 +2,25 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2000-2001 Qualcomm Incorporated - * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2004-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ - + #define __END_SIG__ DBUS_TYPE_INVALID_AS_STRING #define BASE_PATH "/org/bluez" diff --git a/hcid/hcid.conf b/hcid/hcid.conf index d2740b74..cbb2d2eb 100644 --- a/hcid/hcid.conf +++ b/hcid/hcid.conf @@ -1,8 +1,6 @@ # # HCI daemon configuration file. # -# $Id$ -# # HCId options options { diff --git a/hcid/hcid.h b/hcid/hcid.h index e7dfeb82..fb318015 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #include diff --git a/hcid/kword.c b/hcid/kword.c index 30db2da0..19b54566 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -33,6 +28,7 @@ #endif #include +#include #include #include #include diff --git a/hcid/kword.h b/hcid/kword.h index 735e119d..77f9b487 100644 --- a/hcid/kword.h +++ b/hcid/kword.h @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ struct kword { diff --git a/hcid/lexer.l b/hcid/lexer.l index ce34af12..d9585959 100644 --- a/hcid/lexer.l +++ b/hcid/lexer.l @@ -9,30 +9,27 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H #include #endif +#include +#include #include #include diff --git a/hcid/lib.c b/hcid/lib.c index 9b09ca2a..a0457ad4 100644 --- a/hcid/lib.c +++ b/hcid/lib.c @@ -8,37 +8,33 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H #include #endif -#include -#include #include -#include +#include #include -#include +#include +#include +#include #include +#include #include #include diff --git a/hcid/lib.h b/hcid/lib.h index 49ddfb14..eb6154f6 100644 --- a/hcid/lib.h +++ b/hcid/lib.h @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #include diff --git a/hcid/main.c b/hcid/main.c index 8183f42c..e6d43590 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -33,20 +28,17 @@ #endif #include -#include +#include +#include #include +#include #include #include -#include #include -#include -#include -#include - -#include -#include #include #include +#include +#include #include #include diff --git a/hcid/parser.y b/hcid/parser.y index d3cbd936..dd90037f 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -9,24 +9,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -34,6 +29,7 @@ #endif #include +#include #include #include #include diff --git a/hcid/security.c b/hcid/security.c index 1c363906..91f65665 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/hcid/storage.c b/hcid/storage.c index e8d2ce1c..e18076dc 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -2,30 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2000-2001 Qualcomm Incorporated - * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2004-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/hidd/Makefile.am b/hidd/Makefile.am index cd8b4878..4dfbb56e 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# bin_PROGRAMS = hidd diff --git a/hidd/hidd.h b/hidd/hidd.h index ab8a94ec..c8103281 100644 --- a/hidd/hidd.h +++ b/hidd/hidd.h @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #define L2CAP_PSM_HIDP_CTRL 0x11 diff --git a/hidd/main.c b/hidd/main.c index 9ff02705..ee32c53f 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/hidd/sdp.c b/hidd/sdp.c index ea76894b..6ed5d2dc 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/pand/Makefile.am b/pand/Makefile.am index 9e7c3648..3d92aa85 100644 --- a/pand/Makefile.am +++ b/pand/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# bin_PROGRAMS = pand diff --git a/pand/bnep.c b/pand/bnep.c index be0d492a..6c1d205b 100644 --- a/pand/bnep.c +++ b/pand/bnep.c @@ -3,48 +3,42 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H #include #endif -#include -#include #include #include - +#include +#include #include #include -#include - #include #include #include +#include + #include "pand.h" static int ctl; diff --git a/pand/main.c b/pand/main.c index b5a4ee95..576472b7 100644 --- a/pand/main.c +++ b/pand/main.c @@ -3,28 +3,23 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -32,19 +27,18 @@ #endif #include +#include +#include +#include #include #include -#include -#include #include #include -#include #include - -#include #include -#include #include +#include +#include #include #include diff --git a/pand/pand.h b/pand/pand.h index 2981168b..1e4509f9 100644 --- a/pand/pand.h +++ b/pand/pand.h @@ -3,28 +3,23 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ /* PAN scripts & commands */ diff --git a/pand/sdp.c b/pand/sdp.c index 802887b1..0edaf8f3 100644 --- a/pand/sdp.c +++ b/pand/sdp.c @@ -3,28 +3,23 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -33,9 +28,9 @@ #include #include +#include #include #include -#include #include #include #include diff --git a/pcmcia/Makefile.am b/pcmcia/Makefile.am index 59c16334..8ce2a197 100644 --- a/pcmcia/Makefile.am +++ b/pcmcia/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# datafiles = bluetooth bluetooth.conf diff --git a/pcmcia/bluetooth b/pcmcia/bluetooth index 7be4a31d..1b2e577c 100755 --- a/pcmcia/bluetooth +++ b/pcmcia/bluetooth @@ -9,10 +9,6 @@ # environment variables FUNCTION, VENDORID, CARDNAME # -# -# $Id$ -# - if [ -r ./shared ]; then . ./shared ; else . /etc/pcmcia/shared ; fi # Get device attributes diff --git a/rfcomm/Makefile.am b/rfcomm/Makefile.am index 65a5af53..bda4a13f 100644 --- a/rfcomm/Makefile.am +++ b/rfcomm/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# confdir = $(sysconfdir)/bluetooth diff --git a/rfcomm/kword.c b/rfcomm/kword.c index 0747eef3..578a8435 100644 --- a/rfcomm/kword.c +++ b/rfcomm/kword.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -31,6 +26,7 @@ #endif #include +#include #include #include diff --git a/rfcomm/kword.h b/rfcomm/kword.h index c0acd946..9247e1aa 100644 --- a/rfcomm/kword.h +++ b/rfcomm/kword.h @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ extern int lineno; diff --git a/rfcomm/lexer.l b/rfcomm/lexer.l index 89c41828..fb0b5e04 100644 --- a/rfcomm/lexer.l +++ b/rfcomm/lexer.l @@ -3,28 +3,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -32,6 +27,7 @@ #endif #include +#include #include #include diff --git a/rfcomm/main.c b/rfcomm/main.c index decabcc6..48c09682 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -31,14 +26,14 @@ #endif #include -#include +#include +#include #include +#include #include #include #include #include -#include -#include #include #include #include diff --git a/rfcomm/parser.y b/rfcomm/parser.y index 1d5f9024..c0e3eda7 100644 --- a/rfcomm/parser.y +++ b/rfcomm/parser.y @@ -3,28 +3,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -32,8 +27,9 @@ #endif #include -#include +#include #include +#include #include #include #include diff --git a/rfcomm/rfcomm.conf b/rfcomm/rfcomm.conf index c1b10cd5..d5e81ed1 100644 --- a/rfcomm/rfcomm.conf +++ b/rfcomm/rfcomm.conf @@ -1,8 +1,6 @@ # # RFCOMM configuration file. # -# $Id$ -# rfcomm0 { # Automatically bind the device at startup diff --git a/scripts/Makefile.am b/scripts/Makefile.am index e77f3f12..94508c66 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# if BLUEPIN bin_SCRIPTS = bluepin diff --git a/scripts/create_dev b/scripts/create_dev index 4ea0c263..f3054793 100755 --- a/scripts/create_dev +++ b/scripts/create_dev @@ -2,8 +2,6 @@ # # Create Bluetooth devices in /dev # -# $Id$ -# VHCI_MAJOR=10 VHCI_MINOR=250 diff --git a/sdpd/Makefile.am b/sdpd/Makefile.am index f2d55754..018a66f1 100644 --- a/sdpd/Makefile.am +++ b/sdpd/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# sbin_PROGRAMS = sdpd diff --git a/sdpd/cstate.c b/sdpd/cstate.c index c983ef74..6cb8abbd 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -4,29 +4,24 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -34,6 +29,7 @@ #endif #include +#include #include #include #include diff --git a/sdpd/main.c b/sdpd/main.c index 27d2f800..0181657c 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -4,54 +4,49 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H #include #endif -#include -#include #include #include +#include +#include #include #include #include -#include -#include #include #include #include -#include #include #include #include #include +#include +#include + #include "sdpd.h" static int l2cap_sock, unix_sock; diff --git a/sdpd/request.c b/sdpd/request.c index 07051f9f..e0331683 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -4,29 +4,24 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -34,15 +29,17 @@ #endif #include +#include #include #include -#include #include #include #include #include +#include + #include "sdpd.h" #define MIN(x, y) ((x) < (y))? (x): (y) diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index af028a4f..94bd9056 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -4,34 +4,26 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ -#ifndef SDPD_H -#define SDPD_H - #define sdp_get_unaligned bt_get_unaligned #define sdp_put_unaligned bt_put_unaligned @@ -89,5 +81,3 @@ int sdp_check_access(uint32_t handle, bdaddr_t *device); uint32_t sdp_next_handle(void); uint32_t sdp_get_time(); - -#endif diff --git a/sdpd/service.c b/sdpd/service.c index 437bcd69..71b141bc 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -4,29 +4,24 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -34,13 +29,15 @@ #endif #include -#include +#include #include #include #include #include +#include + #include "sdpd.h" extern void update_db_timestamp(void); diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index 6a1e2279..d2c08493 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -4,29 +4,24 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -34,6 +29,7 @@ #endif #include +#include #include #include #include diff --git a/test/Makefile.am b/test/Makefile.am index 8ee5ed06..e63e37be 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# if TEST bin_PROGRAMS = l2test rctest diff --git a/test/attest.c b/test/attest.c index 6e7d3808..10aec939 100644 --- a/test/attest.c +++ b/test/attest.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/test/bdaddr.c b/test/bdaddr.c index ac382e57..be1419d8 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/test/hstest.c b/test/hstest.c index 8949be4b..bea4d3a4 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/test/l2test.c b/test/l2test.c index f475aa4b..f231587e 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/test/rctest.c b/test/rctest.c index 8c76859f..724460c7 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -7,24 +7,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/test/scotest.c b/test/scotest.c index 22a95fed..169f39b7 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -7,24 +7,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/Makefile.am b/tools/Makefile.am index 8a2241c6..479011ec 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# if AVCTRL avctrl_programs = avctrl diff --git a/tools/avctrl.c b/tools/avctrl.c index 03b54117..06540ef5 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/bccmd.c b/tools/bccmd.c index 18d38766..46cc2be1 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/ciptool.c b/tools/ciptool.c index 263e0573..e30db09a 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/csr.c b/tools/csr.c index 41677d22..066ff154 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/csr.h b/tools/csr.h index fe46f4b4..bb87fd9f 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #define CSR_VARID_PS_CLR_ALL 0x000b /* valueless */ diff --git a/tools/csrinit.c b/tools/csrinit.c index 5d939539..a56dbde9 100644 --- a/tools/csrinit.c +++ b/tools/csrinit.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/dfu.c b/tools/dfu.c index bfbc0f2d..436b2e02 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -6,20 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/dfu.h b/tools/dfu.h index 915efd8c..54992e03 100644 --- a/tools/dfu.h +++ b/tools/dfu.h @@ -6,20 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #include diff --git a/tools/dfutool.c b/tools/dfutool.c index 06da5248..451ce957 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -6,20 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hciattach.c b/tools/hciattach.c index b7f6dab6..8091d655 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H @@ -649,7 +644,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) /* * Silicon Wave specific initialization - * Thomas Moser + * Thomas Moser */ static int swave(int fd, struct uart_t *u, struct termios *ti) { diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 7267d564..527c9632 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index ce0082e9..1d557ce1 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -7,24 +7,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hcitool.c b/tools/hcitool.c index 75b09b77..9ae42a12 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/hid2hci.c b/tools/hid2hci.c index a5c2722c..8a19a880 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2004 Marcel Holtmann + * Copyright (C) 2003-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/l2ping.c b/tools/l2ping.c index 9741dc0e..3b46675d 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -8,24 +8,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/oui.c b/tools/oui.c index 985e6e20..0a1d67bc 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/oui.h b/tools/oui.h index 918a248b..93cc7b01 100644 --- a/tools/oui.h +++ b/tools/oui.h @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ char *ouitocomp(const char *oui); diff --git a/tools/ppporc.c b/tools/ppporc.c index 60aefd39..e8275641 100644 --- a/tools/ppporc.c +++ b/tools/ppporc.c @@ -2,28 +2,23 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2004 Marcel Holtmann + * Copyright (C) 2002-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/pskey.c b/tools/pskey.c index b1f6a319..d9bda6a8 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -6,24 +6,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H diff --git a/tools/sdptool.c b/tools/sdptool.c index 6c07cfab..052c0b05 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -10,24 +10,19 @@ * * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; + * 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. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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. * - * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS - * SOFTWARE IS DISCLAIMED. + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA * - * - * $Id$ */ #ifdef HAVE_CONFIG_H -- cgit From c0635ace793c507f7a9ffd57977eeb96d3685a44 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Oct 2005 12:17:08 +0000 Subject: Update some missing PS keys --- tools/csr.c | 20 ++++++++++++++++++++ tools/csr.h | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 066ff154..086c204e 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -565,6 +565,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Maximum transmit power"; case CSR_PSKEY_TX_GAIN_RAMP: return "Transmit gain ramp rate"; + case CSR_PSKEY_LC_POWER_TABLE: + return "Radio power table"; case CSR_PSKEY_LC_PEER_POWER_PERIOD: return "Peer transmit power control interval"; case CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK: @@ -671,6 +673,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Disable the HCI Command_Status event on boot"; case CSR_PSKEY_LM_MAX_EVENT_FILTERS: return "Maximum number of event filters"; + case CSR_PSKEY_LM_USE_ENC_MODE_BROADCAST: + return "Allow LM to use enc_mode=2"; case CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE: return "LM sends two LMP_accepted messages in test mode"; case CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME: @@ -909,6 +913,8 @@ char *csr_pskeytostr(uint16_t pskey) return "IQ calibration channel"; case CSR_PSKEY_IQ_TRIM_GAIN: return "IQ calibration gain"; + case CSR_PSKEY_IQ_TRIM_ENABLE: + return "IQ calibration enable"; case CSR_PSKEY_TX_OFFSET_HALF_MHZ: return "Transmit offset"; case CSR_PSKEY_GBL_MISC_ENABLES: @@ -1193,6 +1199,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Trim value to optimise loop filter"; case CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK: return "Energy consumption estimation current peak"; + case CSR_PSKEY_VM_E2_CACHE_LIMIT: + return "Maximum RAM for caching EEPROM VM application"; case CSR_PSKEY_FORCE_16MHZ_REF_PIO: return "PIO line to force 16 MHz reference to be assumed"; case CSR_PSKEY_CDMA_LO_REF_LIMITS: @@ -1251,6 +1259,8 @@ char *csr_pskeytostr(uint16_t pskey) return "Medium rate value for the ANA_RX_FTRIM register"; case CSR_PSKEY_I2C_CONFIG: return "I2C configuration"; + case CSR_PSKEY_IQ_LVL_RX: + return "IQ demand level for reception"; case CSR_PSKEY_MR_TX_FILTER_CONFIG: return "TX filter configuration used for enhanced data rate"; case CSR_PSKEY_MR_TX_CONFIG2: @@ -1423,6 +1433,8 @@ char *csr_pskeytoval(uint16_t pskey) return "LC_MAX_TX_POWER"; case CSR_PSKEY_TX_GAIN_RAMP: return "TX_GAIN_RAMP"; + case CSR_PSKEY_LC_POWER_TABLE: + return "LC_POWER_TABLE"; case CSR_PSKEY_LC_PEER_POWER_PERIOD: return "LC_PEER_POWER_PERIOD"; case CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK: @@ -1529,6 +1541,8 @@ char *csr_pskeytoval(uint16_t pskey) return "HCI_NOP_DISABLE"; case CSR_PSKEY_LM_MAX_EVENT_FILTERS: return "LM_MAX_EVENT_FILTERS"; + case CSR_PSKEY_LM_USE_ENC_MODE_BROADCAST: + return "LM_USE_ENC_MODE_BROADCAST"; case CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE: return "LM_TEST_SEND_ACCEPTED_TWICE"; case CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME: @@ -1767,6 +1781,8 @@ char *csr_pskeytoval(uint16_t pskey) return "IQ_TRIM_CHANNEL"; case CSR_PSKEY_IQ_TRIM_GAIN: return "IQ_TRIM_GAIN"; + case CSR_PSKEY_IQ_TRIM_ENABLE: + return "IQ_TRIM_ENABLE"; case CSR_PSKEY_TX_OFFSET_HALF_MHZ: return "TX_OFFSET_HALF_MHZ"; case CSR_PSKEY_GBL_MISC_ENABLES: @@ -2051,6 +2067,8 @@ char *csr_pskeytoval(uint16_t pskey) return "LOOP_FILTER_TRIM"; case CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK: return "DRAIN_BORE_CURRENT_PEAK"; + case CSR_PSKEY_VM_E2_CACHE_LIMIT: + return "VM_E2_CACHE_LIMIT"; case CSR_PSKEY_FORCE_16MHZ_REF_PIO: return "FORCE_16MHZ_REF_PIO"; case CSR_PSKEY_CDMA_LO_REF_LIMITS: @@ -2109,6 +2127,8 @@ char *csr_pskeytoval(uint16_t pskey) return "MR_ANA_RX_FTRIM"; case CSR_PSKEY_I2C_CONFIG: return "I2C_CONFIG"; + case CSR_PSKEY_IQ_LVL_RX: + return "IQ_LVL_RX"; case CSR_PSKEY_MR_TX_FILTER_CONFIG: return "MR_TX_FILTER_CONFIG"; case CSR_PSKEY_MR_TX_CONFIG2: diff --git a/tools/csr.h b/tools/csr.h index bb87fd9f..d366d19b 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -80,6 +80,7 @@ #define CSR_PSKEY_LC_FC_BUFFER_LOW_WATER_MARK 0x0015 /* lc_fc_lwm */ #define CSR_PSKEY_LC_MAX_TX_POWER 0x0017 /* int16 */ #define CSR_PSKEY_TX_GAIN_RAMP 0x001d /* uint16 */ +#define CSR_PSKEY_LC_POWER_TABLE 0x001e /* power_setting[] */ #define CSR_PSKEY_LC_PEER_POWER_PERIOD 0x001f /* TIME */ #define CSR_PSKEY_LC_FC_POOLS_LOW_WATER_MARK 0x0020 /* lc_fc_lwm */ #define CSR_PSKEY_LC_DEFAULT_TX_POWER 0x0021 /* int16 */ @@ -133,6 +134,7 @@ #define CSR_PSKEY_LM_USE_UNIT_KEY 0x00f0 /* bool */ #define CSR_PSKEY_HCI_NOP_DISABLE 0x00f2 /* bool */ #define CSR_PSKEY_LM_MAX_EVENT_FILTERS 0x00f4 /* uint8 */ +#define CSR_PSKEY_LM_USE_ENC_MODE_BROADCAST 0x00f5 /* bool */ #define CSR_PSKEY_LM_TEST_SEND_ACCEPTED_TWICE 0x00f6 /* bool */ #define CSR_PSKEY_LM_MAX_PAGE_HOLD_TIME 0x00f7 /* uint16 */ #define CSR_PSKEY_AFH_ADAPTATION_RESPONSE_TIME 0x00f8 /* uint16 */ @@ -252,6 +254,7 @@ #define CSR_PSKEY_LO_ADC_AMPL_MAX 0x0213 /* uint16 */ #define CSR_PSKEY_IQ_TRIM_CHANNEL 0x0214 /* uint16 */ #define CSR_PSKEY_IQ_TRIM_GAIN 0x0215 /* uint16 */ +#define CSR_PSKEY_IQ_TRIM_ENABLE 0x0216 /* iq_trim_enable_flag */ #define CSR_PSKEY_TX_OFFSET_HALF_MHZ 0x0217 /* int16 */ #define CSR_PSKEY_GBL_MISC_ENABLES 0x0221 /* uint16 */ #define CSR_PSKEY_UART_SLEEP_TIMEOUT 0x0222 /* uint16 */ @@ -394,6 +397,7 @@ #define CSR_PSKEY_DRAIN_BORE_COUNTERS 0x03e6 /* uint32[] */ #define CSR_PSKEY_LOOP_FILTER_TRIM 0x03e4 /* uint16 */ #define CSR_PSKEY_DRAIN_BORE_CURRENT_PEAK 0x03e3 /* uint32[] */ +#define CSR_PSKEY_VM_E2_CACHE_LIMIT 0x03e2 /* uint16 */ #define CSR_PSKEY_FORCE_16MHZ_REF_PIO 0x03e1 /* uint16 */ #define CSR_PSKEY_CDMA_LO_REF_LIMITS 0x03df /* uint16 */ #define CSR_PSKEY_CDMA_LO_ERROR_LIMITS 0x03de /* uint16 */ @@ -423,6 +427,7 @@ #define CSR_PSKEY_USB_VM_CONTROL 0x03c0 /* bool */ #define CSR_PSKEY_MR_ANA_RX_FTRIM 0x03bf /* uint16 */ #define CSR_PSKEY_I2C_CONFIG 0x03be /* uint16 */ +#define CSR_PSKEY_IQ_LVL_RX 0x03bd /* uint16 */ #define CSR_PSKEY_MR_TX_FILTER_CONFIG 0x03bb /* uint32 */ #define CSR_PSKEY_MR_TX_CONFIG2 0x03ba /* uint16 */ #define CSR_PSKEY_USB_DONT_RESET_BOOTMODE_ON_HOST_RESET 0x03b9 /* bool */ -- cgit From d20aa9a7a44fea8be06906c7354f4fabc72e5a06 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Oct 2005 12:25:14 +0000 Subject: Fix typos --- tools/csr.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 086c204e..3bd25b46 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -752,33 +752,33 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_HOSTIO_FC_PS_BLOCK: return "HCI flow control block"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO0: - return "Host transport channel 0 settings (BCSP ACK"; + return "Host transport channel 0 settings (BCSP ACK)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO1: - return "Host transport channel 1 settings (BCSP-LE"; + return "Host transport channel 1 settings (BCSP-LE)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO2: - return "Host transport channel 2 settings (BCCMD"; + return "Host transport channel 2 settings (BCCMD)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO3: - return "Host transport channel 3 settings (HQ"; + return "Host transport channel 3 settings (HQ)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO4: - return "Host transport channel 4 settings (DM"; + return "Host transport channel 4 settings (DM)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO5: - return "Host transport channel 5 settings (HCI CMD/EVT"; + return "Host transport channel 5 settings (HCI CMD/EVT)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO6: - return "Host transport channel 6 settings (HCI ACL"; + return "Host transport channel 6 settings (HCI ACL)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO7: - return "Host transport channel 7 settings (HCI SCO"; + return "Host transport channel 7 settings (HCI SCO)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO8: - return "Host transport channel 8 settings (L2CAP"; + return "Host transport channel 8 settings (L2CAP)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO9: - return "Host transport channel 9 settings (RFCOMM"; + return "Host transport channel 9 settings (RFCOMM)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO10: - return "Host transport channel 10 settings (SDP"; + return "Host transport channel 10 settings (SDP)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO11: - return "Host transport channel 11 settings (TEST"; + return "Host transport channel 11 settings (TEST)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO12: - return "Host transport channel 12 settings (DFU"; + return "Host transport channel 12 settings (DFU)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO13: - return "Host transport channel 13 settings (VM"; + return "Host transport channel 13 settings (VM)"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO14: return "Host transport channel 14 settings"; case CSR_PSKEY_HOSTIO_PROTOCOL_INFO15: @@ -798,7 +798,7 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_HOSTIO_AWKWARD_PCM_SYNC: return "PCM interface synchronisation is difficult"; case CSR_PSKEY_HOSTIO_BREAK_POLL_PERIOD: - return "Break poll period (microseconds"; + return "Break poll period (microseconds)"; case CSR_PSKEY_HOSTIO_MIN_UART_HCI_SCO_SIZE: return "Minimum SCO packet size sent to host over UART HCI"; case CSR_PSKEY_HOSTIO_MAP_SCO_CODEC: @@ -870,9 +870,9 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_ANA_FTRIM: return "Crystal frequency trim"; case CSR_PSKEY_WD_TIMEOUT: - return "Watchdog timeout (microseconds"; + return "Watchdog timeout (microseconds)"; case CSR_PSKEY_WD_PERIOD: - return "Watchdog period (microseconds"; + return "Watchdog period (microseconds)"; case CSR_PSKEY_HOST_INTERFACE: return "Host interface"; case CSR_PSKEY_HQ_HOST_TIMEOUT: @@ -888,7 +888,7 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_PMALLOC_SIZES: return "pmalloc sizes array"; case CSR_PSKEY_UART_BAUD_RATE: - return "UART Baud rate (pre 18"; + return "UART Baud rate (pre 18)"; case CSR_PSKEY_UART_CONFIG: return "UART configuration bitfield"; case CSR_PSKEY_STUB: @@ -1150,7 +1150,7 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_USB_ENDPOINT_0_MAX_PACKET_SIZE: return "The maxmimum packet size for USB endpoint 0"; case CSR_PSKEY_USB_CONFIG: - return "USB config params for new chips (>bc2"; + return "USB config params for new chips (>bc2)"; case CSR_PSKEY_RADIOTEST_ATTEN_INIT: return "Radio test initial attenuator"; case CSR_PSKEY_RADIOTEST_FIRST_TRIM_TIME: @@ -1390,7 +1390,7 @@ char *csr_pskeytostr(uint16_t pskey) case CSR_PSKEY_AMUX_AIO3: return "Multiplexer for AIO 3"; case CSR_PSKEY_LOCAL_NAME_SIMPLIFIED: - return "Local Name (simplified"; + return "Local Name (simplified)"; case CSR_PSKEY_EXTENDED_STUB: return "Extended stub"; default: -- cgit From 986881aec01faf3be6986651f9622f4e9787da90 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Oct 2005 15:39:14 +0000 Subject: Add functions for device listing --- hcid/dbus.c | 354 +++++++++++++++++++++++++++++++++++++++++++++++------------- hcid/dbus.h | 103 ++++++++++-------- 2 files changed, 340 insertions(+), 117 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 6fa9f121..399856ff 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -53,6 +53,7 @@ static int up_adapters = 0; #define MAX_PATH_LENGTH (64) #define READ_REMOTE_NAME_TIMEOUT (25000) #define MAX_CONN_NUMBER (10) +#define DEVICE_FLAG_NAME (16) #define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent" #define PINAGENT_INTERFACE PINAGENT_SERVICE_NAME @@ -90,9 +91,9 @@ struct profile_obj_path_data { const char *name; int status; /* 1:active 0:disabled */ int dft_reg; /* dft path registered */ - register_function_t *reg_func; - unregister_function_t *unreg_func; - get_svc_table_func_t *get_svc_table; /* return the service table */ + register_function_t *reg_func; + unregister_function_t *unreg_func; + get_svc_table_func_t *get_svc_table; /* return the service table */ }; /* @@ -101,11 +102,30 @@ struct profile_obj_path_data { * in the future * */ + typedef struct { uint32_t code; const char *str; }bluez_error_t; +typedef struct { + char *str; + unsigned int val; +} hci_map; + +static hci_map dev_flags_map[] = { + { "INIT", HCI_INIT }, + { "RUNNING", HCI_RUNNING }, + { "RAW", HCI_RAW }, + { "PSCAN", HCI_PSCAN }, + { "ISCAN", HCI_ISCAN }, + { "INQUIRY", HCI_INQUIRY }, + { "AUTH", HCI_AUTH }, + { "ENCRYPT", HCI_ENCRYPT }, + { "SECMGR", HCI_SECMGR }, + { NULL } +}; + static const bluez_error_t dbus_error_array[] = { { BLUEZ_EDBUS_UNKNOWN_METHOD, "Method not found" }, { BLUEZ_EDBUS_WRONG_SIGNATURE, "Wrong method signature" }, @@ -114,7 +134,7 @@ static const bluez_error_t dbus_error_array[] = { { BLUEZ_EDBUS_NO_MEM, "No memory" }, { BLUEZ_EDBUS_CONN_NOT_FOUND, "Connection not found" }, { BLUEZ_EDBUS_UNKNOWN_PATH, "Device path is not registered" }, - { 0, NULL } + { 0, NULL } }; static const bluez_error_t hci_error_array[] = { @@ -168,7 +188,7 @@ static const bluez_error_t hci_error_array[] = { { HCI_ROLE_SWITCH_PENDING, "Role Switch Pending" }, { HCI_SLOT_VIOLATION, "Reserved Slot Violation" }, { HCI_ROLE_SWITCH_FAILED, "Role Switch Failed" }, - { 0, NULL }, + { 0, NULL }, }; @@ -182,7 +202,7 @@ static const char *bluez_dbus_error_to_str(const uint32_t ecode) raw_code = (~BLUEZ_ESYSTEM_OFFSET) & ecode; syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, strerror(raw_code)); return strerror(raw_code); - } else if (ecode & BLUEZ_EDBUS_OFFSET) { + } else if (ecode & BLUEZ_EDBUS_OFFSET) { /* D-Bus error */ for (ptr = dbus_error_array; ptr->code; ptr++) { if (ptr->code == ecode) { @@ -234,13 +254,20 @@ static struct profile_obj_path_data obj_path_table[] = { /* * Device Message handler functions object table declaration */ -static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void *data); +static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data); +static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data); -static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data); +static DBusMessage* handle_get_devices_req_device(DBusMessage *msg, void *data); +static DBusMessage* handle_get_devices_req_manager(DBusMessage *msg, void *data); static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data); -static const DBusObjectPathVTable obj_vtable = { - .message_function = &msg_func, +static const DBusObjectPathVTable obj_dev_vtable = { + .message_function = &msg_func_device, + .unregister_function = NULL +}; + +static const DBusObjectPathVTable obj_mgr_vtable = { + .message_function = &msg_func_manager, .unregister_function = NULL }; @@ -248,6 +275,11 @@ static const DBusObjectPathVTable obj_vtable = { * Service provided under the path DEVICE_PATH * TODO add the handlers */ +static const struct service_data dev_root_services[] = { + { DEV_GET_DEV, handle_get_devices_req_device, DEV_GET_DEV_SIGNATURE }, + { NULL, NULL, NULL} +}; + static const struct service_data dev_services[] = { { DEV_UP, handle_not_implemented_req, DEV_UP_SIGNATURE }, { DEV_DOWN, handle_not_implemented_req, DEV_DOWN_SIGNATURE }, @@ -262,11 +294,11 @@ static const struct service_data dev_services[] = { * */ static const struct service_data mgr_services[] = { - { MGR_GET_DEV, handle_get_devices_req, MGR_GET_DEV_SIGNATURE }, + { MGR_GET_DEV, handle_get_devices_req_manager, MGR_GET_DEV_SIGNATURE }, { MGR_INIT, handle_not_implemented_req, NULL }, { MGR_ENABLE, handle_not_implemented_req, NULL }, { MGR_DISABLE, handle_not_implemented_req, NULL }, - { NULL, handle_not_implemented_req, NULL } + { NULL, NULL, NULL } }; /* @@ -293,7 +325,7 @@ static const struct service_data hci_services[] = { { HCI_REMOTE_NAME, handle_remote_name_req, HCI_REMOTE_NAME_SIGNATURE }, { HCI_CONNECTIONS, handle_display_conn_req, HCI_CONNECTIONS_SIGNATURE }, { HCI_AUTHENTICATE, handle_auth_req, HCI_AUTHENTICATE_SIGNATURE }, - { NULL, NULL, NULL } + { NULL, NULL, NULL } }; static void reply_handler_function(DBusPendingCall *call, void *user_data) @@ -352,7 +384,7 @@ static void free_pin_req(void *req) free(req); } -static gboolean register_dbus_path(char *path, uint16_t id) +static gboolean register_dbus_path(char *path, uint16_t id, const DBusObjectPathVTable *pvtable) { struct hci_dbus_data *data; syslog(LOG_INFO,"Registering DBUS Path: %s", path); @@ -363,7 +395,7 @@ static gboolean register_dbus_path(char *path, uint16_t id) } data->id = id; - if (!dbus_connection_register_object_path(connection, path, &obj_vtable, data)) { + if (!dbus_connection_register_object_path(connection, path, pvtable, data)) { syslog(LOG_ERR,"DBUS failed to register %s object", path); free(data); return FALSE; @@ -377,11 +409,11 @@ static gboolean unregister_dbus_path(char *path) syslog(LOG_INFO,"Unregistering DBUS Path: %s", path); if (dbus_connection_get_object_path_data(connection, path, &data) && data) free(data); - + if (!dbus_connection_unregister_object_path (connection, path)) { syslog(LOG_ERR,"DBUS failed to unregister %s object", path); return FALSE; - } + } return TRUE; } @@ -811,7 +843,7 @@ gboolean hcid_dbus_init(void) data->id = DEVICE_PATH_ID; if (!dbus_connection_register_fallback(connection, DEVICE_PATH, - &obj_vtable, data)) { + &obj_dev_vtable, data)) { syslog(LOG_ERR, "Can't register %s object", DEVICE_PATH); return FALSE; } @@ -823,7 +855,7 @@ gboolean hcid_dbus_init(void) data->id = MANAGER_PATH_ID; if (!dbus_connection_register_fallback(connection, MANAGER_PATH, - &obj_vtable, data)) { + &obj_mgr_vtable, data)) { syslog(LOG_ERR, "Can't register %s object", MANAGER_PATH); return FALSE; } @@ -936,7 +968,7 @@ gboolean hcid_dbus_register_device(uint16_t id) snprintf(path, sizeof(path), "%s/%s", DEVICE_PATH, pdev); /* register the default path*/ - return register_dbus_path(path, id); + return register_dbus_path(path, id, &obj_dev_vtable); } gboolean hcid_dbus_unregister_device(uint16_t id) @@ -1066,12 +1098,12 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) /* register the default path*/ if (!dft_reg) { snprintf(path, sizeof(path), "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); - register_dbus_path(path, DEFAULT_DEVICE_PATH_ID); + register_dbus_path(path, DEFAULT_DEVICE_PATH_ID, &obj_mgr_vtable); } /* register the default path*/ snprintf(path, sizeof(path), "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); - register_dbus_path(path, id); + register_dbus_path(path, id, &obj_mgr_vtable); return 0; } @@ -1146,7 +1178,81 @@ static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *m * */ -static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void *data) +static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data) +{ + const struct service_data *ptr_handlers = NULL; + DBusMessage *reply = NULL; + int type; + const char *iface; + const char *method; + const char *signature; + const char *path; + struct hci_dbus_data *dbus_data = data; + uint32_t result = BLUEZ_EDBUS_UNKNOWN_METHOD; + DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + uint8_t found = 0; + + path = dbus_message_get_path(msg); + type = dbus_message_get_type(msg); + iface = dbus_message_get_interface(msg); + method = dbus_message_get_member(msg); + signature = dbus_message_get_signature(msg); + + if (strcmp(iface, DEVICE_INTERFACE)) + return ret; + + if (strcmp(path, DEVICE_PATH) > 0) { + if (dbus_data->id == DEVICE_PATH_ID) { + /* fallback handling. The child path IS NOT registered */ + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_UNKNOWN_PATH); + ret = DBUS_HANDLER_RESULT_HANDLED; + } else { + /* hciX code */ + } + } else { + /* it's the device path */ + ptr_handlers = dev_root_services; + found = 1; + } + + if (found && (type == DBUS_MESSAGE_TYPE_METHOD_CALL) && (method != NULL)) { + + for (; ptr_handlers->name; ptr_handlers++) { + if (strcmp(method, ptr_handlers->name) == 0) { + /* resetting unknown method. It's possible handle method overload */ + result = BLUEZ_EDBUS_WRONG_SIGNATURE; + if (strcmp(ptr_handlers->signature, signature) == 0) { + if (ptr_handlers->handler_func) { + reply = (ptr_handlers->handler_func) (msg, data); + result = 0; /* resetting wrong signature*/ + } else + syslog(LOG_INFO, "Service not implemented"); + + break; + } + + } + } + + if (result) { + reply = bluez_new_failure_msg(msg, result); + } + + ret = DBUS_HANDLER_RESULT_HANDLED; + } + + /* send an error or the success reply*/ + if (reply) { + if (!dbus_connection_send (conn, reply, NULL)) { + syslog(LOG_ERR, "Can't send reply message!"); + } + dbus_message_unref (reply); + } + + return ret; +} + +static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data) { const struct service_data *ptr_handlers = NULL; DBusMessage *reply = NULL; @@ -1156,7 +1262,6 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * const char *signature; const char *path; const char *rel_path; - const char *tmp_iface = NULL; struct hci_dbus_data *dbus_data = data; uint32_t result = BLUEZ_EDBUS_UNKNOWN_METHOD; DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -1170,43 +1275,38 @@ static DBusHandlerResult msg_func(DBusConnection *conn, DBusMessage *msg, void * syslog (LOG_INFO, "%s - path:%s, id:0x%X", __PRETTY_FUNCTION__, path, dbus_data->id); - if (strcmp(path, DEVICE_PATH) == 0) { - ptr_handlers = dev_services; - tmp_iface = DEVICE_INTERFACE; - found = 1; - } else { - if (strcmp(path, MANAGER_PATH) > 0) { - /* it is device specific path */ - if ( dbus_data->id == MANAGER_PATH_ID ) { - /* fallback handling. The child path IS NOT registered */ - reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_UNKNOWN_PATH); - ret = DBUS_HANDLER_RESULT_HANDLED; - } else { - const struct profile_obj_path_data *mgr_child = obj_path_table; - rel_path = strrchr(path,'/'); - rel_path++; - - if (rel_path) { - for ( ;mgr_child->name; mgr_child++) { - if (strcmp(mgr_child->name, rel_path) == 0) { - ptr_handlers = mgr_child->get_svc_table(); - found = 1; - } - } + if (strcmp(iface, MANAGER_INTERFACE)) + return ret; - tmp_iface = MANAGER_INTERFACE; + if (strcmp(path, MANAGER_PATH) > 0) { + /* it is device specific path */ + if (dbus_data->id == MANAGER_PATH_ID) { + /* fallback handling. The child path IS NOT registered */ + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_UNKNOWN_PATH); + ret = DBUS_HANDLER_RESULT_HANDLED; + } else { + const struct profile_obj_path_data *mgr_child = obj_path_table; + rel_path = strrchr(path,'/'); + rel_path++; + + if (rel_path) { + for ( ;mgr_child->name; mgr_child++) { + if (strcmp(mgr_child->name, rel_path) == 0) { + ptr_handlers = mgr_child->get_svc_table(); + found = 1; + break; + } } + } - } else { - /* it's the manager path */ - ptr_handlers = mgr_services; - tmp_iface = MANAGER_INTERFACE; - found = 1; } + } else { + /* it's the manager! path */ + ptr_handlers = mgr_services; + found = 1; } - if (found && (type == DBUS_MESSAGE_TYPE_METHOD_CALL) && - (strcmp(iface, tmp_iface) == 0) && (method != NULL)) { + if (found && (type == DBUS_MESSAGE_TYPE_METHOD_CALL) && (method != NULL)) { for (; ptr_handlers->name; ptr_handlers++) { if (strcmp(method, ptr_handlers->name) == 0) { @@ -1399,20 +1499,21 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) goto failed; } - cp.lap[0] = 0x33; - cp.lap[1] = 0x8b; - cp.lap[2] = 0x9e; - cp.length = length; + memset(&cp, 0, sizeof(cp)); + cp.lap[0] = 0x33; + cp.lap[1] = 0x8b; + cp.lap[2] = 0x9e; + cp.length = length; cp.num_rsp = num_rsp; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_INQUIRY; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_INQUIRY; rq.cparam = &cp; - rq.clen = INQUIRY_CP_SIZE; + rq.clen = INQUIRY_CP_SIZE; rq.rparam = &rp; - rq.rlen = EVT_CMD_STATUS_SIZE; - rq.event = EVT_CMD_STATUS; + rq.rlen = EVT_CMD_STATUS_SIZE; + rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to start inquiry: %s", strerror(errno)); @@ -1565,13 +1666,13 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) cp.pscan_rep_mode = 0x01; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_REMOTE_NAME_REQ; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_REMOTE_NAME_REQ; rq.cparam = &cp; - rq.clen = REMOTE_NAME_REQ_CP_SIZE; + rq.clen = REMOTE_NAME_REQ_CP_SIZE; rq.rparam = &rp; - rq.rlen = EVT_CMD_STATUS_SIZE; - rq.event = EVT_CMD_STATUS; + rq.rlen = EVT_CMD_STATUS_SIZE; + rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to send remote name request: %s", strerror(errno)); @@ -1719,13 +1820,13 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) cp.handle = cr->conn_info->handle; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_AUTH_REQUESTED; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_AUTH_REQUESTED; rq.cparam = &cp; - rq.clen = AUTH_REQUESTED_CP_SIZE; + rq.clen = AUTH_REQUESTED_CP_SIZE; rq.rparam = &rp; - rq.rlen = EVT_CMD_STATUS_SIZE; - rq.event = EVT_CMD_STATUS; + rq.rlen = EVT_CMD_STATUS_SIZE; + rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to send authentication request: %s", strerror(errno)); @@ -1748,8 +1849,111 @@ failed: * Section reserved to Manager D-Bus message handlers * *****************************************************************/ +static DBusMessage* handle_get_devices_req_device(DBusMessage *msg, void *data) +{ + DBusMessageIter iter; + DBusMessageIter array_iter; + DBusMessageIter flag_array_iter; + DBusMessageIter struct_iter; + DBusMessage *reply = NULL; + struct hci_dev_list_req *dl = NULL; + struct hci_dev_req *dr = NULL; + struct hci_dev_info di; + int sk = -1; + int i; + char aname[BLUETOOTH_DEVICE_NAME_LEN+1]; + char aaddr[BLUETOOTH_DEVICE_ADDR_LEN]; + char aflag[DEVICE_FLAG_NAME]; + char *paddr = aaddr; + char *pname = aname; + char *pflag = aflag; + char *ptype; + const char array_sig[] = DEV_GET_DEV_REPLY_STRUCT_SIGNATURE; + hci_map *mp; + + /* Create and bind HCI socket */ + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) { + syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); + if (!dl) { + syslog(LOG_ERR, "Can't allocate memory"); + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); + goto failed; + } + + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(sk, HCIGETDEVLIST, dl) < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + /* active bluetooth adapter found */ + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); + dr = dl->dev_req; + + for (i = 0; i < dl->dev_num; i++, dr++) { + mp = dev_flags_map; + memset(&di, 0 , sizeof(struct hci_dev_info)); + di.dev_id = dr->dev_id; + + if (ioctl(sk, HCIGETDEVINFO, &di) < 0) + continue; + + strncpy(aname, di.name, BLUETOOTH_DEVICE_NAME_LEN); + aname[BLUETOOTH_DEVICE_NAME_LEN] = '\0'; + + ba2str(&di.bdaddr, aaddr); + ptype = hci_dtypetostr(di.type); + + dbus_message_iter_open_container(&array_iter, + DBUS_TYPE_STRUCT, NULL, &struct_iter); + + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &pname); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &paddr); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &ptype); + + if (hci_test_bit(HCI_UP, &dr->dev_opt)) { + sprintf(pflag, "%s", "UP"); + } else { + sprintf(pflag, "%s", "DOWN"); + } + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &pflag); + + dbus_message_iter_open_container(&struct_iter, + DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &flag_array_iter); + + while (mp->str) { + if (hci_test_bit(mp->val, &dr->dev_opt)) { + sprintf(pflag, "%s", mp->str); + dbus_message_iter_append_basic(&flag_array_iter, DBUS_TYPE_STRING, &pflag); + } + mp++; + } + dbus_message_iter_close_container(&struct_iter, &flag_array_iter); + dbus_message_iter_close_container(&array_iter, &struct_iter); + } + + dbus_message_iter_close_container(&iter, &array_iter); + +failed: + if (sk >= 0) + close(sk); + if (dl) + free(dl); + return reply; +} + -static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data) +static DBusMessage* handle_get_devices_req_manager(DBusMessage *msg, void *data) { DBusMessageIter iter; DBusMessageIter array_iter; diff --git a/hcid/dbus.h b/hcid/dbus.h index 8ba45517..4ac2f738 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -44,17 +44,35 @@ /*======================================================================== BlueZ D-Bus Device service definitions "/org/bluez/Device" *========================================================================*/ +#define DEV_GET_DEV "DeviceList" #define DEV_UP "Up" #define DEV_DOWN "Down" #define DEV_RESET "Reset" #define DEV_SET_PROPERTY "SetProperty" #define DEV_GET_PROPERTY "GetProperty" -#define DEV_UP_SIGNATURE __END_SIG__ -#define DEV_DOWN_SIGNATURE __END_SIG__ -#define DEV_RESET_SIGNATURE __END_SIG__ -#define DEV_SET_PROPERTY_SIGNATURE __END_SIG__ -#define DEV_GET_PROPERTY_SIGNATURE __END_SIG__ +#define DEV_GET_DEV_SIGNATURE __END_SIG__ + +/* DeviceList Reply: a(devname, addr, type, up/down, a(flags)) - all types strings */ +#define DEV_GET_DEV_REPLY_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_ARRAY_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_STRUCT_END_CHAR_AS_STRING \ + __END_SIG__ + +#define DEV_GET_DEV_REPLY_SIGNATURE DBUS_TYPE_ARRAY_AS_STRING \ + DEV_GET_DEV_REPLY_STRUCT_SIGNATURE \ + __END_SIG__ + +#define DEV_UP_SIGNATURE __END_SIG__ +#define DEV_DOWN_SIGNATURE __END_SIG__ +#define DEV_RESET_SIGNATURE __END_SIG__ +#define DEV_SET_PROPERTY_SIGNATURE __END_SIG__ +#define DEV_GET_PROPERTY_SIGNATURE __END_SIG__ /*======================================================================== BlueZ D-Bus Manager service definitions "/org/bluez/Manager" @@ -68,14 +86,14 @@ #define MGR_ENABLE "Enable" #define MGR_DISABLE "Disable" -//signatures +/* Signatures */ #define MGR_GET_DEV_SIGNATURE __END_SIG__ -/* yya(ss)*/ -#define MGR_GET_DEV_REPLY_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ - DBUS_TYPE_BYTE_AS_STRING\ - DBUS_TYPE_ARRAY_AS_STRING\ - HCI_DEVICE_STRUCT_SIGNATURE\ +/* yya(ss) */ +#define MGR_GET_DEV_REPLY_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_ARRAY_AS_STRING \ + HCI_DEVICE_STRUCT_SIGNATURE \ __END_SIG__ /* ===== HCI definitions ===== */ @@ -83,7 +101,7 @@ #define BLUEZ_HCI_PATH MANAGER_PATH "/" BLUEZ_HCI #define BLUEZ_HCI_INTERFACE MANAGER_INTERFACE "." BLUEZ_HCI -//Device based HCI signals +/* Device based HCI signals */ #define BLUEZ_HCI_INQ_START "InquiryStart" #define BLUEZ_HCI_INQ_COMPLETE "InquiryComplete" #define BLUEZ_HCI_INQ_RESULT "InquiryResult" @@ -91,11 +109,11 @@ #define BLUEZ_HCI_REMOTE_NAME_FAILED "RemoteNameFailed" #define BLUEZ_HCI_AUTH_COMPLETE "AuthenticationComplete" -//HCI signals sent in the BLUEZ_HCI_PATH +/* HCI signals sent in the BLUEZ_HCI_PATH */ #define BLUEZ_HCI_DEV_ADDED "DeviceAdded" #define BLUEZ_HCI_DEV_REMOVED "DeviceRemoved" -//HCI Provided services +/* HCI Provided services */ #define HCI_PERIODIC_INQ "PeriodicInquiry" #define HCI_CANCEL_PERIODIC_INQ "CancelPeriodic" #define HCI_INQ "Inquiry" @@ -106,51 +124,52 @@ #define HCI_AUTHENTICATE "Authenticate" -#define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ - DBUS_TYPE_BYTE_AS_STRING\ - DBUS_TYPE_BYTE_AS_STRING\ +#define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ __END_SIG__ #define HCI_CANCEL_PERIODIC_INQ_SIGNATURE __END_SIG__ -#define HCI_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ - DBUS_TYPE_BYTE_AS_STRING\ +#define HCI_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ __END_SIG__ #define HCI_CANCEL_INQ_SIGNATURE __END_SIG__ -#define HCI_ROLE_SWITCH_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ - DBUS_TYPE_BYTE_AS_STRING\ +#define HCI_ROLE_SWITCH_SIGNATURE DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ __END_SIG__ - -#define HCI_REMOTE_NAME_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ + +#define HCI_REMOTE_NAME_SIGNATURE DBUS_TYPE_STRING_AS_STRING \ __END_SIG__ - + #define HCI_CONNECTIONS_SIGNATURE __END_SIG__ -#define HCI_CONN_INFO_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING\ - DBUS_TYPE_UINT16_AS_STRING\ - DBUS_TYPE_STRING_AS_STRING\ - DBUS_TYPE_BYTE_AS_STRING\ - DBUS_TYPE_BYTE_AS_STRING\ - DBUS_TYPE_UINT16_AS_STRING\ - DBUS_TYPE_UINT32_AS_STRING\ - DBUS_STRUCT_END_CHAR_AS_STRING\ +#define HCI_CONN_INFO_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ + DBUS_STRUCT_END_CHAR_AS_STRING \ __END_SIG__ -#define HCI_DEVICE_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING\ - DBUS_TYPE_STRING_AS_STRING\ - DBUS_TYPE_STRING_AS_STRING\ - DBUS_STRUCT_END_CHAR_AS_STRING +#define HCI_DEVICE_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_STRUCT_END_CHAR_AS_STRING \ + __END_SIG__ -#define HCI_INQ_REPLY_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING\ - DBUS_TYPE_STRING_AS_STRING\ - DBUS_TYPE_UINT32_AS_STRING\ - DBUS_TYPE_UINT16_AS_STRING\ - DBUS_STRUCT_END_CHAR_AS_STRING\ +#define HCI_INQ_REPLY_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ + DBUS_STRUCT_END_CHAR_AS_STRING \ __END_SIG__ -#define HCI_AUTHENTICATE_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ +#define HCI_AUTHENTICATE_SIGNATURE DBUS_TYPE_STRING_AS_STRING \ __END_SIG__ -- cgit From df7165e91fc0954488a5db6ce235ae4f8896099f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Oct 2005 16:41:53 +0000 Subject: Update changelog and bump version number --- ChangeLog | 10 ++++++++++ configure.in | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c75057be..111275bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +ver 2.22: + Remove D-Bus 0.23 support. + Add initial version of the new D-Bus interface. + Add support for extended inquiry response commands. + Add support for the Logitech diNovo Media Desktop Laser. + Add compile time buffer checks (FORTIFY SOURCE). + + Note: + This version needs at least bluez-libs-2.22 + ver 2.21: Move create_dirs() and create_file() into the textfile library. Let textfile_put() also replace the last key value pair. diff --git a/configure.in b/configure.in index 977a04ef..aa47db4b 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.21) +AM_INIT_AUTOMAKE(bluez-utils, 2.22) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From f1ba02d0f86e0e954ac7a27d4beee3a6ee386223 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Oct 2005 23:56:42 +0000 Subject: Add support for big endian architectures --- tools/dfutool.c | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/tools/dfutool.c b/tools/dfutool.c index 451ce957..0de67bb1 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include @@ -43,6 +45,20 @@ #include "dfu.h" +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define cpu_to_le16(d) (d) +#define cpu_to_le32(d) (d) +#define le16_to_cpu(d) (d) +#define le32_to_cpu(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le16(d) bswap_16(d) +#define cpu_to_le32(d) bswap_32(d) +#define le16_to_cpu(d) bswap_16(d) +#define le32_to_cpu(d) bswap_32(d) +#else +#error "Unknown byte order" +#endif + #ifdef NEED_USB_GET_BUSSES static inline struct usb_bus *usb_get_busses(void) { @@ -211,9 +227,9 @@ static struct usb_dev_handle *open_device(char *device, struct dfu_suffix *suffi fflush(stdout); if (suffix) { - suffix->idVendor = dfu_dev[sel]->descriptor.idVendor; - suffix->idProduct = dfu_dev[sel]->descriptor.idProduct; - suffix->bcdDevice = dfu_dev[sel]->descriptor.bcdDevice; + suffix->idVendor = cpu_to_le16(dfu_dev[sel]->descriptor.idVendor); + suffix->idProduct = cpu_to_le16(dfu_dev[sel]->descriptor.idProduct); + suffix->bcdDevice = cpu_to_le16(dfu_dev[sel]->descriptor.bcdDevice); } if (dfu_detach(udev, intf) < 0) { @@ -302,6 +318,7 @@ static void cmd_verify(char *device, int argc, char **argv) struct stat st; struct dfu_suffix *suffix; uint32_t crc; + uint16_t bcd; char str[16]; unsigned char *buf; unsigned long size; @@ -358,17 +375,19 @@ static void cmd_verify(char *device, int argc, char **argv) suffix = (struct dfu_suffix *) (buf + size - DFU_SUFFIX_SIZE); - printf("idVendor\t%04x\n", suffix->idVendor); - printf("idProduct\t%04x\n", suffix->idProduct); - printf("bcdDevice\t%x\n", suffix->bcdDevice); + printf("idVendor\t%04x\n", le16_to_cpu(suffix->idVendor)); + printf("idProduct\t%04x\n", le16_to_cpu(suffix->idProduct)); + printf("bcdDevice\t%x\n", le16_to_cpu(suffix->bcdDevice)); printf("\n"); - printf("bcdDFU\t\t%x.%x\n", suffix->bcdDFU >> 8, suffix->bcdDFU & 0xff); + bcd = le16_to_cpu(suffix->bcdDFU); + + printf("bcdDFU\t\t%x.%x\n", bcd >> 8, bcd & 0xff); printf("ucDfuSignature\t%c%c%c\n", suffix->ucDfuSignature[2], suffix->ucDfuSignature[1], suffix->ucDfuSignature[0]); printf("bLength\t\t%d\n", suffix->bLength); - printf("dwCRC\t\t%08x\n", suffix->dwCRC); + printf("dwCRC\t\t%08x\n", le32_to_cpu(suffix->dwCRC)); printf("\n"); memset(str, 0, sizeof(str)); @@ -402,7 +421,7 @@ static void cmd_upgrade(char *device, int argc, char **argv) char *buf; unsigned long filesize, count, timeout = 0; char *filename; - uint32_t crc; + uint32_t crc, dwCRC; int fd, i, block, len, size, sent = 0, try = 10; if (argc < 2) { @@ -438,6 +457,7 @@ static void cmd_upgrade(char *device, int argc, char **argv) } memcpy(&suffix, buf + filesize - DFU_SUFFIX_SIZE, sizeof(suffix)); + dwCRC = le32_to_cpu(suffix.dwCRC); printf("Filename\t%s\n", basename(filename)); printf("Filesize\t%ld\n", filesize); @@ -445,10 +465,11 @@ static void cmd_upgrade(char *device, int argc, char **argv) crc = crc32_init(); for (i = 0; i < filesize - 4; i++) crc = crc32_byte(crc, buf[i]); + printf("Checksum\t%08x (%s)\n", crc, - crc == suffix.dwCRC ? "valid" : "corrupt"); + crc == dwCRC ? "valid" : "corrupt"); - if (crc != suffix.dwCRC) { + if (crc != dwCRC) { free(buf); close(fd); exit(1); @@ -654,7 +675,7 @@ static void cmd_archive(char *device, int argc, char **argv) } printf("\n"); - suffix.bcdDFU = 0x0100; + suffix.bcdDFU = cpu_to_le16(0x0100); suffix.ucDfuSignature[0] = 'U'; suffix.ucDfuSignature[1] = 'F'; suffix.ucDfuSignature[2] = 'D'; @@ -664,7 +685,7 @@ static void cmd_archive(char *device, int argc, char **argv) for (i = 0; i < DFU_SUFFIX_SIZE - 4; i++) crc = crc32_byte(crc, buf[i]); - suffix.dwCRC = crc; + suffix.dwCRC = cpu_to_le32(crc); write(fd, &suffix, DFU_SUFFIX_SIZE); -- cgit From 0443fc32d957c04964d6b875fbb203980b57775a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 16:41:24 +0000 Subject: Implement the interface redesign --- hcid/dbus.c | 731 ++++++++++++++++++++++-------------------------------------- hcid/dbus.h | 94 ++++---- hcid/hcid.h | 5 +- hcid/main.c | 10 +- 4 files changed, 319 insertions(+), 521 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 399856ff..b9838b0a 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -45,15 +45,16 @@ #include "dbus.h" static DBusConnection *connection; +static int default_dev = -1; static int up_adapters = 0; -#define TIMEOUT (30 * 1000) /* 30 seconds */ -#define BLUETOOTH_DEVICE_NAME_LEN (18) -#define BLUETOOTH_DEVICE_ADDR_LEN (18) -#define MAX_PATH_LENGTH (64) -#define READ_REMOTE_NAME_TIMEOUT (25000) -#define MAX_CONN_NUMBER (10) -#define DEVICE_FLAG_NAME (16) +#define TIMEOUT (30 * 1000) /* 30 seconds */ +#define BLUETOOTH_DEVICE_NAME_LEN 18 +#define BLUETOOTH_DEVICE_ADDR_LEN 18 +#define MAX_PATH_LENGTH 64 +#define READ_REMOTE_NAME_TIMEOUT 25000 +#define MAX_CONN_NUMBER 10 +#define DEVICE_FLAG_NAME 16 #define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent" #define PINAGENT_INTERFACE PINAGENT_SERVICE_NAME @@ -77,13 +78,13 @@ struct hci_dbus_data { uint16_t id; }; -typedef int register_function_t(DBusConnection *conn, int dft_reg, uint16_t id); -typedef int unregister_function_t(DBusConnection *conn, int unreg_dft, uint16_t id); +typedef int register_function_t(DBusConnection *conn, uint16_t id); +typedef int unregister_function_t(DBusConnection *conn, uint16_t id); const struct service_data *get_hci_table(void); -static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id); -static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t id); +static int hci_dbus_reg_obj_path(DBusConnection *conn, uint16_t id); +static int hci_dbus_unreg_obj_path(DBusConnection *conn, uint16_t id); typedef const struct service_data *get_svc_table_func_t(void); @@ -257,8 +258,8 @@ static struct profile_obj_path_data obj_path_table[] = { static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data); static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data); -static DBusMessage* handle_get_devices_req_device(DBusMessage *msg, void *data); -static DBusMessage* handle_get_devices_req_manager(DBusMessage *msg, void *data); +static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data); +static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data); static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data); static const DBusObjectPathVTable obj_dev_vtable = { @@ -271,16 +272,7 @@ static const DBusObjectPathVTable obj_mgr_vtable = { .unregister_function = NULL }; -/* - * Service provided under the path DEVICE_PATH - * TODO add the handlers - */ -static const struct service_data dev_root_services[] = { - { DEV_GET_DEV, handle_get_devices_req_device, DEV_GET_DEV_SIGNATURE }, - { NULL, NULL, NULL} -}; - -static const struct service_data dev_services[] = { +static const struct service_data device_services[] = { { DEV_UP, handle_not_implemented_req, DEV_UP_SIGNATURE }, { DEV_DOWN, handle_not_implemented_req, DEV_DOWN_SIGNATURE }, { DEV_RESET, handle_not_implemented_req, DEV_RESET_SIGNATURE }, @@ -293,11 +285,12 @@ static const struct service_data dev_services[] = { * Manager Message handler functions object table declaration * */ -static const struct service_data mgr_services[] = { - { MGR_GET_DEV, handle_get_devices_req_manager, MGR_GET_DEV_SIGNATURE }, - { MGR_INIT, handle_not_implemented_req, NULL }, - { MGR_ENABLE, handle_not_implemented_req, NULL }, - { MGR_DISABLE, handle_not_implemented_req, NULL }, +static const struct service_data manager_services[] = { + { MGR_DEVICE_LIST, handle_device_list_req, MGR_GET_DEV_SIGNATURE }, + { MGR_DEFAULT_DEVICE, handle_default_device_req, MGR_DEFAULT_DEV_SIGNATURE }, + { MGR_INIT, handle_not_implemented_req, NULL }, + { MGR_ENABLE, handle_not_implemented_req, NULL }, + { MGR_DISABLE, handle_not_implemented_req, NULL }, { NULL, NULL, NULL } }; @@ -316,7 +309,7 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data); static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data); static DBusMessage* handle_auth_req(DBusMessage *msg, void *data); -static const struct service_data hci_services[] = { +static const struct service_data device_hci_services[] = { { HCI_PERIODIC_INQ, handle_periodic_inq_req, HCI_PERIODIC_INQ_SIGNATURE }, { HCI_CANCEL_PERIODIC_INQ, handle_cancel_periodic_inq_req, HCI_CANCEL_PERIODIC_INQ_SIGNATURE }, { HCI_ROLE_SWITCH, handle_role_switch_req, HCI_ROLE_SWITCH_SIGNATURE }, @@ -384,7 +377,7 @@ static void free_pin_req(void *req) free(req); } -static gboolean register_dbus_path(char *path, uint16_t id, const DBusObjectPathVTable *pvtable) +static gboolean register_dbus_path(const char *path, uint16_t id, const DBusObjectPathVTable *pvtable) { struct hci_dbus_data *data; syslog(LOG_INFO,"Registering DBUS Path: %s", path); @@ -403,7 +396,7 @@ static gboolean register_dbus_path(char *path, uint16_t id, const DBusObjectPath return TRUE; } -static gboolean unregister_dbus_path(char *path) +static gboolean unregister_dbus_path(const char *path) { void *data; syslog(LOG_INFO,"Unregistering DBUS Path: %s", path); @@ -477,10 +470,10 @@ void hcid_dbus_inquiry_start(bdaddr_t *local) goto failed; } - snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); - message = dbus_message_new_signal(path, - BLUEZ_HCI_INTERFACE, BLUEZ_HCI_INQ_START); + message = dbus_message_new_signal(path, DEV_HCI_INTERFACE, + BLUEZ_HCI_INQ_START); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry start message"); goto failed; @@ -517,10 +510,10 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local) goto failed; } - snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); - message = dbus_message_new_signal(path, - BLUEZ_HCI_INTERFACE, BLUEZ_HCI_INQ_COMPLETE); + message = dbus_message_new_signal(path, DEV_HCI_INTERFACE, + BLUEZ_HCI_INQ_COMPLETE); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); goto failed; @@ -560,10 +553,10 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i goto failed; } - snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); - message = dbus_message_new_signal(path, - BLUEZ_HCI_INTERFACE, BLUEZ_HCI_INQ_RESULT); + message = dbus_message_new_signal(path, DEV_HCI_INTERFACE, + BLUEZ_HCI_INQ_RESULT); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry result message"); goto failed; @@ -608,10 +601,10 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) goto failed; } - snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); - message = dbus_message_new_signal(path, - BLUEZ_HCI_INTERFACE, BLUEZ_HCI_REMOTE_NAME); + message = dbus_message_new_signal(path, DEV_HCI_INTERFACE, + BLUEZ_HCI_REMOTE_NAME); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; @@ -655,19 +648,19 @@ void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t statu goto failed; } - snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); - message = dbus_message_new_signal(path, - BLUEZ_HCI_INTERFACE, BLUEZ_HCI_REMOTE_NAME_FAILED); + message = dbus_message_new_signal(path, DEV_HCI_INTERFACE, + BLUEZ_HCI_REMOTE_NAME_FAILED); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; } dbus_message_append_args(message, - DBUS_TYPE_STRING, &peer_addr, - DBUS_TYPE_BYTE, &status, - DBUS_TYPE_INVALID); + DBUS_TYPE_STRING, &peer_addr, + DBUS_TYPE_BYTE, &status, + DBUS_TYPE_INVALID); if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS remote name message"); @@ -710,9 +703,10 @@ void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t stat goto failed; } - snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); - message = dbus_message_new_signal(path, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_AUTH_COMPLETE); + message = dbus_message_new_signal(path, DEV_HCI_INTERFACE, + BLUEZ_HCI_AUTH_COMPLETE); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; @@ -810,6 +804,26 @@ static void watch_toggled(DBusWatch *watch, void *data) remove_watch(watch, data); } +static gboolean unregister_device_path(const char *path) +{ + char **children = NULL; + + if (dbus_connection_list_registered(connection, path, &children)) { + for (; *children; children++) { + char child_path[MAX_PATH_LENGTH]; + + snprintf(child_path, sizeof(child_path), "%s/%s", path, *children); + + unregister_dbus_path(child_path); + } + + if (*children) + dbus_free_string_array(children); + } + + return unregister_dbus_path(path); +} + gboolean hcid_dbus_init(void) { struct hci_dbus_data *data; @@ -854,7 +868,7 @@ gboolean hcid_dbus_init(void) data->id = MANAGER_PATH_ID; - if (!dbus_connection_register_fallback(connection, MANAGER_PATH, + if (!dbus_connection_register_object_path(connection, MANAGER_PATH, &obj_mgr_vtable, data)) { syslog(LOG_ERR, "Can't register %s object", MANAGER_PATH); return FALSE; @@ -873,149 +887,137 @@ gboolean hcid_dbus_init(void) void hcid_dbus_exit(void) { - char path[MAX_PATH_LENGTH]; - char fst_parent[] = MANAGER_PATH; - char snd_parent[MAX_PATH_LENGTH]; - char **fst_level = NULL; - char **snd_level = NULL; - char *ptr1; - char *ptr2; - void *data = NULL; + char **children = NULL; if (!connection) return; - if (dbus_connection_get_object_path_data(connection, - DEVICE_PATH, &data)) { - if (data) { - free(data); - data = NULL; - } - } + /* Unregister all paths in Device path hierarchy */ + if (dbus_connection_list_registered(connection, DEVICE_PATH, &children)) { + + for (; *children; children++) { + char dev_path[MAX_PATH_LENGTH]; - if (!dbus_connection_unregister_object_path(connection, DEVICE_PATH)) - syslog(LOG_ERR, "Can't unregister %s object", DEVICE_PATH); + snprintf(dev_path, sizeof(dev_path), "%s/%s", DEVICE_PATH, *children); - if (dbus_connection_get_object_path_data(connection, - MANAGER_PATH, &data)) { - if (data) { - free(data); - data = NULL; + unregister_device_path(dev_path); } + + if (*children) + dbus_free_string_array(children); } - if (!dbus_connection_unregister_object_path(connection, MANAGER_PATH)) - syslog(LOG_ERR, "Can't unregister %s object", MANAGER_PATH); + unregister_dbus_path(DEVICE_PATH); + unregister_dbus_path(MANAGER_PATH); - if (dbus_connection_list_registered(connection, fst_parent, &fst_level)) { +} - for (; *fst_level; fst_level++) { - ptr1 = *fst_level; - snprintf(snd_parent, sizeof(snd_parent), "%s/%s", fst_parent, ptr1); +gboolean hcid_dbus_register_device(uint16_t id) +{ + char path[MAX_PATH_LENGTH]; + char *pptr = path; + gboolean ret; + DBusMessage *message = NULL; - if (dbus_connection_list_registered(connection, snd_parent, &snd_level)) { + snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); - if (!(*snd_level)) { - snprintf(path, sizeof(path), "%s/%s", MANAGER_PATH, ptr1); + message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE, + BLUEZ_MGR_DEV_ADDED); - if (dbus_connection_get_object_path_data(connection, - path, &data)) { - if (data) { - free(data); - data = NULL; - } - } + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); + goto out; + } - if (!dbus_connection_unregister_object_path(connection, path)) - syslog(LOG_ERR, "Can't unregister %s object", path); + dbus_message_append_args(message, + DBUS_TYPE_STRING, &pptr, + DBUS_TYPE_INVALID); - continue; - } + if (!dbus_connection_send(connection, message, NULL)) { + syslog(LOG_ERR, "Can't send D-BUS added device message"); + goto out; + } - for (; *snd_level; snd_level++) { - ptr2 = *snd_level; - snprintf(path, sizeof(path), "%s/%s/%s", MANAGER_PATH, ptr1, ptr2); + dbus_connection_flush(connection); - if (dbus_connection_get_object_path_data(connection, - path, &data)) { - if (data) { - free(data); - data = NULL; - } - } +out: + if (message) + dbus_message_unref(message); - if (!dbus_connection_unregister_object_path(connection, path)) - syslog(LOG_ERR, "Can't unregister %s object", path); - } + ret = register_dbus_path(path, id, &obj_dev_vtable); - if (*snd_level) - dbus_free_string_array(snd_level); - } - } + if (ret && default_dev < 0) + default_dev = id; - if (*fst_level) - dbus_free_string_array(fst_level); - } + return ret; } -gboolean hcid_dbus_register_device(uint16_t id) +gboolean hcid_dbus_unregister_device(uint16_t id) { + gboolean ret; + DBusMessage *message = NULL; char path[MAX_PATH_LENGTH]; - char dev[BLUETOOTH_DEVICE_NAME_LEN]; - const char *pdev = dev; + char *pptr = path; - snprintf(dev, sizeof(dev), HCI_DEVICE_NAME "%d", id); - snprintf(path, sizeof(path), "%s/%s", DEVICE_PATH, pdev); + snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); - /* register the default path*/ - return register_dbus_path(path, id, &obj_dev_vtable); -} + message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE, + BLUEZ_MGR_DEV_REMOVED); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); + goto out; + } -gboolean hcid_dbus_unregister_device(uint16_t id) -{ - char dev[BLUETOOTH_DEVICE_NAME_LEN]; - char path[MAX_PATH_LENGTH]; - const char *pdev = dev; + dbus_message_append_args(message, + DBUS_TYPE_STRING, &pptr, + DBUS_TYPE_INVALID); + + if (!dbus_connection_send(connection, message, NULL)) { + syslog(LOG_ERR, "Can't send D-BUS added device message"); + goto out; + } - snprintf(dev, sizeof(dev), HCI_DEVICE_NAME "%d", id); - snprintf(path, sizeof(path), "%s/%s", DEVICE_PATH, pdev); + dbus_connection_flush(connection); - return unregister_dbus_path(path); +out: + if (message) + dbus_message_unref(message); + + ret = unregister_device_path(path); + + /* FIXME: If there are any devices left after this removal the default + * device should be changed to one of them */ + if (ret && default_dev == id) + default_dev = -1; + + return ret; } -gboolean hcid_dbus_register_manager(uint16_t id) +gboolean hcid_dbus_dev_up(uint16_t id) { - char dev[BLUETOOTH_DEVICE_NAME_LEN]; + char path[MAX_PATH_LENGTH]; struct profile_obj_path_data *ptr = obj_path_table; DBusMessage *message = NULL; - const char *pdev = dev; - DBusMessageIter iter; - int ret = -1; if (!connection) return FALSE; for (; ptr->name; ptr++) { - ret = ptr->reg_func(connection, ptr->dft_reg, id); - ptr->dft_reg = 1; + if (ptr->reg_func(connection, id) < 0) + goto failed; } - if (!ret) - up_adapters++; + up_adapters++; + + snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); - message = dbus_message_new_signal(BLUEZ_HCI_PATH, - BLUEZ_HCI_INTERFACE, BLUEZ_HCI_DEV_ADDED); + message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_UP); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; } - snprintf(dev, sizeof(dev), HCI_DEVICE_NAME "%d", id); - - dbus_message_iter_init_append(message, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING ,&pdev); - if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS added device message"); goto failed; @@ -1032,40 +1034,30 @@ failed: return TRUE; } -gboolean hcid_dbus_unregister_manager(uint16_t id) +gboolean hcid_dbus_dev_down(uint16_t id) { - char dev[BLUETOOTH_DEVICE_NAME_LEN]; + char path[MAX_PATH_LENGTH]; struct profile_obj_path_data *ptr = obj_path_table; DBusMessage *message = NULL; - const char *pdev = dev; - DBusMessageIter iter; - int dft_unreg = 0; if (!connection) return FALSE; for (; ptr->name; ptr++) { - dft_unreg = (up_adapters > 1) ? 0 : 1; - up_adapters--; - ptr->unreg_func(connection, dft_unreg, id); - - if (dft_unreg ) - ptr->dft_reg = 0; + if (ptr->unreg_func(connection, id) < 0) + goto failed; } - message = dbus_message_new_signal(BLUEZ_HCI_PATH, - BLUEZ_HCI_INTERFACE, BLUEZ_HCI_DEV_REMOVED); + up_adapters--; + + snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); + message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_DOWN); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS device removed message"); goto failed; } - snprintf(dev, sizeof(dev), HCI_DEVICE_NAME "%d", id); - - dbus_message_iter_init_append(message, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING ,&pdev); - if (dbus_connection_send(connection, message, NULL) == FALSE) { syslog(LOG_ERR, "Can't send D-BUS removed device message"); goto failed; @@ -1087,23 +1079,17 @@ failed: * Detailed description: function responsible for register a new hci * D-Bus path. If necessary the default path must be registered too. * @param conn D-Bus connection - * @param dft_reg register the default path(0 or !0) * @param id hci device identification * @return (0-Success/-1 failure) */ -static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) +static int hci_dbus_reg_obj_path(DBusConnection *conn, uint16_t id) { char path[MAX_PATH_LENGTH]; /* register the default path*/ - if (!dft_reg) { - snprintf(path, sizeof(path), "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); - register_dbus_path(path, DEFAULT_DEVICE_PATH_ID, &obj_mgr_vtable); - } - - /* register the default path*/ - snprintf(path, sizeof(path), "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); - register_dbus_path(path, id, &obj_mgr_vtable); + snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); + if (!register_dbus_path(path, id, &obj_dev_vtable)) + return -1; return 0; } @@ -1118,25 +1104,20 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, int dft_reg, uint16_t id) * @param id hci device identification * @return (0-Success/-1 failure) */ -static int hci_dbus_unreg_obj_path(DBusConnection *conn, int unreg_dft, uint16_t id) +static int hci_dbus_unreg_obj_path(DBusConnection *conn, uint16_t id) { - int ret = 0; char path[MAX_PATH_LENGTH]; - if (unreg_dft) { - snprintf(path, sizeof(path), "%s/%s/%s", MANAGER_PATH, HCI_DEFAULT_DEVICE_NAME, BLUEZ_HCI); - unregister_dbus_path(path); - } + snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); + if (!unregister_dbus_path(path)) + return -1; - snprintf(path, sizeof(path), "%s/%s%d/%s", MANAGER_PATH, HCI_DEVICE_NAME, id, BLUEZ_HCI); - unregister_dbus_path(path); - - return ret; + return 0; } const struct service_data *get_hci_table(void) { - return hci_services; + return device_hci_services; } /***************************************************************** @@ -1173,24 +1154,20 @@ static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *m return ret; } -/* - * There is only one message handler function for all object paths - * - */ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data) { - const struct service_data *ptr_handlers = NULL; + const struct service_data *handlers = NULL; DBusMessage *reply = NULL; + struct hci_dbus_data *dbus_data = data; int type; + const char *child; const char *iface; const char *method; const char *signature; const char *path; - struct hci_dbus_data *dbus_data = data; - uint32_t result = BLUEZ_EDBUS_UNKNOWN_METHOD; + uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - uint8_t found = 0; path = dbus_message_get_path(msg); type = dbus_message_get_type(msg); @@ -1198,50 +1175,48 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, method = dbus_message_get_member(msg); signature = dbus_message_get_signature(msg); - if (strcmp(iface, DEVICE_INTERFACE)) + syslog(LOG_INFO, "%s - path:%s, id:%04X", __PRETTY_FUNCTION__, path, dbus_data->id); + + if (dbus_data->id == DEVICE_PATH_ID) return ret; - if (strcmp(path, DEVICE_PATH) > 0) { - if (dbus_data->id == DEVICE_PATH_ID) { - /* fallback handling. The child path IS NOT registered */ - reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_UNKNOWN_PATH); - ret = DBUS_HANDLER_RESULT_HANDLED; - } else { - /* hciX code */ + if (strcmp(path, DEVICE_PATH) == 0) + handlers = device_services; + else { + child = strrchr(path,'/'); + if (child && *child) { + struct profile_obj_path_data *profile; + child++; + + for (profile = obj_path_table ;profile->name != NULL; profile++) { + if (strcmp(profile->name, child) == 0) { + handlers = profile->get_svc_table(); + break; + } + } + } - } else { - /* it's the device path */ - ptr_handlers = dev_root_services; - found = 1; } - if (found && (type == DBUS_MESSAGE_TYPE_METHOD_CALL) && (method != NULL)) { - - for (; ptr_handlers->name; ptr_handlers++) { - if (strcmp(method, ptr_handlers->name) == 0) { - /* resetting unknown method. It's possible handle method overload */ - result = BLUEZ_EDBUS_WRONG_SIGNATURE; - if (strcmp(ptr_handlers->signature, signature) == 0) { - if (ptr_handlers->handler_func) { - reply = (ptr_handlers->handler_func) (msg, data); - result = 0; /* resetting wrong signature*/ - } else - syslog(LOG_INFO, "Service not implemented"); - - break; + if (handlers) { + for (; handlers->name != NULL; handlers++) { + if (strcmp(handlers->name, method) == 0) { + if (strcmp(handlers->signature, signature) != 0) + error = BLUEZ_EDBUS_WRONG_SIGNATURE; + else { + reply = handlers->handler_func(msg, data); + error = 0; } - + + ret = DBUS_HANDLER_RESULT_HANDLED; } } + } - if (result) { - reply = bluez_new_failure_msg(msg, result); - } + if (error) + reply = bluez_new_failure_msg(msg, error); - ret = DBUS_HANDLER_RESULT_HANDLED; - } - /* send an error or the success reply*/ if (reply) { if (!dbus_connection_send (conn, reply, NULL)) { syslog(LOG_ERR, "Can't send reply message!"); @@ -1254,88 +1229,45 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data) { - const struct service_data *ptr_handlers = NULL; + const struct service_data *handlers; DBusMessage *reply = NULL; - int type; const char *iface; const char *method; const char *signature; const char *path; - const char *rel_path; - struct hci_dbus_data *dbus_data = data; - uint32_t result = BLUEZ_EDBUS_UNKNOWN_METHOD; + uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - uint8_t found = 0; path = dbus_message_get_path(msg); - type = dbus_message_get_type(msg); iface = dbus_message_get_interface(msg); method = dbus_message_get_member (msg); signature = dbus_message_get_signature(msg); - syslog (LOG_INFO, "%s - path:%s, id:0x%X", __PRETTY_FUNCTION__, path, dbus_data->id); + syslog (LOG_INFO, "%s - path:%s", __PRETTY_FUNCTION__, path); - if (strcmp(iface, MANAGER_INTERFACE)) + if (strcmp(iface, MANAGER_INTERFACE) != 0) return ret; - if (strcmp(path, MANAGER_PATH) > 0) { - /* it is device specific path */ - if (dbus_data->id == MANAGER_PATH_ID) { - /* fallback handling. The child path IS NOT registered */ - reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_UNKNOWN_PATH); - ret = DBUS_HANDLER_RESULT_HANDLED; - } else { - const struct profile_obj_path_data *mgr_child = obj_path_table; - rel_path = strrchr(path,'/'); - rel_path++; - - if (rel_path) { - for ( ;mgr_child->name; mgr_child++) { - if (strcmp(mgr_child->name, rel_path) == 0) { - ptr_handlers = mgr_child->get_svc_table(); - found = 1; - break; - } - } - + for (handlers = manager_services; handlers->name != NULL; handlers++) { + if (strcmp(handlers->name, method) == 0) { + if (strcmp(handlers->signature, signature) != 0) + error = BLUEZ_EDBUS_WRONG_SIGNATURE; + else { + reply = handlers->handler_func(msg, data); + error = 0; } - } - } else { - /* it's the manager! path */ - ptr_handlers = mgr_services; - found = 1; - } - - if (found && (type == DBUS_MESSAGE_TYPE_METHOD_CALL) && (method != NULL)) { - for (; ptr_handlers->name; ptr_handlers++) { - if (strcmp(method, ptr_handlers->name) == 0) { - /* resetting unknown method. It's possible handle method overload */ - result = BLUEZ_EDBUS_WRONG_SIGNATURE; - if (strcmp(ptr_handlers->signature, signature) == 0) { - if (ptr_handlers->handler_func) { - reply = (ptr_handlers->handler_func)(msg, data); - result = 0; /* resetting wrong signature*/ - } else - syslog(LOG_INFO, "Service not implemented"); - - break; - } - - } + ret = DBUS_HANDLER_RESULT_HANDLED; } + } - if (result) { - reply = bluez_new_failure_msg(msg, result); - } + if (error) + reply = bluez_new_failure_msg(msg, error); - ret = DBUS_HANDLER_RESULT_HANDLED; - } - /* send an error or the success reply*/ if (reply) { if (!dbus_connection_send (conn, reply, NULL)) { - syslog(LOG_ERR, "Can't send reply message!") ; + syslog(LOG_ERR, "Can't send reply message!"); } dbus_message_unref (reply); } @@ -1354,20 +1286,8 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) uint8_t max_period; uint8_t min_period; int dd = -1; - int dev_id = -1; - - if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - dev_id = hci_get_route(NULL); - if (dev_id < 0) { - syslog(LOG_ERR, "Bluetooth device is not available"); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - goto failed; - - } - } else - dev_id = dbus_data->id; - dd = hci_open_dev(dev_id); + dd = hci_open_dev(dbus_data->id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); @@ -1378,7 +1298,7 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) dbus_message_iter_get_basic(&iter, &length); dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &min_period); - dbus_message_iter_next(&iter); + dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &max_period); if (length >= min_period || min_period >= max_period) { @@ -1427,19 +1347,8 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; int dd = -1; - int dev_id = -1; - - if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - dev_id = hci_get_route(NULL); - if (dev_id < 0) { - syslog(LOG_ERR, "Bluetooth device is not available"); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - goto failed; - } - } else - dev_id = dbus_data->id; - dd = hci_open_dev(dev_id); + dd = hci_open_dev(dbus_data->id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); @@ -1469,19 +1378,10 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) evt_cmd_status rp; struct hci_request rq; struct hci_dbus_data *dbus_data = data; - int dev_id = -1, dd = -1; + int dd = -1; int8_t length; int8_t num_rsp; - if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - if ((dev_id = hci_get_route(NULL)) < 0) { - syslog(LOG_ERR, "Bluetooth device is not available"); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - goto failed; - } - } else - dev_id = dbus_data->id; - dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &length); dbus_message_iter_next(&iter); @@ -1492,9 +1392,9 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) goto failed; } - dd = hci_open_dev(dev_id); + dd = hci_open_dev(dbus_data->id); if (dd < 0) { - syslog(LOG_ERR, "Unable to open device %d: %s", dev_id, strerror(errno)); + syslog(LOG_ERR, "Unable to open device %d: %s", dbus_data->id, strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1535,20 +1435,11 @@ static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data) DBusMessage *reply = NULL; struct hci_request rq; struct hci_dbus_data *dbus_data = data; - int dev_id = -1, dd = -1; - - if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - if ((dev_id = hci_get_route(NULL)) < 0) { - syslog(LOG_ERR, "Bluetooth device is not available"); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - goto failed; - } - } else - dev_id = dbus_data->id; + int dd = -1; - dd = hci_open_dev(dev_id); + dd = hci_open_dev(dbus_data->id); if (dd < 0) { - syslog(LOG_ERR, "Unable to open device %d: %s", dev_id, strerror(errno)); + syslog(LOG_ERR, "Unable to open device %d: %s", dbus_data->id, strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1580,8 +1471,7 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) struct hci_dbus_data *dbus_data = data; bdaddr_t bdaddr; uint8_t role; - int dev_id = -1; - int dd = -1; + int dev_id = -1, dd = -1; dbus_message_iter_init(msg, &iter); dbus_message_iter_get_basic(&iter, &str_bdaddr); @@ -1598,7 +1488,7 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) goto failed; } - if (dbus_data->id != DEFAULT_DEVICE_PATH_ID && dbus_data->id != dev_id) { + if (dbus_data->id != dev_id) { syslog(LOG_ERR, "Connection not found\n"); reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; @@ -1631,7 +1521,6 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) DBusMessageIter iter; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; - int dev_id = -1; int dd = -1; const char *str_bdaddr; bdaddr_t bdaddr; @@ -1644,19 +1533,9 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) str2ba(str_bdaddr, &bdaddr); - if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - dev_id = hci_get_route(&bdaddr); - if (dev_id < 0) { - syslog(LOG_ERR, "Bluetooth device is not available"); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - goto failed; - } - } else - dev_id = dbus_data->id; - - dd = hci_open_dev(dev_id); + dd = hci_open_dev(dbus_data->id); if (dd < 0) { - syslog(LOG_ERR, "Unable to open device %d: %s", dev_id, strerror(errno)); + syslog(LOG_ERR, "Unable to open device %d: %s", dbus_data->id, strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1701,21 +1580,9 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) const char array_sig[] = HCI_CONN_INFO_STRUCT_SIGNATURE; const char *paddr = addr; struct hci_dbus_data *dbus_data = data; - int dev_id = -1; int sk = -1; int i; - if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) { - dev_id = hci_get_route(NULL); - if (dev_id < 0) { - syslog(LOG_ERR, "Bluetooth device is not available"); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - goto failed; - } - } else { - dev_id = dbus_data->id; - } - sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); @@ -1728,7 +1595,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) goto failed; } - cl->dev_id = dev_id; + cl->dev_id = dbus_data->id; cl->conn_num = MAX_CONN_NUMBER; ci = cl->conn_info; @@ -1791,7 +1658,7 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) goto failed; } - if (dbus_data->id != DEFAULT_DEVICE_PATH_ID && dbus_data->id != dev_id) { + if (dbus_data->id != dev_id) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; } @@ -1849,27 +1716,16 @@ failed: * Section reserved to Manager D-Bus message handlers * *****************************************************************/ -static DBusMessage* handle_get_devices_req_device(DBusMessage *msg, void *data) +static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data) { DBusMessageIter iter; DBusMessageIter array_iter; - DBusMessageIter flag_array_iter; - DBusMessageIter struct_iter; DBusMessage *reply = NULL; struct hci_dev_list_req *dl = NULL; struct hci_dev_req *dr = NULL; - struct hci_dev_info di; int sk = -1; int i; - char aname[BLUETOOTH_DEVICE_NAME_LEN+1]; - char aaddr[BLUETOOTH_DEVICE_ADDR_LEN]; - char aflag[DEVICE_FLAG_NAME]; - char *paddr = aaddr; - char *pname = aname; - char *pflag = aflag; - char *ptype; - const char array_sig[] = DEV_GET_DEV_REPLY_STRUCT_SIGNATURE; - hci_map *mp; + const char array_sig[] = MGR_GET_DEV_REPLY_STRUCT_SIGNATURE; /* Create and bind HCI socket */ sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); @@ -1901,6 +1757,16 @@ static DBusMessage* handle_get_devices_req_device(DBusMessage *msg, void *data) dr = dl->dev_req; for (i = 0; i < dl->dev_num; i++, dr++) { + char apath[MAX_PATH_LENGTH]; + char aaddr[BLUETOOTH_DEVICE_ADDR_LEN]; + char *paddr = aaddr; + char *ppath = apath; + char *ptype; + const char *flag; + DBusMessageIter flag_array_iter, struct_iter; + struct hci_dev_info di; + hci_map *mp; + mp = dev_flags_map; memset(&di, 0 , sizeof(struct hci_dev_info)); di.dev_id = dr->dev_id; @@ -1908,8 +1774,7 @@ static DBusMessage* handle_get_devices_req_device(DBusMessage *msg, void *data) if (ioctl(sk, HCIGETDEVINFO, &di) < 0) continue; - strncpy(aname, di.name, BLUETOOTH_DEVICE_NAME_LEN); - aname[BLUETOOTH_DEVICE_NAME_LEN] = '\0'; + snprintf(apath, sizeof(apath), "%s/%s", DEVICE_PATH, di.name); ba2str(&di.bdaddr, aaddr); ptype = hci_dtypetostr(di.type); @@ -1917,25 +1782,23 @@ static DBusMessage* handle_get_devices_req_device(DBusMessage *msg, void *data) dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); - dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &pname); + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &ppath); dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &paddr); dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &ptype); - if (hci_test_bit(HCI_UP, &dr->dev_opt)) { - sprintf(pflag, "%s", "UP"); - } else { - sprintf(pflag, "%s", "DOWN"); - } - dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &pflag); + if (hci_test_bit(HCI_UP, &dr->dev_opt)) + flag = "UP"; + else + flag = "DOWN"; + + dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &flag); dbus_message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &flag_array_iter); while (mp->str) { - if (hci_test_bit(mp->val, &dr->dev_opt)) { - sprintf(pflag, "%s", mp->str); - dbus_message_iter_append_basic(&flag_array_iter, DBUS_TYPE_STRING, &pflag); - } + if (hci_test_bit(mp->val, &dr->dev_opt)) + dbus_message_iter_append_basic(&flag_array_iter, DBUS_TYPE_STRING, &mp->str); mp++; } dbus_message_iter_close_container(&struct_iter, &flag_array_iter); @@ -1952,86 +1815,28 @@ failed: return reply; } - -static DBusMessage* handle_get_devices_req_manager(DBusMessage *msg, void *data) -{ - DBusMessageIter iter; - DBusMessageIter array_iter; - DBusMessageIter struct_iter; +static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data) { + char path[MAX_PATH_LENGTH]; + char *pptr = path; DBusMessage *reply = NULL; - struct hci_dev_list_req *dl = NULL; - struct hci_dev_req *dr = NULL; - struct hci_dev_info di; - int sk = -1; - int i; - - char aname[BLUETOOTH_DEVICE_NAME_LEN]; - char aaddr[BLUETOOTH_DEVICE_ADDR_LEN]; - char *paddr = aaddr; - char *pname = aname; - const char array_sig[] = HCI_DEVICE_STRUCT_SIGNATURE; - - /* Create and bind HCI socket */ - sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (sk < 0) { - syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); - goto failed; - } - - dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); - if (!dl) { - syslog(LOG_ERR, "Can't allocate memory"); - reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_NO_MEM); - goto failed; - } - - dl->dev_num = HCI_MAX_DEV; - dr = dl->dev_req; - - if (ioctl(sk, HCIGETDEVLIST, dl) < 0) { - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); - goto failed; + if (default_dev < 0) { + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto out; } - /* active bluetooth adapter found */ reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); - dr = dl->dev_req; - - for (i = 0; i < dl->dev_num; i++, dr++) { - if (!hci_test_bit(HCI_UP, &dr->dev_opt)) - continue; - - memset(&di, 0 , sizeof(struct hci_dev_info)); - di.dev_id = dr->dev_id; - - if (ioctl(sk, HCIGETDEVINFO, &di) < 0) - continue; - - strcpy(aname, di.name); - ba2str(&di.bdaddr, aaddr); - - dbus_message_iter_open_container(&array_iter, - DBUS_TYPE_STRUCT, NULL, &struct_iter); - - dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &pname); - dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &paddr); - - dbus_message_iter_close_container(&array_iter, &struct_iter); + if (reply == NULL) { + syslog(LOG_ERR, "Out of memory while calling new_method_return"); + goto out; } - dbus_message_iter_close_container(&iter, &array_iter); - -failed: - if (sk >= 0) - close(sk); - - if (dl) - free(dl); + snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, default_dev); + dbus_message_append_args(reply, + DBUS_TYPE_STRING, &pptr, + DBUS_TYPE_INVALID); +out: return reply; } diff --git a/hcid/dbus.h b/hcid/dbus.h index 4ac2f738..1ec747a1 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -34,27 +34,31 @@ #define ERROR_INTERFACE BASE_INTERFACE ".Error" -#define DEFAULT_DEVICE_PATH_ID (0xFFFF) -#define MANAGER_PATH_ID (0xFFFE) -#define DEVICE_PATH_ID (0xFFFD) - -#define HCI_DEFAULT_DEVICE_NAME "default" -#define HCI_DEVICE_NAME "hci" +#define MANAGER_PATH_ID (0xFFFF) +#define DEVICE_PATH_ID (0xFFFE) /*======================================================================== - BlueZ D-Bus Device service definitions "/org/bluez/Device" + BlueZ D-Bus Manager service definitions "/org/bluez/Manager" *========================================================================*/ -#define DEV_GET_DEV "DeviceList" -#define DEV_UP "Up" -#define DEV_DOWN "Down" -#define DEV_RESET "Reset" -#define DEV_SET_PROPERTY "SetProperty" -#define DEV_GET_PROPERTY "GetProperty" -#define DEV_GET_DEV_SIGNATURE __END_SIG__ +#define MGR_DEVICE_LIST "DeviceList" +#define MGR_DEFAULT_DEVICE "DefaultDevice" +#define MGR_INIT "Init" + +/* Enable/Disable services controller, pan, serial, ... */ +#define MGR_ENABLE "Enable" +#define MGR_DISABLE "Disable" + +/* Signatures */ + +#define MGR_GET_DEV_SIGNATURE __END_SIG__ /* DeviceList Reply: a(devname, addr, type, up/down, a(flags)) - all types strings */ -#define DEV_GET_DEV_REPLY_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ +#define MGR_GET_DEV_REPLY_SIGNATURE DBUS_TYPE_ARRAY_AS_STRING \ + DEV_GET_DEV_REPLY_STRUCT_SIGNATURE \ + __END_SIG__ + +#define MGR_GET_DEV_REPLY_STRUCT_SIGNATURE DBUS_STRUCT_BEGIN_CHAR_AS_STRING \ DBUS_TYPE_STRING_AS_STRING \ DBUS_TYPE_STRING_AS_STRING \ DBUS_TYPE_STRING_AS_STRING \ @@ -64,44 +68,23 @@ DBUS_STRUCT_END_CHAR_AS_STRING \ __END_SIG__ -#define DEV_GET_DEV_REPLY_SIGNATURE DBUS_TYPE_ARRAY_AS_STRING \ - DEV_GET_DEV_REPLY_STRUCT_SIGNATURE \ - __END_SIG__ - -#define DEV_UP_SIGNATURE __END_SIG__ -#define DEV_DOWN_SIGNATURE __END_SIG__ -#define DEV_RESET_SIGNATURE __END_SIG__ -#define DEV_SET_PROPERTY_SIGNATURE __END_SIG__ -#define DEV_GET_PROPERTY_SIGNATURE __END_SIG__ - -/*======================================================================== - BlueZ D-Bus Manager service definitions "/org/bluez/Manager" - *========================================================================*/ +#define MGR_DEFAULT_DEV_SIGNATURE __END_SIG__ - /* ===== Manager definitions, services under DEVICE_PATH ===== */ -#define MGR_GET_DEV "DeviceList" -#define MGR_INIT "Init" -/* Enable/Disable services controller, pan, serial, ... */ -#define MGR_ENABLE "Enable" -#define MGR_DISABLE "Disable" +/* Signals sent in the Manager path */ +#define BLUEZ_MGR_DEV_ADDED "DeviceAdded" +#define BLUEZ_MGR_DEV_REMOVED "DeviceRemoved" -/* Signatures */ -#define MGR_GET_DEV_SIGNATURE __END_SIG__ -/* yya(ss) */ -#define MGR_GET_DEV_REPLY_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_ARRAY_AS_STRING \ - HCI_DEVICE_STRUCT_SIGNATURE \ - __END_SIG__ +/*======================================================================== + BlueZ D-Bus Device path definitions "/org/bluez/Device" + *========================================================================*/ -/* ===== HCI definitions ===== */ +/* Interfaces implemented in the "/org/bluez/Device" path */ #define BLUEZ_HCI "Controller" -#define BLUEZ_HCI_PATH MANAGER_PATH "/" BLUEZ_HCI -#define BLUEZ_HCI_INTERFACE MANAGER_INTERFACE "." BLUEZ_HCI +#define DEV_HCI_INTERFACE DEVICE_INTERFACE "." BLUEZ_HCI -/* Device based HCI signals */ +/* Control interface signals */ #define BLUEZ_HCI_INQ_START "InquiryStart" #define BLUEZ_HCI_INQ_COMPLETE "InquiryComplete" #define BLUEZ_HCI_INQ_RESULT "InquiryResult" @@ -109,11 +92,7 @@ #define BLUEZ_HCI_REMOTE_NAME_FAILED "RemoteNameFailed" #define BLUEZ_HCI_AUTH_COMPLETE "AuthenticationComplete" -/* HCI signals sent in the BLUEZ_HCI_PATH */ -#define BLUEZ_HCI_DEV_ADDED "DeviceAdded" -#define BLUEZ_HCI_DEV_REMOVED "DeviceRemoved" - -/* HCI Provided services */ +/* Control interface methods */ #define HCI_PERIODIC_INQ "PeriodicInquiry" #define HCI_CANCEL_PERIODIC_INQ "CancelPeriodic" #define HCI_INQ "Inquiry" @@ -123,6 +102,19 @@ #define HCI_CONNECTIONS "Connections" #define HCI_AUTHENTICATE "Authenticate" +/* Control interface methods */ +#define DEV_UP "Up" +#define DEV_DOWN "Down" +#define DEV_RESET "Reset" +#define DEV_SET_PROPERTY "SetProperty" +#define DEV_GET_PROPERTY "GetProperty" + +#define DEV_UP_SIGNATURE __END_SIG__ +#define DEV_DOWN_SIGNATURE __END_SIG__ +#define DEV_RESET_SIGNATURE __END_SIG__ +#define DEV_SET_PROPERTY_SIGNATURE __END_SIG__ +#define DEV_GET_PROPERTY_SIGNATURE __END_SIG__ + #define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ DBUS_TYPE_BYTE_AS_STRING \ diff --git a/hcid/hcid.h b/hcid/hcid.h index fb318015..6dd6437c 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -121,10 +121,11 @@ void toggle_pairing(int enable); gboolean hcid_dbus_init(void); void hcid_dbus_exit(void); gboolean hcid_dbus_register_device(uint16_t id); -gboolean hcid_dbus_register_manager(uint16_t id); gboolean hcid_dbus_unregister_device(uint16_t id); -gboolean hcid_dbus_unregister_manager(uint16_t id); +gboolean hcid_dbus_dev_up(uint16_t id); +gboolean hcid_dbus_dev_down(uint16_t id); void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); + void hcid_dbus_inquiry_start(bdaddr_t *local); void hcid_dbus_inquiry_complete(bdaddr_t *local); void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi); diff --git a/hcid/main.c b/hcid/main.c index e6d43590..5ff9fcf3 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -401,10 +401,10 @@ static void init_all_devices(int ctl) start_security_manager(dr->dev_id); #ifdef ENABLE_DBUS - if (hci_test_bit(HCI_UP, &dr->dev_opt)) - hcid_dbus_register_manager(dr->dev_id); - hcid_dbus_register_device(dr->dev_id); + + if (hci_test_bit(HCI_UP, &dr->dev_opt)) + hcid_dbus_dev_up(dr->dev_id); #endif } @@ -476,7 +476,7 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si) if (hcid.security) start_security_manager(sd->dev_id); #ifdef ENABLE_DBUS - hcid_dbus_register_manager(sd->dev_id); + hcid_dbus_dev_up(sd->dev_id); #endif break; @@ -485,7 +485,7 @@ static inline void device_event(GIOChannel *chan, evt_stack_internal *si) if (hcid.security) stop_security_manager(sd->dev_id); #ifdef ENABLE_DBUS - hcid_dbus_unregister_manager(sd->dev_id); + hcid_dbus_dev_down(sd->dev_id); #endif break; } -- cgit From fe8f6f45a86efb2d356c3084b7991b90d8f319ea Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 16:56:45 +0000 Subject: Move glib-ectomy.[ch] into the common directory --- common/Makefile.am | 4 +- common/glib-ectomy.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++ common/glib-ectomy.h | 92 +++++++++++++++++++++++++ hcid/Makefile.am | 8 ++- hcid/glib-ectomy.c | 185 --------------------------------------------------- hcid/glib-ectomy.h | 92 ------------------------- 6 files changed, 286 insertions(+), 280 deletions(-) create mode 100644 common/glib-ectomy.c create mode 100644 common/glib-ectomy.h delete mode 100644 hcid/glib-ectomy.c delete mode 100644 hcid/glib-ectomy.h diff --git a/common/Makefile.am b/common/Makefile.am index 71592813..5a5a4702 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -1,8 +1,10 @@ -noinst_LIBRARIES = libtextfile.a +noinst_LIBRARIES = libtextfile.a libglib-ectomy.a libtextfile_a_SOURCES = textfile.h textfile.c +libglib_ectomy_a_SOURCES = glib-ectomy.h glib-ectomy.c + noinst_PROGRAMS = test_textfile test_textfile_LDADD = libtextfile.a diff --git a/common/glib-ectomy.c b/common/glib-ectomy.c new file mode 100644 index 00000000..bea7f47c --- /dev/null +++ b/common/glib-ectomy.c @@ -0,0 +1,185 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "glib-ectomy.h" + +GIOError g_io_channel_read(GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read) +{ + int fd = channel->fd; + gssize result; + + /* At least according to the Debian manpage for read */ + if (count > SSIZE_MAX) + count = SSIZE_MAX; + +retry: + result = read (fd, buf, count); + + if (result < 0) { + *bytes_read = 0; + + switch (errno) { +#ifdef EINTR + case EINTR: + goto retry; +#endif +#ifdef EAGAIN + case EAGAIN: + return G_IO_STATUS_AGAIN; +#endif + default: + return G_IO_STATUS_ERROR; + } + } + + *bytes_read = result; + + return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; +} + +void g_io_channel_close(GIOChannel *channel) +{ + if (!channel) + return; + + close(channel->fd); + + memset(channel, 0, sizeof(channel)); + free(channel); +} + +GIOChannel *g_io_channel_unix_new(int fd) +{ + GIOChannel *channel; + + channel = malloc(sizeof(GIOChannel)); + if (!channel) + return NULL; + + channel->fd = fd; + + return channel; +} + +gint g_io_channel_unix_get_fd(GIOChannel *channel) +{ + return channel->fd; +} + +struct watch { + guint id; + GIOChannel *channel; + GIOCondition condition; + GIOFunc func; + gpointer user_data; + + struct watch *next; +}; + +static struct watch watch_head = { .id = 0, .next = 0 }; + +void g_io_remove_watch(guint id) +{ + struct watch *w, *p; + + for (p = &watch_head, w = watch_head.next; w; w = w->next) + if (w->id == id) { + p->next = w->next; + free (w); + return; + } +} + +guint g_io_add_watch(GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data) +{ + struct watch *watch = malloc(sizeof(struct watch)); + + watch->id = ++watch_head.id; + watch->channel = channel; + watch->condition = condition; + watch->func = func; + watch->user_data = user_data; + + watch->next = watch_head.next; + watch_head.next = watch; + + return watch->id; +} + +GMainLoop *g_main_loop_new(GMainContext *context, gboolean is_running) +{ + GMainLoop *ml; + + ml = malloc(sizeof(GMainLoop)); + if (!ml) + return NULL; + + ml->bail = 0; + + return ml; +} + +void g_main_loop_run(GMainLoop *loop) +{ + int open_max = sysconf(_SC_OPEN_MAX); + struct pollfd *ufds; + + ufds = malloc(open_max * sizeof(struct pollfd)); + if (!ufds) + return; + + while (!loop->bail) { + int nfds, rc, i; + struct watch *p, *w; + + nfds = 0; + for (w = watch_head.next; w != NULL; w = w->next) { + ufds[nfds].fd = w->channel->fd; + ufds[nfds].events = w->condition; + ufds[nfds].revents = 0; + nfds++; + } + + rc = poll(ufds, nfds, -1); + if (rc < 0) + continue; + + p = &watch_head; + w = watch_head.next; + i = 0; + + while (w) { + if (ufds[i].revents) { + gboolean keep = w->func(w->channel, ufds[i].revents, w->user_data); + if (!keep) { + p->next = w->next; + memset(w, 0, sizeof(*w)); + w = p->next; + i++; + continue; + } + } + + p = w; + w = w->next; + i++; + } + } + + free(ufds); +} + +void g_main_loop_quit(GMainLoop *loop) +{ + loop->bail = 1; +} diff --git a/common/glib-ectomy.h b/common/glib-ectomy.h new file mode 100644 index 00000000..c507e3c7 --- /dev/null +++ b/common/glib-ectomy.h @@ -0,0 +1,92 @@ +#ifndef __GLIB_ECTOMY_H +#define __GLIB_ECTOMY_H + +#include +#include + +typedef char gchar; +typedef short gshort; +typedef long glong; +typedef int gint; +typedef gint gboolean; + +typedef unsigned char guchar; +typedef unsigned short gushort; +typedef unsigned long gulong; +typedef unsigned int guint; + +typedef float gfloat; +typedef double gdouble; + +typedef void * gpointer; +typedef const void * gconstpointer; + +typedef size_t gsize; +typedef ssize_t gssize; + +#ifndef SSIZE_MAX +#define SSIZE_MAX INT_MAX +#endif + +typedef struct _GIOChannel { + int fd; +} GIOChannel; + +typedef struct _GMainContext { + int dummy; +} GMainContext; + +typedef struct _GMainLoop { + int bail; +} GMainLoop; + +typedef enum { + G_IO_ERROR_NONE, + G_IO_ERROR_AGAIN, + G_IO_ERROR_INVAL, + G_IO_ERROR_UNKNOWN +} GIOError; + +typedef enum { + G_IO_STATUS_ERROR = -1, + G_IO_STATUS_NORMAL = 0, + G_IO_STATUS_EOF = 1, + G_IO_STATUS_AGAIN = 2 +} GIOStatus; + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +typedef enum { + G_IO_IN = POLLIN, + G_IO_OUT = POLLOUT, + G_IO_PRI = POLLPRI, + G_IO_ERR = POLLERR, + G_IO_HUP = POLLHUP, + G_IO_NVAL = POLLNVAL +} GIOCondition; + +typedef gboolean (*GIOFunc) (GIOChannel *source, GIOCondition condition, gpointer data); + +GIOError g_io_channel_read(GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read); +void g_io_channel_close(GIOChannel *channel); + +GIOChannel *g_io_channel_unix_new(int fd); +gint g_io_channel_unix_get_fd(GIOChannel *channel); +guint g_io_add_watch(GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data); +void g_io_remove_watch(guint id); + +GMainLoop *g_main_loop_new(GMainContext *context, gboolean is_running); +void g_main_loop_run(GMainLoop *loop); +void g_main_loop_quit(GMainLoop *loop); + +#define g_main_new(is_running) g_main_loop_new(NULL, is_running); +#define g_main_run(loop) g_main_loop_run(loop) +#define g_main_quit(loop) g_main_loop_quit(loop) + +#endif /* __GLIB_ECTOMY_H */ diff --git a/hcid/Makefile.am b/hcid/Makefile.am index e82a4263..856f6bb5 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -25,8 +25,12 @@ dbus_hcid_libs = dbus_hcid_cflags = endif -hcid_SOURCES = main.c security.c storage.c hcid.h lib.c lib.h parser.h parser.y lexer.l kword.h kword.c glib-ectomy.h glib-ectomy.c $(dbus_hcid_sources) -hcid_LDADD = $(dbus_hcid_libs) @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a +hcid_SOURCES = main.c security.c storage.c hcid.h lib.c lib.h \ + parser.h parser.y lexer.l kword.h kword.c $(dbus_hcid_sources) + +hcid_LDADD = $(dbus_hcid_libs) @BLUEZ_LIBS@ \ + $(top_builddir)/common/libglib-ectomy.a \ + $(top_builddir)/common/libtextfile.a AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ $(dbus_hcid_cflags) diff --git a/hcid/glib-ectomy.c b/hcid/glib-ectomy.c deleted file mode 100644 index bea7f47c..00000000 --- a/hcid/glib-ectomy.c +++ /dev/null @@ -1,185 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "glib-ectomy.h" - -GIOError g_io_channel_read(GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read) -{ - int fd = channel->fd; - gssize result; - - /* At least according to the Debian manpage for read */ - if (count > SSIZE_MAX) - count = SSIZE_MAX; - -retry: - result = read (fd, buf, count); - - if (result < 0) { - *bytes_read = 0; - - switch (errno) { -#ifdef EINTR - case EINTR: - goto retry; -#endif -#ifdef EAGAIN - case EAGAIN: - return G_IO_STATUS_AGAIN; -#endif - default: - return G_IO_STATUS_ERROR; - } - } - - *bytes_read = result; - - return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; -} - -void g_io_channel_close(GIOChannel *channel) -{ - if (!channel) - return; - - close(channel->fd); - - memset(channel, 0, sizeof(channel)); - free(channel); -} - -GIOChannel *g_io_channel_unix_new(int fd) -{ - GIOChannel *channel; - - channel = malloc(sizeof(GIOChannel)); - if (!channel) - return NULL; - - channel->fd = fd; - - return channel; -} - -gint g_io_channel_unix_get_fd(GIOChannel *channel) -{ - return channel->fd; -} - -struct watch { - guint id; - GIOChannel *channel; - GIOCondition condition; - GIOFunc func; - gpointer user_data; - - struct watch *next; -}; - -static struct watch watch_head = { .id = 0, .next = 0 }; - -void g_io_remove_watch(guint id) -{ - struct watch *w, *p; - - for (p = &watch_head, w = watch_head.next; w; w = w->next) - if (w->id == id) { - p->next = w->next; - free (w); - return; - } -} - -guint g_io_add_watch(GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data) -{ - struct watch *watch = malloc(sizeof(struct watch)); - - watch->id = ++watch_head.id; - watch->channel = channel; - watch->condition = condition; - watch->func = func; - watch->user_data = user_data; - - watch->next = watch_head.next; - watch_head.next = watch; - - return watch->id; -} - -GMainLoop *g_main_loop_new(GMainContext *context, gboolean is_running) -{ - GMainLoop *ml; - - ml = malloc(sizeof(GMainLoop)); - if (!ml) - return NULL; - - ml->bail = 0; - - return ml; -} - -void g_main_loop_run(GMainLoop *loop) -{ - int open_max = sysconf(_SC_OPEN_MAX); - struct pollfd *ufds; - - ufds = malloc(open_max * sizeof(struct pollfd)); - if (!ufds) - return; - - while (!loop->bail) { - int nfds, rc, i; - struct watch *p, *w; - - nfds = 0; - for (w = watch_head.next; w != NULL; w = w->next) { - ufds[nfds].fd = w->channel->fd; - ufds[nfds].events = w->condition; - ufds[nfds].revents = 0; - nfds++; - } - - rc = poll(ufds, nfds, -1); - if (rc < 0) - continue; - - p = &watch_head; - w = watch_head.next; - i = 0; - - while (w) { - if (ufds[i].revents) { - gboolean keep = w->func(w->channel, ufds[i].revents, w->user_data); - if (!keep) { - p->next = w->next; - memset(w, 0, sizeof(*w)); - w = p->next; - i++; - continue; - } - } - - p = w; - w = w->next; - i++; - } - } - - free(ufds); -} - -void g_main_loop_quit(GMainLoop *loop) -{ - loop->bail = 1; -} diff --git a/hcid/glib-ectomy.h b/hcid/glib-ectomy.h deleted file mode 100644 index c507e3c7..00000000 --- a/hcid/glib-ectomy.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef __GLIB_ECTOMY_H -#define __GLIB_ECTOMY_H - -#include -#include - -typedef char gchar; -typedef short gshort; -typedef long glong; -typedef int gint; -typedef gint gboolean; - -typedef unsigned char guchar; -typedef unsigned short gushort; -typedef unsigned long gulong; -typedef unsigned int guint; - -typedef float gfloat; -typedef double gdouble; - -typedef void * gpointer; -typedef const void * gconstpointer; - -typedef size_t gsize; -typedef ssize_t gssize; - -#ifndef SSIZE_MAX -#define SSIZE_MAX INT_MAX -#endif - -typedef struct _GIOChannel { - int fd; -} GIOChannel; - -typedef struct _GMainContext { - int dummy; -} GMainContext; - -typedef struct _GMainLoop { - int bail; -} GMainLoop; - -typedef enum { - G_IO_ERROR_NONE, - G_IO_ERROR_AGAIN, - G_IO_ERROR_INVAL, - G_IO_ERROR_UNKNOWN -} GIOError; - -typedef enum { - G_IO_STATUS_ERROR = -1, - G_IO_STATUS_NORMAL = 0, - G_IO_STATUS_EOF = 1, - G_IO_STATUS_AGAIN = 2 -} GIOStatus; - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -typedef enum { - G_IO_IN = POLLIN, - G_IO_OUT = POLLOUT, - G_IO_PRI = POLLPRI, - G_IO_ERR = POLLERR, - G_IO_HUP = POLLHUP, - G_IO_NVAL = POLLNVAL -} GIOCondition; - -typedef gboolean (*GIOFunc) (GIOChannel *source, GIOCondition condition, gpointer data); - -GIOError g_io_channel_read(GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read); -void g_io_channel_close(GIOChannel *channel); - -GIOChannel *g_io_channel_unix_new(int fd); -gint g_io_channel_unix_get_fd(GIOChannel *channel); -guint g_io_add_watch(GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data); -void g_io_remove_watch(guint id); - -GMainLoop *g_main_loop_new(GMainContext *context, gboolean is_running); -void g_main_loop_run(GMainLoop *loop); -void g_main_loop_quit(GMainLoop *loop); - -#define g_main_new(is_running) g_main_loop_new(NULL, is_running); -#define g_main_run(loop) g_main_loop_run(loop) -#define g_main_quit(loop) g_main_loop_quit(loop) - -#endif /* __GLIB_ECTOMY_H */ -- cgit From 4b623ab3d9307b4790a5228309b83804bead8777 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 17:42:24 +0000 Subject: The parameter is called stores and not store --- tools/csr.c | 24 ++++++++++++------------ tools/csr.h | 12 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 3bd25b46..b3d26adf 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2433,13 +2433,13 @@ int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *val return 0; } -int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length) +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, pskey & 0xff, pskey >> 8, (length / 2) & 0xff, (length / 2) >> 8, - store & 0xff, store >> 8, 0x00, 0x00 }; + stores & 0xff, stores >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; struct hci_request rq; @@ -2475,13 +2475,13 @@ int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t sto return 0; } -int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length) +int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x02, 0x00, ((length / 2) + 8) & 0xff, ((length / 2) + 8) >> 8, seqnum & 0xff, seqnum >> 8, 0x03, 0x70, 0x00, 0x00, pskey & 0xff, pskey >> 8, (length / 2) & 0xff, (length / 2) >> 8, - store & 0xff, store >> 8, 0x00, 0x00 }; + stores & 0xff, stores >> 8, 0x00, 0x00 }; unsigned char cp[254], rp[254]; struct hci_request rq; @@ -2517,31 +2517,31 @@ int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t st return 0; } -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value) +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t *value) { uint8_t array[2] = { 0x00, 0x00 }; int err; - err = csr_read_pskey_complex(dd, seqnum, pskey, store, array, 2); + err = csr_read_pskey_complex(dd, seqnum, pskey, stores, array, 2); *value = array[0] + (array[1] << 8); return err; } -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value) +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t value) { uint8_t array[2] = { value & 0xff, value >> 8 }; - return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 2); + return csr_write_pskey_complex(dd, seqnum, pskey, stores, array, 2); } -int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value) +int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t *value) { uint8_t array[4] = { 0x00, 0x00, 0x00, 0x00 }; int err; - err = csr_read_pskey_complex(dd, seqnum, pskey, store, array, 4); + err = csr_read_pskey_complex(dd, seqnum, pskey, stores, array, 4); *value = ((array[0] + (array[1] << 8)) << 16) + (array[2] + (array[3] << 8)); @@ -2549,12 +2549,12 @@ int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stor return err; } -int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value) +int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t value) { uint8_t array[4] = { (value & 0xff0000) >> 16, value >> 24, value & 0xff, (value & 0xff00) >> 8 }; - return csr_write_pskey_complex(dd, seqnum, pskey, store, array, 4); + return csr_write_pskey_complex(dd, seqnum, pskey, stores, array, 4); } int psr_put(uint16_t pskey, uint8_t *value, uint16_t size) diff --git a/tools/csr.h b/tools/csr.h index d366d19b..af5af63f 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -505,12 +505,12 @@ int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); -int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); -int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint8_t *value, uint16_t length); -int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t *value); -int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint16_t value); -int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t *value); -int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t store, uint32_t value); +int csr_read_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length); +int csr_write_pskey_complex(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint8_t *value, uint16_t length); +int csr_read_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t *value); +int csr_write_pskey_uint16(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint16_t value); +int csr_read_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t *value); +int csr_write_pskey_uint32(int dd, uint16_t seqnum, uint16_t pskey, uint16_t stores, uint32_t value); int psr_put(uint16_t pskey, uint8_t *value, uint16_t size); int psr_get(uint16_t *pskey, uint8_t *value, uint16_t *size); -- cgit From bbf0b522084d22e9fa1ec5ab6e5d850a298d55d6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 17:43:22 +0000 Subject: Add support for different stores --- tools/pskey.c | 72 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/tools/pskey.c b/tools/pskey.c index d9bda6a8..f6bc0a7e 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -49,9 +49,7 @@ enum { READ, }; -static int transient = 0; - -static int cmd_list(int dd, int argc, char *argv[]) +static int cmd_list(int dd, uint16_t stores, int argc, char *argv[]) { uint8_t array[8]; uint16_t length, seqnum = 0x0000, pskey = 0x0000; @@ -61,6 +59,8 @@ static int cmd_list(int dd, int argc, char *argv[]) memset(array, 0, sizeof(array)); array[0] = pskey & 0xff; array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_PS_NEXT, array, sizeof(array)); @@ -74,6 +74,8 @@ static int cmd_list(int dd, int argc, char *argv[]) memset(array, 0, sizeof(array)); array[0] = pskey & 0xff; array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_PS_SIZE, array, sizeof(array)); @@ -89,7 +91,7 @@ static int cmd_list(int dd, int argc, char *argv[]) return 0; } -static int cmd_read(int dd, int argc, char *argv[]) +static int cmd_read(int dd, uint16_t stores, int argc, char *argv[]) { uint8_t array[256]; uint16_t length, seqnum = 0x0000, pskey = 0x0000; @@ -100,9 +102,11 @@ static int cmd_read(int dd, int argc, char *argv[]) memset(array, 0, sizeof(array)); array[0] = pskey & 0xff; array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, 8); + CSR_VARID_PS_NEXT, array, 8); if (err < 0) break; @@ -113,9 +117,11 @@ static int cmd_read(int dd, int argc, char *argv[]) memset(array, 0, sizeof(array)); array[0] = pskey & 0xff; array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); + CSR_VARID_PS_SIZE, array, 8); if (err < 0) continue; @@ -124,7 +130,7 @@ static int cmd_read(int dd, int argc, char *argv[]) continue; err = csr_read_pskey_complex(dd, seqnum++, pskey, - 0x0000, array, length * 2); + stores, array, length * 2); if (err < 0) continue; @@ -158,7 +164,7 @@ static int pskey_size(uint16_t pskey) } } -static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) +static int write_pskey(int dd, uint16_t pskey, uint16_t stores, int type, int argc, char *argv[]) { uint8_t array[64]; uint16_t value; @@ -183,7 +189,7 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) array[i] = atoi(argv[i]); err = csr_write_pskey_complex(dd, 0x4711, pskey, - transient ? 0x0008 : 0x0000, array, size); + stores, array, size); break; case CSR_TYPE_UINT8: @@ -198,8 +204,7 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) else value = atoi(argv[0]); - err = csr_write_pskey_uint16(dd, 0x4711, pskey, - transient ? 0x0008 : 0x0000, value); + err = csr_write_pskey_uint16(dd, 0x4711, pskey, stores, value); break; case CSR_TYPE_UINT32: @@ -213,8 +218,7 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) else val32 = atoi(argv[0]); - err = csr_write_pskey_uint32(dd, 0x4711, pskey, - transient ? 0x0008 : 0x0000, val32); + err = csr_write_pskey_uint32(dd, 0x4711, pskey, stores, val32); break; default: @@ -226,7 +230,7 @@ static int write_pskey(int dd, uint16_t pskey, int type, int argc, char *argv[]) return err; } -static int read_pskey(int dd, uint16_t pskey, int type) +static int read_pskey(int dd, uint16_t pskey, uint16_t stores, int type) { uint8_t array[64]; uint16_t value = 0; @@ -239,7 +243,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) case CSR_TYPE_ARRAY: size = pskey_size(pskey); - err = csr_read_pskey_complex(dd, 0x4711, pskey, 0x0000, array, size); + err = csr_read_pskey_complex(dd, 0x4711, pskey, stores, array, size); if (err < 0) return err; @@ -251,7 +255,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) case CSR_TYPE_UINT8: case CSR_TYPE_UINT16: - err = csr_read_pskey_uint16(dd, 0x4711, pskey, 0x0000, &value); + err = csr_read_pskey_uint16(dd, 0x4711, pskey, stores, &value); if (err < 0) return err; @@ -259,7 +263,7 @@ static int read_pskey(int dd, uint16_t pskey, int type) break; case CSR_TYPE_UINT32: - err = csr_read_pskey_uint32(dd, 0x4711, pskey, 0x0000, &val32); + err = csr_read_pskey_uint32(dd, 0x4711, pskey, stores, &val32); if (err < 0) return err; @@ -308,7 +312,7 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [-r] [-t] [value]\n" + "\tpskey [-i ] [-r] [-s stores] [-t] [value]\n" "\tpskey [-i ] --list\n" "\tpskey [-i ] --read\n\n"); @@ -327,6 +331,7 @@ static void usage(void) static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, + { "stores", 1, 0, 's' }, { "transient", 0, 0, 't' }, { "list", 0, 0, 'L' }, { "read", 0, 0, 'R' }, @@ -338,9 +343,10 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; + uint16_t stores = 0x0001; int i, err, dd, opt, dev = 0, reset = 0, mode = NONE; - while ((opt=getopt_long(argc, argv, "+i:rtLRh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rs:tLRh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -354,8 +360,25 @@ int main(int argc, char *argv[]) reset = 1; break; + case 's': + if (!strcasecmp(optarg, "default")) + stores = 0x0000; + else if (!strcasecmp(optarg, "psi")) + stores = 0x0001; + else if (!strcasecmp(optarg, "psf")) + stores = 0x0002; + else if (!strcasecmp(optarg, "psrom")) + stores = 0x0004; + else if (!strcasecmp(optarg, "psram")) + stores = 0x0008; + else if (!strncasecmp(optarg, "0x", 2)) + stores = strtol(optarg, NULL, 16); + else + stores = atoi(optarg); + break; + case 't': - transient = 1; + stores = 0x0008; break; case 'L': @@ -412,11 +435,11 @@ int main(int argc, char *argv[]) if (mode > 0) { switch (mode) { case LIST: - err = cmd_list(dd, argc, argv); + err = cmd_list(dd, stores, argc, argv); break; case READ: - err = cmd_read(dd, argc, argv); + err = cmd_read(dd, stores, argc, argv); break; default: @@ -434,14 +457,15 @@ int main(int argc, char *argv[]) continue; if (argc > 1) { - err = write_pskey(dd, storage[i].pskey, + err = write_pskey(dd, storage[i].pskey, stores, storage[i].type, argc - 1, argv + 1); if (!err && reset) csr_write_varid_valueless(dd, 0x0000, CSR_VARID_WARM_RESET); } else - err = read_pskey(dd, storage[i].pskey, storage[i].type); + err = read_pskey(dd, storage[i].pskey, + stores, storage[i].type); hci_close_dev(dd); -- cgit From 5adba470b7929bf1ae8355484d08b353b3d8f77e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 17:49:00 +0000 Subject: Add alternate names for the stores --- tools/pskey.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/pskey.c b/tools/pskey.c index f6bc0a7e..701a47fd 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -363,6 +363,14 @@ int main(int argc, char *argv[]) case 's': if (!strcasecmp(optarg, "default")) stores = 0x0000; + else if (!strcasecmp(optarg, "implementation")) + stores = 0x0001; + else if (!strcasecmp(optarg, "factory")) + stores = 0x0002; + else if (!strcasecmp(optarg, "rom")) + stores = 0x0004; + else if (!strcasecmp(optarg, "ram")) + stores = 0x0008; else if (!strcasecmp(optarg, "psi")) stores = 0x0001; else if (!strcasecmp(optarg, "psf")) -- cgit From 37c4010967b3e87fa1d510a66adb1c61526fef09 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 18:28:04 +0000 Subject: Use psi, psf and psram as default store --- tools/pskey.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pskey.c b/tools/pskey.c index 701a47fd..46d837d4 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -343,7 +343,7 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - uint16_t stores = 0x0001; + uint16_t stores = 0x0001 | 0x0002 | 0x0008; int i, err, dd, opt, dev = 0, reset = 0, mode = NONE; while ((opt=getopt_long(argc, argv, "+i:rs:tLRh", main_options, NULL)) != -1) { -- cgit From e6f085ddedd4159c9c07fba0c2babaa0f0053b01 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 19:05:48 +0000 Subject: Add support for writing complex BCCMD commands --- tools/csr.c | 39 +++++++++++++++++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 40 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index b3d26adf..698122dc 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2312,6 +2312,45 @@ int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid) return 0; } +int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + unsigned char cmd[] = { 0x02, 0x00, ((length / 2) + 5) & 0xff, ((length / 2) + 5) >> 8, + seqnum & 0xff, seqnum >> 8, varid & 0xff, varid >> 8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + unsigned char cp[254], rp[254]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + memcpy(cp + 11, value, length); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = sizeof(cmd) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + return 0; +} + int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { unsigned char cmd[] = { 0x00, 0x00, ((length / 2) + 5) & 0xff, ((length / 2) + 5) >> 8, diff --git a/tools/csr.h b/tools/csr.h index af5af63f..760235b1 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -502,6 +502,7 @@ char *csr_pskeytostr(uint16_t pskey); char *csr_pskeytoval(uint16_t pskey); int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); +int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_uint16(int dd, uint16_t seqnum, uint16_t varid, uint16_t *value); int csr_read_varid_uint32(int dd, uint16_t seqnum, uint16_t varid, uint32_t *value); -- cgit From d320d7de71d05d4aeffee7481b8efa3d5c626d21 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 19:09:03 +0000 Subject: Add support for deleting PS keys --- tools/pskey.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/tools/pskey.c b/tools/pskey.c index 46d837d4..247f0c35 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -279,6 +279,23 @@ static int read_pskey(int dd, uint16_t pskey, uint16_t stores, int type) return err; } +static int delete_pskey(int dd, uint16_t pskey, uint16_t stores) +{ + uint8_t array[8]; + int err; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_write_varid_complex(dd, 0x4711, + CSR_VARID_PS_CLR_STORES, array, sizeof(array)); + + return err; +} + static struct { uint16_t pskey; int type; @@ -312,7 +329,8 @@ static void usage(void) printf("pskey - Utility for changing CSR persistent storage\n\n"); printf("Usage:\n" - "\tpskey [-i ] [-r] [-s stores] [-t] [value]\n" + "\tpskey [-i ] [-r] [-s stores] [value]\n" + "\tpskey [-i ] [-r] [-s stores] --clear \n" "\tpskey [-i ] --list\n" "\tpskey [-i ] --read\n\n"); @@ -332,7 +350,7 @@ static struct option main_options[] = { { "device", 1, 0, 'i' }, { "reset", 0, 0, 'r' }, { "stores", 1, 0, 's' }, - { "transient", 0, 0, 't' }, + { "clear", 0, 0, 'c' }, { "list", 0, 0, 'L' }, { "read", 0, 0, 'R' }, { "help", 0, 0, 'h' }, @@ -344,9 +362,9 @@ int main(int argc, char *argv[]) struct hci_dev_info di; struct hci_version ver; uint16_t stores = 0x0001 | 0x0002 | 0x0008; - int i, err, dd, opt, dev = 0, reset = 0, mode = NONE; + int i, err, dd, opt, dev = 0, reset = 0, clear = 0, mode = NONE; - while ((opt=getopt_long(argc, argv, "+i:rs:tLRh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rs:cLRh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -385,8 +403,8 @@ int main(int argc, char *argv[]) stores = atoi(optarg); break; - case 't': - stores = 0x0008; + case 'c': + clear = 1; break; case 'L': @@ -471,9 +489,13 @@ int main(int argc, char *argv[]) if (!err && reset) csr_write_varid_valueless(dd, 0x0000, CSR_VARID_WARM_RESET); - } else - err = read_pskey(dd, storage[i].pskey, - stores, storage[i].type); + } else { + if (clear) + err = delete_pskey(dd, storage[i].pskey, stores); + else + err = read_pskey(dd, storage[i].pskey, + stores, storage[i].type); + } hci_close_dev(dd); -- cgit From 9168e1f8c1e19c14b4b49d13bc91c6041c646f0d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 19:38:02 +0000 Subject: Add missing definition for memory type --- tools/csr.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/csr.h b/tools/csr.h index 760235b1..cd807c38 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -40,6 +40,7 @@ #define CSR_VARID_PICONET_INSTANCE 0x3009 /* complex */ #define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ #define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ +#define CSR_VARID_PS_MEMORY_TYPE 0x3012 /* complex */ #define CSR_VARID_COLD_RESET 0x4001 /* valueless */ #define CSR_VARID_WARM_RESET 0x4002 /* valueless */ #define CSR_VARID_COLD_HALT 0x4003 /* valueless */ -- cgit From b525d3b600bc325a4d1937b0bb6920d51b99dd79 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 19:38:29 +0000 Subject: Add support for checking the memory type --- tools/pskey.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/tools/pskey.c b/tools/pskey.c index 247f0c35..c185cf58 100644 --- a/tools/pskey.c +++ b/tools/pskey.c @@ -45,10 +45,68 @@ enum { NONE = 0, + MEMORY, LIST, READ, }; +static char *storestostr(uint16_t stores) +{ + switch (stores) { + case 0x0000: + return "Default"; + case 0x0001: + return "psi"; + case 0x0002: + return "psf"; + case 0x0004: + return "psrom"; + case 0x0008: + return "psram"; + default: + return "Unknown"; + } +} + +static char *memorytostr(uint16_t type) +{ + switch (type) { + case 0x0000: + return "Flash memory"; + case 0x0001: + return "EEPROM"; + case 0x0002: + return "RAM (transient)"; + case 0x0003: + return "ROM (or \"read-only\" flash memory)"; + default: + return "Unknown"; + } +} + +static int cmd_memory(int dd, uint16_t stores, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t type; + int err; + + memset(array, 0, sizeof(array)); + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, 0x4711, + CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); + if (err < 0) + return err; + + type = array[4] + (array[5] << 8); + + printf("%s (0x%04x) = %s (%d)\n", storestostr(stores), stores, + memorytostr(type), type); + + return 0; +} + static int cmd_list(int dd, uint16_t stores, int argc, char *argv[]) { uint8_t array[8]; @@ -331,8 +389,9 @@ static void usage(void) printf("Usage:\n" "\tpskey [-i ] [-r] [-s stores] [value]\n" "\tpskey [-i ] [-r] [-s stores] --clear \n" - "\tpskey [-i ] --list\n" - "\tpskey [-i ] --read\n\n"); + "\tpskey [-i ] [-s stores] --memory\n" + "\tpskey [-i ] [-s stores] --list\n" + "\tpskey [-i ] [-s stores] --read\n\n"); printf("Keys:\n\t"); for (i = 0; storage[i].pskey; i++) { @@ -351,6 +410,7 @@ static struct option main_options[] = { { "reset", 0, 0, 'r' }, { "stores", 1, 0, 's' }, { "clear", 0, 0, 'c' }, + { "memory", 0, 0, 'M' }, { "list", 0, 0, 'L' }, { "read", 0, 0, 'R' }, { "help", 0, 0, 'h' }, @@ -364,7 +424,7 @@ int main(int argc, char *argv[]) uint16_t stores = 0x0001 | 0x0002 | 0x0008; int i, err, dd, opt, dev = 0, reset = 0, clear = 0, mode = NONE; - while ((opt=getopt_long(argc, argv, "+i:rs:cLRh", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+i:rs:cMLRh", main_options, NULL)) != -1) { switch (opt) { case 'i': dev = hci_devid(optarg); @@ -407,6 +467,10 @@ int main(int argc, char *argv[]) clear = 1; break; + case 'M': + mode = MEMORY; + break; + case 'L': mode = LIST; break; @@ -460,14 +524,15 @@ int main(int argc, char *argv[]) if (mode > 0) { switch (mode) { + case MEMORY: + err = cmd_memory(dd, stores, argc, argv); + break; case LIST: err = cmd_list(dd, stores, argc, argv); break; - case READ: err = cmd_read(dd, stores, argc, argv); break; - default: usage(); err = -1; -- cgit From 4b50da3bc0de3797ead5b632c77d49a45db12444 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Nov 2005 19:49:49 +0000 Subject: Add up and down methods --- hcid/dbus.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 8 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index b9838b0a..bdc5e2aa 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -258,6 +258,8 @@ static struct profile_obj_path_data obj_path_table[] = { static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data); static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data); +static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data); +static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data); static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data); static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data); static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data); @@ -273,8 +275,8 @@ static const DBusObjectPathVTable obj_mgr_vtable = { }; static const struct service_data device_services[] = { - { DEV_UP, handle_not_implemented_req, DEV_UP_SIGNATURE }, - { DEV_DOWN, handle_not_implemented_req, DEV_DOWN_SIGNATURE }, + { DEV_UP, handle_device_up_req, DEV_UP_SIGNATURE }, + { DEV_DOWN, handle_device_down_req, DEV_DOWN_SIGNATURE }, { DEV_RESET, handle_not_implemented_req, DEV_RESET_SIGNATURE }, { DEV_SET_PROPERTY, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE }, { DEV_GET_PROPERTY, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, @@ -380,12 +382,15 @@ static void free_pin_req(void *req) static gboolean register_dbus_path(const char *path, uint16_t id, const DBusObjectPathVTable *pvtable) { struct hci_dbus_data *data; + syslog(LOG_INFO,"Registering DBUS Path: %s", path); + data = malloc(sizeof(struct hci_dbus_data)); if (data == NULL) { syslog(LOG_ERR,"Failed to alloc memory to DBUS path register data (%s)", path); return FALSE; } + data->id = id; if (!dbus_connection_register_object_path(connection, path, pvtable, data)) { @@ -393,13 +398,16 @@ static gboolean register_dbus_path(const char *path, uint16_t id, const DBusObje free(data); return FALSE; } + return TRUE; } static gboolean unregister_dbus_path(const char *path) { void *data; + syslog(LOG_INFO,"Unregistering DBUS Path: %s", path); + if (dbus_connection_get_object_path_data(connection, path, &data) && data) free(data); @@ -407,6 +415,7 @@ static gboolean unregister_dbus_path(const char *path) syslog(LOG_ERR,"DBUS failed to unregister %s object", path); return FALSE; } + return TRUE; } @@ -1187,14 +1196,16 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, if (child && *child) { struct profile_obj_path_data *profile; child++; - - for (profile = obj_path_table ;profile->name != NULL; profile++) { - if (strcmp(profile->name, child) == 0) { - handlers = profile->get_svc_table(); - break; + if (!strncmp(child, "hci", 3)) { + handlers = device_services; + } else { + for (profile = obj_path_table; profile->name != NULL; profile++) { + if (strcmp(profile->name, child) == 0) { + handlers = profile->get_svc_table(); + break; + } } } - } } @@ -1716,6 +1727,80 @@ failed: * Section reserved to Manager D-Bus message handlers * *****************************************************************/ +static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data) +{ + DBusMessage *reply = NULL; + struct hci_dbus_data *dbus_data = data; + struct hci_dev_info di; + struct hci_dev_req dr; + int sk = -1; + + /* Create and bind HCI socket */ + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) { + syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (ioctl(sk, HCIDEVUP, dbus_data->id) < 0 && errno != EALREADY) { + syslog(LOG_ERR, "Can't init device hci%d: %s (%d)\n", + dbus_data->id, strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (ioctl(sk, HCIGETDEVINFO, (void *) &di) >= 0 && + !hci_test_bit(HCI_RAW, &di.flags)) { + dr.dev_id = dbus_data->id; + dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; /* piscan */ + if (ioctl(sk, HCISETSCAN, (unsigned long) &dr) < 0) { + syslog(LOG_ERR, "Can't set scan mode on hci%d: %s (%d)\n", + dbus_data->id, strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + } + + reply = dbus_message_new_method_return(msg); + +failed: + if (sk >= 0) + close(sk); + + return reply; +} + +static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data) +{ + DBusMessage *reply = NULL; + struct hci_dbus_data *dbus_data = data; + int sk = -1; + + /* Create and bind HCI socket */ + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) { + syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (ioctl(sk, HCIDEVDOWN, dbus_data->id) < 0) { + syslog(LOG_ERR, "Can't down device hci%d: %s (%d)\n", + dbus_data->id, strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + reply = dbus_message_new_method_return(msg); + +failed: + if (sk >= 0) + close(sk); + + return reply; +} + static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data) { DBusMessageIter iter; @@ -1810,8 +1895,10 @@ static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data) failed: if (sk >= 0) close(sk); + if (dl) free(dl); + return reply; } -- cgit From d4462970fa423b41666b5f8e33319100784fd673 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 2 Nov 2005 14:25:13 +0000 Subject: Send a proper method return to the authenticate method call --- hcid/dbus.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hcid/dbus.c b/hcid/dbus.c index bdc5e2aa..cef259f1 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -1712,6 +1712,8 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) goto failed; } + reply = dbus_message_new_method_return(msg); + failed: if (dd >= 0) close(dd); -- cgit From 82e1a94c4e31d674d1303bdaf7b1ca7a8b4298c8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 2 Nov 2005 15:44:05 +0000 Subject: Introduce a new path_id field --- hcid/dbus.c | 135 ++++++++++++++++++++++++++++-------------------------------- hcid/dbus.h | 19 ++++++++- 2 files changed, 81 insertions(+), 73 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index cef259f1..1db7b46b 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -75,7 +75,8 @@ struct service_data { }; struct hci_dbus_data { - uint16_t id; + uint16_t dev_id; + uint16_t path_id; }; typedef int register_function_t(DBusConnection *conn, uint16_t id); @@ -89,9 +90,7 @@ static int hci_dbus_unreg_obj_path(DBusConnection *conn, uint16_t id); typedef const struct service_data *get_svc_table_func_t(void); struct profile_obj_path_data { - const char *name; - int status; /* 1:active 0:disabled */ - int dft_reg; /* dft path registered */ + uint16_t id; register_function_t *reg_func; unregister_function_t *unreg_func; get_svc_table_func_t *get_svc_table; /* return the service table */ @@ -247,9 +246,9 @@ static DBusMessage *bluez_new_failure_msg(DBusMessage *msg, const uint32_t ecode * */ static struct profile_obj_path_data obj_path_table[] = { - { BLUEZ_HCI, 1, 0, hci_dbus_reg_obj_path, hci_dbus_unreg_obj_path, get_hci_table }, + { HCI_PATH_ID, hci_dbus_reg_obj_path, hci_dbus_unreg_obj_path, get_hci_table }, /* add other profiles here */ - { NULL, 0, 0, NULL, NULL, NULL } + { INVALID_PATH_ID, NULL, NULL, NULL } }; /* @@ -379,7 +378,8 @@ static void free_pin_req(void *req) free(req); } -static gboolean register_dbus_path(const char *path, uint16_t id, const DBusObjectPathVTable *pvtable) +static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t dev_id, + const DBusObjectPathVTable *pvtable, gboolean fallback) { struct hci_dbus_data *data; @@ -391,12 +391,21 @@ static gboolean register_dbus_path(const char *path, uint16_t id, const DBusObje return FALSE; } - data->id = id; + data->path_id = path_id; + data->dev_id = dev_id; - if (!dbus_connection_register_object_path(connection, path, pvtable, data)) { - syslog(LOG_ERR,"DBUS failed to register %s object", path); - free(data); - return FALSE; + if (fallback) { + if (!dbus_connection_register_fallback(connection, path, pvtable, data)) { + syslog(LOG_ERR,"DBUS failed to register %s object", path); + free(data); + return FALSE; + } + } else { + if (!dbus_connection_register_object_path(connection, path, pvtable, data)) { + syslog(LOG_ERR,"DBUS failed to register %s object", path); + free(data); + return FALSE; + } } return TRUE; @@ -835,7 +844,6 @@ static gboolean unregister_device_path(const char *path) gboolean hcid_dbus_init(void) { - struct hci_dbus_data *data; DBusError error; dbus_error_init(&error); @@ -859,29 +867,13 @@ gboolean hcid_dbus_init(void) return FALSE; } - data = malloc(sizeof(struct hci_dbus_data)); - if (data == NULL) - return FALSE; - - data->id = DEVICE_PATH_ID; - - if (!dbus_connection_register_fallback(connection, DEVICE_PATH, - &obj_dev_vtable, data)) { - syslog(LOG_ERR, "Can't register %s object", DEVICE_PATH); - return FALSE; - } - - data = malloc(sizeof(struct hci_dbus_data)); - if (data == NULL) + if (!register_dbus_path(DEVICE_PATH, DEVICE_ROOT_ID, INVALID_DEV_ID, + &obj_dev_vtable, TRUE)) return FALSE; - data->id = MANAGER_PATH_ID; - - if (!dbus_connection_register_object_path(connection, MANAGER_PATH, - &obj_mgr_vtable, data)) { - syslog(LOG_ERR, "Can't register %s object", MANAGER_PATH); + if (!register_dbus_path(MANAGER_PATH, MANAGER_ROOT_ID, INVALID_DEV_ID, + &obj_mgr_vtable, FALSE)) return FALSE; - } if (!dbus_connection_add_filter(connection, hci_signal_filter, NULL, NULL)) { syslog(LOG_ERR, "Can't add new HCI filter"); @@ -953,7 +945,7 @@ out: if (message) dbus_message_unref(message); - ret = register_dbus_path(path, id, &obj_dev_vtable); + ret = register_dbus_path(path, DEVICE_PATH_ID, id, &obj_dev_vtable, FALSE); if (ret && default_dev < 0) default_dev = id; @@ -1011,7 +1003,7 @@ gboolean hcid_dbus_dev_up(uint16_t id) if (!connection) return FALSE; - for (; ptr->name; ptr++) { + for (; ptr->id != INVALID_PATH_ID; ptr++) { if (ptr->reg_func(connection, id) < 0) goto failed; } @@ -1052,7 +1044,7 @@ gboolean hcid_dbus_dev_down(uint16_t id) if (!connection) return FALSE; - for (; ptr->name; ptr++) { + for (; ptr->id != INVALID_PATH_ID; ptr++) { if (ptr->unreg_func(connection, id) < 0) goto failed; } @@ -1097,7 +1089,7 @@ static int hci_dbus_reg_obj_path(DBusConnection *conn, uint16_t id) /* register the default path*/ snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI); - if (!register_dbus_path(path, id, &obj_dev_vtable)) + if (!register_dbus_path(path, HCI_PATH_ID, id, &obj_dev_vtable, FALSE)) return -1; return 0; @@ -1170,7 +1162,6 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; int type; - const char *child; const char *iface; const char *method; const char *signature; @@ -1184,27 +1175,25 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, method = dbus_message_get_member(msg); signature = dbus_message_get_signature(msg); - syslog(LOG_INFO, "%s - path:%s, id:%04X", __PRETTY_FUNCTION__, path, dbus_data->id); + syslog(LOG_INFO, "%s - path:%s, path_id:%04X dev_id:%04X", __PRETTY_FUNCTION__, + path, dbus_data->path_id, dbus_data->dev_id); - if (dbus_data->id == DEVICE_PATH_ID) + /* Check for message that doesn't belong in this path */ + if (!(dbus_data->path_id & DEVICE_PATH_MASK)) return ret; - if (strcmp(path, DEVICE_PATH) == 0) + /* Fallback services not currently supported */ + if (dbus_data->path_id == DEVICE_ROOT_ID) + return ret; + + if (dbus_data->path_id == DEVICE_PATH_ID) handlers = device_services; else { - child = strrchr(path,'/'); - if (child && *child) { - struct profile_obj_path_data *profile; - child++; - if (!strncmp(child, "hci", 3)) { - handlers = device_services; - } else { - for (profile = obj_path_table; profile->name != NULL; profile++) { - if (strcmp(profile->name, child) == 0) { - handlers = profile->get_svc_table(); - break; - } - } + struct profile_obj_path_data *profile; + for (profile = obj_path_table; profile->id != INVALID_PATH_ID; profile++) { + if (profile->id == dbus_data->path_id) { + handlers = profile->get_svc_table(); + break; } } } @@ -1298,7 +1287,7 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) uint8_t min_period; int dd = -1; - dd = hci_open_dev(dbus_data->id); + dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); @@ -1359,7 +1348,7 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) struct hci_dbus_data *dbus_data = data; int dd = -1; - dd = hci_open_dev(dbus_data->id); + dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); @@ -1403,9 +1392,9 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) goto failed; } - dd = hci_open_dev(dbus_data->id); + dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { - syslog(LOG_ERR, "Unable to open device %d: %s", dbus_data->id, strerror(errno)); + syslog(LOG_ERR, "Unable to open device %d: %s", dbus_data->dev_id, strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1448,9 +1437,10 @@ static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data) struct hci_dbus_data *dbus_data = data; int dd = -1; - dd = hci_open_dev(dbus_data->id); + dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { - syslog(LOG_ERR, "Unable to open device %d: %s", dbus_data->id, strerror(errno)); + syslog(LOG_ERR, "Unable to open device %d: %s", + dbus_data->dev_id, strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1499,7 +1489,7 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) goto failed; } - if (dbus_data->id != dev_id) { + if (dbus_data->dev_id != dev_id) { syslog(LOG_ERR, "Connection not found\n"); reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; @@ -1544,9 +1534,10 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) str2ba(str_bdaddr, &bdaddr); - dd = hci_open_dev(dbus_data->id); + dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { - syslog(LOG_ERR, "Unable to open device %d: %s", dbus_data->id, strerror(errno)); + syslog(LOG_ERR, "Unable to open device %d: %s", + dbus_data->dev_id, strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1606,7 +1597,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) goto failed; } - cl->dev_id = dbus_data->id; + cl->dev_id = dbus_data->dev_id; cl->conn_num = MAX_CONN_NUMBER; ci = cl->conn_info; @@ -1669,7 +1660,7 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) goto failed; } - if (dbus_data->id != dev_id) { + if (dbus_data->dev_id != dev_id) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; } @@ -1714,6 +1705,8 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) reply = dbus_message_new_method_return(msg); + reply = dbus_message_new_method_return(msg); + failed: if (dd >= 0) close(dd); @@ -1745,20 +1738,20 @@ static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data) goto failed; } - if (ioctl(sk, HCIDEVUP, dbus_data->id) < 0 && errno != EALREADY) { + if (ioctl(sk, HCIDEVUP, dbus_data->dev_id) < 0 && errno != EALREADY) { syslog(LOG_ERR, "Can't init device hci%d: %s (%d)\n", - dbus_data->id, strerror(errno), errno); + dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (ioctl(sk, HCIGETDEVINFO, (void *) &di) >= 0 && !hci_test_bit(HCI_RAW, &di.flags)) { - dr.dev_id = dbus_data->id; + dr.dev_id = dbus_data->dev_id; dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; /* piscan */ if (ioctl(sk, HCISETSCAN, (unsigned long) &dr) < 0) { syslog(LOG_ERR, "Can't set scan mode on hci%d: %s (%d)\n", - dbus_data->id, strerror(errno), errno); + dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1787,9 +1780,9 @@ static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data) goto failed; } - if (ioctl(sk, HCIDEVDOWN, dbus_data->id) < 0) { + if (ioctl(sk, HCIDEVDOWN, dbus_data->dev_id) < 0) { syslog(LOG_ERR, "Can't down device hci%d: %s (%d)\n", - dbus_data->id, strerror(errno), errno); + dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } diff --git a/hcid/dbus.h b/hcid/dbus.h index 1ec747a1..0e863846 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -34,8 +34,23 @@ #define ERROR_INTERFACE BASE_INTERFACE ".Error" -#define MANAGER_PATH_ID (0xFFFF) -#define DEVICE_PATH_ID (0xFFFE) +#define MANAGER_PATH_MASK (1 << 15) +#define DEVICE_PATH_MASK (1 << 14) + +/* /org/bluez/Manager */ +#define MANAGER_ROOT_ID MANAGER_PATH_MASK + +/* /org/bluez/Device */ +#define DEVICE_ROOT_ID DEVICE_PATH_MASK + +/* E.g. /org/bluez/Device/hci0 */ +#define DEVICE_PATH_ID (DEVICE_PATH_MASK | 0x0001) + +/* E.g. /org/bluez/Device/hci0/Controller */ +#define HCI_PATH_ID (DEVICE_PATH_MASK | 0x0002) + +#define INVALID_PATH_ID 0xFFFF +#define INVALID_DEV_ID 0xFFFF /*======================================================================== BlueZ D-Bus Manager service definitions "/org/bluez/Manager" -- cgit From 9051e7c708c05746f29054bb0158a17450bf22bc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 2 Nov 2005 18:46:46 +0000 Subject: Fix memory lack in authentication --- hcid/dbus.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 1db7b46b..1d0db2c0 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -1705,8 +1705,6 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) reply = dbus_message_new_method_return(msg); - reply = dbus_message_new_method_return(msg); - failed: if (dd >= 0) close(dd); -- cgit From 36e09e831cd166da955aeabc471fe6d2f63ac128 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 3 Nov 2005 08:33:25 +0000 Subject: Some more coding style cleanups --- hcid/dbus.c | 92 ++++++++++++++++++++++++------------------------------------- 1 file changed, 36 insertions(+), 56 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 1d0db2c0..c125e0c0 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -106,7 +106,7 @@ struct profile_obj_path_data { typedef struct { uint32_t code; const char *str; -}bluez_error_t; +} bluez_error_t; typedef struct { char *str; @@ -381,14 +381,15 @@ static void free_pin_req(void *req) static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t dev_id, const DBusObjectPathVTable *pvtable, gboolean fallback) { - struct hci_dbus_data *data; + gboolean ret = FALSE; + struct hci_dbus_data *data = NULL; - syslog(LOG_INFO,"Registering DBUS Path: %s", path); + syslog(LOG_INFO, "Registering DBUS Path: %s", path); data = malloc(sizeof(struct hci_dbus_data)); if (data == NULL) { - syslog(LOG_ERR,"Failed to alloc memory to DBUS path register data (%s)", path); - return FALSE; + syslog(LOG_ERR, "Failed to alloc memory to DBUS path register data (%s)", path); + goto out; } data->path_id = path_id; @@ -396,32 +397,36 @@ static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t if (fallback) { if (!dbus_connection_register_fallback(connection, path, pvtable, data)) { - syslog(LOG_ERR,"DBUS failed to register %s object", path); - free(data); - return FALSE; + syslog(LOG_ERR, "DBUS failed to register %s fallback", path); + goto out; } } else { if (!dbus_connection_register_object_path(connection, path, pvtable, data)) { - syslog(LOG_ERR,"DBUS failed to register %s object", path); - free(data); - return FALSE; + syslog(LOG_ERR, "DBUS failed to register %s object", path); + goto out; } } - return TRUE; + ret = TRUE; + +out: + if (!ret && data) + free(data); + + return ret; } static gboolean unregister_dbus_path(const char *path) { void *data; - syslog(LOG_INFO,"Unregistering DBUS Path: %s", path); + syslog(LOG_INFO, "Unregistering DBUS Path: %s", path); if (dbus_connection_get_object_path_data(connection, path, &data) && data) free(data); if (!dbus_connection_unregister_object_path (connection, path)) { - syslog(LOG_ERR,"DBUS failed to unregister %s object", path); + syslog(LOG_ERR, "DBUS failed to unregister %s object", path); return FALSE; } @@ -468,8 +473,7 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) failed: dbus_message_unref(message); - hci_send_cmd(dev, OGF_LINK_CTL, - OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); } void hcid_dbus_inquiry_start(bdaddr_t *local) @@ -506,10 +510,7 @@ void hcid_dbus_inquiry_start(bdaddr_t *local) failed: dbus_message_unref(message); - bt_free(local_addr); - - return; } void hcid_dbus_inquiry_complete(bdaddr_t *local) @@ -546,10 +547,7 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local) failed: dbus_message_unref(message); - bt_free(local_addr); - - return; } void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) @@ -598,8 +596,6 @@ failed: bt_free(local_addr); bt_free(peer_addr); - - return; } void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) @@ -645,8 +641,6 @@ failed: bt_free(local_addr); bt_free(peer_addr); - - return; } void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status) @@ -692,8 +686,6 @@ failed: bt_free(local_addr); bt_free(peer_addr); - - return; } void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) @@ -851,7 +843,7 @@ gboolean hcid_dbus_init(void) connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); if (dbus_error_is_set(&error)) { - syslog(LOG_ERR, "Can't open system message bus connection: %s\n", + syslog(LOG_ERR, "Can't open system message bus connection: %s", error.message); dbus_error_free(&error); return FALSE; @@ -861,7 +853,7 @@ gboolean hcid_dbus_init(void) DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &error); if (dbus_error_is_set(&error)) { - syslog(LOG_ERR,"Can't get system message bus name: %s\n", + syslog(LOG_ERR, "Can't get system message bus name: %s", error.message); dbus_error_free(&error); return FALSE; @@ -910,7 +902,6 @@ void hcid_dbus_exit(void) unregister_dbus_path(DEVICE_PATH); unregister_dbus_path(MANAGER_PATH); - } gboolean hcid_dbus_register_device(uint16_t id) @@ -1046,7 +1037,7 @@ gboolean hcid_dbus_dev_down(uint16_t id) for (; ptr->id != INVALID_PATH_ID; ptr++) { if (ptr->unreg_func(connection, id) < 0) - goto failed; + syslog(LOG_ERR, "Unregistering profile id %04X failed", ptr->id); } up_adapters--; @@ -1161,8 +1152,6 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, const struct service_data *handlers = NULL; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; - int type; - const char *iface; const char *method; const char *signature; const char *path; @@ -1170,8 +1159,6 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; path = dbus_message_get_path(msg); - type = dbus_message_get_type(msg); - iface = dbus_message_get_interface(msg); method = dbus_message_get_member(msg); signature = dbus_message_get_signature(msg); @@ -1216,11 +1203,9 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, if (error) reply = bluez_new_failure_msg(msg, error); - if (reply) { - if (!dbus_connection_send (conn, reply, NULL)) { + if (!dbus_connection_send (conn, reply, NULL)) syslog(LOG_ERR, "Can't send reply message!"); - } dbus_message_unref (reply); } @@ -1240,7 +1225,7 @@ static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg path = dbus_message_get_path(msg); iface = dbus_message_get_interface(msg); - method = dbus_message_get_member (msg); + method = dbus_message_get_member(msg); signature = dbus_message_get_signature(msg); syslog (LOG_INFO, "%s - path:%s", __PRETTY_FUNCTION__, path); @@ -1264,11 +1249,9 @@ static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg if (error) reply = bluez_new_failure_msg(msg, error); - if (reply) { - if (!dbus_connection_send (conn, reply, NULL)) { + if (!dbus_connection_send (conn, reply, NULL)) syslog(LOG_ERR, "Can't send reply message!"); - } dbus_message_unref (reply); } @@ -1484,35 +1467,32 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (dev_id < 0) { - syslog(LOG_ERR, "Bluetooth device failed\n"); + syslog(LOG_ERR, "Bluetooth device failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } if (dbus_data->dev_id != dev_id) { - syslog(LOG_ERR, "Connection not found\n"); + syslog(LOG_ERR, "Connection not found"); reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_CONN_NOT_FOUND); goto failed; } dd = hci_open_dev(dev_id); if (dd < 0) { - syslog(LOG_ERR, "HCI device open failed\n"); + syslog(LOG_ERR, "HCI device open failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } if (hci_switch_role(dd, &bdaddr, role, 10000) < 0) { - syslog(LOG_ERR, "Switch role request failed\n"); + syslog(LOG_ERR, "Switch role request failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); - } else { - uint8_t result = 0; - /* return TRUE to indicate that operation was completed */ - reply = dbus_message_new_method_return(msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE, &result); + goto failed; } + reply = dbus_message_new_method_return(msg); + failed: return reply; } @@ -1737,7 +1717,7 @@ static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data) } if (ioctl(sk, HCIDEVUP, dbus_data->dev_id) < 0 && errno != EALREADY) { - syslog(LOG_ERR, "Can't init device hci%d: %s (%d)\n", + syslog(LOG_ERR, "Can't init device hci%d: %s (%d)", dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; @@ -1748,7 +1728,7 @@ static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data) dr.dev_id = dbus_data->dev_id; dr.dev_opt = SCAN_PAGE | SCAN_INQUIRY; /* piscan */ if (ioctl(sk, HCISETSCAN, (unsigned long) &dr) < 0) { - syslog(LOG_ERR, "Can't set scan mode on hci%d: %s (%d)\n", + syslog(LOG_ERR, "Can't set scan mode on hci%d: %s (%d)", dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; @@ -1779,7 +1759,7 @@ static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data) } if (ioctl(sk, HCIDEVDOWN, dbus_data->dev_id) < 0) { - syslog(LOG_ERR, "Can't down device hci%d: %s (%d)\n", + syslog(LOG_ERR, "Can't down device hci%d: %s (%d)", dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; -- cgit From 3313f2a7f2e56d6c8e02fc4cf36ba54e33fb8e37 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 3 Nov 2005 10:32:32 +0000 Subject: Add the dbus-test script --- hcid/Makefile.am | 4 +- hcid/dbus-test | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 286 insertions(+), 1 deletion(-) create mode 100755 hcid/dbus-test diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 856f6bb5..d9e8ddbe 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -15,6 +15,8 @@ endif sbin_PROGRAMS = hcid +noinst_SCRIPTS = dbus-test + if DBUS dbus_hcid_sources = dbus.h dbus.c dbus_hcid_libs = @DBUS_LIBS@ @@ -42,7 +44,7 @@ AM_YFLAGS = -d CLEANFILES = lexer.c parser.c parser.h -EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.h dbus.c bluez-hcid.conf +EXTRA_DIST = $(man_MANS) $(conf_DATA) dbus.h dbus.c dbus-test bluez-hcid.conf MAINTAINERCLEANFILES = Makefile.in diff --git a/hcid/dbus-test b/hcid/dbus-test new file mode 100755 index 00000000..830d3bf7 --- /dev/null +++ b/hcid/dbus-test @@ -0,0 +1,283 @@ +#!/usr/bin/env python + +import dbus +import dbus.glib +import gobject +import sys +import getopt +from signal import * + +mgr_cmds = [ "DeviceList", "DefaultDevice" ] +dev_cmds = [ "Inquiry", "CancelInquiry", "PeriodicInquiry", "CancelPeriodic", + "RemoteName", "Connections", "Authenticate", "RoleSwitch" ] + +class Tester: + exit_events = [] + dev_path = None + need_dev = False + listen = False + at_interrupt = None + + def __init__(self, argv): + self.name = argv[0] + + self.parse_args(argv[1:]) + + try: + self.dbus_setup() + except dbus.DBusException, e: + print 'Failed to do D-BUS setup: %s' % e + sys.exit(1) + + self.dev_setup() + + def parse_args(self, argv): + try: + opts, args = getopt.getopt(argv, "hli:") + except getopt.GetoptError: + self.usage() + sys.exit(1) + + for o, a in opts: + if o == "-h": + self.usage() + sys.exit() + elif o == "-l": + self.need_dev = True + self.listen = True + elif o == "-i": + if a[0] == '/': + self.dev_path = a + else: + self.dev_path = '/org/bluez/Device/%s' % a + + if not (args or self.listen): + self.usage() + sys.exit(1) + + if args: + self.cmd = args[0] + self.cmd_args = args[1:] + + if not self.cmd in mgr_cmds: + self.need_dev = True + + def dev_setup(self): + if self.need_dev and not self.dev_path: + try: + self.dev_path = self.manager.DefaultDevice() + except dbus.DBusException, e: + print 'Failed to get default device: %s' % e + sys.exit(1) + + if self.dev_path: + try: + obj = self.bus.get_object('org.bluez', self.dev_path) + self.dev = dbus.Interface(obj, 'org.bluez.Device') + + self.dev.connect_to_signal('Up', self.dev_up) + self.dev.connect_to_signal('Down', self.dev_down) + + obj = self.bus.get_object('org.bluez', '%s/Controller' % self.dev_path) + self.ctl = dbus.Interface(obj, 'org.bluez.Device.Controller') + + self.ctl.connect_to_signal('InquiryStart', self.inquiry_start) + self.ctl.connect_to_signal('InquiryResult', self.inquiry_result) + self.ctl.connect_to_signal('InquiryComplete', self.inquiry_complete) + self.ctl.connect_to_signal('RemoteName', self.remote_name) + self.ctl.connect_to_signal('RemoteNameFailed', self.remote_name_failed) + self.ctl.connect_to_signal('AuthenticationComplete', self.authentication_complete) + + except dbus.DBusException, e: + print 'Failed to setup device path: %s' % e + sys.exit(1) + + def dbus_setup(self): + self.bus = dbus.SystemBus() + manager_obj = self.bus.get_object('org.bluez', '/org/bluez/Manager') + self.manager = dbus.Interface(manager_obj, 'org.bluez.Manager') + self.manager.connect_to_signal('DeviceAdded', self.device_added) + self.manager.connect_to_signal('DeviceRemoved', self.device_removed) + + def usage(self): + print 'Usage: %s [-i] [-l] [-h] [arg1..]' % self.name + print ' -i Specify device (e.g. "hci0" or "/dev/bluez/Device/hci0")' + print ' -l Listen for events (no command required)' + print ' -h Show this help' + print 'Manager commands:' + for cmd in mgr_cmds: + print '\t%s' % cmd + print 'Device commands:' + for cmd in dev_cmds: + print '\t%s' % cmd + + def device_added(self, path): + print 'DeviceAdded: %s' % path + + def device_removed(self, path): + print 'DeviceRemoved: %s' % path + + def remote_name(self, bda, name): + print 'RemoteName: %s, %s' % (bda, name) + if 'RemoteName' in self.exit_events: + self.main_loop.quit() + + def remote_name_failed(self, bda, status): + print 'RemoteNameFailed: %s, 0x%02X' % (bda, status) + if 'RemoteNameFailed' in self.exit_events: + self.main_loop.quit() + + def inquiry_start(self): + print 'InquiryStart' + + def inquiry_complete(self): + print 'InquiryComplete' + if 'InquiryComplete' in self.exit_events: + self.main_loop.quit() + + def inquiry_result(self, bda, cls, rssi): + print 'InquiryResult: %s, %06X, %02X' % (bda, cls, rssi) + + def authentication_complete(self, bda, status): + print 'AuthenticationComplete: %s, 0x%02X' % (bda, status) + if 'AuthenticationComplete' in self.exit_events: + self.main_loop.quit() + + def dev_up(self): + print 'Up' + + def dev_down(self): + print 'Down' + + def signal_cb(self, sig, frame): + print 'Caught signal, exiting' + if self.at_interrupt: + self.at_interrupt() + self.main_loop.quit() + + def run(self): + # Manager methods + if self.listen: + print 'Listening for events...' + elif self.cmd == 'DeviceList': + for dev in self.manager.DeviceList(): + print dev + elif self.cmd == 'DefaultDevice': + print self.manager.DefaultDevice() + + # Device methods + elif self.cmd == 'Up': + try: + self.dev.Up() + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + elif self.cmd == 'Down': + try: + self.dev.Down() + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + + # Device.Controller methods + elif self.cmd == 'Inquiry': + if len(self.cmd_args) != 2: + length, maxrsp = (10, 100) + else: + length, maxrsp = self.cmd_args + try: + self.ctl.Inquiry(dbus.Byte(length), dbus.Byte(maxrsp)) + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + self.listen = True + self.exit_events.append('InquiryComplete') + self.at_interrupt = self.ctl.CancelInquiry + + elif self.cmd == 'CancelInquiry': + try: + self.ctl.CancelInquiry() + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + + elif self.cmd == 'RemoteName': + if len(self.cmd_args) < 1: + print 'Bluetooth address needed' + sys.exit(1) + try: + self.ctl.RemoteName(self.cmd_args[0]) + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + self.listen = True + self.exit_events.append('RemoteNameFailed') + self.exit_events.append('RemoteName') + + elif self.cmd == 'PeriodicInquiry': + if len(self.cmd_args) != 3: + length, min, max = (6, 20, 60) + else: + length, min, max = self.cmd_args + self.listen = True + try: + self.ctl.PeriodicInquiry(dbus.Byte(length), dbus.Byte(min), dbus.Byte(max)) + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + + elif self.cmd == 'CancelPeriodic': + try: + self.ctl.CancelPeriodic() + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + + elif self.cmd == 'Authenticate': + if len(self.cmd_args) < 1: + print 'Bluetooth address needed' + sys.exit(1) + try: + self.ctl.Authenticate(self.cmd_args[0]) + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + self.listen = True + self.exit_events.append('AuthenticationComplete') + + elif self.cmd == 'RoleSwitch': + if len(self.cmd_args) < 2: + print 'Bluetooth address and role needed' + exit.exit(1) + bda, role = self.cmd_args + if not (role == '0' or role == '1'): + print 'Role should be 0 (master) or 1 (slave)' + sys.exit(1) + try: + self.ctl.RoleSwitch(bda, dbus.Byte(role)) + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + + elif self.cmd == 'Connections': + connections = self.ctl.Connections() + for conn in connections: + print conn + + else: + print 'Unknown command: %s' % self.cmd + sys.exit(1) + + if self.listen: + signal(SIGINT, self.signal_cb) + signal(SIGTERM, self.signal_cb) + self.main_loop = gobject.MainLoop() + self.main_loop.run() + +if __name__ == '__main__': + gobject.threads_init() + dbus.glib.init_threads() + + tester = Tester(sys.argv) + tester.run() + -- cgit From 004a8f318415fec7b3dfc338520a3c1d44da8c85 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 3 Nov 2005 13:58:28 +0000 Subject: More cleanups --- hcid/dbus.c | 117 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index c125e0c0..0923f552 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -46,15 +46,11 @@ static DBusConnection *connection; static int default_dev = -1; -static int up_adapters = 0; #define TIMEOUT (30 * 1000) /* 30 seconds */ -#define BLUETOOTH_DEVICE_NAME_LEN 18 -#define BLUETOOTH_DEVICE_ADDR_LEN 18 +#define BTADDR_LEN 18 #define MAX_PATH_LENGTH 64 -#define READ_REMOTE_NAME_TIMEOUT 25000 #define MAX_CONN_NUMBER 10 -#define DEVICE_FLAG_NAME 16 #define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent" #define PINAGENT_INTERFACE PINAGENT_SERVICE_NAME @@ -133,7 +129,7 @@ static const bluez_error_t dbus_error_array[] = { { BLUEZ_EDBUS_RECORD_NOT_FOUND, "No record found" }, { BLUEZ_EDBUS_NO_MEM, "No memory" }, { BLUEZ_EDBUS_CONN_NOT_FOUND, "Connection not found" }, - { BLUEZ_EDBUS_UNKNOWN_PATH, "Device path is not registered" }, + { BLUEZ_EDBUS_UNKNOWN_PATH, "Unknown D-BUS path" }, { 0, NULL } }; @@ -252,15 +248,10 @@ static struct profile_obj_path_data obj_path_table[] = { }; /* - * Device Message handler functions object table declaration + * Virtual table that handle the object path hierarchy */ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data); static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data); - -static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data); -static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data); -static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data); -static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data); static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data); static const DBusObjectPathVTable obj_dev_vtable = { @@ -273,6 +264,12 @@ static const DBusObjectPathVTable obj_mgr_vtable = { .unregister_function = NULL }; +/* + * Services provided under the path DEVICE_PATH + */ +static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data); +static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data); + static const struct service_data device_services[] = { { DEV_UP, handle_device_up_req, DEV_UP_SIGNATURE }, { DEV_DOWN, handle_device_down_req, DEV_DOWN_SIGNATURE }, @@ -283,9 +280,11 @@ static const struct service_data device_services[] = { }; /* - * Manager Message handler functions object table declaration - * + * Services provided under the path MANAGER_PATH */ +static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data); +static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data); + static const struct service_data manager_services[] = { { MGR_DEVICE_LIST, handle_device_list_req, MGR_GET_DEV_SIGNATURE }, { MGR_DEFAULT_DEVICE, handle_default_device_req, MGR_DEFAULT_DEV_SIGNATURE }, @@ -296,8 +295,7 @@ static const struct service_data manager_services[] = { }; /* - * HCI Manager Message handler functions object table declaration - * + * HCI D-Bus services */ static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *msg, void *data); @@ -389,7 +387,7 @@ static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t data = malloc(sizeof(struct hci_dbus_data)); if (data == NULL) { syslog(LOG_ERR, "Failed to alloc memory to DBUS path register data (%s)", path); - goto out; + goto failed; } data->path_id = path_id; @@ -398,18 +396,18 @@ static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t if (fallback) { if (!dbus_connection_register_fallback(connection, path, pvtable, data)) { syslog(LOG_ERR, "DBUS failed to register %s fallback", path); - goto out; + goto failed; } } else { if (!dbus_connection_register_object_path(connection, path, pvtable, data)) { syslog(LOG_ERR, "DBUS failed to register %s object", path); - goto out; + goto failed; } } ret = TRUE; -out: +failed: if (!ret && data) free(data); @@ -735,8 +733,7 @@ void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t stat dbus_connection_flush(connection); failed: - if (message) - dbus_message_unref(message); + dbus_message_unref(message); bt_free(local_addr); bt_free(peer_addr); @@ -902,6 +899,8 @@ void hcid_dbus_exit(void) unregister_dbus_path(DEVICE_PATH); unregister_dbus_path(MANAGER_PATH); + + dbus_connection_close(connection); } gboolean hcid_dbus_register_device(uint16_t id) @@ -918,7 +917,7 @@ gboolean hcid_dbus_register_device(uint16_t id) if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); - goto out; + goto failed; } dbus_message_append_args(message, @@ -927,14 +926,13 @@ gboolean hcid_dbus_register_device(uint16_t id) if (!dbus_connection_send(connection, message, NULL)) { syslog(LOG_ERR, "Can't send D-BUS added device message"); - goto out; + goto failed; } dbus_connection_flush(connection); -out: - if (message) - dbus_message_unref(message); +failed: + dbus_message_unref(message); ret = register_dbus_path(path, DEVICE_PATH_ID, id, &obj_dev_vtable, FALSE); @@ -957,7 +955,7 @@ gboolean hcid_dbus_unregister_device(uint16_t id) BLUEZ_MGR_DEV_REMOVED); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); - goto out; + goto failed; } dbus_message_append_args(message, @@ -966,14 +964,13 @@ gboolean hcid_dbus_unregister_device(uint16_t id) if (!dbus_connection_send(connection, message, NULL)) { syslog(LOG_ERR, "Can't send D-BUS added device message"); - goto out; + goto failed; } dbus_connection_flush(connection); -out: - if (message) - dbus_message_unref(message); +failed: + dbus_message_unref(message); ret = unregister_device_path(path); @@ -999,8 +996,6 @@ gboolean hcid_dbus_dev_up(uint16_t id) goto failed; } - up_adapters++; - snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_UP); @@ -1020,8 +1015,7 @@ gboolean hcid_dbus_dev_up(uint16_t id) failed: /* if the signal can't be sent ignore the error */ - if (message) - dbus_message_unref(message); + dbus_message_unref(message); return TRUE; } @@ -1040,8 +1034,6 @@ gboolean hcid_dbus_dev_down(uint16_t id) syslog(LOG_ERR, "Unregistering profile id %04X failed", ptr->id); } - up_adapters--; - snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_DOWN); @@ -1060,8 +1052,7 @@ gboolean hcid_dbus_dev_down(uint16_t id) failed: /* if the signal can't be sent ignore the error */ - if (message) - dbus_message_unref(message); + dbus_message_unref(message); return TRUE; } @@ -1114,10 +1105,9 @@ const struct service_data *get_hci_table(void) /***************************************************************** * - * Section reserved to HCI Manaher D-Bus message handlers + * Section reserved to HCI D-Bus services * *****************************************************************/ - static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *msg, void *data) { DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -1165,13 +1155,12 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, syslog(LOG_INFO, "%s - path:%s, path_id:%04X dev_id:%04X", __PRETTY_FUNCTION__, path, dbus_data->path_id, dbus_data->dev_id); - /* Check for message that doesn't belong in this path */ - if (!(dbus_data->path_id & DEVICE_PATH_MASK)) - return ret; - - /* Fallback services not currently supported */ - if (dbus_data->path_id == DEVICE_ROOT_ID) - return ret; + if (dbus_data->path_id == DEVICE_ROOT_ID) { + /* Device is down(path unregistered) or the path is wrong */ + ret = DBUS_HANDLER_RESULT_HANDLED; + error = BLUEZ_EDBUS_UNKNOWN_PATH; + goto failed; + } if (dbus_data->path_id == DEVICE_PATH_ID) handlers = device_services; @@ -1200,6 +1189,7 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, } } +failed: if (error) reply = bluez_new_failure_msg(msg, error); @@ -1558,7 +1548,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter struct_iter; - char addr[18]; + char addr[BTADDR_LEN]; const char array_sig[] = HCI_CONN_INFO_STRUCT_SIGNATURE; const char *paddr = addr; struct hci_dbus_data *dbus_data = data; @@ -1587,6 +1577,11 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) } reply = dbus_message_new_method_return(msg); + if (reply == NULL) { + syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); + goto failed; + } + dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); @@ -1697,7 +1692,7 @@ failed: /***************************************************************** * - * Section reserved to Manager D-Bus message handlers + * Section reserved to local device configuration D-Bus Services * *****************************************************************/ static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data) @@ -1810,13 +1805,18 @@ static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data) /* active bluetooth adapter found */ reply = dbus_message_new_method_return(msg); + if (reply == NULL) { + syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); + goto failed; + } + dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, array_sig, &array_iter); dr = dl->dev_req; for (i = 0; i < dl->dev_num; i++, dr++) { char apath[MAX_PATH_LENGTH]; - char aaddr[BLUETOOTH_DEVICE_ADDR_LEN]; + char aaddr[BTADDR_LEN]; char *paddr = aaddr; char *ppath = apath; char *ptype; @@ -1875,6 +1875,11 @@ failed: return reply; } +/***************************************************************** + * + * Section reserved to Manager D-Bus services + * + *****************************************************************/ static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data) { char path[MAX_PATH_LENGTH]; char *pptr = path; @@ -1882,13 +1887,13 @@ static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data) { if (default_dev < 0) { reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); - goto out; + goto failed; } reply = dbus_message_new_method_return(msg); if (reply == NULL) { - syslog(LOG_ERR, "Out of memory while calling new_method_return"); - goto out; + syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); + goto failed; } snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, default_dev); @@ -1896,7 +1901,7 @@ static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data) { DBUS_TYPE_STRING, &pptr, DBUS_TYPE_INVALID); -out: +failed: return reply; } -- cgit From a204981f9c2cd042b1b314385cc2c218dcf6f7b5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 3 Nov 2005 14:35:15 +0000 Subject: Update dbus-test script --- hcid/dbus-test | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hcid/dbus-test b/hcid/dbus-test index 830d3bf7..c931fa85 100755 --- a/hcid/dbus-test +++ b/hcid/dbus-test @@ -8,8 +8,9 @@ import getopt from signal import * mgr_cmds = [ "DeviceList", "DefaultDevice" ] -dev_cmds = [ "Inquiry", "CancelInquiry", "PeriodicInquiry", "CancelPeriodic", - "RemoteName", "Connections", "Authenticate", "RoleSwitch" ] +dev_cmds = [ "Up", "Down", "Inquiry", "CancelInquiry", "PeriodicInquiry", + "CancelPeriodic", "RemoteName", "Connections", "Authenticate", + "RoleSwitch" ] class Tester: exit_events = [] @@ -100,8 +101,8 @@ class Tester: self.manager.connect_to_signal('DeviceRemoved', self.device_removed) def usage(self): - print 'Usage: %s [-i] [-l] [-h] [arg1..]' % self.name - print ' -i Specify device (e.g. "hci0" or "/dev/bluez/Device/hci0")' + print 'Usage: %s [-i ] [-l] [-h] [arg1..]' % self.name + print ' -i Specify device (e.g. "hci0" or "/org/bluez/Device/hci0")' print ' -l Listen for events (no command required)' print ' -h Show this help' print 'Manager commands:' -- cgit From 473446233d1a259f526777782aada53b993d73cc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 3 Nov 2005 14:46:17 +0000 Subject: Remove usage of BTADDR_LEN --- hcid/dbus.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 0923f552..aef9ecc0 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -48,7 +48,6 @@ static DBusConnection *connection; static int default_dev = -1; #define TIMEOUT (30 * 1000) /* 30 seconds */ -#define BTADDR_LEN 18 #define MAX_PATH_LENGTH 64 #define MAX_CONN_NUMBER 10 @@ -1548,7 +1547,7 @@ static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data) DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter struct_iter; - char addr[BTADDR_LEN]; + char addr[18]; const char array_sig[] = HCI_CONN_INFO_STRUCT_SIGNATURE; const char *paddr = addr; struct hci_dbus_data *dbus_data = data; @@ -1816,7 +1815,7 @@ static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data) for (i = 0; i < dl->dev_num; i++, dr++) { char apath[MAX_PATH_LENGTH]; - char aaddr[BTADDR_LEN]; + char aaddr[18]; char *paddr = aaddr; char *ppath = apath; char *ptype; -- cgit From 9410c612d365b3aabf13da966e6782225068954f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 4 Nov 2005 15:42:24 +0000 Subject: Add initial support of setproperty and getproperty --- hcid/dbus.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- hcid/dbus.h | 40 ++++++++++++++++++-- 2 files changed, 152 insertions(+), 10 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index aef9ecc0..347cf218 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -268,13 +268,61 @@ static const DBusObjectPathVTable obj_mgr_vtable = { */ static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data); static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data); +static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data); +static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data); static const struct service_data device_services[] = { { DEV_UP, handle_device_up_req, DEV_UP_SIGNATURE }, { DEV_DOWN, handle_device_down_req, DEV_DOWN_SIGNATURE }, - { DEV_RESET, handle_not_implemented_req, DEV_RESET_SIGNATURE }, - { DEV_SET_PROPERTY, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE }, - { DEV_GET_PROPERTY, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_2 }, + { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_3 }, + { DEV_GET_PROPERTY, handle_device_get_propety_req, DEV_GET_PROPERTY_SIGNATURE }, + { NULL, NULL, NULL} +}; + +static const struct service_data set_property_services[] = { + { DEV_PROPERTY_AUTH, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_ENCRYPT, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_SECMGR, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_PISCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_PSCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_ISCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_PTYPE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_LM, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_LP, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_NAME, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_CLASS, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_VOICE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_IAC, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_INCMODE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_INCTYPE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_INCPARMS, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_PAGEPARMS, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_PAGETO, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_AFHMODE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_ACLMTU, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_SCOMTU, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_PUTKEY, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_DELKEY, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { NULL, NULL, NULL} +}; + +static const struct service_data get_property_services[] = { + { DEV_PROPERTY_DEV_INFO, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_PTYPE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_LM, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_LP, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_NAME, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_CLASS, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_VOICE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_IAC, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_INCMODE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_INCTYPE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_INCPARMS, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_PAGEPARMS, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_PAGETO, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_AFHMODE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, { NULL, NULL, NULL} }; @@ -1174,16 +1222,16 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, } if (handlers) { + error = BLUEZ_EDBUS_WRONG_SIGNATURE; for (; handlers->name != NULL; handlers++) { if (strcmp(handlers->name, method) == 0) { - if (strcmp(handlers->signature, signature) != 0) - error = BLUEZ_EDBUS_WRONG_SIGNATURE; - else { + if (strcmp(handlers->signature, signature) == 0) { reply = handlers->handler_func(msg, data); error = 0; + ret = DBUS_HANDLER_RESULT_HANDLED; + break; } - ret = DBUS_HANDLER_RESULT_HANDLED; } } } @@ -1768,6 +1816,66 @@ failed: return reply; } +static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data) +{ + const struct service_data *handlers = set_property_services; + DBusMessageIter iter; + DBusMessage *reply = NULL; + const char *signature; + char *str_name; + uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; + + signature = dbus_message_get_signature(msg); + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &str_name); + + for (; handlers->name != NULL; handlers++) { + if (strcasecmp(handlers->name, str_name) == 0) { + if (strcmp(handlers->signature, signature) == 0) { + reply = handlers->handler_func(msg, data); + error = 0; + break; + } else { + error = BLUEZ_EDBUS_WRONG_SIGNATURE; + break; + } + + } + } + + if (error) + reply = bluez_new_failure_msg(msg, error); + + return reply; +} + +static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data) +{ + const struct service_data *handlers = get_property_services; + DBusMessageIter iter; + DBusMessage *reply = NULL; + char *str_name; + uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; + + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &str_name); + + for (; handlers->name != NULL; handlers++) { + if (strcasecmp(handlers->name, str_name) == 0) { + reply = handlers->handler_func(msg, data); + error = 0; + break; + } + } + + if (error) + reply = bluez_new_failure_msg(msg, error); + + return reply; +} + static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data) { DBusMessageIter iter; diff --git a/hcid/dbus.h b/hcid/dbus.h index 0e863846..bf344bf7 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -120,15 +120,49 @@ /* Control interface methods */ #define DEV_UP "Up" #define DEV_DOWN "Down" -#define DEV_RESET "Reset" #define DEV_SET_PROPERTY "SetProperty" #define DEV_GET_PROPERTY "GetProperty" +#define DEV_PROPERTY_AUTH "auth" +#define DEV_PROPERTY_ENCRYPT "encrypt" +#define DEV_PROPERTY_SECMGR "secmgr" +#define DEV_PROPERTY_PISCAN "piscan" +#define DEV_PROPERTY_PSCAN "pscan" +#define DEV_PROPERTY_ISCAN "iscan" +#define DEV_PROPERTY_PTYPE "ptype" +#define DEV_PROPERTY_LM "lm" +#define DEV_PROPERTY_LP "lp" +#define DEV_PROPERTY_NAME "name" +#define DEV_PROPERTY_CLASS "class" +#define DEV_PROPERTY_VOICE "voice" +#define DEV_PROPERTY_IAC "iac" +#define DEV_PROPERTY_INCMODE "incmode" +#define DEV_PROPERTY_INCTYPE "inctype" +#define DEV_PROPERTY_INCPARMS "incparms" +#define DEV_PROPERTY_PAGEPARMS "pageparms" +#define DEV_PROPERTY_PAGETO "pageto" +#define DEV_PROPERTY_AFHMODE "afhmode" +#define DEV_PROPERTY_ACLMTU "aclmtu" +#define DEV_PROPERTY_SCOMTU "scomtu" +#define DEV_PROPERTY_PUTKEY "putkey" +#define DEV_PROPERTY_DELKEY "delkey" +#define DEV_PROPERTY_DEV_INFO "info" + #define DEV_UP_SIGNATURE __END_SIG__ #define DEV_DOWN_SIGNATURE __END_SIG__ #define DEV_RESET_SIGNATURE __END_SIG__ -#define DEV_SET_PROPERTY_SIGNATURE __END_SIG__ -#define DEV_GET_PROPERTY_SIGNATURE __END_SIG__ +#define DEV_SET_PROPERTY_SIGNATURE_1 DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_BOOLEAN_AS_STRING \ + __END_SIG__ +#define DEV_SET_PROPERTY_SIGNATURE_2 DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_STRING_AS_STRING \ + __END_SIG__ +#define DEV_SET_PROPERTY_SIGNATURE_3 DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ + __END_SIG__ + +#define DEV_GET_PROPERTY_SIGNATURE DBUS_TYPE_STRING_AS_STRING \ + __END_SIG__ #define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ -- cgit From 50a8cc8a256f3ef56a6144cabd2ae6ee5848e46d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Nov 2005 21:00:58 +0000 Subject: Update to the new BCCMD interface utility --- acinclude.m4 | 18 +- tools/Makefile.am | 36 +-- tools/bccmd.c | 749 ++++++++++++++++++++++++++++++++++++++++++++++++++---- tools/csrinit.8 | 35 --- tools/csrinit.c | 97 ------- tools/pskey.c | 581 ------------------------------------------ 6 files changed, 727 insertions(+), 789 deletions(-) delete mode 100644 tools/csrinit.8 delete mode 100644 tools/csrinit.c delete mode 100644 tools/pskey.c diff --git a/acinclude.m4 b/acinclude.m4 index 8b8b4f06..65ae27b3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -297,9 +297,9 @@ AC_DEFUN([AC_ARG_BLUEZ], [ cups_enable=no pcmcia_enable=no initscripts_enable=no - avctrl_enable=${usb_found} + bccmd_enable=no + avctrl_enable=no hid2hci_enable=${usb_found} - csrinit_enable=no dfutool_enable=no bcm203x_enable=no bluepin_enable=yes @@ -325,9 +325,9 @@ AC_DEFUN([AC_ARG_BLUEZ], [ cups_enable=${enableval} pcmcia_enable=${enableval} initscripts_enable=${enableval} + bccmd_enable=${enableval} avctrl_enable=${enableval} hid2hci_enable=${enableval} - csrinit_enable=${enableval} dfutool_enable=${enableval} bcm203x_enable=${enableval} bluepin_enable=${enableval} @@ -365,6 +365,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [ initscripts_enable=${enableval} ]) + AC_ARG_ENABLE(bccmd, AC_HELP_STRING([--enable-bccmd], [install BCCMD interface utility]), [ + bccmd_enable=${enableval} + ]) + AC_ARG_ENABLE(avctrl, AC_HELP_STRING([--enable-avctrl], [install Audio/Video control utility]), [ avctrl_enable=${enableval} ]) @@ -373,10 +377,6 @@ AC_DEFUN([AC_ARG_BLUEZ], [ hid2hci_enable=${enableval} ]) - AC_ARG_ENABLE(csrinit, AC_HELP_STRING([--enable-csrinit], [install CSR ROM chip setup utility]), [ - csrinit_enable=${enableval} - ]) - AC_ARG_ENABLE(dfutool, AC_HELP_STRING([--enable-dfutool], [install DFU firmware upgrade utility]), [ dfutool_enable=${enableval} ]) @@ -385,7 +385,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ bcm203x_enable=${enableval} ]) - AC_ARG_ENABLE(bluepin, AC_HELP_STRING([--enable-bluepin], [install Python based PIN helper utility]), [ + AC_ARG_ENABLE(bluepin, AC_HELP_STRING([--enable-bluepin], [install Python based PIN helper]), [ bluepin_enable=${enableval} ]) @@ -410,9 +410,9 @@ AC_DEFUN([AC_ARG_BLUEZ], [ AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") AM_CONDITIONAL(PCMCIA, test "${pcmcia_enable}" = "yes") AM_CONDITIONAL(INITSCRIPTS, test "${initscripts_enable}" = "yes") + AM_CONDITIONAL(BCCMD, test "${bccmd_enable}" = "yes") AM_CONDITIONAL(AVCTRL, test "${avctrl_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes") - AM_CONDITIONAL(CSRINIT, test "${csrinit_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(DFUTOOL, test "${dfutool_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(BCM203X, test "${bcm203x_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(BLUEPIN, test "${bluepin_enable}" = "yes") diff --git a/tools/Makefile.am b/tools/Makefile.am index 479011ec..238a2df1 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,4 +1,12 @@ +if BCCMD +bccmd_programs = bccmd +bccmd_manfiles = bccmd.8 +else +bccmd_programs = +bccmd_manfiles = +endif + if AVCTRL avctrl_programs = avctrl avctrl_manfiles = avctrl.8 @@ -15,14 +23,6 @@ hid2hci_programs = hid2hci_manfiles = endif -if CSRINIT -csrinit_programs = csrinit -csrinit_manfiles = csrinit.8 -else -csrinit_programs = -csrinit_manfiles = -endif - if DFUTOOL dfutool_programs = dfutool dfutool_manfiles = dfutool.1 @@ -31,11 +31,11 @@ dfutool_programs = dfutool_manfiles = endif -sbin_PROGRAMS = hciattach hciconfig $(avctrl_programs) $(hid2hci_programs) $(csrinit_programs) +sbin_PROGRAMS = hciattach hciconfig $(bccmd_programs) $(avctrl_programs) $(hid2hci_programs) bin_PROGRAMS = hcitool l2ping sdptool ciptool $(dfutool_programs) -noinst_PROGRAMS = hcisecfilter ppporc pskey bccmd +noinst_PROGRAMS = hcisecfilter ppporc hciconfig_SOURCES = hciconfig.c csr.h csr.c hciconfig_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a @@ -51,11 +51,10 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ -pskey_SOURCES = pskey.c csr.h csr.c -pskey_LDADD = @BLUEZ_LIBS@ - +if BCCMD bccmd_SOURCES = bccmd.c csr.h csr.c bccmd_LDADD = @BLUEZ_LIBS@ +endif if AVCTRL avctrl_LDADD = @USB_LIBS@ @@ -65,11 +64,6 @@ if HID2HCI hid2hci_LDADD = @USB_LIBS@ endif -if CSRINIT -csrinit_SOURCES = csrinit.c csr.h -csrinit_LDADD = @USB_LIBS@ -endif - if DFUTOOL dfutool_SOURCES = dfutool.c dfu.h dfu.c dfutool_LDADD = @USB_LIBS@ @@ -80,10 +74,8 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @USB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common man_MANS = hciattach.8 hciconfig.8 hcitool.1 l2ping.1 sdptool.1 ciptool.1 \ - $(avctrl_manfiles) $(hid2hci_manfiles) $(csrinit_manfiles) $(dfutool_manfiles) - -noinst_MANS = bccmd.8 + $(bccmd_manfiles) $(avctrl_manfiles) $(hid2hci_manfiles) $(dfutool_manfiles) -EXTRA_DIST = $(man_MANS) avctrl.8 hid2hci.8 csrinit.8 dfutool.1 bccmd.8 example.psr +EXTRA_DIST = $(man_MANS) bccmd.8 avctrl.8 hid2hci.8 dfutool.1 example.psr MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/bccmd.c b/tools/bccmd.c index 46cc2be1..e41f08f5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -37,12 +37,144 @@ #include "csr.h" +#define CSR_TRANSPORT_UNKNOWN 0 +#define CSR_TRANSPORT_HCI 1 +#define CSR_TRANSPORT_USB 2 +#define CSR_TRANSPORT_BCSP 3 +#define CSR_TRANSPORT_H4 4 +#define CSR_TRANSPORT_3WIRE 5 + +#define CSR_STORES_PSI (0x0001) +#define CSR_STORES_PSF (0x0002) +#define CSR_STORES_PSROM (0x0004) +#define CSR_STORES_PSRAM (0x0008) +#define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF | CSR_STORES_PSRAM) + +#define CSR_TYPE_NULL 0 +#define CSR_TYPE_COMPLEX 1 +#define CSR_TYPE_UINT8 2 +#define CSR_TYPE_UINT16 3 +#define CSR_TYPE_UINT32 4 + +#define CSR_TYPE_ARRAY CSR_TYPE_COMPLEX +#define CSR_TYPE_BDADDR CSR_TYPE_COMPLEX + +static uint16_t seqnum = 0x0000; + +static struct { + uint16_t pskey; + int type; + int size; + char *str; +} storage[] = { + { CSR_PSKEY_BDADDR, CSR_TYPE_BDADDR, 8, "bdaddr" }, + { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, 0, "country" }, + { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, 0, "devclass" }, + { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, 0, "keymin" }, + { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, 0, "keymax" }, + { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, 8, "features" }, + { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, 18, "commands" }, + { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, 0, "version" }, + { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, 0, "remver" }, + { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, 0, "hciextn" }, + { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, 0, "mapsco" }, + { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, 0, "baudrate" }, + { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, 0, "hostintf" }, + { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, 0, "anafreq" }, + { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, 0, "anaftrim" }, + { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, 0, "usbvid" }, + { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, 0, "usbpid" }, + { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, 0, "dfupid" }, + { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, 0, "bootmode" }, + { 0x0000 }, +}; + +static int pskey_size(uint16_t pskey) +{ + switch (pskey) { + case CSR_PSKEY_BDADDR: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: + return 8; + case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: + return 18; + default: + return 64; + } +} + +static char *storestostr(uint16_t stores) +{ + switch (stores) { + case 0x0000: + return "Default"; + case 0x0001: + return "psi"; + case 0x0002: + return "psf"; + case 0x0004: + return "psrom"; + case 0x0008: + return "psram"; + default: + return "Unknown"; + } +} + +static char *memorytostr(uint16_t type) +{ + switch (type) { + case 0x0000: + return "Flash memory"; + case 0x0001: + return "EEPROM"; + case 0x0002: + return "RAM (transient)"; + case 0x0003: + return "ROM (or \"read-only\" flash memory)"; + default: + return "Unknown"; + } +} + +#define OPT_RANGE(range) \ + if (argc < (range)) { errno = EINVAL; return -1; } \ + if (argc > (range)) { errno = E2BIG; return -1; } + +static struct option help_options[] = { + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static int opt_help(int argc, char *argv[], int *help) +{ + int opt; + + while ((opt=getopt_long(argc, argv, "+h", help_options, NULL)) != EOF) { + switch (opt) { + case 'h': + if (help) + *help = 1; + break; + } + } + + return optind; +} + +#define OPT_HELP(range, help) \ + opt_help(argc, argv, (help)); \ + argc -= optind; argv += optind; optind = 0; \ + OPT_RANGE((range)) + static int cmd_builddef(int dd, int argc, char *argv[]) { uint8_t buf[8]; - uint16_t seqnum = 0x4711, def = 0x0000, nextdef = 0x0000; + uint16_t def = 0x0000, nextdef = 0x0000; int err = 0; + OPT_HELP(0, NULL); + printf("Build definitions:\n"); while (1) { @@ -76,15 +208,7 @@ static int cmd_keylen(int dd, int argc, char *argv[]) uint16_t handle, keylen; int err; - if (argc < 1) { - errno = EINVAL; - return -1; - } - - if (argc > 1) { - errno = E2BIG; - return -1; - } + OPT_HELP(1, NULL); handle = atoi(argv[0]); @@ -92,7 +216,7 @@ static int cmd_keylen(int dd, int argc, char *argv[]) buf[0] = handle & 0xff; buf[1] = handle >> 8; - err = csr_read_varid_complex(dd, 0x4711, + err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); if (err < 0) { errno = -err; @@ -112,7 +236,9 @@ static int cmd_clock(int dd, int argc, char *argv[]) uint32_t clock = 0; int err; - err = csr_read_varid_uint32(dd, 0x4711, CSR_VARID_BT_CLOCK, &clock); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint32(dd, seqnum++, CSR_VARID_BT_CLOCK, &clock); if (err < 0) { errno = -err; return -1; @@ -128,7 +254,9 @@ static int cmd_rand(int dd, int argc, char *argv[]) uint16_t rand = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_RAND, &rand); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_RAND, &rand); if (err < 0) { errno = -err; return -1; @@ -144,7 +272,9 @@ static int cmd_panicarg(int dd, int argc, char *argv[]) uint16_t error = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_PANIC_ARG, &error); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_PANIC_ARG, &error); if (err < 0) { errno = -err; return -1; @@ -161,7 +291,9 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) uint16_t error = 0; int err; - err = csr_read_varid_uint16(dd, 5, CSR_VARID_FAULT_ARG, &error); + OPT_HELP(0, NULL); + + err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_FAULT_ARG, &error); if (err < 0) { errno = -err; return -1; @@ -175,60 +307,555 @@ static int cmd_faultarg(int dd, int argc, char *argv[]) static int cmd_coldreset(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_COLD_RESET); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_COLD_RESET); } static int cmd_warmreset(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_WARM_RESET); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); } static int cmd_disabletx(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_DISABLE_TX); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_DISABLE_TX); } static int cmd_enabletx(int dd, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, 0, CSR_VARID_ENABLE_TX); + return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_ENABLE_TX); +} + +static int cmd_memtypes(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 }; + int i, err; + + OPT_HELP(0, NULL); + + for (i = 0; i < 4; i++) { + memset(array, 0, sizeof(array)); + array[2] = stores[i] & 0xff; + array[3] = stores[i] >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); + if (err < 0) + break; + + type = array[4] + (array[5] << 8); + + printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]), + stores[i], memorytostr(type), type); + } + + return err; +} + +static struct option pskey_options[] = { + { "stores", 1, 0, 's' }, + { "reset", 0, 0, 'r' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int *help) +{ + int opt; + + while ((opt=getopt_long(argc, argv, "+s:rh", pskey_options, NULL)) != EOF) { + switch (opt) { + case 's': + if (!stores) + break; + if (!strcasecmp(optarg, "default")) + *stores = 0x0000; + else if (!strcasecmp(optarg, "implementation")) + *stores = 0x0001; + else if (!strcasecmp(optarg, "factory")) + *stores = 0x0002; + else if (!strcasecmp(optarg, "rom")) + *stores = 0x0004; + else if (!strcasecmp(optarg, "ram")) + *stores = 0x0008; + else if (!strcasecmp(optarg, "psi")) + *stores = 0x0001; + else if (!strcasecmp(optarg, "psf")) + *stores = 0x0002; + else if (!strcasecmp(optarg, "psrom")) + *stores = 0x0004; + else if (!strcasecmp(optarg, "psram")) + *stores = 0x0008; + else if (!strncasecmp(optarg, "0x", 2)) + *stores = strtol(optarg, NULL, 16); + else + *stores = atoi(optarg); + break; + + case 'r': + if (reset) + *reset = 1; + break; + + case 'h': + if (help) + *help = 1; + break; + } + } + + return optind; +} + +#define OPT_PSKEY(range, stores, reset, help) \ + opt_pskey(argc, argv, (stores), (reset), (help)); \ + argc -= optind; argv += optind; optind = 0; \ + OPT_RANGE((range)) + +static int cmd_psget(int dd, int argc, char *argv[]) +{ + uint8_t array[64]; + uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT; + uint32_t val32; + int i, err, size, reset = 0, type = CSR_TYPE_NULL; + + memset(array, 0, sizeof(array)); + + OPT_PSKEY(1, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + type = storage[i].type; + size = storage[i].type; + break; + } + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } else { + pskey = strtol(argv[0] + 2, NULL, 16); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } + + switch (type) { + case CSR_TYPE_COMPLEX: + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + return err; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + return -EIO; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, stores, + array, length * 2); + if (err < 0) + return err; + + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < length; i++) + printf(" 0x%02x%02x", array[i * 2], array[(i * 2) + 1]); + printf("\n"); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: + err = csr_read_pskey_uint16(dd, seqnum++, pskey, stores, &value); + if (err < 0) + return err; + + printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); + break; + + case CSR_TYPE_UINT32: + err = csr_read_pskey_uint32(dd, seqnum++, pskey, stores, &val32); + if (err < 0) + return err; + + printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; + } + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_psset(int dd, int argc, char *argv[]) +{ + uint8_t array[64]; + uint16_t pskey, value, stores = CSR_STORES_PSRAM; + uint32_t val32; + int i, err, size, reset = 0, type = CSR_TYPE_NULL; + + memset(array, 0, sizeof(array)); + + OPT_PSKEY(2, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + type = storage[i].type; + size = storage[i].type; + break; + } + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } else { + pskey = strtol(argv[0] + 2, NULL, 16); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + } + + argc--; + argv++; + + switch (type) { + case CSR_TYPE_COMPLEX: + size = pskey_size(pskey); + + if (argc != size) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < size; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i] = strtol(argv[i] + 2, NULL, 16); + else + array[i] = atoi(argv[i]); + + err = csr_write_pskey_complex(dd, seqnum++, pskey, + stores, array, size); + break; + + case CSR_TYPE_UINT8: + case CSR_TYPE_UINT16: + if (argc != 1) { + errno = E2BIG; + return -1; + } + + if (!strncasecmp(argv[0], "0x", 2)) + value = strtol(argv[0] + 2, NULL, 16); + else + value = atoi(argv[0]); + + err = csr_write_pskey_uint16(dd, seqnum++, pskey, stores, value); + break; + + case CSR_TYPE_UINT32: + if (argc != 1) { + errno = E2BIG; + return -1; + } + + if (!strncasecmp(argv[0], "0x", 2)) + val32 = strtol(argv[0] + 2, NULL, 16); + else + val32 = atoi(argv[0]); + + err = csr_write_pskey_uint32(dd, seqnum++, pskey, stores, val32); + break; + + default: + errno = EFAULT; + err = -1; + break; + } + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_psclr(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t pskey, stores = CSR_STORES_PSRAM; + int i, err, reset = 0; + + OPT_PSKEY(1, &stores, &reset, NULL); + + if (strncasecmp(argv[0], "0x", 2)) { + for (i = 0; storage[i].pskey; i++) { + if (strcasecmp(storage[i].str, argv[0])) + continue; + + pskey = storage[i].pskey; + break; + } + pskey = atoi(argv[0]); + } else + pskey = strtol(argv[0] + 2, NULL, 16); + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_write_varid_complex(dd, seqnum++, + CSR_VARID_PS_CLR_STORES, array, sizeof(array)); + + if (!err && reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return err; +} + +static int cmd_pslist(int dd, int argc, char *argv[]) +{ + uint8_t array[8]; + uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; + int err, reset = 0; + + OPT_PSKEY(0, &stores, &reset, NULL); + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, sizeof(array)); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, sizeof(array)); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + + printf("0x%04x - %s (%d bytes)\n", pskey, + csr_pskeytostr(pskey), length * 2); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_psread(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; + char *str, val[7]; + int i, err, reset = 0; + + OPT_PSKEY(0, &stores, &reset, NULL); + + while (1) { + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_NEXT, array, 8); + if (err < 0) + break; + + pskey = array[4] + (array[5] << 8); + if (pskey == 0x0000) + break; + + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; + + err = csr_read_varid_complex(dd, seqnum++, + CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + continue; + + length = array[2] + (array[3] << 8); + if (length > sizeof(array) / 2) + continue; + + err = csr_read_pskey_complex(dd, seqnum++, pskey, + stores, array, length * 2); + if (err < 0) + continue; + + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", + str ? str : val, pskey); + for (i = 0; i < length; i++) + printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf("\n"); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_psload(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey, size, stores = CSR_STORES_PSRAM; + char *str, val[7]; + int err, reset = 0; + + OPT_PSKEY(1, &stores, &reset, NULL); + + psr_read(argv[0]); + + while (psr_get(&pskey, array, &size) == 0) { + str = csr_pskeytoval(pskey); + if (!strcasecmp(str, "UNKNOWN")) { + sprintf(val, "0x%04x", pskey); + str = NULL; + } + + printf("Loading %s%s ... ", str ? "PSKEY_" : "", + str ? str : val); + fflush(stdout); + + err = csr_write_pskey_complex(dd, seqnum++, pskey, + stores, array, size); + + printf("%s\n", err < 0 ? "failed" : "done"); + } + + if (reset) + csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + + return 0; +} + +static int cmd_pscheck(int dd, int argc, char *argv[]) +{ + uint8_t array[256]; + uint16_t pskey, size; + int i; + + OPT_HELP(1, NULL); + + psr_read(argv[0]); + + while (psr_get(&pskey, array, &size) == 0) { + printf("0x%04x =", pskey); + for (i = 0; i < size; i++) + printf(" 0x%02x", array[i]); + printf("\n"); + } + + return 0; } static struct { char *str; - int (*func)(int dd, int argc, char **argv); + int (*func)(int dd, int argc, char *argv[]); char *arg; char *doc; } commands[] = { - { "builddef", cmd_builddef, "", "Get build definitions" }, - { "keylen", cmd_keylen, "", "Get current crypt key length" }, - { "clock", cmd_clock, "", "Get local Bluetooth clock" }, - { "rand", cmd_rand, "", "Get random number" }, - { "panicarg", cmd_panicarg, "", "Get panic code argument" }, - { "faultarg", cmd_faultarg, "", "Get fault code argument" }, - { "coldreset", cmd_coldreset, "", "Perform cold reset" }, - { "warmreset", cmd_warmreset, "", "Perform warm reset" }, - { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, - { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, - { NULL }, + { "builddef", cmd_builddef, "", "Get build definitions" }, + { "keylen", cmd_keylen, "", "Get current crypt key length" }, + { "clock", cmd_clock, "", "Get local Bluetooth clock" }, + { "rand", cmd_rand, "", "Get random number" }, + { "panicarg", cmd_panicarg, "", "Get panic code argument" }, + { "faultarg", cmd_faultarg, "", "Get fault code argument" }, + { "coldreset", cmd_coldreset, "", "Perform cold reset" }, + { "warmreset", cmd_warmreset, "", "Perform warm reset" }, + { "disabletx", cmd_disabletx, "", "Disable TX on the device" }, + { "enabletx", cmd_enabletx, "", "Enable TX on the device" }, + { "memtypes", cmd_memtypes, NULL, "Get memory types" }, + { "psget", cmd_psget, "", "Get value for PS key" }, + { "psset", cmd_psset, " ", "Set value for PS key" }, + { "psclr", cmd_psclr, "", "Clear value for PS key" }, + { "pslist", cmd_pslist, NULL, "List all PS keys" }, + { "psread", cmd_psread, NULL, "Read all PS keys" }, + { "psload", cmd_psload, "", "Load all PS keys from PSR file" }, + { "pscheck", cmd_pscheck, "", "Check PSR file" }, + { NULL } }; static void usage(void) { - int i; + int i, pos = 0; printf("bccmd - Utility for the CSR BCCMD interface\n\n"); printf("Usage:\n" - "\tbccmd [-i ] \n\n"); + "\tbccmd [options] \n\n"); + + printf("Options:\n" + "\t-t Select the transport\n" + "\t-d Select the device\n" + "\t-h, --help Display help\n" + "\n"); printf("Commands:\n"); - for (i = 0; commands[i].str; i++) - printf("\t%-10s%-8s\t%s\n", commands[i].str, - commands[i].arg, commands[i].doc); + for (i = 0; commands[i].str; i++) + printf("\t%-10s %-14s\t%s\n", commands[i].str, + commands[i].arg ? commands[i].arg : " ", + commands[i].doc); + printf("\n"); + + printf("Keys:\n\t"); + for (i = 0; storage[i].pskey; i++) { + printf("%s ", storage[i].str); + pos += strlen(storage[i].str) + 1; + if (pos > 60) { + printf("\n\t"); + pos = 0; + } + } + printf("\n"); } static struct option main_options[] = { + { "transport", 1, 0, 't' }, + { "device", 1, 0, 'd' }, { "help", 0, 0, 'h' }, - { "device", 1, 0, 'i' }, { 0, 0, 0, 0 } }; @@ -236,16 +863,33 @@ int main(int argc, char *argv[]) { struct hci_dev_info di; struct hci_version ver; - int i, err, dd, opt, dev = 0; + char *device = NULL; + int i, err, opt, dd, dev, transport = CSR_TRANSPORT_HCI; - while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { + while ((opt=getopt_long(argc, argv, "+t:d:i:h", main_options, NULL)) != EOF) { switch (opt) { + case 't': + if (!strcasecmp(optarg, "hci")) + transport = CSR_TRANSPORT_HCI; + else if (!strcasecmp(optarg, "usb")) + transport = CSR_TRANSPORT_USB; + else if (!strcasecmp(optarg, "bcsp")) + transport = CSR_TRANSPORT_BCSP; + else if (!strcasecmp(optarg, "h4")) + transport = CSR_TRANSPORT_H4; + else if (!strcasecmp(optarg, "h5")) + transport = CSR_TRANSPORT_3WIRE; + else if (!strcasecmp(optarg, "3wire")) + transport = CSR_TRANSPORT_3WIRE; + else if (!strcasecmp(optarg, "twutl")) + transport = CSR_TRANSPORT_3WIRE; + else + transport = CSR_TRANSPORT_UNKNOWN; + break; + + case 'd': case 'i': - dev = hci_devid(optarg); - if (dev < 0) { - perror("Invalid device"); - exit(1); - } + device = strdup(optarg); break; case 'h': @@ -264,6 +908,21 @@ int main(int argc, char *argv[]) exit(1); } + if (transport != CSR_TRANSPORT_HCI) { + fprintf(stderr, "Unsupported transport\n"); + exit(1); + } + + if (device) { + dev = hci_devid(device); + if (dev < 0) { + fprintf(stderr, "Device not available\n"); + exit(1); + } + free(device); + } else + dev = 0; + dd = hci_open_dev(dev); if (dd < 0) { fprintf(stderr, "Can't open device hci%d: %s (%d)\n", @@ -295,7 +954,7 @@ int main(int argc, char *argv[]) if (strcasecmp(commands[i].str, argv[0])) continue; - err = commands[i].func(dd, argc - 1, argv + 1); + err = commands[i].func(dd, argc, argv); hci_close_dev(dd); diff --git a/tools/csrinit.8 b/tools/csrinit.8 deleted file mode 100644 index 35a033d9..00000000 --- a/tools/csrinit.8 +++ /dev/null @@ -1,35 +0,0 @@ -.\" -.\" 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., 675 Mass Ave, Cambridge, MA 02139, USA. -.\" -.\" -.TH CSRINIT 8 "SEPTEMBER 8, 2005" "" "" - -.SH NAME -csrinit \- Utility for the setting up CSR ROM chips -.SH SYNOPSIS -.BR "csrinit -[ -.I options -] -.SH DESCRIPTION -.B csrinit -is used to setup the ROM chips from CSR. -.SH OPTIONS -.TP -.BI -h -Gives a list of possible options. -.SH AUTHOR -Written by Marcel Holtmann . -.br diff --git a/tools/csrinit.c b/tools/csrinit.c deleted file mode 100644 index a56dbde9..00000000 --- a/tools/csrinit.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2005 Marcel Holtmann - * - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include - -#include "csr.h" - -#ifdef NEED_USB_GET_BUSSES -static inline struct usb_bus *usb_get_busses(void) -{ - return usb_busses; -} -#endif - -#ifndef USB_DIR_OUT -#define USB_DIR_OUT 0x00 -#endif - -#ifndef USB_DIR_IN -#define USB_DIR_IN 0x80 -#endif - -static void usage(void) -{ - printf("csrinit - Utility for the setting up CSR ROM chips\n\n"); - - printf("Usage:\n" - "\tcsrinit [options]\n" - "\n"); - - printf("Options:\n" - "\t-h, --help Display help\n" - "\n"); -} - -static struct option main_options[] = { - { "help", 0, 0, 'h' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char *argv[]) -{ - int opt; - - while ((opt = getopt_long(argc, argv, "+h", main_options, NULL)) != -1) { - switch (opt) { - case 'h': - usage(); - exit(0); - - default: - exit(0); - } - } - - argc -= optind; - argv += optind; - optind = 0; - - if (argc < 1) { - usage(); - exit(1); - } - - usb_init(); - - return 0; -} diff --git a/tools/pskey.c b/tools/pskey.c deleted file mode 100644 index c185cf58..00000000 --- a/tools/pskey.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2004-2005 Marcel Holtmann - * - * - * 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 St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "csr.h" - -#define CSR_TYPE_NULL 0 -#define CSR_TYPE_ARRAY 1 -#define CSR_TYPE_UINT8 2 -#define CSR_TYPE_UINT16 3 -#define CSR_TYPE_UINT32 4 - -enum { - NONE = 0, - MEMORY, - LIST, - READ, -}; - -static char *storestostr(uint16_t stores) -{ - switch (stores) { - case 0x0000: - return "Default"; - case 0x0001: - return "psi"; - case 0x0002: - return "psf"; - case 0x0004: - return "psrom"; - case 0x0008: - return "psram"; - default: - return "Unknown"; - } -} - -static char *memorytostr(uint16_t type) -{ - switch (type) { - case 0x0000: - return "Flash memory"; - case 0x0001: - return "EEPROM"; - case 0x0002: - return "RAM (transient)"; - case 0x0003: - return "ROM (or \"read-only\" flash memory)"; - default: - return "Unknown"; - } -} - -static int cmd_memory(int dd, uint16_t stores, int argc, char *argv[]) -{ - uint8_t array[8]; - uint16_t type; - int err; - - memset(array, 0, sizeof(array)); - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, 0x4711, - CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); - if (err < 0) - return err; - - type = array[4] + (array[5] << 8); - - printf("%s (0x%04x) = %s (%d)\n", storestostr(stores), stores, - memorytostr(type), type); - - return 0; -} - -static int cmd_list(int dd, uint16_t stores, int argc, char *argv[]) -{ - uint8_t array[8]; - uint16_t length, seqnum = 0x0000, pskey = 0x0000; - int err; - - while (1) { - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, sizeof(array)); - if (err < 0) - break; - - pskey = array[4] + (array[5] << 8); - if (pskey == 0x0000) - break; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, sizeof(array)); - if (err < 0) - continue; - - length = array[2] + (array[3] << 8); - - printf("0x%04x - %s (%d bytes)\n", pskey, - csr_pskeytostr(pskey), length * 2); - } - - return 0; -} - -static int cmd_read(int dd, uint16_t stores, int argc, char *argv[]) -{ - uint8_t array[256]; - uint16_t length, seqnum = 0x0000, pskey = 0x0000; - char *str, val[7]; - int i, err; - - while (1) { - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, 8); - if (err < 0) - break; - - pskey = array[4] + (array[5] << 8); - if (pskey == 0x0000) - break; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); - if (err < 0) - continue; - - length = array[2] + (array[3] << 8); - if (length > sizeof(array) / 2) - continue; - - err = csr_read_pskey_complex(dd, seqnum++, pskey, - stores, array, length * 2); - if (err < 0) - continue; - - str = csr_pskeytoval(pskey); - if (!strcasecmp(str, "UNKNOWN")) { - sprintf(val, "0x%04x", pskey); - str = NULL; - } - - printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", - str ? str : val, pskey); - for (i = 0; i < length; i++) - printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); - printf("\n"); - } - - return 0; -} - -static int pskey_size(uint16_t pskey) -{ - switch (pskey) { - case CSR_PSKEY_BDADDR: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: - return 18; - default: - return 64; - } -} - -static int write_pskey(int dd, uint16_t pskey, uint16_t stores, int type, int argc, char *argv[]) -{ - uint8_t array[64]; - uint16_t value; - uint32_t val32; - int i, err, size = sizeof(array); - - memset(array, 0, sizeof(array)); - - switch (type) { - case CSR_TYPE_ARRAY: - size = pskey_size(pskey); - - if (argc != size) { - errno = EINVAL; - return -1; - } - - for (i = 0; i < size; i++) - if (!strncasecmp(argv[0], "0x", 2)) - array[i] = strtol(argv[i] + 2, NULL, 16); - else - array[i] = atoi(argv[i]); - - err = csr_write_pskey_complex(dd, 0x4711, pskey, - stores, array, size); - break; - - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: - if (argc != 1) { - errno = E2BIG; - return -1; - } - - if (!strncasecmp(argv[0], "0x", 2)) - value = strtol(argv[0] + 2, NULL, 16); - else - value = atoi(argv[0]); - - err = csr_write_pskey_uint16(dd, 0x4711, pskey, stores, value); - break; - - case CSR_TYPE_UINT32: - if (argc != 1) { - errno = E2BIG; - return -1; - } - - if (!strncasecmp(argv[0], "0x", 2)) - val32 = strtol(argv[0] + 2, NULL, 16); - else - val32 = atoi(argv[0]); - - err = csr_write_pskey_uint32(dd, 0x4711, pskey, stores, val32); - break; - - default: - errno = EFAULT; - err = -1; - break; - } - - return err; -} - -static int read_pskey(int dd, uint16_t pskey, uint16_t stores, int type) -{ - uint8_t array[64]; - uint16_t value = 0; - uint32_t val32 = 0; - int i, err, size = sizeof(array); - - memset(array, 0, sizeof(array)); - - switch (type) { - case CSR_TYPE_ARRAY: - size = pskey_size(pskey); - - err = csr_read_pskey_complex(dd, 0x4711, pskey, stores, array, size); - if (err < 0) - return err; - - printf("%s:", csr_pskeytostr(pskey)); - for (i = 0; i < size; i++) - printf(" 0x%02x", array[i]); - printf("\n"); - break; - - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: - err = csr_read_pskey_uint16(dd, 0x4711, pskey, stores, &value); - if (err < 0) - return err; - - printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); - break; - - case CSR_TYPE_UINT32: - err = csr_read_pskey_uint32(dd, 0x4711, pskey, stores, &val32); - if (err < 0) - return err; - - printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); - break; - - default: - errno = EFAULT; - err = -1; - break; - } - - return err; -} - -static int delete_pskey(int dd, uint16_t pskey, uint16_t stores) -{ - uint8_t array[8]; - int err; - - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - - err = csr_write_varid_complex(dd, 0x4711, - CSR_VARID_PS_CLR_STORES, array, sizeof(array)); - - return err; -} - -static struct { - uint16_t pskey; - int type; - char *str; -} storage[] = { - { CSR_PSKEY_BDADDR, CSR_TYPE_ARRAY, "bdaddr" }, - { CSR_PSKEY_COUNTRYCODE, CSR_TYPE_UINT16, "country" }, - { CSR_PSKEY_CLASSOFDEVICE, CSR_TYPE_UINT32, "devclass" }, - { CSR_PSKEY_ENC_KEY_LMIN, CSR_TYPE_UINT16, "keymin" }, - { CSR_PSKEY_ENC_KEY_LMAX, CSR_TYPE_UINT16, "keymax" }, - { CSR_PSKEY_LOCAL_SUPPORTED_FEATURES, CSR_TYPE_ARRAY, "features" }, - { CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS, CSR_TYPE_ARRAY, "commands" }, - { CSR_PSKEY_HCI_LMP_LOCAL_VERSION, CSR_TYPE_UINT16, "version" }, - { CSR_PSKEY_LMP_REMOTE_VERSION, CSR_TYPE_UINT8, "remver" }, - { CSR_PSKEY_HOSTIO_USE_HCI_EXTN, CSR_TYPE_UINT16, "hciextn" }, - { CSR_PSKEY_HOSTIO_MAP_SCO_PCM, CSR_TYPE_UINT16, "mapsco" }, - { CSR_PSKEY_UART_BAUDRATE, CSR_TYPE_UINT16, "baudrate" }, - { CSR_PSKEY_HOST_INTERFACE, CSR_TYPE_UINT16, "hostintf" }, - { CSR_PSKEY_ANA_FREQ, CSR_TYPE_UINT16, "anafreq" }, - { CSR_PSKEY_ANA_FTRIM, CSR_TYPE_UINT16, "anaftrim" }, - { CSR_PSKEY_USB_VENDOR_ID, CSR_TYPE_UINT16, "usbvid" }, - { CSR_PSKEY_USB_PRODUCT_ID, CSR_TYPE_UINT16, "usbpid" }, - { CSR_PSKEY_USB_DFU_PRODUCT_ID, CSR_TYPE_UINT16, "dfupid" }, - { CSR_PSKEY_INITIAL_BOOTMODE, CSR_TYPE_UINT16, "bootmode" }, - { 0x0000, CSR_TYPE_NULL, NULL }, -}; - -static void usage(void) -{ - int i, pos = 0; - - printf("pskey - Utility for changing CSR persistent storage\n\n"); - printf("Usage:\n" - "\tpskey [-i ] [-r] [-s stores] [value]\n" - "\tpskey [-i ] [-r] [-s stores] --clear \n" - "\tpskey [-i ] [-s stores] --memory\n" - "\tpskey [-i ] [-s stores] --list\n" - "\tpskey [-i ] [-s stores] --read\n\n"); - - printf("Keys:\n\t"); - for (i = 0; storage[i].pskey; i++) { - printf("%s ", storage[i].str); - pos += strlen(storage[i].str) + 1; - if (pos > 60) { - printf("\n\t"); - pos = 0; - } - } - printf("\n"); -} - -static struct option main_options[] = { - { "device", 1, 0, 'i' }, - { "reset", 0, 0, 'r' }, - { "stores", 1, 0, 's' }, - { "clear", 0, 0, 'c' }, - { "memory", 0, 0, 'M' }, - { "list", 0, 0, 'L' }, - { "read", 0, 0, 'R' }, - { "help", 0, 0, 'h' }, - { 0, 0, 0, 0 } -}; - -int main(int argc, char *argv[]) -{ - struct hci_dev_info di; - struct hci_version ver; - uint16_t stores = 0x0001 | 0x0002 | 0x0008; - int i, err, dd, opt, dev = 0, reset = 0, clear = 0, mode = NONE; - - while ((opt=getopt_long(argc, argv, "+i:rs:cMLRh", main_options, NULL)) != -1) { - switch (opt) { - case 'i': - dev = hci_devid(optarg); - if (dev < 0) { - perror("Invalid device"); - exit(1); - } - break; - - case 'r': - reset = 1; - break; - - case 's': - if (!strcasecmp(optarg, "default")) - stores = 0x0000; - else if (!strcasecmp(optarg, "implementation")) - stores = 0x0001; - else if (!strcasecmp(optarg, "factory")) - stores = 0x0002; - else if (!strcasecmp(optarg, "rom")) - stores = 0x0004; - else if (!strcasecmp(optarg, "ram")) - stores = 0x0008; - else if (!strcasecmp(optarg, "psi")) - stores = 0x0001; - else if (!strcasecmp(optarg, "psf")) - stores = 0x0002; - else if (!strcasecmp(optarg, "psrom")) - stores = 0x0004; - else if (!strcasecmp(optarg, "psram")) - stores = 0x0008; - else if (!strncasecmp(optarg, "0x", 2)) - stores = strtol(optarg, NULL, 16); - else - stores = atoi(optarg); - break; - - case 'c': - clear = 1; - break; - - case 'M': - mode = MEMORY; - break; - - case 'L': - mode = LIST; - break; - - case 'R': - mode = READ; - break; - - case 'h': - default: - usage(); - exit(0); - } - } - - argc -= optind; - argv += optind; - optind = 0; - - if (mode == NONE && argc < 1) { - usage(); - exit(1); - } - - dd = hci_open_dev(dev); - if (dd < 0) { - fprintf(stderr, "Can't open device hci%d: %s (%d)\n", - dev, strerror(errno), errno); - exit(1); - } - - if (hci_devinfo(dev, &di) < 0) { - fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (hci_read_local_version(dd, &ver, 1000) < 0) { - fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (ver.manufacturer != 10) { - fprintf(stderr, "Unsupported manufacturer\n"); - hci_close_dev(dd); - exit(1); - } - - if (mode > 0) { - switch (mode) { - case MEMORY: - err = cmd_memory(dd, stores, argc, argv); - break; - case LIST: - err = cmd_list(dd, stores, argc, argv); - break; - case READ: - err = cmd_read(dd, stores, argc, argv); - break; - default: - usage(); - err = -1; - break; - } - - hci_close_dev(dd); - exit(err < 0 ? 1 : 0); - } - - for (i = 0; storage[i].pskey; i++) { - if (strcasecmp(storage[i].str, argv[0])) - continue; - - if (argc > 1) { - err = write_pskey(dd, storage[i].pskey, stores, - storage[i].type, argc - 1, argv + 1); - - if (!err && reset) - csr_write_varid_valueless(dd, 0x0000, - CSR_VARID_WARM_RESET); - } else { - if (clear) - err = delete_pskey(dd, storage[i].pskey, stores); - else - err = read_pskey(dd, storage[i].pskey, - stores, storage[i].type); - } - - hci_close_dev(dd); - - if (err < 0) { - fprintf(stderr, "Can't %s persistent storage: %s (%d)\n", - argc > 1 ? "write" : "read", strerror(errno), errno); - exit(1); - } - - exit(0); - } - - fprintf(stderr, "Unsupported persistent storage\n"); - - hci_close_dev(dd); - - exit(1); -} -- cgit From 14d3b87c5357f5df85d167084ba8048a48f8df7e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Nov 2005 21:21:19 +0000 Subject: Some more big endian fixes --- tools/dfutool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/dfutool.c b/tools/dfutool.c index 0de67bb1..eb087011 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -211,9 +211,9 @@ static struct usb_dev_handle *open_device(char *device, struct dfu_suffix *suffi if (status.bState == DFU_STATE_DFU_IDLE) { if (suffix) { - suffix->idVendor = 0x0000; - suffix->idProduct = 0x0000; - suffix->bcdDevice = 0x0000; + suffix->idVendor = cpu_to_le16(0x0000); + suffix->idProduct = cpu_to_le16(0x0000); + suffix->bcdDevice = cpu_to_le16(0x0000); } return udev; } @@ -262,7 +262,7 @@ static struct usb_dev_handle *open_device(char *device, struct dfu_suffix *suffi if (dev->descriptor.bDeviceClass != USB_CLASS_APPLICATION) continue; - if (suffix && dev->descriptor.idVendor != suffix->idVendor) + if (suffix && dev->descriptor.idVendor != le16_to_cpu(suffix->idVendor)) continue; if (num > 9 || get_interface_number(dev) != 0) -- cgit From 520068bb1f73ea1a82b416461feecccded1ffc78 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Nov 2005 21:23:29 +0000 Subject: Cleanup the args handling --- hcid/dbus.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 347cf218..0799e0ca 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -1222,15 +1222,19 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, } if (handlers) { - error = BLUEZ_EDBUS_WRONG_SIGNATURE; for (; handlers->name != NULL; handlers++) { if (strcmp(handlers->name, method) == 0) { + ret = DBUS_HANDLER_RESULT_HANDLED; if (strcmp(handlers->signature, signature) == 0) { reply = handlers->handler_func(msg, data); error = 0; - ret = DBUS_HANDLER_RESULT_HANDLED; break; } + else + /* Set the error, but continue looping incase there is + * another method with the same name but a different + * signature */ + error = BLUEZ_EDBUS_WRONG_SIGNATURE; } } @@ -1392,22 +1396,20 @@ failed: static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) { - DBusMessageIter iter; DBusMessage *reply = NULL; inquiry_cp cp; evt_cmd_status rp; struct hci_request rq; struct hci_dbus_data *dbus_data = data; int dd = -1; - int8_t length; - int8_t num_rsp; + uint8_t length, num_rsp; - dbus_message_iter_init(msg, &iter); - dbus_message_iter_get_basic(&iter, &length); - dbus_message_iter_next(&iter); - dbus_message_iter_get_basic(&iter, &num_rsp); + dbus_message_get_args(msg, NULL, + DBUS_TYPE_BYTE, &length, + DBUS_TYPE_BYTE, &num_rsp, + DBUS_TYPE_INVALID); - if ((length <= 0) || (num_rsp <= 0)) { + if (length < 0x01 || length > 0x30) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); goto failed; } @@ -1486,7 +1488,6 @@ failed: static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) { - DBusMessageIter iter; DBusMessage *reply = NULL; char *str_bdaddr = NULL; struct hci_dbus_data *dbus_data = data; @@ -1494,10 +1495,10 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) uint8_t role; int dev_id = -1, dd = -1; - dbus_message_iter_init(msg, &iter); - dbus_message_iter_get_basic(&iter, &str_bdaddr); - dbus_message_iter_next(&iter); - dbus_message_iter_get_basic(&iter, &role); + dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &str_bdaddr, + DBUS_TYPE_BYTE, &role, + DBUS_TYPE_INVALID); str2ba(str_bdaddr, &bdaddr); @@ -1536,7 +1537,6 @@ failed: static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) { - DBusMessageIter iter; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; int dd = -1; @@ -1546,8 +1546,9 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) remote_name_req_cp cp; evt_cmd_status rp; - dbus_message_iter_init(msg, &iter); - dbus_message_iter_get_basic(&iter, &str_bdaddr); + dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &str_bdaddr, + DBUS_TYPE_INVALID); str2ba(str_bdaddr, &bdaddr); @@ -1662,7 +1663,6 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) struct hci_request rq; auth_requested_cp cp; evt_cmd_status rp; - DBusMessageIter iter; DBusMessage *reply = NULL; char *str_bdaddr = NULL; struct hci_dbus_data *dbus_data = data; @@ -1671,8 +1671,10 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) int dev_id = -1; int dd = -1; - dbus_message_iter_init(msg, &iter); - dbus_message_iter_get_basic(&iter, &str_bdaddr); + dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &str_bdaddr, + DBUS_TYPE_INVALID); + str2ba(str_bdaddr, &bdaddr); dev_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); -- cgit From e228331a074d749719048ea55b06a05afb9137dd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Nov 2005 21:24:05 +0000 Subject: Some parameters of the inquiry must be uint16 --- hcid/dbus-test | 2 +- hcid/dbus.c | 22 +++++++++++----------- hcid/dbus.h | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/hcid/dbus-test b/hcid/dbus-test index c931fa85..ddd3c5f3 100755 --- a/hcid/dbus-test +++ b/hcid/dbus-test @@ -222,7 +222,7 @@ class Tester: length, min, max = self.cmd_args self.listen = True try: - self.ctl.PeriodicInquiry(dbus.Byte(length), dbus.Byte(min), dbus.Byte(max)) + self.ctl.PeriodicInquiry(dbus.Byte(length), dbus.UInt16(min), dbus.UInt16(max)) except dbus.DBusException, e: print 'Sending %s failed: %s' % (self.cmd, e) sys.exit(1) diff --git a/hcid/dbus.c b/hcid/dbus.c index 0799e0ca..44414d2a 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -1303,12 +1303,11 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) { write_inquiry_mode_cp inq_mode; periodic_inquiry_cp inq_param; - DBusMessageIter iter; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; uint8_t length; - uint8_t max_period; - uint8_t min_period; + uint16_t max_period; + uint16_t min_period; int dd = -1; dd = hci_open_dev(dbus_data->dev_id); @@ -1318,12 +1317,13 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) goto failed; } - dbus_message_iter_init(msg, &iter); - dbus_message_iter_get_basic(&iter, &length); - dbus_message_iter_next(&iter); - dbus_message_iter_get_basic(&iter, &min_period); - dbus_message_iter_next(&iter); - dbus_message_iter_get_basic(&iter, &max_period); + dbus_message_get_args(msg, NULL, + DBUS_TYPE_BYTE, &length, + DBUS_TYPE_UINT16, &min_period, + DBUS_TYPE_UINT16, &max_period, + DBUS_TYPE_INVALID); + + syslog(LOG_DEBUG, "%02X %04X %04X", length, min_period, max_period); if (length >= min_period || min_period >= max_period) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); @@ -1333,8 +1333,8 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) inq_param.num_rsp = 100; inq_param.length = length; - inq_param.max_period = max_period; - inq_param.min_period = min_period; + inq_param.max_period = htobs(max_period); + inq_param.min_period = htobs(min_period); /* General/Unlimited Inquiry Access Code (GIAC) */ inq_param.lap[0] = 0x33; diff --git a/hcid/dbus.h b/hcid/dbus.h index bf344bf7..aee5b416 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -166,8 +166,8 @@ #define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ __END_SIG__ #define HCI_CANCEL_PERIODIC_INQ_SIGNATURE __END_SIG__ -- cgit From 4c230395b79375ac7448ac4a60603b4c46b66386 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 6 Nov 2005 21:37:17 +0000 Subject: More coding style cleanups --- hcid/dbus.c | 185 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 96 insertions(+), 89 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index 44414d2a..cbc18ef2 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -64,9 +64,9 @@ struct pin_request { typedef DBusMessage* (service_handler_func_t)(DBusMessage *, void *); struct service_data { - const char *name; - service_handler_func_t *handler_func; - const char *signature; + const char *name; + service_handler_func_t *handler_func; + const char *signature; }; struct hci_dbus_data { @@ -88,7 +88,7 @@ struct profile_obj_path_data { uint16_t id; register_function_t *reg_func; unregister_function_t *unreg_func; - get_svc_table_func_t *get_svc_table; /* return the service table */ + get_svc_table_func_t *get_svc_table; /* return the service table */ }; /* @@ -186,7 +186,6 @@ static const bluez_error_t hci_error_array[] = { { 0, NULL }, }; - static const char *bluez_dbus_error_to_str(const uint32_t ecode) { const bluez_error_t *ptr; @@ -221,17 +220,17 @@ static const char *bluez_dbus_error_to_str(const uint32_t ecode) static DBusMessage *bluez_new_failure_msg(DBusMessage *msg, const uint32_t ecode) { DBusMessageIter iter; - DBusMessage *reply = NULL; - const char *error_msg = NULL; + DBusMessage *reply; + const char *error_msg; error_msg = bluez_dbus_error_to_str(ecode); + if (!error_msg) + return NULL; - if (error_msg) { - reply = dbus_message_new_error(msg, ERROR_INTERFACE, error_msg); + reply = dbus_message_new_error(msg, ERROR_INTERFACE, error_msg); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32 ,&ecode); - } + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32 ,&ecode); return reply; } @@ -254,13 +253,13 @@ static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data); static const DBusObjectPathVTable obj_dev_vtable = { - .message_function = &msg_func_device, - .unregister_function = NULL + .message_function = &msg_func_device, + .unregister_function = NULL }; static const DBusObjectPathVTable obj_mgr_vtable = { - .message_function = &msg_func_manager, - .unregister_function = NULL + .message_function = &msg_func_manager, + .unregister_function = NULL }; /* @@ -344,7 +343,7 @@ static const struct service_data manager_services[] = { /* * HCI D-Bus services */ -static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *msg, void *data); +static DBusHandlerResult hci_signal_filter(DBusConnection *conn, DBusMessage *msg, void *data); static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data); static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data); @@ -381,40 +380,42 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) message = dbus_pending_call_steal_reply(call); - if (message) { - msg_type = dbus_message_get_type(message); - dbus_message_iter_init(message, &iter); - - if (msg_type == DBUS_MESSAGE_TYPE_ERROR) { - dbus_message_iter_get_basic(&iter, &error_msg); + if (!message) + goto done; + + msg_type = dbus_message_get_type(message); + dbus_message_iter_init(message, &iter); + + if (msg_type == DBUS_MESSAGE_TYPE_ERROR) { + dbus_message_iter_get_basic(&iter, &error_msg); - /* handling WRONG_ARGS_ERROR, DBUS_ERROR_NO_REPLY, DBUS_ERROR_SERVICE_UNKNOWN */ - syslog(LOG_ERR, "%s: %s", dbus_message_get_error_name(message), error_msg); + /* handling WRONG_ARGS_ERROR, DBUS_ERROR_NO_REPLY, DBUS_ERROR_SERVICE_UNKNOWN */ + syslog(LOG_ERR, "%s: %s", dbus_message_get_error_name(message), error_msg); + hci_send_cmd(req->dev, OGF_LINK_CTL, + OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); + } else { + /* check signature */ + arg_type = dbus_message_iter_get_arg_type(&iter); + if (arg_type != DBUS_TYPE_STRING) { + syslog(LOG_ERR, "Wrong reply signature: expected PIN"); hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); } else { - /* check signature */ - arg_type = dbus_message_iter_get_arg_type(&iter); - if (arg_type != DBUS_TYPE_STRING) { - syslog(LOG_ERR, "Wrong reply signature: expected PIN"); - hci_send_cmd(req->dev, OGF_LINK_CTL, - OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); - } else { - dbus_message_iter_get_basic(&iter, &pin); - len = strlen(pin); - - memset(&pr, 0, sizeof(pr)); - bacpy(&pr.bdaddr, &req->bda); - memcpy(pr.pin_code, pin, len); - pr.pin_len = len; - hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, - PIN_CODE_REPLY_CP_SIZE, &pr); - } - } + dbus_message_iter_get_basic(&iter, &pin); + len = strlen(pin); - dbus_message_unref(message); + memset(&pr, 0, sizeof(pr)); + bacpy(&pr.bdaddr, &req->bda); + memcpy(pr.pin_code, pin, len); + pr.pin_len = len; + hci_send_cmd(req->dev, OGF_LINK_CTL, + OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); + } } + dbus_message_unref(message); + +done: dbus_pending_call_unref(call); } @@ -502,7 +503,7 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) &addr, sizeof(bdaddr_t), DBUS_TYPE_INVALID); if (dbus_connection_send_with_reply(connection, message, - &pending, TIMEOUT) == FALSE) { + &pending, TIMEOUT) == FALSE) { syslog(LOG_ERR, "D-BUS send failed"); goto failed; } @@ -862,19 +863,21 @@ static gboolean unregister_device_path(const char *path) { char **children = NULL; - if (dbus_connection_list_registered(connection, path, &children)) { - for (; *children; children++) { - char child_path[MAX_PATH_LENGTH]; + if (!dbus_connection_list_registered(connection, path, &children)) + goto done; - snprintf(child_path, sizeof(child_path), "%s/%s", path, *children); + for (; *children; children++) { + char child_path[MAX_PATH_LENGTH]; - unregister_dbus_path(child_path); - } + snprintf(child_path, sizeof(child_path), "%s/%s", path, *children); - if (*children) - dbus_free_string_array(children); + unregister_dbus_path(child_path); } + if (*children) + dbus_free_string_array(children); + +done: return unregister_dbus_path(path); } @@ -1221,22 +1224,25 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, } } - if (handlers) { - for (; handlers->name != NULL; handlers++) { - if (strcmp(handlers->name, method) == 0) { - ret = DBUS_HANDLER_RESULT_HANDLED; - if (strcmp(handlers->signature, signature) == 0) { - reply = handlers->handler_func(msg, data); - error = 0; - break; - } - else - /* Set the error, but continue looping incase there is - * another method with the same name but a different - * signature */ - error = BLUEZ_EDBUS_WRONG_SIGNATURE; + if (!handlers) + goto failed; - } + for (; handlers->name != NULL; handlers++) { + if (strcmp(handlers->name, method)) + continue; + + ret = DBUS_HANDLER_RESULT_HANDLED; + + if (!strcmp(handlers->signature, signature)) { + reply = handlers->handler_func(msg, data); + error = 0; + break; + } else { + /* Set the error, but continue looping incase there is + * another method with the same name but a different + * signature */ + error = BLUEZ_EDBUS_WRONG_SIGNATURE; + continue; } } @@ -1247,7 +1253,7 @@ failed: if (reply) { if (!dbus_connection_send (conn, reply, NULL)) syslog(LOG_ERR, "Can't send reply message!"); - dbus_message_unref (reply); + dbus_message_unref(reply); } return ret; @@ -1275,16 +1281,17 @@ static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg return ret; for (handlers = manager_services; handlers->name != NULL; handlers++) { - if (strcmp(handlers->name, method) == 0) { - if (strcmp(handlers->signature, signature) != 0) - error = BLUEZ_EDBUS_WRONG_SIGNATURE; - else { - reply = handlers->handler_func(msg, data); - error = 0; - } + if (strcmp(handlers->name, method)) + continue; - ret = DBUS_HANDLER_RESULT_HANDLED; + if (strcmp(handlers->signature, signature) != 0) + error = BLUEZ_EDBUS_WRONG_SIGNATURE; + else { + reply = handlers->handler_func(msg, data); + error = 0; } + + ret = DBUS_HANDLER_RESULT_HANDLED; } if (error) @@ -1293,7 +1300,7 @@ static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg if (reply) { if (!dbus_connection_send (conn, reply, NULL)) syslog(LOG_ERR, "Can't send reply message!"); - dbus_message_unref (reply); + dbus_message_unref(reply); } return ret; @@ -1405,9 +1412,9 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) uint8_t length, num_rsp; dbus_message_get_args(msg, NULL, - DBUS_TYPE_BYTE, &length, - DBUS_TYPE_BYTE, &num_rsp, - DBUS_TYPE_INVALID); + DBUS_TYPE_BYTE, &length, + DBUS_TYPE_BYTE, &num_rsp, + DBUS_TYPE_INVALID); if (length < 0x01 || length > 0x30) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); @@ -1496,9 +1503,9 @@ static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) int dev_id = -1, dd = -1; dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &str_bdaddr, - DBUS_TYPE_BYTE, &role, - DBUS_TYPE_INVALID); + DBUS_TYPE_STRING, &str_bdaddr, + DBUS_TYPE_BYTE, &role, + DBUS_TYPE_INVALID); str2ba(str_bdaddr, &bdaddr); @@ -1547,8 +1554,8 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) evt_cmd_status rp; dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &str_bdaddr, - DBUS_TYPE_INVALID); + DBUS_TYPE_STRING, &str_bdaddr, + DBUS_TYPE_INVALID); str2ba(str_bdaddr, &bdaddr); @@ -1672,8 +1679,8 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) int dd = -1; dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &str_bdaddr, - DBUS_TYPE_INVALID); + DBUS_TYPE_STRING, &str_bdaddr, + DBUS_TYPE_INVALID); str2ba(str_bdaddr, &bdaddr); @@ -1865,7 +1872,7 @@ static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data) dbus_message_iter_get_basic(&iter, &str_name); for (; handlers->name != NULL; handlers++) { - if (strcasecmp(handlers->name, str_name) == 0) { + if (!strcasecmp(handlers->name, str_name)) { reply = handlers->handler_func(msg, data); error = 0; break; -- cgit From 226949879e3ed5578d678c817a955bd38597eddb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Nov 2005 09:31:00 +0000 Subject: Fix the memory types command --- tools/bccmd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/bccmd.c b/tools/bccmd.c index e41f08f5..902555e5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -335,21 +335,21 @@ static int cmd_memtypes(int dd, int argc, char *argv[]) for (i = 0; i < 4; i++) { memset(array, 0, sizeof(array)); - array[2] = stores[i] & 0xff; - array[3] = stores[i] >> 8; + array[0] = stores[i] & 0xff; + array[1] = stores[i] >> 8; err = csr_read_varid_complex(dd, seqnum++, CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); if (err < 0) - break; + continue; - type = array[4] + (array[5] << 8); + type = array[2] + (array[3] << 8); printf("%s (0x%04x) = %s (%d)\n", storestostr(stores[i]), stores[i], memorytostr(type), type); } - return err; + return 0; } static struct option pskey_options[] = { -- cgit From ff1e0556d0a88335924aea13cfbce67de82d9c19 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Nov 2005 09:41:28 +0000 Subject: Fix parsing of the PS key identifier --- tools/bccmd.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tools/bccmd.c b/tools/bccmd.c index 902555e5..50de4f17 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -424,6 +424,10 @@ static int cmd_psget(int dd, int argc, char *argv[]) OPT_PSKEY(1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; @@ -433,9 +437,6 @@ static int cmd_psget(int dd, int argc, char *argv[]) size = storage[i].type; break; } - pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); } else { pskey = strtol(argv[0] + 2, NULL, 16); type = CSR_TYPE_COMPLEX; @@ -511,6 +512,10 @@ static int cmd_psset(int dd, int argc, char *argv[]) OPT_PSKEY(2, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { + pskey = atoi(argv[0]); + type = CSR_TYPE_COMPLEX; + size = sizeof(array); + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; @@ -520,9 +525,6 @@ static int cmd_psset(int dd, int argc, char *argv[]) size = storage[i].type; break; } - pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); } else { pskey = strtol(argv[0] + 2, NULL, 16); type = CSR_TYPE_COMPLEX; @@ -601,6 +603,8 @@ static int cmd_psclr(int dd, int argc, char *argv[]) OPT_PSKEY(1, &stores, &reset, NULL); if (strncasecmp(argv[0], "0x", 2)) { + pskey = atoi(argv[0]); + for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; @@ -608,7 +612,6 @@ static int cmd_psclr(int dd, int argc, char *argv[]) pskey = storage[i].pskey; break; } - pskey = atoi(argv[0]); } else pskey = strtol(argv[0] + 2, NULL, 16); -- cgit From 254b7892bcfdbbc4ba6c8118f3d0aafc424d1f58 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 7 Nov 2005 14:32:29 +0000 Subject: Only use psi and psf stores as default --- tools/bccmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/bccmd.c b/tools/bccmd.c index 50de4f17..357620f5 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -48,7 +48,7 @@ #define CSR_STORES_PSF (0x0002) #define CSR_STORES_PSROM (0x0004) #define CSR_STORES_PSRAM (0x0008) -#define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF | CSR_STORES_PSRAM) +#define CSR_STORES_DEFAULT (CSR_STORES_PSI | CSR_STORES_PSF) #define CSR_TYPE_NULL 0 #define CSR_TYPE_COMPLEX 1 -- cgit From 118f08c948b7e90066f5340c87bd3f356f696c51 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 8 Nov 2005 14:54:58 +0000 Subject: Support multiple signatures for inquiry --- hcid/dbus-test | 27 ++++++++++++-------- hcid/dbus.c | 79 ++++++++++++++++++++++++++++++++++------------------------ hcid/dbus.h | 13 +++++++--- 3 files changed, 73 insertions(+), 46 deletions(-) diff --git a/hcid/dbus-test b/hcid/dbus-test index ddd3c5f3..0d20ae7d 100755 --- a/hcid/dbus-test +++ b/hcid/dbus-test @@ -182,12 +182,12 @@ class Tester: # Device.Controller methods elif self.cmd == 'Inquiry': - if len(self.cmd_args) != 2: - length, maxrsp = (10, 100) - else: - length, maxrsp = self.cmd_args try: - self.ctl.Inquiry(dbus.Byte(length), dbus.Byte(maxrsp)) + if len(self.cmd_args) != 2: + self.ctl.Inquiry() + else: + length, lap = self.cmd_args + self.ctl.Inquiry(dbus.Byte(length), dbus.UInt32(long(lap, 0))) except dbus.DBusException, e: print 'Sending %s failed: %s' % (self.cmd, e) sys.exit(1) @@ -216,13 +216,18 @@ class Tester: self.exit_events.append('RemoteName') elif self.cmd == 'PeriodicInquiry': - if len(self.cmd_args) != 3: - length, min, max = (6, 20, 60) - else: - length, min, max = self.cmd_args - self.listen = True try: - self.ctl.PeriodicInquiry(dbus.Byte(length), dbus.UInt16(min), dbus.UInt16(max)) + if len(self.cmd_args) < 3: + length, min, max = (6, 20, 60) + self.ctl.PeriodicInquiry(dbus.Byte(length), dbus.UInt16(min), dbus.UInt16(max)) + elif len(self.cmd_args) == 3: + length, min, max = self.cmd_args + self.ctl.PeriodicInquiry(dbus.Byte(length), dbus.UInt16(min), dbus.UInt16(max)) + else: + length, min, max, lap = self.cmd_args + self.ctl.PeriodicInquiry(dbus.Byte(length), dbus.UInt16(min), dbus.UInt16(max), + dbus.UInt32(long(lap, 0))) + self.listen = True except dbus.DBusException, e: print 'Sending %s failed: %s' % (self.cmd, e) sys.exit(1) diff --git a/hcid/dbus.c b/hcid/dbus.c index cbc18ef2..c450a66f 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -356,9 +356,11 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data); static const struct service_data device_hci_services[] = { { HCI_PERIODIC_INQ, handle_periodic_inq_req, HCI_PERIODIC_INQ_SIGNATURE }, + { HCI_PERIODIC_INQ, handle_periodic_inq_req, HCI_PERIODIC_INQ_EXT_SIGNATURE }, { HCI_CANCEL_PERIODIC_INQ, handle_cancel_periodic_inq_req, HCI_CANCEL_PERIODIC_INQ_SIGNATURE }, { HCI_ROLE_SWITCH, handle_role_switch_req, HCI_ROLE_SWITCH_SIGNATURE }, { HCI_INQ, handle_inq_req, HCI_INQ_SIGNATURE }, + { HCI_INQ, handle_inq_req, HCI_INQ_EXT_SIGNATURE }, { HCI_CANCEL_INQ, handle_cancel_inq_req, HCI_CANCEL_INQ_SIGNATURE }, { HCI_REMOTE_NAME, handle_remote_name_req, HCI_REMOTE_NAME_SIGNATURE }, { HCI_CONNECTIONS, handle_display_conn_req, HCI_CONNECTIONS_SIGNATURE }, @@ -1312,9 +1314,10 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) periodic_inquiry_cp inq_param; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; - uint8_t length; + uint8_t length, num_rsp = 0; uint16_t max_period; uint16_t min_period; + uint32_t lap = 0x9e8b33; int dd = -1; dd = hci_open_dev(dbus_data->dev_id); @@ -1324,42 +1327,50 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) goto failed; } - dbus_message_get_args(msg, NULL, - DBUS_TYPE_BYTE, &length, - DBUS_TYPE_UINT16, &min_period, - DBUS_TYPE_UINT16, &max_period, - DBUS_TYPE_INVALID); - - syslog(LOG_DEBUG, "%02X %04X %04X", length, min_period, max_period); - - if (length >= min_period || min_period >= max_period) { + if (dbus_message_has_signature(msg, HCI_PERIODIC_INQ_EXT_SIGNATURE)) + dbus_message_get_args(msg, NULL, + DBUS_TYPE_BYTE, &length, + DBUS_TYPE_UINT16, &min_period, + DBUS_TYPE_UINT16, &max_period, + DBUS_TYPE_UINT32, &lap, + DBUS_TYPE_INVALID); + else + dbus_message_get_args(msg, NULL, + DBUS_TYPE_BYTE, &length, + DBUS_TYPE_UINT16, &min_period, + DBUS_TYPE_UINT16, &max_period, + DBUS_TYPE_INVALID); + + /* Check for valid parameters */ + if (length >= min_period || min_period >= max_period + || length < 0x01 || length > 0x30 + || lap < 0x9e8b00 || lap > 0x9e8b3f) { reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); goto failed; } - inq_param.num_rsp = 100; + inq_param.num_rsp = num_rsp; inq_param.length = length; inq_param.max_period = htobs(max_period); inq_param.min_period = htobs(min_period); - /* General/Unlimited Inquiry Access Code (GIAC) */ - inq_param.lap[0] = 0x33; - inq_param.lap[1] = 0x8b; - inq_param.lap[2] = 0x9e; + inq_param.lap[0] = lap & 0xff; + inq_param.lap[1] = (lap >> 8) & 0xff; + inq_param.lap[2] = (lap >> 16) & 0xff; - inq_mode.mode = 1; //INQUIRY_WITH_RSSI; + inq_mode.mode = 1; // INQUIRY_WITH_RSSI if (hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, WRITE_INQUIRY_MODE_CP_SIZE, &inq_mode) < 0) { - syslog(LOG_ERR, "Can't set inquiry mode:%s.", strerror(errno)); + syslog(LOG_ERR, "Can't set inquiry mode: %s", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, PERIODIC_INQUIRY_CP_SIZE, &inq_param) < 0) { - syslog(LOG_ERR, "Can't send HCI commands:%s.", strerror(errno)); + syslog(LOG_ERR, "Can't send HCI commands: %s", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1387,7 +1398,7 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) } if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY, 0 , NULL) < 0) { - syslog(LOG_ERR, "Send hci command failed."); + syslog(LOG_ERR, "Send HCI command failed"); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1409,16 +1420,20 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) struct hci_request rq; struct hci_dbus_data *dbus_data = data; int dd = -1; - uint8_t length, num_rsp; - - dbus_message_get_args(msg, NULL, - DBUS_TYPE_BYTE, &length, - DBUS_TYPE_BYTE, &num_rsp, - DBUS_TYPE_INVALID); - - if (length < 0x01 || length > 0x30) { - reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); - goto failed; + uint8_t length = 8, num_rsp = 0; + uint32_t lap = 0x9e8b33; + + if (dbus_message_has_signature(msg, HCI_INQ_EXT_SIGNATURE)) { + dbus_message_get_args(msg, NULL, + DBUS_TYPE_BYTE, &length, + DBUS_TYPE_UINT32, &lap, + DBUS_TYPE_INVALID); + + if (length < 0x01 || length > 0x30 + || lap < 0x9e8b00 || lap > 0x9e8b3f) { + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); + goto failed; + } } dd = hci_open_dev(dbus_data->dev_id); @@ -1429,9 +1444,9 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) } memset(&cp, 0, sizeof(cp)); - cp.lap[0] = 0x33; - cp.lap[1] = 0x8b; - cp.lap[2] = 0x9e; + cp.lap[0] = lap & 0xff; + cp.lap[1] = (lap >> 8) & 0xff; + cp.lap[2] = (lap >> 16) & 0xff; cp.length = length; cp.num_rsp = num_rsp; diff --git a/hcid/dbus.h b/hcid/dbus.h index aee5b416..557a6686 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -164,16 +164,23 @@ #define DEV_GET_PROPERTY_SIGNATURE DBUS_TYPE_STRING_AS_STRING \ __END_SIG__ - #define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ DBUS_TYPE_UINT16_AS_STRING \ DBUS_TYPE_UINT16_AS_STRING \ __END_SIG__ +#define HCI_PERIODIC_INQ_EXT_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ + DBUS_TYPE_UINT16_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ + __END_SIG__ + #define HCI_CANCEL_PERIODIC_INQ_SIGNATURE __END_SIG__ -#define HCI_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ - DBUS_TYPE_BYTE_AS_STRING \ +#define HCI_INQ_SIGNATURE __END_SIG__ + +#define HCI_INQ_EXT_SIGNATURE DBUS_TYPE_BYTE_AS_STRING \ + DBUS_TYPE_UINT32_AS_STRING \ __END_SIG__ #define HCI_CANCEL_INQ_SIGNATURE __END_SIG__ -- cgit From db176529529c142333f668f2c1334753f7f406bf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Nov 2005 00:04:15 +0000 Subject: Include checks for mmap() returning NULL --- common/textfile.c | 4 ++-- tools/csr.c | 2 +- tools/oui.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/textfile.c b/common/textfile.c index dd77980c..b2134562 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -149,7 +149,7 @@ int textfile_put(char *pathname, char *key, char *value) } map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, fd, 0); - if (map == MAP_FAILED) { + if (!map || map == MAP_FAILED) { err = errno; goto unlock; } @@ -243,7 +243,7 @@ char *textfile_get(char *pathname, char *key) size = st.st_size; map = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); - if (map == MAP_FAILED) { + if (!map || map == MAP_FAILED) { err = errno; goto unlock; } diff --git a/tools/csr.c b/tools/csr.c index 698122dc..3f671740 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2697,7 +2697,7 @@ int psr_read(const char *filename) } map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (map == MAP_FAILED) { + if (!map || map == MAP_FAILED) { err = -errno; goto close; } diff --git a/tools/oui.c b/tools/oui.c index 0a1d67bc..6ebf91a5 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -65,7 +65,7 @@ char *ouitocomp(const char *oui) memset(str, 0, 128); map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (map == MAP_FAILED) { + if (!map || map == MAP_FAILED) { free(str); close(fd); return NULL; -- cgit From fee89e0ae84a9fe54252872e6badec024573f70d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Nov 2005 14:44:14 +0000 Subject: Add build ids for Unified 21c firmwares --- tools/csr.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tools/csr.c b/tools/csr.c index 3f671740..c101422b 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -297,6 +297,29 @@ static struct { { 2387, "Unified 21a" }, { 2423, "Unified 21a" }, { 2424, "Unified 21a" }, + { 2623, "Unified 21c" }, + { 2624, "Unified 21c" }, + { 2625, "Unified 21c" }, + { 2626, "Unified 21c" }, + { 2627, "Unified 21c" }, + { 2628, "Unified 21c" }, + { 2629, "Unified 21c" }, + { 2630, "Unified 21c" }, + { 2631, "Unified 21c" }, + { 2632, "Unified 21c" }, + { 2633, "Unified 21c" }, + { 2634, "Unified 21c" }, + { 2635, "Unified 21c" }, + { 2636, "Unified 21c" }, + { 2649, "Unified 21c" }, + { 2650, "Unified 21c" }, + { 2651, "Unified 21c" }, + { 2652, "Unified 21c" }, + { 2653, "Unified 21c" }, + { 2654, "Unified 21c" }, + { 2655, "Unified 21c" }, + { 2656, "Unified 21c" }, + { 2658, "Unified 21c" }, { 2526, "Marcel 1 (2005-09-26)" }, { 2543, "Marcel 2 (2005-09-28)" }, { 2622, "Marcel 3 (2005-10-27)" }, -- cgit From d46119704d437932ce905917b69ce665c1ac0149 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Nov 2005 15:42:43 +0000 Subject: Remove setting of inquiry mode and use hci_send_req() --- hcid/dbus.c | 109 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 73 insertions(+), 36 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index c450a66f..ab1e2fc8 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -1083,7 +1083,7 @@ gboolean hcid_dbus_dev_down(uint16_t id) for (; ptr->id != INVALID_PATH_ID; ptr++) { if (ptr->unreg_func(connection, id) < 0) - syslog(LOG_ERR, "Unregistering profile id %04X failed", ptr->id); + syslog(LOG_ERR, "Unregistering profile id 0x%04x failed", ptr->id); } snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); @@ -1204,7 +1204,7 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, method = dbus_message_get_member(msg); signature = dbus_message_get_signature(msg); - syslog(LOG_INFO, "%s - path:%s, path_id:%04X dev_id:%04X", __PRETTY_FUNCTION__, + syslog(LOG_INFO, "%s - path:%s, path_id:0x%04x dev_id:0x%04x", __PRETTY_FUNCTION__, path, dbus_data->path_id, dbus_data->dev_id); if (dbus_data->path_id == DEVICE_ROOT_ID) { @@ -1310,8 +1310,9 @@ static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) { - write_inquiry_mode_cp inq_mode; periodic_inquiry_cp inq_param; + struct hci_request rq; + uint8_t status; DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; uint8_t length, num_rsp = 0; @@ -1359,19 +1360,24 @@ static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) inq_param.lap[1] = (lap >> 8) & 0xff; inq_param.lap[2] = (lap >> 16) & 0xff; - inq_mode.mode = 1; // INQUIRY_WITH_RSSI + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_PERIODIC_INQUIRY; + rq.cparam = &inq_param; + rq.clen = PERIODIC_INQUIRY_CP_SIZE; + rq.rparam = &status; + rq.rlen = sizeof(status); - if (hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, - WRITE_INQUIRY_MODE_CP_SIZE, &inq_mode) < 0) { - syslog(LOG_ERR, "Can't set inquiry mode: %s", strerror(errno)); + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, "Sending periodic inquiry command failed: %s (%d)", + strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } - if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, - PERIODIC_INQUIRY_CP_SIZE, &inq_param) < 0) { - syslog(LOG_ERR, "Can't send HCI commands: %s", strerror(errno)); - reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + if (status) { + syslog(LOG_ERR, "Periodic inquiry failed with status 0x%02x", status); + reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status); goto failed; } @@ -1387,7 +1393,9 @@ failed: static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) { DBusMessage *reply = NULL; + struct hci_request rq; struct hci_dbus_data *dbus_data = data; + uint8_t status; int dd = -1; dd = hci_open_dev(dbus_data->dev_id); @@ -1397,12 +1405,25 @@ static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) goto failed; } - if (hci_send_cmd(dd, OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY, 0 , NULL) < 0) { - syslog(LOG_ERR, "Send HCI command failed"); + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_EXIT_PERIODIC_INQUIRY; + rq.rparam = &status; + rq.rlen = sizeof(status); + + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, "Sending exit periodic inquiry command failed: %s (%d)", + strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } + if (status) { + syslog(LOG_ERR, "Exit periodic inquiry failed with status 0x%02x", status); + reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status); + goto failed; + } + reply = dbus_message_new_method_return(msg); failed: @@ -1438,7 +1459,8 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { - syslog(LOG_ERR, "Unable to open device %d: %s", dbus_data->dev_id, strerror(errno)); + syslog(LOG_ERR, "Unable to open device %d: %s (%d)", + dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1460,7 +1482,8 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { - syslog(LOG_ERR, "Unable to start inquiry: %s", strerror(errno)); + syslog(LOG_ERR, "Unable to start inquiry: %s (%d)", + strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1479,26 +1502,36 @@ static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data) DBusMessage *reply = NULL; struct hci_request rq; struct hci_dbus_data *dbus_data = data; + uint8_t status; int dd = -1; dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { - syslog(LOG_ERR, "Unable to open device %d: %s", - dbus_data->dev_id, strerror(errno)); + syslog(LOG_ERR, "Unable to open device %d: %s (%d)", + dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_INQUIRY_CANCEL; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_INQUIRY_CANCEL; + rq.rparam = &status; + rq.rlen = sizeof(status); if (hci_send_req(dd, &rq, 100) < 0) { - syslog(LOG_ERR, "Unable to cancel inquiry: %s", strerror(errno)); + syslog(LOG_ERR, "Sending cancel inquiry failed: %s (%d)", + strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } + if (status) { + syslog(LOG_ERR, "Cancel inquiry failed with status 0x%02x", status); + reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status); + goto failed; + } + reply = dbus_message_new_method_return(msg); failed: @@ -1576,8 +1609,8 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) dd = hci_open_dev(dbus_data->dev_id); if (dd < 0) { - syslog(LOG_ERR, "Unable to open device %d: %s", - dbus_data->dev_id, strerror(errno)); + syslog(LOG_ERR, "Unable to open device %d: %s (%d)", + dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1596,7 +1629,8 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data) rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { - syslog(LOG_ERR, "Unable to send remote name request: %s", strerror(errno)); + syslog(LOG_ERR, "Unable to send remote name request: %s (%d)", + strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1744,7 +1778,8 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) rq.event = EVT_CMD_STATUS; if (hci_send_req(dd, &rq, 100) < 0) { - syslog(LOG_ERR, "Unable to send authentication request: %s", strerror(errno)); + syslog(LOG_ERR, "Unable to send authentication request: %s (%d)", + strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1777,14 +1812,15 @@ static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data) /* Create and bind HCI socket */ sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) { - syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", + strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } if (ioctl(sk, HCIDEVUP, dbus_data->dev_id) < 0 && errno != EALREADY) { syslog(LOG_ERR, "Can't init device hci%d: %s (%d)", - dbus_data->dev_id, strerror(errno), errno); + dbus_data->dev_id, strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1819,7 +1855,8 @@ static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data) /* Create and bind HCI socket */ sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) { - syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", strerror(errno), errno); + syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", + strerror(errno), errno); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; } @@ -1855,16 +1892,16 @@ static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data) dbus_message_iter_get_basic(&iter, &str_name); for (; handlers->name != NULL; handlers++) { - if (strcasecmp(handlers->name, str_name) == 0) { - if (strcmp(handlers->signature, signature) == 0) { - reply = handlers->handler_func(msg, data); - error = 0; - break; - } else { - error = BLUEZ_EDBUS_WRONG_SIGNATURE; - break; - } + if (strcasecmp(handlers->name, str_name)) + continue; + if (strcmp(handlers->signature, signature) == 0) { + reply = handlers->handler_func(msg, data); + error = 0; + break; + } else { + error = BLUEZ_EDBUS_WRONG_SIGNATURE; + break; } } -- cgit From 5a6a10b3e5bcaaa92cacfa09d2aea930eff41205 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Nov 2005 22:54:20 +0000 Subject: Handle the D-Bus system "Disconnect" signal --- hcid/dbus.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 7 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index ab1e2fc8..45b101f9 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -28,10 +28,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -47,7 +49,8 @@ static DBusConnection *connection; static int default_dev = -1; -#define TIMEOUT (30 * 1000) /* 30 seconds */ +#define TIMEOUT (30 * 1000) /* 30 seconds */ +#define DBUS_RECONNECT_TIMER (5 * 1000 * 1000) /* 5 sec */ #define MAX_PATH_LENGTH 64 #define MAX_CONN_NUMBER 10 @@ -61,7 +64,7 @@ struct pin_request { bdaddr_t bda; }; -typedef DBusMessage* (service_handler_func_t)(DBusMessage *, void *); +typedef DBusMessage* (service_handler_func_t) (DBusMessage *, void *); struct service_data { const char *name; @@ -898,6 +901,8 @@ gboolean hcid_dbus_init(void) return FALSE; } + dbus_connection_set_exit_on_disconnect(connection, FALSE); + dbus_bus_request_name(connection, BASE_INTERFACE, DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, &error); @@ -1155,6 +1160,89 @@ const struct service_data *get_hci_table(void) return device_hci_services; } +/***************************************************************** + * + * Section reserved to re-connection timer + * + *****************************************************************/ +static void reconnect_timer_handler(int signum) +{ + struct hci_dev_list_req *dl = NULL; + struct hci_dev_req *dr; + int sk; + int i; + + if (hcid_dbus_init() == FALSE) + return; + + /* stop the timer */ + sigaction(SIGALRM, NULL, NULL); + setitimer(ITIMER_REAL, NULL, NULL); + + /* register the device based paths */ + + /* Create and bind HCI socket */ + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) { + syslog(LOG_ERR, "Can't open HCI socket: %s (%d)", + strerror(errno), errno); + return; + } + + dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); + if (!dl) { + syslog(LOG_ERR, "Can't allocate memory"); + goto failed; + } + + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) { + syslog(LOG_INFO, "Can't get device list: %s (%d)", + strerror(errno), errno); + goto failed; + } + + /* reset the default device */ + default_dev = -1; + + for (i = 0; i < dl->dev_num; i++, dr++) { + + hcid_dbus_register_device(dr->dev_id); + + if (hci_test_bit(HCI_UP, &dr->dev_opt)) + hcid_dbus_dev_up(dr->dev_id); + } +failed: + if (sk >= 0) + close(sk); + + if (dl) + free(dl); + +} + +static void reconnect_timer_start(void) +{ + struct sigaction sa; + struct itimerval timer; + + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = &reconnect_timer_handler; + sigaction(SIGALRM, &sa, NULL); + + /* expire after X msec... */ + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = DBUS_RECONNECT_TIMER; + + /* ... and every x msec after that. */ + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = DBUS_RECONNECT_TIMER; + + setitimer(ITIMER_REAL, &timer, NULL); +} + /***************************************************************** * * Section reserved to HCI D-Bus services @@ -1175,14 +1263,18 @@ static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *m iface = dbus_message_get_interface(msg); method = dbus_message_get_member(msg); - if (strcmp(iface, DBUS_INTERFACE_LOCAL) == 0) { - if (strcmp(method, "Disconnected") == 0) - ret = DBUS_HANDLER_RESULT_HANDLED; + if ((strcmp(iface, DBUS_INTERFACE_LOCAL) == 0) && + (strcmp(method, "Disconnected") == 0)) { + syslog(LOG_ERR, "Got disconnected from the system message bus"); + dbus_connection_dispatch(conn); + dbus_connection_close(conn); + dbus_connection_unref(conn); + reconnect_timer_start(); + ret = DBUS_HANDLER_RESULT_HANDLED; } else if (strcmp(iface, DBUS_INTERFACE_DBUS) == 0) { if (strcmp(method, "NameOwnerChanged") == 0) ret = DBUS_HANDLER_RESULT_HANDLED; - - if (strcmp(method, "NameAcquired") == 0) + else if (strcmp(method, "NameAcquired") == 0) ret = DBUS_HANDLER_RESULT_HANDLED; } -- cgit From 9fb18057b298238f576aa57a95fed56e1743a3e9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 15:08:57 +0000 Subject: Use constants for modes --- hidd/main.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index ee32c53f..be50bf7a 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -47,6 +47,15 @@ #include "hidd.h" +enum { + NONE, + SHOW, + SERVER, + SEARCH, + CONNECT, + KILL +}; + static volatile sig_atomic_t __io_canceled = 0; static void sig_hup(int sig) @@ -582,7 +591,7 @@ int main(int argc, char *argv[]) char addr[18]; int log_option = LOG_NDELAY | LOG_PID; int opt, fd, ctl, csk, isk; - int mode = 0, daemon = 1, nosdp = 0, encrypt = 0, timeout = 30, lm = 0; + int mode = SHOW, daemon = 1, nosdp = 0, encrypt = 0, timeout = 30, lm = 0; bacpy(&bdaddr, BDADDR_ANY); @@ -616,30 +625,30 @@ int main(int argc, char *argv[]) nosdp = 1; break; case 'l': - mode = 0; + mode = SHOW; break; case 'd': - mode = 1; + mode = SERVER; break; case 's': - mode = 2; + mode = SEARCH; break; case 'c': str2ba(optarg, &dev); - mode = 3; + mode = CONNECT; break; case 'k': str2ba(optarg, &dev); - mode = 4; + mode = KILL; break; case 'K': bacpy(&dev, BDADDR_ALL); - mode = 4; + mode = KILL; break; case 'u': str2ba(optarg, &dev); flags = (1 << HIDP_VIRTUAL_CABLE_UNPLUG); - mode = 4; + mode = KILL; break; case 'h': usage(); @@ -658,7 +667,7 @@ int main(int argc, char *argv[]) } switch (mode) { - case 1: + case SERVER: csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, lm, 10); if (csk < 0) { perror("Can't listen on HID control channel"); @@ -675,17 +684,17 @@ int main(int argc, char *argv[]) } break; - case 2: + case SEARCH: do_search(ctl, &bdaddr, subclass, nosdp, encrypt, timeout); close(ctl); exit(0); - case 3: + case CONNECT: do_connect(ctl, &bdaddr, &dev, subclass, nosdp, encrypt, timeout); close(ctl); exit(0); - case 4: + case KILL: do_kill(ctl, &dev, flags); close(ctl); exit(0); -- cgit From 2ba0839002159cd293bb1a3d85645f04010cf33b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 20:23:47 +0000 Subject: Add USB transport to the bccmd utility --- acinclude.m4 | 2 +- tools/Makefile.am | 4 +- tools/bccmd.c | 465 +++++++++++++++++++++++++++++------------------------- tools/csr.c | 4 +- tools/csr.h | 12 +- tools/csr_hci.c | 160 +++++++++++++++++++ tools/csr_usb.c | 173 ++++++++++++++++++++ 7 files changed, 597 insertions(+), 223 deletions(-) create mode 100644 tools/csr_hci.c create mode 100644 tools/csr_usb.c diff --git a/acinclude.m4 b/acinclude.m4 index 65ae27b3..8334785c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -410,7 +410,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [ AM_CONDITIONAL(CUPS, test "${cups_enable}" = "yes") AM_CONDITIONAL(PCMCIA, test "${pcmcia_enable}" = "yes") AM_CONDITIONAL(INITSCRIPTS, test "${initscripts_enable}" = "yes") - AM_CONDITIONAL(BCCMD, test "${bccmd_enable}" = "yes") + AM_CONDITIONAL(BCCMD, test "${bccmd_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(AVCTRL, test "${avctrl_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes") AM_CONDITIONAL(DFUTOOL, test "${dfutool_enable}" = "yes" && test "${usb_found}" = "yes") diff --git a/tools/Makefile.am b/tools/Makefile.am index 238a2df1..9d7065b2 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -52,8 +52,8 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c -bccmd_LDADD = @BLUEZ_LIBS@ +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c +bccmd_LDADD = @USB_LIBS@ @BLUEZ_LIBS@ endif if AVCTRL diff --git a/tools/bccmd.c b/tools/bccmd.c index 357620f5..f39686eb 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -59,7 +59,56 @@ #define CSR_TYPE_ARRAY CSR_TYPE_COMPLEX #define CSR_TYPE_BDADDR CSR_TYPE_COMPLEX -static uint16_t seqnum = 0x0000; +static inline int transport_open(int transport, char *device) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + return csr_open_hci(device); + case CSR_TRANSPORT_USB: + return csr_open_usb(device); + default: + fprintf(stderr, "Unsupported transport\n"); + return -1; + } +} + +static inline void transport_close(int transport) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + csr_close_hci(); + break; + case CSR_TRANSPORT_USB: + csr_close_usb(); + break; + } +} + +static inline int transport_read(int transport, uint16_t varid, uint8_t *value, uint16_t length) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + return csr_read_hci(varid, value, length); + case CSR_TRANSPORT_USB: + return csr_read_usb(varid, value, length); + default: + errno = EOPNOTSUPP; + return -1; + } +} + +static inline int transport_write(int transport, uint16_t varid, uint8_t *value, uint16_t length) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + return csr_write_hci(varid, value, length); + case CSR_TRANSPORT_USB: + return csr_write_usb(varid, value, length); + default: + errno = EOPNOTSUPP; + return -1; + } +} static struct { uint16_t pskey; @@ -89,20 +138,6 @@ static struct { { 0x0000 }, }; -static int pskey_size(uint16_t pskey) -{ - switch (pskey) { - case CSR_PSKEY_BDADDR: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_FEATURES: - return 8; - case CSR_PSKEY_LOCAL_SUPPORTED_COMMANDS: - return 18; - default: - return 64; - } -} - static char *storestostr(uint16_t stores) { switch (stores) { @@ -167,9 +202,9 @@ static int opt_help(int argc, char *argv[], int *help) argc -= optind; argv += optind; optind = 0; \ OPT_RANGE((range)) -static int cmd_builddef(int dd, int argc, char *argv[]) +static int cmd_builddef(int transport, int argc, char *argv[]) { - uint8_t buf[8]; + uint8_t array[8]; uint16_t def = 0x0000, nextdef = 0x0000; int err = 0; @@ -178,18 +213,17 @@ static int cmd_builddef(int dd, int argc, char *argv[]) printf("Build definitions:\n"); while (1) { - memset(buf, 0, sizeof(buf)); - buf[0] = def & 0xff; - buf[1] = def >> 8; + memset(array, 0, sizeof(array)); + array[0] = def & 0xff; + array[1] = def >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_GET_NEXT_BUILDDEF, buf, sizeof(buf)); + err = transport_read(transport, CSR_VARID_GET_NEXT_BUILDDEF, array, 8); if (err < 0) { errno = -err; break; } - nextdef = buf[2] | (buf[3] << 8); + nextdef = array[2] | (array[3] << 8); if (nextdef == 0x0000) break; @@ -202,9 +236,9 @@ static int cmd_builddef(int dd, int argc, char *argv[]) return err; } -static int cmd_keylen(int dd, int argc, char *argv[]) +static int cmd_keylen(int transport, int argc, char *argv[]) { - uint8_t buf[8]; + uint8_t array[8]; uint16_t handle, keylen; int err; @@ -212,120 +246,139 @@ static int cmd_keylen(int dd, int argc, char *argv[]) handle = atoi(argv[0]); - memset(buf, 0, sizeof(buf)); - buf[0] = handle & 0xff; - buf[1] = handle >> 8; + memset(array, 0, sizeof(array)); + array[0] = handle & 0xff; + array[1] = handle >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_CRYPT_KEY_LENGTH, buf, sizeof(buf)); + err = transport_read(transport, CSR_VARID_CRYPT_KEY_LENGTH, array, 8); if (err < 0) { errno = -err; return -1; } - handle = buf[0] | (buf[1] << 8); - keylen = buf[2] | (buf[3] << 8); + handle = array[0] | (array[1] << 8); + keylen = array[2] | (array[3] << 8); printf("Crypt key length: %d bit\n", keylen * 8); return 0; } -static int cmd_clock(int dd, int argc, char *argv[]) +static int cmd_clock(int transport, int argc, char *argv[]) { - uint32_t clock = 0; + uint8_t array[8]; + uint32_t clock; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint32(dd, seqnum++, CSR_VARID_BT_CLOCK, &clock); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_BT_CLOCK, array, 8); if (err < 0) { errno = -err; return -1; } + clock = array[2] | (array[3] << 8) | (array[0] << 16) | (array[1] << 24); + printf("Bluetooth clock: 0x%04x (%d)\n", clock, clock); return 0; } -static int cmd_rand(int dd, int argc, char *argv[]) +static int cmd_rand(int transport, int argc, char *argv[]) { - uint16_t rand = 0; + uint8_t array[8]; + uint16_t rand; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_RAND, &rand); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_RAND, array, 8); if (err < 0) { errno = -err; return -1; } + rand = array[0] | (array[1] << 8); + printf("Random number: 0x%02x (%d)\n", rand, rand); return 0; } -static int cmd_panicarg(int dd, int argc, char *argv[]) +static int cmd_panicarg(int transport, int argc, char *argv[]) { - uint16_t error = 0; + uint8_t array[8]; + uint16_t error; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_PANIC_ARG, &error); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_PANIC_ARG, array, 8); if (err < 0) { errno = -err; return -1; } + error = array[0] | (array[1] << 8); + printf("Panic code: 0x%02x (%s)\n", error, error < 0x100 ? "valid" : "invalid"); return 0; } -static int cmd_faultarg(int dd, int argc, char *argv[]) +static int cmd_faultarg(int transport, int argc, char *argv[]) { - uint16_t error = 0; + uint8_t array[8]; + uint16_t error; int err; OPT_HELP(0, NULL); - err = csr_read_varid_uint16(dd, seqnum++, CSR_VARID_FAULT_ARG, &error); + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_FAULT_ARG, array, 8); if (err < 0) { errno = -err; return -1; } + error = array[0] | (array[1] << 8); + printf("Fault code: 0x%02x (%s)\n", error, error < 0x100 ? "valid" : "invalid"); return 0; } -static int cmd_coldreset(int dd, int argc, char *argv[]) +static int cmd_coldreset(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_COLD_RESET); + return transport_write(transport, CSR_VARID_COLD_RESET, NULL, 0); } -static int cmd_warmreset(int dd, int argc, char *argv[]) +static int cmd_warmreset(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + return transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); } -static int cmd_disabletx(int dd, int argc, char *argv[]) +static int cmd_disabletx(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_DISABLE_TX); + return transport_write(transport, CSR_VARID_DISABLE_TX, NULL, 0); } -static int cmd_enabletx(int dd, int argc, char *argv[]) +static int cmd_enabletx(int transport, int argc, char *argv[]) { - return csr_write_varid_valueless(dd, seqnum++, CSR_VARID_ENABLE_TX); + return transport_write(transport, CSR_VARID_ENABLE_TX, NULL, 0); } -static int cmd_memtypes(int dd, int argc, char *argv[]) +static int cmd_memtypes(int transport, int argc, char *argv[]) { uint8_t array[8]; uint16_t type, stores[4] = { 0x0001, 0x0002, 0x0004, 0x0008 }; @@ -338,8 +391,7 @@ static int cmd_memtypes(int dd, int argc, char *argv[]) array[0] = stores[i] & 0xff; array[1] = stores[i] >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_MEMORY_TYPE, array, sizeof(array)); + err = transport_read(transport, CSR_VARID_PS_MEMORY_TYPE, array, 8); if (err < 0) continue; @@ -412,12 +464,12 @@ static int opt_pskey(int argc, char *argv[], uint16_t *stores, int *reset, int * argc -= optind; argv += optind; optind = 0; \ OPT_RANGE((range)) -static int cmd_psget(int dd, int argc, char *argv[]) +static int cmd_psget(int transport, int argc, char *argv[]) { - uint8_t array[64]; + uint8_t array[128]; uint16_t pskey, length, value, stores = CSR_STORES_DEFAULT; uint32_t val32; - int i, err, size, reset = 0, type = CSR_TYPE_NULL; + int i, err, reset = 0; memset(array, 0, sizeof(array)); @@ -425,87 +477,74 @@ static int cmd_psget(int dd, int argc, char *argv[]) if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; pskey = storage[i].pskey; - type = storage[i].type; - size = storage[i].type; break; } - } else { + } else pskey = strtol(argv[0] + 2, NULL, 16); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); - } - - switch (type) { - case CSR_TYPE_COMPLEX: - memset(array, 0, sizeof(array)); - array[0] = pskey & 0xff; - array[1] = pskey >> 8; - array[2] = stores & 0xff; - array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); - if (err < 0) - return err; - - length = array[2] + (array[3] << 8); - if (length > sizeof(array) / 2) - return -EIO; + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; - err = csr_read_pskey_complex(dd, seqnum++, pskey, stores, - array, length * 2); - if (err < 0) - return err; + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + return err; - printf("%s:", csr_pskeytostr(pskey)); - for (i = 0; i < length; i++) - printf(" 0x%02x%02x", array[i * 2], array[(i * 2) + 1]); - printf("\n"); - break; - - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: - err = csr_read_pskey_uint16(dd, seqnum++, pskey, stores, &value); - if (err < 0) - return err; + length = array[2] + (array[3] << 8); + if (length + 6 > sizeof(array) / 2) + return -EIO; + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; + + err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2); + if (err < 0) + return err; + + switch (length) { + case 1: + value = array[6] | (array[7] << 8); printf("%s: 0x%04x (%d)\n", csr_pskeytostr(pskey), value, value); break; - case CSR_TYPE_UINT32: - err = csr_read_pskey_uint32(dd, seqnum++, pskey, stores, &val32); - if (err < 0) - return err; - + case 2: + val32 = array[8] | (array[9] << 8) | (array[6] << 16) | (array[7] << 24); printf("%s: 0x%08x (%d)\n", csr_pskeytostr(pskey), val32, val32); break; default: - errno = EFAULT; - err = -1; + printf("%s:", csr_pskeytostr(pskey)); + for (i = 0; i < length; i++) + printf(" 0x%02x%02x", array[(i * 2) + 6], array[(i * 2) + 7]); + printf("\n"); break; } - if (!err && reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + if (reset) + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return err; } -static int cmd_psset(int dd, int argc, char *argv[]) +static int cmd_psset(int transport, int argc, char *argv[]) { - uint8_t array[64]; - uint16_t pskey, value, stores = CSR_STORES_PSRAM; + uint8_t array[128]; + uint16_t pskey, length, value, stores = CSR_STORES_PSRAM; uint32_t val32; - int i, err, size, reset = 0, type = CSR_TYPE_NULL; + int i, err, reset = 0; memset(array, 0, sizeof(array)); @@ -513,48 +552,44 @@ static int cmd_psset(int dd, int argc, char *argv[]) if (strncasecmp(argv[0], "0x", 2)) { pskey = atoi(argv[0]); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); for (i = 0; storage[i].pskey; i++) { if (strcasecmp(storage[i].str, argv[0])) continue; pskey = storage[i].pskey; - type = storage[i].type; - size = storage[i].type; break; } - } else { + } else pskey = strtol(argv[0] + 2, NULL, 16); - type = CSR_TYPE_COMPLEX; - size = sizeof(array); - } - argc--; - argv++; + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = stores & 0xff; + array[3] = stores >> 8; - switch (type) { - case CSR_TYPE_COMPLEX: - size = pskey_size(pskey); + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); + if (err < 0) + return err; - if (argc != size) { - errno = EINVAL; - return -1; - } + length = array[2] + (array[3] << 8); + if (length + 6 > sizeof(array) / 2) + return -EIO; - for (i = 0; i < size; i++) - if (!strncasecmp(argv[0], "0x", 2)) - array[i] = strtol(argv[i] + 2, NULL, 16); - else - array[i] = atoi(argv[i]); + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; - err = csr_write_pskey_complex(dd, seqnum++, pskey, - stores, array, size); - break; + argc--; + argv++; - case CSR_TYPE_UINT8: - case CSR_TYPE_UINT16: + switch (length) { + case 1: if (argc != 1) { errno = E2BIG; return -1; @@ -565,10 +600,11 @@ static int cmd_psset(int dd, int argc, char *argv[]) else value = atoi(argv[0]); - err = csr_write_pskey_uint16(dd, seqnum++, pskey, stores, value); + array[6] = value & 0xff; + array[7] = value >> 8; break; - case CSR_TYPE_UINT32: + case 2: if (argc != 1) { errno = E2BIG; return -1; @@ -579,22 +615,37 @@ static int cmd_psset(int dd, int argc, char *argv[]) else val32 = atoi(argv[0]); - err = csr_write_pskey_uint32(dd, seqnum++, pskey, stores, val32); + array[6] = (val32 & 0xff0000) >> 16; + array[7] = val32 >> 24; + array[8] = val32 & 0xff; + array[9] = (val32 & 0xff00) >> 8; break; default: - errno = EFAULT; - err = -1; + if (argc != length * 2) { + errno = EINVAL; + return -1; + } + + for (i = 0; i < length * 2; i++) + if (!strncasecmp(argv[0], "0x", 2)) + array[i + 6] = strtol(argv[i] + 2, NULL, 16); + else + array[i + 6] = atoi(argv[i]); break; } - if (!err && reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + err = transport_write(transport, CSR_VARID_PS, array, (length + 3) * 2); + if (err < 0) + return err; + + if (reset) + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return err; } -static int cmd_psclr(int dd, int argc, char *argv[]) +static int cmd_psclr(int transport, int argc, char *argv[]) { uint8_t array[8]; uint16_t pskey, stores = CSR_STORES_PSRAM; @@ -621,16 +672,17 @@ static int cmd_psclr(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_write_varid_complex(dd, seqnum++, - CSR_VARID_PS_CLR_STORES, array, sizeof(array)); + err = transport_write(transport, CSR_VARID_PS_CLR_STORES, array, 8); + if (err < 0) + return err; - if (!err && reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + if (reset) + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return err; } -static int cmd_pslist(int dd, int argc, char *argv[]) +static int cmd_pslist(int transport, int argc, char *argv[]) { uint8_t array[8]; uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; @@ -645,8 +697,7 @@ static int cmd_pslist(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, sizeof(array)); + err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8); if (err < 0) break; @@ -660,8 +711,7 @@ static int cmd_pslist(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, sizeof(array)); + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); if (err < 0) continue; @@ -672,12 +722,12 @@ static int cmd_pslist(int dd, int argc, char *argv[]) } if (reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return 0; } -static int cmd_psread(int dd, int argc, char *argv[]) +static int cmd_psread(int transport, int argc, char *argv[]) { uint8_t array[256]; uint16_t pskey = 0x0000, length, stores = CSR_STORES_DEFAULT; @@ -693,8 +743,7 @@ static int cmd_psread(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_NEXT, array, 8); + err = transport_read(transport, CSR_VARID_PS_NEXT, array, 8); if (err < 0) break; @@ -708,17 +757,23 @@ static int cmd_psread(int dd, int argc, char *argv[]) array[2] = stores & 0xff; array[3] = stores >> 8; - err = csr_read_varid_complex(dd, seqnum++, - CSR_VARID_PS_SIZE, array, 8); + err = transport_read(transport, CSR_VARID_PS_SIZE, array, 8); if (err < 0) continue; length = array[2] + (array[3] << 8); - if (length > sizeof(array) / 2) + if (length + 6 > sizeof(array) / 2) continue; - err = csr_read_pskey_complex(dd, seqnum++, pskey, - stores, array, length * 2); + memset(array, 0, sizeof(array)); + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; + + err = transport_read(transport, CSR_VARID_PS, array, (length + 3) * 2); if (err < 0) continue; @@ -731,20 +786,20 @@ static int cmd_psread(int dd, int argc, char *argv[]) printf("// %s%s\n&%04x =", str ? "PSKEY_" : "", str ? str : val, pskey); for (i = 0; i < length; i++) - printf(" %02x%02x", array[i * 2 + 1], array[i * 2]); + printf(" %02x%02x", array[(i * 2) + 7], array[(i * 2) + 6]); printf("\n"); } if (reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return 0; } -static int cmd_psload(int dd, int argc, char *argv[]) +static int cmd_psload(int transport, int argc, char *argv[]) { uint8_t array[256]; - uint16_t pskey, size, stores = CSR_STORES_PSRAM; + uint16_t pskey, length, size, stores = CSR_STORES_PSRAM; char *str, val[7]; int err, reset = 0; @@ -752,7 +807,10 @@ static int cmd_psload(int dd, int argc, char *argv[]) psr_read(argv[0]); - while (psr_get(&pskey, array, &size) == 0) { + memset(array, 0, sizeof(array)); + size = sizeof(array) - 6; + + while (psr_get(&pskey, array + 6, &size) == 0) { str = csr_pskeytoval(pskey); if (!strcasecmp(str, "UNKNOWN")) { sprintf(val, "0x%04x", pskey); @@ -763,19 +821,30 @@ static int cmd_psload(int dd, int argc, char *argv[]) str ? str : val); fflush(stdout); - err = csr_write_pskey_complex(dd, seqnum++, pskey, - stores, array, size); + length = size / 2; + + array[0] = pskey & 0xff; + array[1] = pskey >> 8; + array[2] = length & 0xff; + array[3] = length >> 8; + array[4] = stores & 0xff; + array[5] = stores >> 8; + + err = transport_write(transport, CSR_VARID_PS, array, size + 6); printf("%s\n", err < 0 ? "failed" : "done"); + + memset(array, 0, sizeof(array)); + size = sizeof(array) - 6; } if (reset) - csr_write_varid_valueless(dd, seqnum++, CSR_VARID_WARM_RESET); + transport_write(transport, CSR_VARID_WARM_RESET, NULL, 0); return 0; } -static int cmd_pscheck(int dd, int argc, char *argv[]) +static int cmd_pscheck(int transport, int argc, char *argv[]) { uint8_t array[256]; uint16_t pskey, size; @@ -797,7 +866,7 @@ static int cmd_pscheck(int dd, int argc, char *argv[]) static struct { char *str; - int (*func)(int dd, int argc, char *argv[]); + int (*func)(int transport, int argc, char *argv[]); char *arg; char *doc; } commands[] = { @@ -864,10 +933,8 @@ static struct option main_options[] = { int main(int argc, char *argv[]) { - struct hci_dev_info di; - struct hci_version ver; char *device = NULL; - int i, err, opt, dd, dev, transport = CSR_TRANSPORT_HCI; + int i, err, opt, transport = CSR_TRANSPORT_HCI; while ((opt=getopt_long(argc, argv, "+t:d:i:h", main_options, NULL)) != EOF) { switch (opt) { @@ -911,55 +978,19 @@ int main(int argc, char *argv[]) exit(1); } - if (transport != CSR_TRANSPORT_HCI) { - fprintf(stderr, "Unsupported transport\n"); + if (transport_open(transport, device) < 0) exit(1); - } - if (device) { - dev = hci_devid(device); - if (dev < 0) { - fprintf(stderr, "Device not available\n"); - exit(1); - } + if (device) free(device); - } else - dev = 0; - - dd = hci_open_dev(dev); - if (dd < 0) { - fprintf(stderr, "Can't open device hci%d: %s (%d)\n", - dev, strerror(errno), errno); - exit(1); - } - - if (hci_devinfo(dev, &di) < 0) { - fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (hci_read_local_version(dd, &ver, 1000) < 0) { - fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", - dev, strerror(errno), errno); - hci_close_dev(dd); - exit(1); - } - - if (ver.manufacturer != 10) { - fprintf(stderr, "Unsupported manufacturer\n"); - hci_close_dev(dd); - exit(1); - } for (i = 0; commands[i].str; i++) { if (strcasecmp(commands[i].str, argv[0])) continue; - err = commands[i].func(dd, argc, argv); + err = commands[i].func(transport, argc, argv); - hci_close_dev(dd); + transport_close(transport); if (err < 0) { fprintf(stderr, "Can't execute command: %s (%d)\n", @@ -972,7 +1003,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Unsupported command\n"); - hci_close_dev(dd); + transport_close(transport); exit(1); } diff --git a/tools/csr.c b/tools/csr.c index c101422b..10856749 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2354,7 +2354,7 @@ int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *va rq.ocf = 0x00; rq.event = EVT_VENDOR; rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; + rq.clen = sizeof(cmd) + length + 1; rq.rparam = rp; rq.rlen = sizeof(rp); @@ -2393,7 +2393,7 @@ int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *val rq.ocf = 0x00; rq.event = EVT_VENDOR; rq.cparam = cp; - rq.clen = sizeof(cmd) + 1; + rq.clen = sizeof(cmd) + length + 1; rq.rparam = rp; rq.rlen = sizeof(rp); diff --git a/tools/csr.h b/tools/csr.h index cd807c38..ec066b81 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -63,7 +63,7 @@ #define CSR_VARID_FAULT_ARG 0x6806 /* uint16 */ #define CSR_VARID_MAX_TX_POWER 0x6827 /* int8 */ #define CSR_VARID_DEFAULT_TX_POWER 0x682b /* int8 */ -#define CSR_VARID_PS 0x7002 /* complex */ +#define CSR_VARID_PS 0x7003 /* complex */ #define CSR_PSKEY_BDADDR 0x0001 /* bdaddr / uint16[] = { 0x00A5A5, 0x5b, 0x0002 } */ #define CSR_PSKEY_COUNTRYCODE 0x0002 /* uint16 */ @@ -502,6 +502,16 @@ char *csr_chipvertostr(uint16_t ver, uint16_t rev); char *csr_pskeytostr(uint16_t pskey); char *csr_pskeytoval(uint16_t pskey); +int csr_open_hci(char *device); +int csr_read_hci(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_hci(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_hci(void); + +int csr_open_usb(char *device); +int csr_read_usb(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_usb(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_usb(void); + int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); diff --git a/tools/csr_hci.c b/tools/csr_hci.c new file mode 100644 index 00000000..ebeb8aa7 --- /dev/null +++ b/tools/csr_hci.c @@ -0,0 +1,160 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include "csr.h" + +static uint16_t seqnum = 0x0000; + +static int dd = -1; + +int csr_open_hci(char *device) +{ + struct hci_dev_info di; + struct hci_version ver; + int dev = 0; + + if (device) { + dev = hci_devid(device); + if (dev < 0) { + fprintf(stderr, "Device not available\n"); + return -1; + } + } + + dd = hci_open_dev(dev); + if (dd < 0) { + fprintf(stderr, "Can't open device hci%d: %s (%d)\n", + dev, strerror(errno), errno); + return -1; + } + + if (hci_devinfo(dev, &di) < 0) { + fprintf(stderr, "Can't get device info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + return -1; + } + + if (hci_read_local_version(dd, &ver, 1000) < 0) { + fprintf(stderr, "Can't read version info for hci%d: %s (%d)\n", + dev, strerror(errno), errno); + hci_close_dev(dd); + return -1; + } + + if (ver.manufacturer != 10) { + fprintf(stderr, "Unsupported manufacturer\n"); + hci_close_dev(dd); + return -1; + } + + return 0; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + unsigned char cp[254], rp[254]; + struct hci_request rq; + uint8_t cmd[10]; + uint16_t size; + + size = (length < 8) ? 9 : ((length + 1) / 2) + 5; + + cmd[0] = command & 0xff; + cmd[1] = command >> 8; + cmd[2] = size & 0xff; + cmd[3] = size >> 8; + cmd[4] = seqnum & 0xff; + cmd[5] = seqnum >> 8; + cmd[6] = varid & 0xff; + cmd[7] = varid >> 8; + cmd[8] = 0x00; + cmd[9] = 0x00; + + memset(cp, 0, sizeof(cp)); + cp[0] = 0xc2; + memcpy(cp + 1, cmd, sizeof(cmd)); + memcpy(cp + 11, value, length); + + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return hci_send_cmd(dd, OGF_VENDOR_CMD, 0x00, (size * 2) + 1, cp); + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = 0x00; + rq.event = EVT_VENDOR; + rq.cparam = cp; + rq.clen = (size * 2) + 1; + rq.rparam = rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(dd, &rq, 2000) < 0) + return -1; + + if (rp[0] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[9] + (rp[10] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 11, length); + + return 0; +} + +int csr_read_hci(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_hci(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_hci(void) +{ + hci_close_dev(dd); +} diff --git a/tools/csr_usb.c b/tools/csr_usb.c new file mode 100644 index 00000000..2c29251f --- /dev/null +++ b/tools/csr_usb.c @@ -0,0 +1,173 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#include "csr.h" + +#ifdef NEED_USB_GET_BUSSES +static inline struct usb_bus *usb_get_busses(void) +{ + return usb_busses; +} +#endif + +#ifndef USB_DIR_OUT +#define USB_DIR_OUT 0x00 +#endif + +static uint16_t seqnum = 0x0000; + +static struct usb_dev_handle *udev = NULL; + +int csr_open_usb(char *device) +{ + struct usb_bus *bus; + struct usb_device *dev; + + usb_init(); + + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_get_busses(); bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if (dev->descriptor.bDeviceClass == USB_CLASS_HUB) + continue; + + if (dev->descriptor.idVendor != 0x0a12 || + dev->descriptor.idProduct != 0x0001) + continue; + + goto found; + } + } + + fprintf(stderr, "Device not available\n"); + + return -1; + +found: + udev = usb_open(dev); + if (!udev) { + fprintf(stderr, "Can't open device: %s (%d)\n", + strerror(errno), errno); + return -1; + } + + if (usb_claim_interface(udev, 0) < 0) { + fprintf(stderr, "Can't claim interface: %s (%d)\n", + strerror(errno), errno); + usb_close(udev); + return -1; + } + + return 0; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + unsigned char cp[254], rp[254]; + uint8_t cmd[10]; + uint16_t size; + int len, offset = 0; + + size = (length < 8) ? 9 : ((length + 1) / 2) + 5; + + cmd[0] = command & 0xff; + cmd[1] = command >> 8; + cmd[2] = size & 0xff; + cmd[3] = size >> 8; + cmd[4] = seqnum & 0xff; + cmd[5] = seqnum >> 8; + cmd[6] = varid & 0xff; + cmd[7] = varid >> 8; + cmd[8] = 0x00; + cmd[9] = 0x00; + + memset(cp, 0, sizeof(cp)); + cp[0] = 0x00; + cp[1] = 0xfc; + cp[2] = (size * 2) + 1; + cp[3] = 0xc2; + memcpy(cp + 4, cmd, sizeof(cmd)); + memcpy(cp + 14, value, length); + + usb_interrupt_read(udev, 0x81, (void *) rp, sizeof(rp), 2); + + if (usb_control_msg(udev, USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_DEVICE, + 0, 0, 0, (void *) cp, (size * 2) + 4, 1000) < 0) + return -1; + + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return 0; + } + + do { + len = usb_interrupt_read(udev, 0x81, + (void *) (rp + offset), sizeof(rp), 10); + offset += len; + } while (len > 0); + + if (rp[0] != 0xff || rp[2] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[11] + (rp[12] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 13, length); + + return 0; +} + +int csr_read_usb(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_usb(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_usb(void) +{ + usb_release_interface(udev, 0); + usb_close(udev); +} -- cgit From 016c7033f4b73e35ebd66ada66093f3c5fe9fbff Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 21:05:14 +0000 Subject: Add skeletons for BCSP and H4 transports --- tools/Makefile.am | 2 +- tools/bccmd.c | 42 +++++++++++++++++++++++++++----------- tools/csr.h | 10 ++++++++++ tools/csr_bcsp.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/csr_h4.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 161 insertions(+), 13 deletions(-) create mode 100644 tools/csr_bcsp.c create mode 100644 tools/csr_h4.c diff --git a/tools/Makefile.am b/tools/Makefile.am index 9d7065b2..a038582a 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -52,7 +52,7 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c bccmd_LDADD = @USB_LIBS@ @BLUEZ_LIBS@ endif diff --git a/tools/bccmd.c b/tools/bccmd.c index f39686eb..3bdf702a 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -66,24 +66,16 @@ static inline int transport_open(int transport, char *device) return csr_open_hci(device); case CSR_TRANSPORT_USB: return csr_open_usb(device); + case CSR_TRANSPORT_BCSP: + return csr_open_bcsp(device); + case CSR_TRANSPORT_H4: + return csr_open_h4(device); default: fprintf(stderr, "Unsupported transport\n"); return -1; } } -static inline void transport_close(int transport) -{ - switch (transport) { - case CSR_TRANSPORT_HCI: - csr_close_hci(); - break; - case CSR_TRANSPORT_USB: - csr_close_usb(); - break; - } -} - static inline int transport_read(int transport, uint16_t varid, uint8_t *value, uint16_t length) { switch (transport) { @@ -91,6 +83,10 @@ static inline int transport_read(int transport, uint16_t varid, uint8_t *value, return csr_read_hci(varid, value, length); case CSR_TRANSPORT_USB: return csr_read_usb(varid, value, length); + case CSR_TRANSPORT_BCSP: + return csr_read_bcsp(varid, value, length); + case CSR_TRANSPORT_H4: + return csr_read_h4(varid, value, length); default: errno = EOPNOTSUPP; return -1; @@ -104,12 +100,34 @@ static inline int transport_write(int transport, uint16_t varid, uint8_t *value, return csr_write_hci(varid, value, length); case CSR_TRANSPORT_USB: return csr_write_usb(varid, value, length); + case CSR_TRANSPORT_BCSP: + return csr_write_bcsp(varid, value, length); + case CSR_TRANSPORT_H4: + return csr_write_h4(varid, value, length); default: errno = EOPNOTSUPP; return -1; } } +static inline void transport_close(int transport) +{ + switch (transport) { + case CSR_TRANSPORT_HCI: + csr_close_hci(); + break; + case CSR_TRANSPORT_USB: + csr_close_usb(); + break; + case CSR_TRANSPORT_BCSP: + csr_close_bcsp(); + break; + case CSR_TRANSPORT_H4: + csr_close_h4(); + break; + } +} + static struct { uint16_t pskey; int type; diff --git a/tools/csr.h b/tools/csr.h index ec066b81..01e4d803 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -512,6 +512,16 @@ int csr_read_usb(uint16_t varid, uint8_t *value, uint16_t length); int csr_write_usb(uint16_t varid, uint8_t *value, uint16_t length); void csr_close_usb(void); +int csr_open_bcsp(char *device); +int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_bcsp(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_bcsp(void); + +int csr_open_h4(char *device); +int csr_read_h4(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_h4(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_h4(void); + int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c new file mode 100644 index 00000000..8847fec5 --- /dev/null +++ b/tools/csr_bcsp.c @@ -0,0 +1,60 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +static uint16_t seqnum = 0x0000; + +int csr_open_bcsp(char *device) +{ + fprintf(stderr, "Transport not implemented\n"); + + return -1; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + errno = EIO; + + return -1; +} + +int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_bcsp(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_bcsp(void) +{ +} diff --git a/tools/csr_h4.c b/tools/csr_h4.c new file mode 100644 index 00000000..9140d30d --- /dev/null +++ b/tools/csr_h4.c @@ -0,0 +1,60 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +static uint16_t seqnum = 0x0000; + +int csr_open_h4(char *device) +{ + fprintf(stderr, "Transport not implemented\n"); + + return -1; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + errno = EIO; + + return -1; +} + +int csr_read_h4(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_h4(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_h4(void) +{ +} -- cgit From ae3ff343f09da4e2f1b63dd4dde8d283848becd0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 21:45:44 +0000 Subject: Add workaround for missing usb_interrupt_read() --- tools/csr_usb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/csr_usb.c b/tools/csr_usb.c index 2c29251f..3e2a4144 100644 --- a/tools/csr_usb.c +++ b/tools/csr_usb.c @@ -40,6 +40,13 @@ static inline struct usb_bus *usb_get_busses(void) } #endif +#ifdef NEED_USB_INTERRUPT_READ +static inline int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) +{ + return usb_bulk_read(dev, ep, bytes, size, timeout); +} +#endif + #ifndef USB_DIR_OUT #define USB_DIR_OUT 0x00 #endif -- cgit From 1933d78da59b5965adbc223b5080c31b47081259 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 23:01:38 +0000 Subject: Fix length calculation --- tools/csr_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/csr_usb.c b/tools/csr_usb.c index 3e2a4144..617e7ccf 100644 --- a/tools/csr_usb.c +++ b/tools/csr_usb.c @@ -144,7 +144,7 @@ static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t do { len = usb_interrupt_read(udev, 0x81, - (void *) (rp + offset), sizeof(rp), 10); + (void *) (rp + offset), sizeof(rp) - offset, 10); offset += len; } while (len > 0); -- cgit From a61c4d6cd0882acb8d76f9a59f7847d7027ff539 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Nov 2005 23:24:54 +0000 Subject: Add H4 transport for serial ports --- tools/csr_h4.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 4 deletions(-) diff --git a/tools/csr_h4.c b/tools/csr_h4.c index 9140d30d..2a6c156f 100644 --- a/tools/csr_h4.c +++ b/tools/csr_h4.c @@ -27,22 +27,133 @@ #include #include +#include +#include +#include #include +#include + +#include "csr.h" static uint16_t seqnum = 0x0000; +static int fd = -1; + int csr_open_h4(char *device) { - fprintf(stderr, "Transport not implemented\n"); + struct termios ti; + + if (!device) + device = "/dev/ttyS0"; + + fd = open(device, O_RDWR | O_NOCTTY); + if (fd < 0) { + fprintf(stderr, "Can't open serial port: %s (%d)\n", + strerror(errno), errno); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (tcgetattr(fd, &ti) < 0) { + fprintf(stderr, "Can't get port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + cfmakeraw(&ti); + + ti.c_cflag |= CLOCAL; + ti.c_cflag |= CRTSCTS; + + if (tcsetattr(fd, TCSANOW, &ti) < 0) { + fprintf(stderr, "Can't change port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + cfsetospeed(&ti, B38400); + + if (tcsetattr(fd, TCSANOW, &ti) < 0) { + fprintf(stderr, "Can't change port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + tcflush(fd, TCIOFLUSH); - return -1; + return 0; } static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { - errno = EIO; + unsigned char cp[254], rp[254]; + uint8_t cmd[10]; + uint16_t size; + int len, offset = 3; + + size = (length < 8) ? 9 : ((length + 1) / 2) + 5; + + cmd[0] = command & 0xff; + cmd[1] = command >> 8; + cmd[2] = size & 0xff; + cmd[3] = size >> 8; + cmd[4] = seqnum & 0xff; + cmd[5] = seqnum >> 8; + cmd[6] = varid & 0xff; + cmd[7] = varid >> 8; + cmd[8] = 0x00; + cmd[9] = 0x00; + + memset(cp, 0, sizeof(cp)); + cp[0] = 0x01; + cp[1] = 0x00; + cp[2] = 0xfc; + cp[3] = (size * 2) + 1; + cp[4] = 0xc2; + memcpy(cp + 5, cmd, sizeof(cmd)); + memcpy(cp + 15, value, length); + + if (write(fd, cp, (size * 2) + 5) < 0) + return -1; + + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return 0; + } + + do { + if (read(fd, rp, 1) < 1) + return -1; + } while (rp[0] != 0x04); + + if (read(fd, rp + 1, 2) < 2) + return -1; + + do { + len = read(fd, rp + offset, sizeof(rp) - offset); + offset += len; + } while (offset < rp[2] + 3); + + if (rp[0] != 0x04 || rp[1] != 0xff || rp[3] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[12] + (rp[13] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 14, length); - return -1; + return 0; } int csr_read_h4(uint16_t varid, uint8_t *value, uint16_t length) @@ -57,4 +168,5 @@ int csr_write_h4(uint16_t varid, uint8_t *value, uint16_t length) void csr_close_h4(void) { + close(fd); } -- cgit From 1a31ffaa3c1bca7a26448069bf2aa5007ae7f826 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 00:50:01 +0000 Subject: Fix PSR parsing on big endian --- tools/csr.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index 10856749..b28289a5 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2685,20 +2685,25 @@ static int parse_line(char *str) { uint8_t array[256]; uint16_t value, pskey, length = 0; - char *tmp, *end; + char *off, *end; pskey = strtol(str + 1, NULL, 16); - tmp = strstr(str, "=") + 1; + off = strstr(str, "=") + 1; + if (!off) + return -EIO; while (1) { - value = strtol(tmp, &end, 16); - if (value == 0 && tmp == end) + value = strtol(off, &end, 16); + if (value == 0 && off == end) break; array[length++] = value & 0xff; array[length++] = value >> 8; - tmp = end + 1; + if (*end == '\0') + break; + + off = end + 1; } return psr_put(pskey, array, length); @@ -2728,6 +2733,11 @@ int psr_read(const char *filename) off = map; while (1) { + if (*off == '\r' || *off == '\n') { + off++; + continue; + } + end = strpbrk(off, "\r\n"); if (!end) break; -- cgit From 979392c3e5cd32a4d570f7d37f22baebd04699ba Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 20:59:28 +0000 Subject: Add skeleton for 3-Wire UART transport --- tools/Makefile.am | 2 +- tools/bccmd.c | 9 +++++++++ tools/csr.h | 5 +++++ tools/csr_3wire.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tools/csr_3wire.c diff --git a/tools/Makefile.am b/tools/Makefile.am index a038582a..4e7f8d1c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -52,7 +52,7 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c csr_3wire.c bccmd_LDADD = @USB_LIBS@ @BLUEZ_LIBS@ endif diff --git a/tools/bccmd.c b/tools/bccmd.c index 3bdf702a..7c1260cf 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -70,6 +70,8 @@ static inline int transport_open(int transport, char *device) return csr_open_bcsp(device); case CSR_TRANSPORT_H4: return csr_open_h4(device); + case CSR_TRANSPORT_3WIRE: + return csr_open_3wire(device); default: fprintf(stderr, "Unsupported transport\n"); return -1; @@ -87,6 +89,8 @@ static inline int transport_read(int transport, uint16_t varid, uint8_t *value, return csr_read_bcsp(varid, value, length); case CSR_TRANSPORT_H4: return csr_read_h4(varid, value, length); + case CSR_TRANSPORT_3WIRE: + return csr_read_3wire(varid, value, length); default: errno = EOPNOTSUPP; return -1; @@ -104,6 +108,8 @@ static inline int transport_write(int transport, uint16_t varid, uint8_t *value, return csr_write_bcsp(varid, value, length); case CSR_TRANSPORT_H4: return csr_write_h4(varid, value, length); + case CSR_TRANSPORT_3WIRE: + return csr_write_3wire(varid, value, length); default: errno = EOPNOTSUPP; return -1; @@ -125,6 +131,9 @@ static inline void transport_close(int transport) case CSR_TRANSPORT_H4: csr_close_h4(); break; + case CSR_TRANSPORT_3WIRE: + csr_close_3wire(); + break; } } diff --git a/tools/csr.h b/tools/csr.h index 01e4d803..daa2e669 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -522,6 +522,11 @@ int csr_read_h4(uint16_t varid, uint8_t *value, uint16_t length); int csr_write_h4(uint16_t varid, uint8_t *value, uint16_t length); void csr_close_h4(void); +int csr_open_3wire(char *device); +int csr_read_3wire(uint16_t varid, uint8_t *value, uint16_t length); +int csr_write_3wire(uint16_t varid, uint8_t *value, uint16_t length); +void csr_close_3wire(void); + int csr_write_varid_valueless(int dd, uint16_t seqnum, uint16_t varid); int csr_write_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); int csr_read_varid_complex(int dd, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length); diff --git a/tools/csr_3wire.c b/tools/csr_3wire.c new file mode 100644 index 00000000..322fb437 --- /dev/null +++ b/tools/csr_3wire.c @@ -0,0 +1,60 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2005 Marcel Holtmann + * + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +static uint16_t seqnum = 0x0000; + +int csr_open_3wire(char *device) +{ + fprintf(stderr, "Transport not implemented\n"); + + return -1; +} + +static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) +{ + errno = EIO; + + return -1; +} + +int csr_read_3wire(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0000, seqnum++, varid, value, length); +} + +int csr_write_3wire(uint16_t varid, uint8_t *value, uint16_t length) +{ + return do_command(0x0002, seqnum++, varid, value, length); +} + +void csr_close_3wire(void) +{ +} -- cgit From 858c6b70e59fc7b44243c0c7fb0455323e723b1d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 21:07:04 +0000 Subject: No need for double tcsetattr() --- tools/csr_h4.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tools/csr_h4.c b/tools/csr_h4.c index 2a6c156f..1e051903 100644 --- a/tools/csr_h4.c +++ b/tools/csr_h4.c @@ -67,13 +67,6 @@ int csr_open_h4(char *device) ti.c_cflag |= CLOCAL; ti.c_cflag |= CRTSCTS; - if (tcsetattr(fd, TCSANOW, &ti) < 0) { - fprintf(stderr, "Can't change port settings: %s (%d)\n", - strerror(errno), errno); - close(fd); - return -1; - } - cfsetospeed(&ti, B38400); if (tcsetattr(fd, TCSANOW, &ti) < 0) { -- cgit From d3d625a0e1027c0f328d2d1f620390ecec1fb3cf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 21:13:25 +0000 Subject: Add basic device initialization --- tools/csr_bcsp.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 8847fec5..582d6859 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -27,15 +27,73 @@ #include #include +#include +#include +#include #include +#include + +#include "csr.h" static uint16_t seqnum = 0x0000; +static int fd = -1; + int csr_open_bcsp(char *device) { - fprintf(stderr, "Transport not implemented\n"); + struct termios ti; - return -1; + if (!device) + device = "/dev/ttyS0"; + + fd = open(device, O_RDWR | O_NOCTTY); + if (fd < 0) { + fprintf(stderr, "Can't open serial port: %s (%d)\n", + strerror(errno), errno); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (tcgetattr(fd, &ti) < 0) { + fprintf(stderr, "Can't get port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + cfmakeraw(&ti); + + ti.c_cflag |= CLOCAL; + ti.c_cflag &= ~CRTSCTS; + ti.c_cflag |= PARENB; + ti.c_cflag &= ~PARODD; + ti.c_cflag &= ~CSIZE; + ti.c_cflag |= CS8; + ti.c_cflag &= ~CSTOPB; + + ti.c_cc[VMIN] = 1; + ti.c_cc[VTIME] = 0; + + cfsetospeed(&ti, B38400); + + if (tcsetattr(fd, TCSANOW, &ti) < 0) { + fprintf(stderr, "Can't change port settings: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + tcflush(fd, TCIOFLUSH); + + if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK) < 0) { + fprintf(stderr, "Can't set non blocking mode: %s (%d)\n", + strerror(errno), errno); + close(fd); + return -1; + } + + return 0; } static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) @@ -57,4 +115,5 @@ int csr_write_bcsp(uint16_t varid, uint8_t *value, uint16_t length) void csr_close_bcsp(void) { + close(fd); } -- cgit From 9c4ddbfafab6fe96480edeb8c5fee1b76e103300 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Nov 2005 22:49:28 +0000 Subject: Add support for using the uBCSP implementation --- tools/csr_bcsp.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 2 deletions(-) diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 582d6859..f39a4182 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -39,9 +39,40 @@ static uint16_t seqnum = 0x0000; static int fd = -1; +#ifdef HAVE_UBCSP +#include "ubcsp.h" +#else +#define UBCSP_PACKET_SENT 0x01 +#define UBCSP_PACKET_RECEIVED 0x02 +#define UBCSP_PEER_RESET 0x04 +#define UBCSP_PACKET_ACK 0x08 + +struct ubcsp_packet +{ + uint8_t channel; + uint8_t reliable; + uint8_t use_crc; + uint16_t length; + uint8_t *payload; +}; + +static inline void ubcsp_initialize(void) {} +static inline void ubcsp_send_packet(struct ubcsp_packet *send_packet) {} +static inline void ubcsp_receive_packet(struct ubcsp_packet *receive_packet) {} +static inline uint8_t ubcsp_poll(uint8_t *activity) { return 20; } +#endif + +static struct ubcsp_packet send_packet; +static uint8_t send_buffer[512]; + +static struct ubcsp_packet receive_packet; +static uint8_t receive_buffer[512]; + int csr_open_bcsp(char *device) { struct termios ti; + uint8_t delay, activity = 0x00; + int timeout = 0; if (!device) device = "/dev/ttyS0"; @@ -93,14 +124,140 @@ int csr_open_bcsp(char *device) return -1; } + memset(&send_packet, 0, sizeof(send_packet)); + memset(&receive_packet, 0, sizeof(receive_packet)); + + ubcsp_initialize(); + + send_packet.length = 512; + send_packet.payload = send_buffer; + + receive_packet.length = 512; + receive_packet.payload = receive_buffer; + + ubcsp_receive_packet(&receive_packet); + + while (1) { + delay = ubcsp_poll(&activity); + + if (activity & UBCSP_PACKET_RECEIVED) + break; + + if (delay) { + usleep(delay * 100); + + if (timeout++ > 100) { + fprintf(stderr, "Initialization timed out\n"); + return -1; + } + } + } + return 0; } +void put_uart(uint8_t ch) +{ + write(fd, &ch, 1); +} + +uint8_t get_uart(uint8_t *ch) +{ + int res = read(fd, ch, 1); + return res > 0 ? res : 0; +} + static int do_command(uint16_t command, uint16_t seqnum, uint16_t varid, uint8_t *value, uint16_t length) { - errno = EIO; + unsigned char cp[254], rp[254]; + uint8_t cmd[10]; + uint16_t size; + uint8_t delay, activity = 0x00; + int timeout = 0, sent = 0; - return -1; + size = (length < 8) ? 9 : ((length + 1) / 2) + 5; + + cmd[0] = command & 0xff; + cmd[1] = command >> 8; + cmd[2] = size & 0xff; + cmd[3] = size >> 8; + cmd[4] = seqnum & 0xff; + cmd[5] = seqnum >> 8; + cmd[6] = varid & 0xff; + cmd[7] = varid >> 8; + cmd[8] = 0x00; + cmd[9] = 0x00; + + memset(cp, 0, sizeof(cp)); + cp[0] = 0x00; + cp[1] = 0xfc; + cp[2] = (size * 2) + 1; + cp[3] = 0xc2; + memcpy(cp + 4, cmd, sizeof(cmd)); + memcpy(cp + 14, value, length); + + receive_packet.length = 512; + ubcsp_receive_packet(&receive_packet); + + send_packet.channel = 5; + send_packet.reliable = 1; + send_packet.length = (size * 2) + 4; + memcpy(send_packet.payload, cp, (size * 2) + 4); + + ubcsp_send_packet(&send_packet); + + while (1) { + delay = ubcsp_poll(&activity); + + if (activity & UBCSP_PACKET_RECEIVED) { + if (sent && receive_packet.channel == 5 && + receive_packet.payload[0] == 0xff) { + memcpy(rp, receive_packet.payload, + receive_packet.length); + break; + } + + receive_packet.length = 512; + ubcsp_receive_packet(&receive_packet); + timeout = 0; + } + + if (activity & UBCSP_PACKET_SENT) { + switch (varid) { + case CSR_VARID_COLD_RESET: + case CSR_VARID_WARM_RESET: + case CSR_VARID_COLD_HALT: + case CSR_VARID_WARM_HALT: + return 0; + } + + sent = 1; + timeout = 0; + } + + if (delay) { + usleep(delay * 100); + + if (timeout++ > 100) { + fprintf(stderr, "Operation timed out\n"); + return -1; + } + } + } + + if (rp[0] != 0xff || rp[2] != 0xc2) { + errno = EIO; + return -1; + } + + if ((rp[11] + (rp[12] << 8)) != 0) { + errno = ENXIO; + return -1; + } + + memcpy(value, rp + 13, length); + + return 0; } int csr_read_bcsp(uint16_t varid, uint8_t *value, uint16_t length) -- cgit From 3e9d510274d6560e026c76dc3ecf415db0dd7e68 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Nov 2005 12:18:09 +0000 Subject: Add initial fake HID support --- hidd/Makefile.am | 2 +- hidd/fakehid.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ hidd/hidd.h | 4 ++++ hidd/main.c | 52 +++++++++++++++++++++++++++++++++++++++++++++------- hidd/sdp.c | 19 +++++++++++++++++++ 5 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 hidd/fakehid.c diff --git a/hidd/Makefile.am b/hidd/Makefile.am index 4dfbb56e..cc043457 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -1,7 +1,7 @@ bin_PROGRAMS = hidd -hidd_SOURCES = main.c hidd.h sdp.c +hidd_SOURCES = main.c hidd.h sdp.c fakehid.c hidd_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/hidd/fakehid.c b/hidd/fakehid.c new file mode 100644 index 00000000..1483f022 --- /dev/null +++ b/hidd/fakehid.c @@ -0,0 +1,49 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include + +#include "hidd.h" + +#include +#include + +#include + +void epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) +{ +} + +void headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) +{ +} diff --git a/hidd/hidd.h b/hidd/hidd.h index c8103281..ca9712aa 100644 --- a/hidd/hidd.h +++ b/hidd/hidd.h @@ -26,3 +26,7 @@ int get_stored_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req); int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_connadd_req *req); +int get_alternate_device_info(const bdaddr_t *src, const bdaddr_t *dst, uint16_t *uuid, uint8_t *channel); + +void epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel); +void headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel); diff --git a/hidd/main.c b/hidd/main.c index be50bf7a..ebb9b745 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -406,19 +406,42 @@ static void do_show(int ctl) } } -static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int nosdp, int encrypt, int timeout) +static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, int fakehid, int encrypt, int timeout) { struct hidp_connadd_req req; + uint16_t uuid = HID_SVCLASS_ID; + uint8_t channel = 0; int csk, isk, err; memset(&req, 0, sizeof(req)); - if (get_sdp_device_info(src, dst, &req) < 0) { + err = get_sdp_device_info(src, dst, &req); + if (err < 0 && fakehid) + err = get_alternate_device_info(src, dst, &uuid, &channel); + + if (err < 0) { perror("Can't get device information"); close(ctl); exit(1); } + switch (uuid) { + case HID_SVCLASS_ID: + goto connect; + + case SERIAL_PORT_SVCLASS_ID: + epox_presenter(src, dst, channel); + break; + + case HEADSET_SVCLASS_ID: + case HANDSFREE_SVCLASS_ID: + headset_presenter(src, dst, channel); + break; + } + + return; + +connect: csk = l2cap_connect(src, dst, L2CAP_PSM_HIDP_CTRL); if (csk < 0) { perror("Can't create HID control channel"); @@ -446,7 +469,7 @@ static void do_connect(int ctl, bdaddr_t *src, bdaddr_t *dst, uint8_t subclass, } } -static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int nosdp, int encrypt, int timeout) +static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int fakehid, int encrypt, int timeout) { inquiry_info *info = NULL; bdaddr_t src, dst; @@ -477,10 +500,25 @@ static void do_search(int ctl, bdaddr_t *bdaddr, uint8_t subclass, int nosdp, in ba2str(&dst, addr); printf("\tConnecting to device %s\n", addr); - do_connect(ctl, &src, &dst, subclass, nosdp, encrypt, timeout); + do_connect(ctl, &src, &dst, subclass, fakehid, encrypt, timeout); + } + } + + if (!fakehid) + goto done; + + for (i = 0; i < num_rsp; i++) { + memcpy(class, (info+i)->dev_class, 3); + if (class[0] == 0x00 && class[1] == 0x40 && class[2] == 0x00) { + bacpy(&dst, &(info+i)->bdaddr); + ba2str(&dst, addr); + + printf("\tConnecting to device %s\n", addr); + do_connect(ctl, &src, &dst, subclass, 1, 0, timeout); } } +done: bt_free(info); if (!num_rsp) { @@ -591,7 +629,7 @@ int main(int argc, char *argv[]) char addr[18]; int log_option = LOG_NDELAY | LOG_PID; int opt, fd, ctl, csk, isk; - int mode = SHOW, daemon = 1, nosdp = 0, encrypt = 0, timeout = 30, lm = 0; + int mode = SHOW, daemon = 1, nosdp = 0, fakehid = 1, encrypt = 0, timeout = 30, lm = 0; bacpy(&bdaddr, BDADDR_ANY); @@ -685,12 +723,12 @@ int main(int argc, char *argv[]) break; case SEARCH: - do_search(ctl, &bdaddr, subclass, nosdp, encrypt, timeout); + do_search(ctl, &bdaddr, subclass, fakehid, encrypt, timeout); close(ctl); exit(0); case CONNECT: - do_connect(ctl, &bdaddr, &dev, subclass, nosdp, encrypt, timeout); + do_connect(ctl, &bdaddr, &dev, subclass, fakehid, encrypt, timeout); close(ctl); exit(0); diff --git a/hidd/sdp.c b/hidd/sdp.c index 6ed5d2dc..285438e8 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -267,3 +267,22 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co return 0; } + +int get_alternate_device_info(const bdaddr_t *src, const bdaddr_t *dst, uint16_t *uuid, uint8_t *channel) +{ + sdp_session_t *s; + + s = sdp_connect(src, dst, SDP_RETRY_IF_BUSY | SDP_WAIT_ON_CLOSE); + if (!s) + return -1; + + sdp_close(s); + + if (uuid) + *uuid = 0x0000; + + if (channel) + *channel = 0; + + return 0; +} -- cgit From dd5f6c5572b954ea569a918a1612820d3c7b8318 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 23 Nov 2005 19:38:22 +0000 Subject: Fix strict-aliasing warning --- tools/hciconfig.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 527c9632..417147a5 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -348,8 +348,7 @@ static void cmd_aclmtu(int ctl, int hdev, char *opt) if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; - *((uint16_t *)&dr.dev_opt + 1) = mtu; - *((uint16_t *)&dr.dev_opt + 0) = mpkt; + dr.dev_opt = mpkt | (mtu << 16); if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n", @@ -369,9 +368,8 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; - *((uint16_t *)&dr.dev_opt + 1) = mtu; - *((uint16_t *)&dr.dev_opt + 0) = mpkt; - + dr.dev_opt = mpkt | (mtu << 16); + if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", hdev, strerror(errno), errno); -- cgit From 64ff01e4de2931c0092cd927330e95d82aa413ad Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Nov 2005 04:10:46 +0000 Subject: Add support for device properties --- hcid/dbus-test | 42 ++++++++- hcid/dbus.c | 258 ++++++++++++++++++++++++++++++++++++++++++++------------ hcid/dbus.h | 32 ++----- hcid/hcid.h | 2 + hcid/security.c | 9 +- 5 files changed, 262 insertions(+), 81 deletions(-) diff --git a/hcid/dbus-test b/hcid/dbus-test index 0d20ae7d..00cdfeda 100755 --- a/hcid/dbus-test +++ b/hcid/dbus-test @@ -1,6 +1,7 @@ #!/usr/bin/env python import dbus +import dbus.decorators import dbus.glib import gobject import sys @@ -8,9 +9,11 @@ import getopt from signal import * mgr_cmds = [ "DeviceList", "DefaultDevice" ] -dev_cmds = [ "Up", "Down", "Inquiry", "CancelInquiry", "PeriodicInquiry", - "CancelPeriodic", "RemoteName", "Connections", "Authenticate", - "RoleSwitch" ] +dev_cmds = [ "Up", "Down", "SetProperty", "GetProperty", "Inquiry", + "CancelInquiry", "PeriodicInquiry","CancelPeriodic", "RemoteName", + "Connections", "Authenticate", "RoleSwitch" ] +dev_setprop_bool = [ "auth", "encrypt", "discoverable", "connectable" ] +dev_setprop_byte = [ "incmode" ] class Tester: exit_events = [] @@ -78,6 +81,9 @@ class Tester: self.dev.connect_to_signal('Up', self.dev_up) self.dev.connect_to_signal('Down', self.dev_down) + self.bus.add_signal_receiver(self.dev_name_changed, 'DeviceNameChanged', + 'org.bluez.Device', 'org.bluez', + '/org/bluez/Device/hci0') obj = self.bus.get_object('org.bluez', '%s/Controller' % self.dev_path) self.ctl = dbus.Interface(obj, 'org.bluez.Device.Controller') @@ -150,6 +156,12 @@ class Tester: def dev_down(self): print 'Down' + @dbus.decorators.explicitly_pass_message + def dev_name_changed(*args, **keywords): + name = args[1] + dbus_message = keywords["dbus_message"] + print 'Device %s name changed: %s' % (dbus_message.get_path(), name) + def signal_cb(self, sig, frame): print 'Caught signal, exiting' if self.at_interrupt: @@ -179,7 +191,29 @@ class Tester: except dbus.DBusException, e: print 'Sending %s failed: %s' % (self.cmd, e) sys.exit(1) - + elif self.cmd == 'SetProperty': + if len(self.cmd_args) < 2: + print 'Usage: %s -i SetProperty strPropName arg' % self.name + sys.exit(1) + try: + if self.cmd_args[0].lower() in dev_setprop_bool: + self.dev.SetProperty(self.cmd_args[0], dbus.Boolean(self.cmd_args[1])) + elif self.cmd_args[0].lower() in dev_setprop_byte: + self.dev.SetProperty(self.cmd_args[0], dbus.Byte(self.cmd_args[1])) + else: + self.dev.SetProperty(self.cmd_args[0], self.cmd_args[1]) + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) + elif self.cmd == 'GetProperty': + if len(self.cmd_args) < 1: + print 'Usage: %s -i GetProperty strPropName' % self.name + sys.exit(1) + try: + print self.dev.GetProperty(self.cmd_args[0]) + except dbus.DBusException, e: + print 'Sending %s failed: %s' % (self.cmd, e) + sys.exit(1) # Device.Controller methods elif self.cmd == 'Inquiry': try: diff --git a/hcid/dbus.c b/hcid/dbus.c index 45b101f9..eb2e0578 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -272,59 +272,33 @@ static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data); static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data); static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data); static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data); +static DBusMessage* handle_device_set_propety_req_name(DBusMessage *msg, void *data); +static DBusMessage* handle_device_get_propety_req_name(DBusMessage *msg, void *data); static const struct service_data device_services[] = { { DEV_UP, handle_device_up_req, DEV_UP_SIGNATURE }, { DEV_DOWN, handle_device_down_req, DEV_DOWN_SIGNATURE }, - { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_2 }, - { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_3 }, + { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, + { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_STR }, + { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_BYTE }, { DEV_GET_PROPERTY, handle_device_get_propety_req, DEV_GET_PROPERTY_SIGNATURE }, { NULL, NULL, NULL} }; static const struct service_data set_property_services[] = { - { DEV_PROPERTY_AUTH, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_ENCRYPT, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_SECMGR, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_PISCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_PSCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_ISCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_PTYPE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_LM, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_LP, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_NAME, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_CLASS, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_VOICE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_IAC, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_INCMODE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_INCTYPE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_INCPARMS, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_PAGEPARMS, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_PAGETO, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_AFHMODE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_ACLMTU, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_SCOMTU, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_PUTKEY, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, - { DEV_PROPERTY_DELKEY, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_1 }, + { DEV_PROPERTY_AUTH, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, + { DEV_PROPERTY_ENCRYPT, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, + { DEV_PROPERTY_PSCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, + { DEV_PROPERTY_ISCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, + { DEV_PROPERTY_NAME, handle_device_set_propety_req_name, DEV_SET_PROPERTY_SIGNATURE_STR }, + { DEV_PROPERTY_INCMODE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BYTE }, { NULL, NULL, NULL} }; static const struct service_data get_property_services[] = { - { DEV_PROPERTY_DEV_INFO, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_PTYPE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_LM, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_LP, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_NAME, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_CLASS, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_VOICE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_IAC, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_INCMODE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_INCTYPE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_INCPARMS, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_PAGEPARMS, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_PAGETO, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_AFHMODE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_DEV_INFO, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_NAME, handle_device_get_propety_req_name, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_INCMODE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, { NULL, NULL, NULL} }; @@ -435,8 +409,6 @@ static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t gboolean ret = FALSE; struct hci_dbus_data *data = NULL; - syslog(LOG_INFO, "Registering DBUS Path: %s", path); - data = malloc(sizeof(struct hci_dbus_data)); if (data == NULL) { syslog(LOG_ERR, "Failed to alloc memory to DBUS path register data (%s)", path); @@ -471,9 +443,7 @@ static gboolean unregister_dbus_path(const char *path) { void *data; - syslog(LOG_INFO, "Unregistering DBUS Path: %s", path); - - if (dbus_connection_get_object_path_data(connection, path, &data) && data) + if (dbus_connection_get_object_path_data(connection, path, &data) && data) free(data); if (!dbus_connection_unregister_object_path (connection, path)) { @@ -1296,9 +1266,6 @@ static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, method = dbus_message_get_member(msg); signature = dbus_message_get_signature(msg); - syslog(LOG_INFO, "%s - path:%s, path_id:0x%04x dev_id:0x%04x", __PRETTY_FUNCTION__, - path, dbus_data->path_id, dbus_data->dev_id); - if (dbus_data->path_id == DEVICE_ROOT_ID) { /* Device is down(path unregistered) or the path is wrong */ ret = DBUS_HANDLER_RESULT_HANDLED; @@ -1369,8 +1336,6 @@ static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg method = dbus_message_get_member(msg); signature = dbus_message_get_signature(msg); - syslog (LOG_INFO, "%s - path:%s", __PRETTY_FUNCTION__, path); - if (strcmp(iface, MANAGER_INTERFACE) != 0) return ret; @@ -1976,7 +1941,7 @@ static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data) DBusMessage *reply = NULL; const char *signature; char *str_name; - uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; + uint32_t error = BLUEZ_EDBUS_WRONG_PARAM; signature = dbus_message_get_signature(msg); @@ -2009,7 +1974,7 @@ static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data) DBusMessageIter iter; DBusMessage *reply = NULL; char *str_name; - uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD; + uint32_t error = BLUEZ_EDBUS_WRONG_PARAM; dbus_message_iter_init(msg, &iter); @@ -2029,6 +1994,195 @@ static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data) return reply; } +static DBusMessage* handle_device_set_propety_req_name(DBusMessage *msg, void *data) +{ + struct hci_dbus_data *dbus_data = data; + DBusMessageIter iter; + DBusMessage *reply = NULL; + char *str_name; + int dd = -1; + uint8_t status; + change_local_name_cp cp; + struct hci_request rq; + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &str_name); + + if(strlen(str_name) == 0) { + syslog(LOG_ERR, "HCI change name failed - Invalid Name!"); + reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); + goto failed; + } + + dd = hci_open_dev(dbus_data->dev_id); + if (dd < 0) { + syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + + memset(&rq, 0, sizeof(rq)); + strncpy((char *) cp.name, str_name, sizeof(cp.name)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_CHANGE_LOCAL_NAME; + rq.cparam = &cp; + rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; + rq.rparam = &status; + rq.rlen = sizeof(status); + + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, "Sending change name command failed: %s (%d)", + strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (status) { + syslog(LOG_ERR, "Setting name failed with status 0x%02x", status); + reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + status); + goto failed; + } + + reply = dbus_message_new_method_return(msg); + +failed: + if (dd >= 0) + close(dd); + + return reply; +} + +void hcid_dbus_setname_complete(bdaddr_t *local) +{ + DBusMessage *message = NULL; + char path[MAX_PATH_LENGTH]; + char *local_addr; + bdaddr_t tmp; + int id; + int dd = -1; + read_local_name_rp rp; + struct hci_request rq; + const char *pname = (char*) rp.name; + char name[249]; + + baswap(&tmp, local); local_addr = batostr(&tmp); + + id = hci_devid(local_addr); + if (id < 0) { + syslog(LOG_ERR, "No matching device id for %s", local_addr); + goto failed; + } + + snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); + + message = dbus_message_new_signal(path, DEVICE_INTERFACE, + BLUEZ_HCI_SET_NAME); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); + goto failed; + } + + dd = hci_open_dev(id); + memset(&rq, 0, sizeof(rq)); + if (dd < 0) { + syslog(LOG_ERR, "HCI device open failed: hci%d", id); + } else { + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_NAME; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_NAME_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, + "Sending getting name command failed: %s (%d)", + strerror(errno), errno); + rp.name[0] = '\0'; + } + if (rp.status) { + syslog(LOG_ERR, + "Getting name failed with status 0x%02x", + rp.status); + rp.name[0] = '\0'; + } + } + + strncpy(name,pname,sizeof(name)-1); + name[248]='\0'; + pname = name; + + dbus_message_append_args(message, + DBUS_TYPE_STRING, &pname, + DBUS_TYPE_INVALID); + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS NameChanged signal"); + goto failed; + } + dbus_connection_flush(connection); + +failed: + if (dd >= 0) + close(dd); + dbus_message_unref(message); + bt_free(local_addr); +} + +static DBusMessage* handle_device_get_propety_req_name(DBusMessage *msg, void *data) +{ + struct hci_dbus_data *dbus_data = data; + DBusMessage *reply = NULL; + int dd = -1; + read_local_name_rp rp; + struct hci_request rq; + const char *pname = (char*) rp.name; + char name[249]; + + dd = hci_open_dev(dbus_data->dev_id); + if (dd < 0) { + syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_NAME; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_NAME_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, "Sending getting name command failed: %s (%d)", + strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (rp.status) { + syslog(LOG_ERR, "Getting name failed with status 0x%02x", rp.status); + reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + rp.status); + goto failed; + } + + reply = dbus_message_new_method_return(msg); + if (reply == NULL) { + syslog(LOG_ERR, "Out of memory while calling dbus_message_new_method_return"); + goto failed; + } + + strncpy(name,pname,sizeof(name)-1); + name[248]='\0'; + pname = name; + + dbus_message_append_args(reply, + DBUS_TYPE_STRING, &pname, + DBUS_TYPE_INVALID); + +failed: + if (dd >= 0) + close(dd); + + return reply; +} + static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data) { DBusMessageIter iter; diff --git a/hcid/dbus.h b/hcid/dbus.h index 557a6686..949f4b0d 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -99,6 +99,9 @@ #define BLUEZ_HCI "Controller" #define DEV_HCI_INTERFACE DEVICE_INTERFACE "." BLUEZ_HCI +/* /org/bluez/Device signals */ +#define BLUEZ_HCI_SET_NAME "DeviceNameChanged" + /* Control interface signals */ #define BLUEZ_HCI_INQ_START "InquiryStart" #define BLUEZ_HCI_INQ_COMPLETE "InquiryComplete" @@ -125,40 +128,23 @@ #define DEV_PROPERTY_AUTH "auth" #define DEV_PROPERTY_ENCRYPT "encrypt" -#define DEV_PROPERTY_SECMGR "secmgr" -#define DEV_PROPERTY_PISCAN "piscan" -#define DEV_PROPERTY_PSCAN "pscan" -#define DEV_PROPERTY_ISCAN "iscan" -#define DEV_PROPERTY_PTYPE "ptype" -#define DEV_PROPERTY_LM "lm" -#define DEV_PROPERTY_LP "lp" +#define DEV_PROPERTY_PSCAN "connectable" +#define DEV_PROPERTY_ISCAN "discoverable" #define DEV_PROPERTY_NAME "name" -#define DEV_PROPERTY_CLASS "class" -#define DEV_PROPERTY_VOICE "voice" -#define DEV_PROPERTY_IAC "iac" #define DEV_PROPERTY_INCMODE "incmode" -#define DEV_PROPERTY_INCTYPE "inctype" -#define DEV_PROPERTY_INCPARMS "incparms" -#define DEV_PROPERTY_PAGEPARMS "pageparms" -#define DEV_PROPERTY_PAGETO "pageto" -#define DEV_PROPERTY_AFHMODE "afhmode" -#define DEV_PROPERTY_ACLMTU "aclmtu" -#define DEV_PROPERTY_SCOMTU "scomtu" -#define DEV_PROPERTY_PUTKEY "putkey" -#define DEV_PROPERTY_DELKEY "delkey" #define DEV_PROPERTY_DEV_INFO "info" #define DEV_UP_SIGNATURE __END_SIG__ #define DEV_DOWN_SIGNATURE __END_SIG__ #define DEV_RESET_SIGNATURE __END_SIG__ -#define DEV_SET_PROPERTY_SIGNATURE_1 DBUS_TYPE_STRING_AS_STRING \ +#define DEV_SET_PROPERTY_SIGNATURE_BOOL DBUS_TYPE_STRING_AS_STRING \ DBUS_TYPE_BOOLEAN_AS_STRING \ __END_SIG__ -#define DEV_SET_PROPERTY_SIGNATURE_2 DBUS_TYPE_STRING_AS_STRING \ +#define DEV_SET_PROPERTY_SIGNATURE_STR DBUS_TYPE_STRING_AS_STRING \ DBUS_TYPE_STRING_AS_STRING \ __END_SIG__ -#define DEV_SET_PROPERTY_SIGNATURE_3 DBUS_TYPE_STRING_AS_STRING \ - DBUS_TYPE_UINT16_AS_STRING \ +#define DEV_SET_PROPERTY_SIGNATURE_BYTE DBUS_TYPE_STRING_AS_STRING \ + DBUS_TYPE_BYTE_AS_STRING \ __END_SIG__ #define DEV_GET_PROPERTY_SIGNATURE DBUS_TYPE_STRING_AS_STRING \ diff --git a/hcid/hcid.h b/hcid/hcid.h index 6dd6437c..bac3ef26 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -134,6 +134,7 @@ void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t statu void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer); void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason); void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status); +void hcid_dbus_setname_complete(bdaddr_t *local); #else static inline void hcid_dbus_inquiry_start(bdaddr_t *local) {} static inline void hcid_dbus_inquiry_complete(bdaddr_t *local) {} @@ -143,6 +144,7 @@ static inline void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, static inline void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) {} static inline void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) {} static inline void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status) {} +static inline void hcid_dbus_setname_complete(bdaddr_t *local) {} #endif int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); diff --git a/hcid/security.c b/hcid/security.c index 91f65665..76a8600d 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -491,9 +491,14 @@ static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr) static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr) { evt_cmd_complete *evt = ptr; - - if (evt->opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL)) + switch (evt->opcode) { + case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL): hcid_dbus_inquiry_complete(sba); + break; + case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME): + hcid_dbus_setname_complete(sba); + break; + }; } static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr) -- cgit From c20d8468a85840b9235694f369d021118abe23c5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Nov 2005 04:47:48 +0000 Subject: Fix big endian problem with ACL and SCO MTU settings --- tools/hciconfig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 417147a5..47488546 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -348,7 +348,7 @@ static void cmd_aclmtu(int ctl, int hdev, char *opt) if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; - dr.dev_opt = mpkt | (mtu << 16); + dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16)); if (ioctl(ctl, HCISETACLMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set ACL mtu on hci%d: %s(%d)\n", @@ -368,7 +368,7 @@ static void cmd_scomtu(int ctl, int hdev, char *opt) if (sscanf(opt, "%4hu:%4hu", &mtu, &mpkt) != 2) return; - dr.dev_opt = mpkt | (mtu << 16); + dr.dev_opt = htobl(htobs(mpkt) | (htobs(mtu) << 16)); if (ioctl(ctl, HCISETSCOMTU, (unsigned long) &dr) < 0) { fprintf(stderr, "Can't set SCO mtu on hci%d: %s (%d)\n", -- cgit From 518f2131be6bbc676121e6558f190950308958e3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 29 Nov 2005 20:37:43 +0000 Subject: Add support for AVRCP specific service records --- tools/sdptool.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 159 insertions(+), 33 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 052c0b05..6074ef77 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2047,6 +2047,162 @@ done: return ret; } +static int add_avrct(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, avctp, avrct; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + sdp_data_t *psm, *version, *features; + uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&avrct, AV_REMOTE_SVCLASS_ID); + svclass_id = sdp_list_append(0, &avrct); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&avctp, AVCTP_UUID); + proto[1] = sdp_list_append(0, &avctp); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + features = sdp_data_alloc(SDP_UINT16, &feat); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); + + sdp_set_info_attr(&record, "AVRCP CT", 0, 0); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto done; + } + + printf("Remote control service registered\n"); + +done: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static int add_avrtg(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, l2cap, avctp, avrtg; + sdp_profile_desc_t profile[1]; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + sdp_data_t *psm, *version, *features; + uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = 0xffffffff; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&avrtg, AV_REMOTE_TARGET_SVCLASS_ID); + svclass_id = sdp_list_append(0, &avrtg); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(0, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap); + psm = sdp_data_alloc(SDP_UINT16, &lp); + proto[0] = sdp_list_append(proto[0], psm); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&avctp, AVCTP_UUID); + proto[1] = sdp_list_append(0, &avctp); + version = sdp_data_alloc(SDP_UINT16, &ver); + proto[1] = sdp_list_append(proto[1], version); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + features = sdp_data_alloc(SDP_UINT16, &feat); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); + + sdp_set_info_attr(&record, "AVRCP TG", 0, 0); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto done; + } + + printf("Remote target service registered\n"); + +done: + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + +static unsigned char sr1_uuid[] = { 0xbc, 0x19, 0x9c, 0x24, 0x95, 0x8b, 0x4c, 0xc0, + 0xa2, 0xcb, 0xfd, 0x8a, 0x30, 0xbf, 0x32, 0x06 }; + +static int add_sr1(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass; + uuid_t root_uuid, svclass_uuid; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid128_create(&svclass_uuid, (void *) sr1_uuid); + svclass = sdp_list_append(NULL, &svclass_uuid); + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Toshiba Speech Recognition SR-1 service record registered\n"); + + return 0; +} + static unsigned char syncml_uuid[] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x02 }; @@ -2283,38 +2439,6 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) return 0; } -static unsigned char sr1_uuid[] = { 0xbc, 0x19, 0x9c, 0x24, 0x95, 0x8b, 0x4c, 0xc0, - 0xa2, 0xcb, 0xfd, 0x8a, 0x30, 0xbf, 0x32, 0x06 }; - -static int add_sr1(sdp_session_t *session, svc_info_t *si) -{ - sdp_record_t record; - sdp_list_t *root, *svclass; - uuid_t root_uuid, svclass_uuid; - - memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; - - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(&record, root); - - sdp_uuid128_create(&svclass_uuid, (void *) sr1_uuid); - svclass = sdp_list_append(NULL, &svclass_uuid); - sdp_set_service_classes(&record, svclass); - - sdp_set_info_attr(&record, "TOSHIBA SR-1", NULL, NULL); - - if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { - printf("Service Record registration failed\n"); - return -1; - } - - printf("Toshiba Speech Recognition SR-1 service record registered\n"); - - return 0; -} - struct { char *name; uint16_t class; @@ -2344,14 +2468,16 @@ struct { { "A2SRC", AUDIO_SOURCE_SVCLASS_ID, add_a2source }, { "A2SNK", AUDIO_SINK_SVCLASS_ID, add_a2sink }, + { "AVRCT", AV_REMOTE_SVCLASS_ID, add_avrct }, + { "AVRTG", AV_REMOTE_TARGET_SVCLASS_ID, add_avrtg }, + { "SR1", 0, add_sr1, sr1_uuid }, { "SYNCML", 0, add_syncml, syncml_uuid }, { "ACTIVESYNC", 0, add_activesync, async_uuid }, { "HOTSYNC", 0, add_hotsync, hotsync_uuid }, { "PALMOS", 0, add_palmos, palmos_uuid }, { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, - { "SR1", 0, add_sr1, sr1_uuid }, { 0 } }; -- cgit From bd3e52e30a0529e096abb4e2429122dba22e589b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 03:27:23 +0000 Subject: Update the l2ping manual page --- tools/l2ping.1 | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tools/l2ping.1 b/tools/l2ping.1 index 0c7da44b..f415dd9c 100644 --- a/tools/l2ping.1 +++ b/tools/l2ping.1 @@ -4,7 +4,7 @@ l2ping \- Send L2CAP echo request and receive answer .SH SYNOPSIS .B l2ping [ -.I -S source addr +.I -i ] [ .I -s size ] [ @@ -23,8 +23,13 @@ L2ping sends a L2CAP echo request to the Bluetooth MAC address given in dotted hex notation. .SH OPTIONS .TP -.I -S source addr -Select address to be used as source address for the request. +.I -i " " +The command is applied to device +.I +hciX +, which must be the name of an installed Bluetooth device (X = 0, 1, 2, ...) +If not specified, the command will be sent to the first available Bluetooth +device. .TP .I -s size The @@ -36,10 +41,10 @@ Send .B count number of packets then exit. .TP -.I -c timeout +.I -c \fBtimeout\fP Wait -.B timeout -for the response. +.B \fBtimeout\fP +seconds for the response. .TP .I -f Kind of flood ping. Use with care! It reduces the delay time between packets @@ -53,4 +58,4 @@ or .SH AUTHORS Written by Maxim Krasnyansky and Marcel Holtmann .PP -man page by Nils Faerber +man page by Nils Faerber . -- cgit From 7c115e06a562978ff2df7b32d7cb1aed72000a16 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 05:11:19 +0000 Subject: Add support for reading the full build name --- tools/bccmd.c | 25 +++++++++++++++++++++++++ tools/csr.h | 1 + 2 files changed, 26 insertions(+) diff --git a/tools/bccmd.c b/tools/bccmd.c index 7c1260cf..291ed6a3 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -337,6 +337,30 @@ static int cmd_rand(int transport, int argc, char *argv[]) return 0; } +static int cmd_buildname(int transport, int argc, char *argv[]) +{ + uint8_t array[130]; + char name[64]; + int i, err; + + OPT_HELP(0, NULL); + + memset(array, 0, sizeof(array)); + + err = transport_read(transport, CSR_VARID_READ_BUILD_NAME, array, 128); + if (err < 0) { + errno = -err; + return -1; + } + + for (i = 0; i < sizeof(name); i++) + name[i] = array[(i * 2) + 4]; + + printf("Build name: %s\n", name); + + return 0; +} + static int cmd_panicarg(int transport, int argc, char *argv[]) { uint8_t array[8]; @@ -901,6 +925,7 @@ static struct { { "keylen", cmd_keylen, "", "Get current crypt key length" }, { "clock", cmd_clock, "", "Get local Bluetooth clock" }, { "rand", cmd_rand, "", "Get random number" }, + { "buildname", cmd_buildname, "", "Get the full build name" }, { "panicarg", cmd_panicarg, "", "Get panic code argument" }, { "faultarg", cmd_faultarg, "", "Get fault code argument" }, { "coldreset", cmd_coldreset, "", "Perform cold reset" }, diff --git a/tools/csr.h b/tools/csr.h index daa2e669..9cdc7225 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -41,6 +41,7 @@ #define CSR_VARID_GET_CLR_EVT 0x300a /* complex */ #define CSR_VARID_GET_NEXT_BUILDDEF 0x300b /* complex */ #define CSR_VARID_PS_MEMORY_TYPE 0x3012 /* complex */ +#define CSR_VARID_READ_BUILD_NAME 0x301c /* complex */ #define CSR_VARID_COLD_RESET 0x4001 /* valueless */ #define CSR_VARID_WARM_RESET 0x4002 /* valueless */ #define CSR_VARID_COLD_HALT 0x4003 /* valueless */ -- cgit From dc443fe8e6f81ae76f034e6acdc8ab5adca228fc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 05:36:33 +0000 Subject: List available transports --- tools/bccmd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/bccmd.c b/tools/bccmd.c index 291ed6a3..78018d48 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -957,6 +957,9 @@ static void usage(void) "\t-h, --help Display help\n" "\n"); + printf("Transports:\n" + "\tHCI USB BCSP H4 3WIRE\n\n"); + printf("Commands:\n"); for (i = 0; commands[i].str; i++) printf("\t%-10s %-14s\t%s\n", commands[i].str, -- cgit From 90049a54d90557db7c7963c83ba9ff8d3b433c15 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 30 Nov 2005 08:32:00 +0000 Subject: Read oui.txt in current directory first --- tools/oui.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/oui.c b/tools/oui.c index 6ebf91a5..13d6c2f5 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -46,10 +46,12 @@ char *ouitocomp(const char *oui) char *str, *map, *off, *end; int fd; - - fd = open(OUIFILE, O_RDONLY); - if (fd < 0) - return NULL; + fd = open("oui.txt", O_RDONLY); + if (fd < 0) { + fd = open(OUIFILE, O_RDONLY); + if (fd < 0) + return NULL; + } if (fstat(fd, &st) < 0) { close(fd); -- cgit From 2a6755856c498491474e64aa506b81031a1269f7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Dec 2005 15:01:51 +0000 Subject: Fix array length for device name --- tools/hciattach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index 8091d655..bcdad95b 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -968,7 +968,7 @@ int main(int argc, char *argv[]) int send_break = 0; pid_t pid; struct sigaction sa; - char dev[20]; + char dev[PATH_MAX]; detach = 1; printpid = 0; -- cgit From 138621bf2dbcfa89e85a35010a406d447365cf7e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 2 Dec 2005 19:34:29 +0000 Subject: Add MicroBCSP implementation --- tools/Makefile.am | 2 +- tools/csr_bcsp.c | 24 +- tools/ubcsp.c | 1193 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/ubcsp.h | 208 ++++++++++ 4 files changed, 1403 insertions(+), 24 deletions(-) create mode 100644 tools/ubcsp.c create mode 100644 tools/ubcsp.h diff --git a/tools/Makefile.am b/tools/Makefile.am index 4e7f8d1c..08f5d742 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -52,7 +52,7 @@ ciptool_LDADD = @BLUEZ_LIBS@ ppporc_LDADD = @BLUEZ_LIBS@ if BCCMD -bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c csr_3wire.c +bccmd_SOURCES = bccmd.c csr.h csr.c csr_hci.c csr_usb.c csr_bcsp.c csr_h4.c csr_3wire.c ubcsp.h ubcsp.c bccmd_LDADD = @USB_LIBS@ @BLUEZ_LIBS@ endif diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index f39a4182..2e1cea6e 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -34,34 +34,12 @@ #include #include "csr.h" +#include "ubcsp.h" static uint16_t seqnum = 0x0000; static int fd = -1; -#ifdef HAVE_UBCSP -#include "ubcsp.h" -#else -#define UBCSP_PACKET_SENT 0x01 -#define UBCSP_PACKET_RECEIVED 0x02 -#define UBCSP_PEER_RESET 0x04 -#define UBCSP_PACKET_ACK 0x08 - -struct ubcsp_packet -{ - uint8_t channel; - uint8_t reliable; - uint8_t use_crc; - uint16_t length; - uint8_t *payload; -}; - -static inline void ubcsp_initialize(void) {} -static inline void ubcsp_send_packet(struct ubcsp_packet *send_packet) {} -static inline void ubcsp_receive_packet(struct ubcsp_packet *receive_packet) {} -static inline uint8_t ubcsp_poll(uint8_t *activity) { return 20; } -#endif - static struct ubcsp_packet send_packet; static uint8_t send_buffer[512]; diff --git a/tools/ubcsp.c b/tools/ubcsp.c new file mode 100644 index 00000000..6928da95 --- /dev/null +++ b/tools/ubcsp.c @@ -0,0 +1,1193 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2005 CSR Ltd. + * + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/** **/ +/** ubcsp,c **/ +/** **/ +/** MicroBCSP - a very low cost implementation of the BCSP protocol **/ +/** **/ +/*****************************************************************************/ + +#include "ubcsp.h" + +#if SHOW_PACKET_ERRORS || SHOW_LE_STATES +#include +#include +#endif + +static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc); +static uint16 ubcsp_crc_reverse (uint16); + +/*****************************************************************************/ +/** **/ +/** Constant Data - ROM **/ +/** **/ +/*****************************************************************************/ + +/* This is the storage for the link establishment messages */ + +static const uint8 ubcsp_le_buffer[4][4] = + { + { 0xDA, 0xDC, 0xED, 0xED }, + { 0xAC, 0xAF, 0xEF, 0xEE }, + { 0xAD, 0xEF, 0xAC, 0xED }, + { 0xDE, 0xAD, 0xD0, 0xD0 }, + }; + +/* These are the link establishment headers */ +/* The two version are for the CRC and non-CRC varients */ + +#if UBCSP_CRC +static const uint8 ubcsp_send_le_header[4] = + { + 0x40, 0x41, 0x00, 0x7E + }; +#else +static const uint8 ubcsp_send_le_header[4] = + { + 0x00, 0x41, 0x00, 0xBE + }; +#endif + +/*****************************************************************************/ +/** **/ +/** Static Data - RAM **/ +/** **/ +/*****************************************************************************/ + +/* This is the storage for all state data for ubcsp */ + +static struct ubcsp_configuration ubcsp_config; + +/* This is the ACK packet header - this will be overwritten when + we create an ack packet */ + +static uint8 ubcsp_send_ack_header[4] = + { + 0x00, 0x00, 0x00, 0x00 + }; + +/* This is the deslip lookup table */ + +static const uint8 ubcsp_deslip[2] = + { + SLIP_FRAME, SLIP_ESCAPE, + }; + +/* This is a state machine table for link establishment */ + +static uint8 next_le_packet[16] = + { + ubcsp_le_sync, // uninit + ubcsp_le_conf, // init + ubcsp_le_none, // active + ubcsp_le_none, + ubcsp_le_sync_resp, // sync_resp + ubcsp_le_sync_resp, + ubcsp_le_none, + ubcsp_le_none, + ubcsp_le_none, // conf_resp + ubcsp_le_conf_resp, + ubcsp_le_conf_resp, + ubcsp_le_none, + }; + +/* This is the storage required for building send and crc data */ + +static uint8 ubcsp_send_header[4]; +static uint8 ubcsp_send_crc[2]; + +/* This is where the receive header is stored before the payload arrives */ + +static uint8 ubcsp_receive_header[4]; + +/*****************************************************************************/ +/** **/ +/** Code - ROM or RAM **/ +/** **/ +/*****************************************************************************/ + +/*****************************************************************************/ +/** **/ +/** ubcsp_initialize **/ +/** **/ +/** This initializes the state of the ubcsp engine to a known values **/ +/** **/ +/*****************************************************************************/ + +void ubcsp_initialize (void) +{ + ubcsp_config.ack_number = 0; + ubcsp_config.sequence_number = 0; + ubcsp_config.send_ptr = 0; + ubcsp_config.send_size = 0; + ubcsp_config.receive_index = -4; + + ubcsp_config.delay = 0; + +#if SHOW_LE_STATES + printf ("Hello Link Uninitialized\n"); +#endif + + ubcsp_config.link_establishment_state = ubcsp_le_uninitialized; + ubcsp_config.link_establishment_packet = ubcsp_le_sync; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_send_packet **/ +/** **/ +/** This sends a packet structure for sending to the ubcsp engine **/ +/** This can only be called when the activity indication from ubcsp_poll **/ +/** indicates that a packet can be sent with UBCSP_PACKET_SENT **/ +/** **/ +/*****************************************************************************/ + +void ubcsp_send_packet (struct ubcsp_packet *send_packet) +{ + /* Initialize the send data to the packet we want to send */ + + ubcsp_config.send_packet = send_packet; + + /* we cannot send the packet at the moment + when we can at the moment, just set things to 0 */ + + ubcsp_config.send_size = 0; + ubcsp_config.send_ptr = 0; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_receive_packet **/ +/** **/ +/** This sends a packet structure for receiving to the ubcsp engine **/ +/** This can only be called when the activity indication from ubcsp_poll **/ +/** indicates that a packet can be sent with UBCSP_PACKET_RECEIVED **/ +/** **/ +/*****************************************************************************/ + +void ubcsp_receive_packet (struct ubcsp_packet *receive_packet) +{ + /* Initialize the receive data to the packet we want to receive */ + + ubcsp_config.receive_packet = receive_packet; + + /* setup to receive the header first */ + + ubcsp_config.receive_index = -4; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_calc_crc **/ +/** **/ +/** Takes the next 8 bit value ch, and updates the crc with this value **/ +/** **/ +/*****************************************************************************/ + + +#ifdef UBCSP_CRC + +static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc) +{ + /* Calculate the CRC using the above 16 entry lookup table */ + + static const uint16 crc_table[] = + { + 0x0000, 0x1081, 0x2102, 0x3183, + 0x4204, 0x5285, 0x6306, 0x7387, + 0x8408, 0x9489, 0xa50a, 0xb58b, + 0xc60c, 0xd68d, 0xe70e, 0xf78f + }; + + /* Do this four bits at a time - more code, less space */ + + crc = (crc >> 4) ^ crc_table[(crc ^ ch) & 0x000f]; + crc = (crc >> 4) ^ crc_table[(crc ^ (ch >> 4)) & 0x000f]; + + return crc; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_crc_reverse **/ +/** **/ +/** Reserves the bits in crc and returns the new value **/ +/** **/ +/*****************************************************************************/ + +static uint16 ubcsp_crc_reverse (uint16 crc) +{ + int32 + b, + rev; + + /* Reserse the bits to compute the actual CRC value */ + + for (b = 0, rev=0; b < 16; b++) + { + rev = rev << 1; + rev |= (crc & 1); + crc = crc >> 1; + } + + return rev; +} + +#endif + +/*****************************************************************************/ +/** **/ +/** ubcsp_put_slip_uart **/ +/** **/ +/** Outputs a single octet to the uart **/ +/** If the octet needs to be escaped, then output the escape value **/ +/** and then store the second octet to be output later **/ +/** **/ +/*****************************************************************************/ + +static void ubcsp_put_slip_uart (uint8 ch) +{ + /* output a single UART octet */ + + /* If it needs to be escaped, then output the escape octet + and set the send_slip_escape so that the next time we + output the second octet for the escape correctly. + This is done right at the top of ubcsp_poll */ + + if (ch == SLIP_FRAME) + { + put_uart (SLIP_ESCAPE); + ubcsp_config.send_slip_escape = SLIP_ESCAPE_FRAME; + } + else if (ch == SLIP_ESCAPE) + { + put_uart (SLIP_ESCAPE); + ubcsp_config.send_slip_escape = SLIP_ESCAPE_ESCAPE; + } + else + { + /* Not escaped, so just output octet */ + + put_uart (ch); + } +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_which_le_payload **/ +/** **/ +/** Check the payload of this packet, and determine which of the four **/ +/** link establishment packets this was. **/ +/** Can return 5 if it is not a valid link establishment packet **/ +/** **/ +/*****************************************************************************/ + +static uint32 ubcsp_which_le_payload (const uint8 *payload) +{ + static int32 + octet, + loop; + + /* Search through the various link establishment payloads to find + which one we have received */ + + for (loop = 0; loop < 4; loop ++) + { + for (octet = 0; octet < 4; octet ++) + { + if (payload[octet] != ubcsp_le_buffer[loop][octet]) + { + /* Bad match, just to loop again */ + goto bad_match_loop; + } + } + + /* All the octets matched, return the value */ + + return loop; + + /* Jumps out of octet loop if we got a bad match */ +bad_match_loop: + {} + } + + /* Non of the link establishment payloads matched - return invalid value */ + + return 5; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_recevied_packet **/ +/** **/ +/** This function is called when we have a SLIP END octet and a full **/ +/** packet header and possibly data in the receive packet **/ +/** **/ +/*****************************************************************************/ + +static uint8 ubcsp_recevied_packet (void) +{ + static uint8 + receive_crc, + receive_seq, + receive_ack, + activity; + +#if UBCSP_CRC + static int32 + loop; + + static uint16 + crc; +#endif + + static uint16 + length; + + /* Keep track of what activity this received packet will cause */ + + activity = 0; + + /*** Do all error checks that we can ***/ + + /* First check the header checksum */ + + if (((ubcsp_receive_header[0] + ubcsp_receive_header[1] + ubcsp_receive_header[2] + ubcsp_receive_header[3]) & 0xff) != 0xff) + { + /* Header Checksum Error */ + +#if SHOW_PACKET_ERRORS + printf ("\n######################## Header Checksum Error %02X %02X %02X %02X\n", + ubcsp_receive_header[0], + ubcsp_receive_header[1], + ubcsp_receive_header[2], + ubcsp_receive_header[3]); +#endif + + /* If we have a header checksum error, send an ack in return + this gets a packet to be resent as quickly as possible */ + + ubcsp_config.send_ack = 1; + + return activity; + } + + /* Decode the received packets header */ + + ubcsp_config.receive_packet->reliable = (ubcsp_receive_header[0] & 0x80) >> 7; + + receive_crc = (ubcsp_receive_header[0] & 0x40) >> 6; + receive_ack = (ubcsp_receive_header[0] & 0x38) >> 3; + receive_seq = (ubcsp_receive_header[0] & 0x07); + + ubcsp_config.receive_packet->channel = (ubcsp_receive_header[1] & 0x0f); + + length = + ((ubcsp_receive_header[1] & 0xf0) >> 4) | + (ubcsp_receive_header[2] << 4); + +#if SHOW_PACKET_ERRORS + if (ubcsp_config.receive_packet->reliable) + { + printf (" : %10d Recv SEQ: %d ACK %d\n", + GetTickCount () % 100000, + receive_seq, + receive_ack); + } + else if (ubcsp_config.receive_packet->channel != 1) + { + printf (" : %10d Recv ACK %d\n", + GetTickCount () % 100000, + receive_ack); + } +#endif + + /* Check for length errors */ + +#if UBCSP_CRC + if (receive_crc) + { + /* If this packet had a CRC, then the length of the payload + should be 2 less than the received size of the payload */ + + if (length + 2 != ubcsp_config.receive_index) + { + /* Slip Length Error */ + +#if SHOW_PACKET_ERRORS + printf ("\n######################## Slip Length Error (With CRC) %d,%d\n", length, ubcsp_config.receive_index - 2); +#endif + + /* If we have a payload length error, send an ack in return + this gets a packet to be resent as quickly as possible */ + + ubcsp_config.send_ack = 1; + return activity; + } + + /* We have a CRC at the end of this packet */ + + ubcsp_config.receive_index -= 2; + + /* Calculate the packet CRC */ + + crc = 0xffff; + + /* CRC the packet header */ + + for (loop = 0; loop < 4; loop ++) + { + crc = ubcsp_calc_crc (ubcsp_receive_header[loop], crc); + } + + /* CRC the packet payload - without the CRC bytes */ + + for (loop = 0; loop < ubcsp_config.receive_index; loop ++) + { + crc = ubcsp_calc_crc (ubcsp_config.receive_packet->payload[loop], crc); + } + + /* Reverse the CRC */ + + crc = ubcsp_crc_reverse (crc); + + /* Check the CRC is correct */ + + if + ( + (((crc & 0xff00) >> 8) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index]) || + ((crc & 0xff) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index + 1]) + ) + { +#if SHOW_PACKET_ERRORS + printf ("\n######################## CRC Error\n"); +#endif + + /* If we have a packet crc error, send an ack in return + this gets a packet to be resent as quickly as possible */ + + ubcsp_config.send_ack = 1; + return activity; + } + } + else + { +#endif + /* No CRC present, so just check the length of payload with that received */ + + if (length != ubcsp_config.receive_index) + { + /* Slip Length Error */ + +#if SHOW_PACKET_ERRORS + printf ("\n######################## Slip Length Error (No CRC) %d,%d\n", length, ubcsp_config.receive_index); +#endif + + /* If we have a payload length error, send an ack in return + this gets a packet to be resent as quickly as possible */ + + ubcsp_config.send_ack = 1; + return activity; + } +#if UBCSP_CRC + } +#endif + + /*** We have a fully formed packet having passed all data integrity checks ***/ + + /* Check if we have an ACK for the last packet we sent */ + + if (receive_ack != ubcsp_config.sequence_number) + { + /* Since we only have a window size of 1, if the ACK is not equal to SEQ + then the packet was sent */ + + if + ( + (ubcsp_config.send_packet) && + (ubcsp_config.send_packet->reliable) + ) + { + /* We had sent a reliable packet, so clear this packet + Then increament the sequence number for the next packet */ + + ubcsp_config.send_packet = 0; + ubcsp_config.sequence_number ++; + ubcsp_config.delay = 0; + + /* Notify the caller that we have SENT a packet */ + + activity |= UBCSP_PACKET_SENT; + } + } + + /*** Now we can concentrate of the packet we have received ***/ + + /* Check for Link Establishment packets */ + + if (ubcsp_config.receive_packet->channel == 1) + { + /* Link Establishment */ + + ubcsp_config.delay = 0; + + /* Find which link establishment packet this payload means + This could return 5, meaning none */ + + switch (ubcsp_which_le_payload (ubcsp_config.receive_packet->payload)) + { + case 0: + { + /* SYNC Recv'd */ + +#if SHOW_LE_STATES + printf ("Recv SYNC\n"); +#endif + + /* If we receive a SYNC, then we respond to it with a SYNC RESP + but only if we are not active. + If we are active, then we have a PEER RESET */ + + if (ubcsp_config.link_establishment_state < ubcsp_le_active) + { + ubcsp_config.link_establishment_resp = 1; + } + else + { + /* Peer reset !!!! */ + +#if SHOW_LE_STATES + printf ("\n\n\n\n\nPEER RESET\n\n"); +#endif + + /* Reinitialize the link */ + + ubcsp_initialize (); + + /* Tell the host what has happened */ + + return UBCSP_PEER_RESET; + } + break; + } + + case 1: + { + /* SYNC RESP Recv'd */ + +#if SHOW_LE_STATES + printf ("Recv SYNC RESP\n"); +#endif + + /* If we receive a SYNC RESP, push us into the initialized state */ + + if (ubcsp_config.link_establishment_state < ubcsp_le_initialized) + { +#if SHOW_LE_STATES + printf ("Link Initialized\n"); +#endif + ubcsp_config.link_establishment_state = ubcsp_le_initialized; + } + + break; + } + + case 2: + { + /* CONF Recv'd */ + +#if SHOW_LE_STATES + printf ("Recv CONF\n"); +#endif + + /* If we receive a CONF, and we are initialized or active + then respond with a CONF RESP */ + + if (ubcsp_config.link_establishment_state >= ubcsp_le_initialized) + { + ubcsp_config.link_establishment_resp = 2; + } + + break; + } + + case 3: + { + /* CONF RESP Recv'd */ + +#if SHOW_LE_STATES + printf ("Recv CONF RESP\n"); +#endif + + /* If we received a CONF RESP, then push us into the active state */ + + if (ubcsp_config.link_establishment_state < ubcsp_le_active) + { +#if SHOW_LE_STATES + printf ("Link Active\n"); +#endif + + ubcsp_config.link_establishment_state = ubcsp_le_active; + ubcsp_config.send_size = 0; + + return activity | UBCSP_PACKET_SENT; + } + + break; + } + } + + /* We have finished processing Link Establishment packets */ + } + else if (ubcsp_config.receive_index) + { + /* We have some payload data we need to process + but only if we are active - otherwise, we just ignore it */ + + if (ubcsp_config.link_establishment_state == ubcsp_le_active) + { + if (ubcsp_config.receive_packet->reliable) + { + /* If the packet we've just received was reliable + then send an ACK */ + + ubcsp_config.send_ack = 1; + + /* We the sequence number we received is the same as + the last ACK we sent, then we have received a packet in sequence */ + + if (receive_seq == ubcsp_config.ack_number) + { + /* Increase the ACK number - which will be sent in the next ACK + or normal packet we send */ + + ubcsp_config.ack_number ++; + + /* Set the values in the receive_packet structure, so the caller + knows how much data we have */ + + ubcsp_config.receive_packet->length = length; + ubcsp_config.receive_packet = 0; + + /* Tell the caller that we have received a packet, and that it + will be ACK'ed */ + + activity |= UBCSP_PACKET_RECEIVED | UBCSP_PACKET_ACK; + } + } + else + { + /* Set the values in the receive_packet structure, so the caller + knows how much data we have */ + + ubcsp_config.receive_packet->length = length; + ubcsp_config.receive_packet = 0; + + /* Tell the caller that we have received a packet */ + + activity |= UBCSP_PACKET_RECEIVED; + } + } + } + + /* Just return any activity that occured */ + + return activity; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_setup_packet **/ +/** **/ +/** This function is called to setup a packet to be sent **/ +/** This allows just a header, or a header and payload to be sent **/ +/** It also allows the header checksum to be precalcuated **/ +/** or calculated here **/ +/** part1 is always 4 bytes **/ +/** **/ +/*****************************************************************************/ + +static void ubcsp_setup_packet (uint8 *part1, uint8 calc, uint8 *part2, uint16 len2) +{ + /* If we need to calculate the checksum, do that now */ + + if (calc) + { + part1[3] = + ~(part1[0] + part1[1] + part1[2]); + } + + /* Setup the header send pointer and size so we can clock this out */ + + ubcsp_config.send_ptr = part1; + ubcsp_config.send_size = 4; + + /* Setup the payload send pointer and size */ + + ubcsp_config.next_send_ptr = part2; + ubcsp_config.next_send_size = len2; + +#if UBCSP_CRC + /* Initialize the crc as required */ + + ubcsp_config.send_crc = -1; + + ubcsp_config.need_send_crc = 1; +#endif +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_sent_packet **/ +/** **/ +/** Called when we have finished sending a packet **/ +/** If this packet was unreliable, then notify caller, and clear the data **/ +/** **/ +/*****************************************************************************/ + +static uint8 ubcsp_sent_packet (void) +{ + if (ubcsp_config.send_packet) + { + if (!ubcsp_config.send_packet->reliable) + { + /* We had a packet sent that was unreliable */ + + /* Forget about this packet */ + + ubcsp_config.send_packet = 0; + + /* Notify caller that they can send another one */ + + return UBCSP_PACKET_SENT; + } + } + + /* We didn't have a packet, or it was reliable + Must wait for ACK before allowing another packet to be sent */ + + return 0; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_poll **/ +/** **/ +/** This is the main function for ubcsp **/ +/** It performs a number of tasks **/ +/** **/ +/** 1) Send another octet to the UART - escaping as required **/ +/** 2) Setup the payload to be sent after the header has been sent **/ +/** 3) Send the CRC for the packet if required **/ +/** **/ +/** 4) Calculate the next Link Establishment State **/ +/** 5) Send a Link Establishment packet **/ +/** 6) Send a normal packet if available **/ +/** 7) Send an ACK packet if required **/ +/** **/ +/** 8) Receive octets from UART and deslip them as required **/ +/** 9) Place received octets into receive header or receive payload buffer **/ +/** 10) Process received packet when SLIP_END is received **/ +/** **/ +/** 11) Keep track of ability of caller to delay recalling **/ +/** **/ +/*****************************************************************************/ + +uint8 ubcsp_poll (uint8 *activity) +{ + uint8 + delay = UBCSP_POLL_TIME_IMMEDIATE; + + uint8 + value; + + /* Assume no activity to start with */ + + *activity = 0; + + /* If we don't have to delay, then send something if we can */ + + if (!ubcsp_config.delay) + { + /* Do we have something we are sending to send */ + + if (ubcsp_config.send_size) + { + /* We have something to send so send it */ + + if (ubcsp_config.send_slip_escape) + { + /* Last time we send a SLIP_ESCAPE octet + this time send the second escape code */ + + put_uart (ubcsp_config.send_slip_escape); + + ubcsp_config.send_slip_escape = 0; + } + else + { +#if UBCSP_CRC + /* get the value to send, and calculate CRC as we go */ + + value = *ubcsp_config.send_ptr ++; + + ubcsp_config.send_crc = ubcsp_calc_crc (value, ubcsp_config.send_crc); + + /* Output the octet */ + + ubcsp_put_slip_uart (value); +#else + /* Just output the octet*/ + + ubcsp_put_slip_uart (*ubcsp_config.send_ptr ++); +#endif + } + + /* If we did output a SLIP_ESCAPE, then don't process the end of a block */ + + if ((!ubcsp_config.send_slip_escape) && ((ubcsp_config.send_size = ubcsp_config.send_size - 1) == 0)) + { + /*** We are at the end of a block - either header or payload ***/ + + /* setup the next block */ + + ubcsp_config.send_ptr = ubcsp_config.next_send_ptr; + ubcsp_config.send_size = ubcsp_config.next_send_size; + ubcsp_config.next_send_ptr = 0; + ubcsp_config.next_send_size = 0; + +#if UBCSP_CRC + /* If we have no successor block + then we might need to send the CRC */ + + if (!ubcsp_config.send_ptr) + { + if (ubcsp_config.need_send_crc) + { + /* reverse the CRC from what we computed along the way */ + + ubcsp_config.need_send_crc = 0; + + ubcsp_config.send_crc = ubcsp_crc_reverse (ubcsp_config.send_crc); + + /* Save in the send_crc buffer */ + + ubcsp_send_crc[0] = (uint8) (ubcsp_config.send_crc >> 8); + ubcsp_send_crc[1] = (uint8) ubcsp_config.send_crc; + + /* Setup to send this buffer */ + + ubcsp_config.send_ptr = ubcsp_send_crc; + ubcsp_config.send_size = 2; + } + else + { + /* We don't need to send the crc + either we just have, or this packet doesn't include it */ + + /* Output the end of FRAME marker */ + + put_uart (SLIP_FRAME); + + /* Check if this is an unreliable packet */ + + *activity |= ubcsp_sent_packet (); + + /* We've sent the packet, so don't need to have be called quickly soon */ + + delay = UBCSP_POLL_TIME_DELAY; + } + } +#else + /* If we have no successor block + then we might need to send the CRC */ + + if (!ubcsp_config.send_ptr) + { + /* Output the end of FRAME marker */ + + put_uart (SLIP_FRAME); + + /* Check if this is an unreliable packet */ + + *activity |= ubcsp_sent_packet (); + + /* We've sent the packet, so don't need to have be called quickly soon */ + + delay = UBCSP_POLL_TIME_DELAY; + } +#endif + } + } + else if (ubcsp_config.link_establishment_packet == ubcsp_le_none) + { + /* We didn't have something to send + AND we have no Link Establishment packet to send */ + + if (ubcsp_config.link_establishment_resp & 2) + { + /* Send the start of FRAME packet */ + + put_uart (SLIP_FRAME); + + /* We did require a RESP packet - so setup the send */ + + ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_le_conf_resp], 4); + + /* We have now "sent" this packet */ + + ubcsp_config.link_establishment_resp = 0; + } + else if (ubcsp_config.send_packet) + { + /* There is a packet ready to be sent */ + + /* Send the start of FRAME packet */ + + put_uart (SLIP_FRAME); + + /* Encode up the packet header using ACK and SEQ numbers */ + + ubcsp_send_header[0] = + (ubcsp_config.send_packet->reliable << 7) | +#if UBCSP_CRC + 0x40 | /* Always use CRC's */ +#endif + (ubcsp_config.ack_number << 3) | + (ubcsp_config.sequence_number); + + /* Encode up the packet header's channel and length */ + ubcsp_send_header[1] = + (ubcsp_config.send_packet->channel & 0x0f) | + ((ubcsp_config.send_packet->length << 4) & 0xf0); + + ubcsp_send_header[2] = + (ubcsp_config.send_packet->length >> 4) & 0xff; + + /* Let the ubcsp_setup_packet function calculate the header checksum */ + + ubcsp_setup_packet ((uint8*) ubcsp_send_header, 1, ubcsp_config.send_packet->payload, ubcsp_config.send_packet->length); + + /* Don't need to send an ACK - we just place on in this packet */ + + ubcsp_config.send_ack = 0; + +#if SHOW_PACKET_ERRORS + printf (" : %10d Send %d Ack %d\n", + GetTickCount () % 100000, + ubcsp_config.sequence_number, + ubcsp_config.ack_number); +#endif + } + else if (ubcsp_config.send_ack) + { + /* Send the start of FRAME packet */ + + put_uart (SLIP_FRAME); + +#if SHOW_PACKET_ERRORS + printf (" : %10d Send ACK %d\n", + GetTickCount () % 100000, + ubcsp_config.ack_number); +#endif + + /* The ack packet is already computed apart from the first octet */ + + ubcsp_send_ack_header[0] = +#if UBCSP_CRC + 0x40 | +#endif + (ubcsp_config.ack_number << 3); + + /* Let the ubcsp_setup_packet function calculate the header checksum */ + + ubcsp_setup_packet (ubcsp_send_ack_header, 1, 0, 0); + + /* We've now sent the ack */ + + ubcsp_config.send_ack = 0; + } + else + { + /* We didn't have a Link Establishment response packet, + a normal packet or an ACK packet to send */ + + delay = UBCSP_POLL_TIME_DELAY; + } + } + else + { +#if SHOW_PACKET_ERRORS +// printf (" : %10d Send LE %d\n", +// GetTickCount () % 100000, +// ubcsp_config.link_establishment_packet); +#endif + + /* Send A Link Establishment Message */ + + put_uart (SLIP_FRAME); + + /* Send the Link Establishment header followed by the + Link Establishment packet */ + + ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_config.link_establishment_packet], 4); + + /* start sending immediately */ + + ubcsp_config.delay = 0; + + /* workout what the next link establishment packet should be */ + + ubcsp_config.link_establishment_packet = next_le_packet[ubcsp_config.link_establishment_state + ubcsp_config.link_establishment_resp * 4]; + + /* We have now delt with any response packet that we needed */ + + ubcsp_config.link_establishment_resp = 0; + + return 0; + } + } + + /* We now need to receive any octets from the UART */ + + while ((ubcsp_config.receive_packet) && (get_uart (&value))) + { + /* If the last octet was SLIP_ESCAPE, then special processing is required */ + + if (ubcsp_config.receive_slip_escape) + { + /* WARNING - out of range values are not detected !!! + This will probably be caught with the checksum or CRC check */ + + value = ubcsp_deslip[value - SLIP_ESCAPE_FRAME]; + + ubcsp_config.receive_slip_escape = 0; + } + else + { + /* Check for the SLIP_FRAME octet - must be start or end of packet */ + if (value == SLIP_FRAME) + { + /* If we had a full header then we have a packet */ + + if (ubcsp_config.receive_index >= 0) + { + /* process the received packet */ + + *activity |= ubcsp_recevied_packet (); + + if (*activity & UBCSP_PACKET_ACK) + { + /* We need to ACK this packet, then don't delay its sending */ + ubcsp_config.delay = 0; + } + } + + /* Setup to receive the next packet */ + + ubcsp_config.receive_index = -4; + + /* Ok, next octet */ + + goto finished_receive; + } + else if (value == SLIP_ESCAPE) + { + /* If we receive a SLIP_ESCAPE, + then remember to process the next special octet */ + + ubcsp_config.receive_slip_escape = 1; + + goto finished_receive; + } + } + + if (ubcsp_config.receive_index < 0) + { + /* We are still receiving the header */ + + ubcsp_receive_header[ubcsp_config.receive_index + 4] = value; + + ubcsp_config.receive_index ++; + } + else if (ubcsp_config.receive_index < ubcsp_config.receive_packet->length) + { + /* We are receiving the payload */ + /* We might stop comming here if we are receiving a + packet which is longer than the receive_packet->length + given by the host */ + + ubcsp_config.receive_packet->payload[ubcsp_config.receive_index] = value; + + ubcsp_config.receive_index ++; + } + +finished_receive: + { + } + } + + if (ubcsp_config.delay > 0) + { + /* We were delayed so delay some more + this could be cancelled if we received something */ + + ubcsp_config.delay --; + } + else + { + /* We had no delay, so use the delay we just decided to us */ + + ubcsp_config.delay = delay; + } + + /* Report the current delay to the user */ + + return ubcsp_config.delay; +} + +/*****************************************************************************/ +/** **/ +/** ubcsp_end_of_functions **/ +/** **/ +/*****************************************************************************/ + +/* This function is only included to allow for the size + of the code to be determined */ + +void ubcsp_end_of_functions (void) +{ +} diff --git a/tools/ubcsp.h b/tools/ubcsp.h new file mode 100644 index 00000000..6a74e9a1 --- /dev/null +++ b/tools/ubcsp.h @@ -0,0 +1,208 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2005 CSR Ltd. + * + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef UBCSP_INCLUDE_H +#define UBCSP_INCLUDE_H + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/** **/ +/** ubcsp.h **/ +/** **/ +/** MicroBCSP - a very low cost implementation of the BCSP protocol **/ +/** **/ +/*****************************************************************************/ + +/* If we wish to use CRC's, then change 0 to 1 in the next line */ +#define UBCSP_CRC 1 + +/* Define some basic types - change these for your architecture */ +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef signed char int8; +typedef signed short int16; +typedef signed int int32; + +/* The defines below require a printf function to be available */ + +/* Do we want to show packet errors in debug output */ +#define SHOW_PACKET_ERRORS 0 + +/* Do we want to show Link Establishment State transitions in debug output */ +#define SHOW_LE_STATES 0 + +/*****************************************************************************/ +/** **/ +/** ubcsp_packet **/ +/** **/ +/** This is description of a bcsp packet for the upper layer **/ +/** **/ +/*****************************************************************************/ + +struct ubcsp_packet +{ + uint8 channel; /* Which Channel this packet is to/from */ + uint8 reliable; /* Is this packet reliable */ + uint8 use_crc; /* Does this packet use CRC data protection */ + uint16 length; /* What is the length of the payload data */ + uint8 *payload; /* The payload data itself - size of length */ +}; + +/*****************************************************************************/ +/** **/ +/** ubcsp_configuration **/ +/** **/ +/** This is the main configuration of the ubcsp engine **/ +/** All state variables are stored in this structure **/ +/** **/ +/*****************************************************************************/ + +enum ubcsp_link_establishment_state +{ + ubcsp_le_uninitialized, + ubcsp_le_initialized, + ubcsp_le_active +}; + +enum ubcsp_link_establishment_packet +{ + ubcsp_le_sync, + ubcsp_le_sync_resp, + ubcsp_le_conf, + ubcsp_le_conf_resp, + ubcsp_le_none +}; + +struct ubcsp_configuration +{ + uint8 link_establishment_state; + uint8 link_establishment_resp; + uint8 link_establishment_packet; + + uint8 sequence_number:3; + uint8 ack_number:3; + uint8 send_ack; + struct ubcsp_packet *send_packet; + struct ubcsp_packet *receive_packet; + + uint8 receive_header_checksum; + uint8 receive_slip_escape; + int32 receive_index; + + uint8 send_header_checksum; +#ifdef UBCSP_CRC + uint8 need_send_crc; + uint16 send_crc; +#endif + uint8 send_slip_escape; + + uint8 *send_ptr; + int32 send_size; + uint8 *next_send_ptr; + int32 next_send_size; + + int8 delay; +}; + +/*****************************************************************************/ +/** **/ +/** ubcsp_poll sets activity from an OR of these flags **/ +/** **/ +/*****************************************************************************/ + +#define UBCSP_PACKET_SENT 0x01 +#define UBCSP_PACKET_RECEIVED 0x02 +#define UBCSP_PEER_RESET 0x04 +#define UBCSP_PACKET_ACK 0x08 + +/*****************************************************************************/ +/** **/ +/** This is the functional interface for ucbsp **/ +/** **/ +/*****************************************************************************/ + +void ubcsp_initialize (void); +void ubcsp_send_packet (struct ubcsp_packet *send_packet); +void ubcsp_receive_packet (struct ubcsp_packet *receive_packet); +uint8 ubcsp_poll (uint8 *activity); + +/*****************************************************************************/ +/** **/ +/** Slip Escape Values **/ +/** **/ +/*****************************************************************************/ + +#define SLIP_FRAME 0xC0 +#define SLIP_ESCAPE 0xDB +#define SLIP_ESCAPE_FRAME 0xDC +#define SLIP_ESCAPE_ESCAPE 0xDD + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ + +/*****************************************************************************/ +/** **/ +/** These functions need to be linked into your system **/ +/** **/ +/*****************************************************************************/ + +/*****************************************************************************/ +/** **/ +/** put_uart outputs a single octet over the UART Tx line **/ +/** **/ +/*****************************************************************************/ + +extern void put_uart (uint8); + +/*****************************************************************************/ +/** **/ +/** get_uart receives a single octet over the UART Rx line **/ +/** if no octet is available, then this returns 0 **/ +/** if an octet was read, then this is returned in the argument and **/ +/** the function returns 1 **/ +/** **/ +/*****************************************************************************/ + +extern uint8 get_uart (uint8 *); + +/*****************************************************************************/ +/** **/ +/** These defines should be changed to your systems concept of 100ms **/ +/** **/ +/*****************************************************************************/ + +#define UBCSP_POLL_TIME_IMMEDIATE 0 +#define UBCSP_POLL_TIME_DELAY 25 + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +#endif -- cgit From ea6747ecff0ec1a738da67c39cae965caab03c5b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Dec 2005 06:31:42 +0000 Subject: Add HCI emulation tool --- test/Makefile.am | 8 +- test/hciemu.c | 1351 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1357 insertions(+), 2 deletions(-) create mode 100644 test/hciemu.c diff --git a/test/Makefile.am b/test/Makefile.am index e63e37be..751fa50c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,8 +1,12 @@ if TEST +sbin_PROGRAMS = hciemu + bin_PROGRAMS = l2test rctest -noinst_PROGRAMS = scotest attest hstest bdaddr +noinst_PROGRAMS = scotest attest hstest bdaddr + +hciemu_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libglib-ectomy.a l2test_LDADD = @BLUEZ_LIBS@ @@ -23,7 +27,7 @@ noinst_MANS = bdaddr.8 AM_CFLAGS = @BLUEZ_CFLAGS@ endif -INCLUDES = -I$(top_srcdir)/tools +INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/tools EXTRA_DIST = hsplay hsmicro bdaddr.8 diff --git a/test/hciemu.c b/test/hciemu.c new file mode 100644 index 00000000..be033c2a --- /dev/null +++ b/test/hciemu.c @@ -0,0 +1,1351 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2002 Maxim Krasnyansky + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "glib-ectomy.h" + +#if __BYTE_ORDER == __LITTLE_ENDIAN +static inline uint64_t ntoh64(uint64_t n) +{ + uint64_t h; + uint64_t tmp = ntohl(n & 0x00000000ffffffff); + h = ntohl(n >> 32); + h |= tmp << 32; + return h; +} +#elif __BYTE_ORDER == __BIG_ENDIAN +#define ntoh64(x) (x) +#else +#error "Unknown byte order" +#endif +#define hton64(x) ntoh64(x) + +#define GHCI_DEV "/dev/ghci" + +#define VHCI_DEV "/dev/vhci" +#define VHCI_UDEV "/dev/hci_vhci" + +#define VHCI_MAX_CONN 12 + +#define VHCI_ACL_MTU 192 +#define VHCI_ACL_MAX_PKT 8 + +struct vhci_device { + uint8_t features[8]; + uint8_t name[248]; + uint8_t dev_class[3]; + uint8_t inq_mode; + uint8_t eir_fec; + uint8_t eir_data[240]; + uint16_t acl_cnt; + bdaddr_t bdaddr; + int fd; + int dd; + GIOChannel *scan; +}; + +struct vhci_conn { + bdaddr_t dest; + uint16_t handle; + GIOChannel *chan; +}; + +struct vhci_link_info { + bdaddr_t bdaddr; + uint8_t dev_class[3]; + uint8_t link_type; + uint8_t role; +} __attribute__ ((packed)); + +static struct vhci_device vdev; +static struct vhci_conn *vconn[VHCI_MAX_CONN]; + +struct btsnoop_hdr { + uint8_t id[8]; /* Identification Pattern */ + uint32_t version; /* Version Number = 1 */ + uint32_t type; /* Datalink Type */ +} __attribute__ ((packed)); +#define BTSNOOP_HDR_SIZE (sizeof(struct btsnoop_hdr)) + +struct btsnoop_pkt { + uint32_t size; /* Original Length */ + uint32_t len; /* Included Length */ + uint32_t flags; /* Packet Flags */ + uint32_t drops; /* Cumulative Drops */ + uint64_t ts; /* Timestamp microseconds */ + uint8_t data[0]; /* Packet Data */ +} __attribute__ ((packed)); +#define BTSNOOP_PKT_SIZE (sizeof(struct btsnoop_pkt)) + +static uint8_t btsnoop_id[] = { 0x62, 0x74, 0x73, 0x6e, 0x6f, 0x6f, 0x70, 0x00 }; + +static GMainLoop *event_loop; + +static volatile sig_atomic_t __io_canceled; + +static inline void io_init(void) +{ + __io_canceled = 0; +} + +static inline void io_cancel(void) +{ + __io_canceled = 1; +} + +static void sig_term(int sig) +{ + io_cancel(); + g_main_quit(event_loop); +} + +static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data); +static gboolean io_conn_ind(GIOChannel *chan, GIOCondition cond, gpointer data); +static gboolean io_hci_data(GIOChannel *chan, GIOCondition cond, gpointer data); + +static inline int read_n(int fd, void *buf, int len) +{ + register int w, t = 0; + + while (!__io_canceled && len > 0) { + if ((w = read(fd, buf, len)) < 0 ){ + if( errno == EINTR || errno == EAGAIN ) + continue; + return -1; + } + if (!w) + return 0; + len -= w; buf += w; t += w; + } + return t; +} + +/* Write exactly len bytes (Signal safe)*/ +static inline int write_n(int fd, void *buf, int len) +{ + register int w, t = 0; + + while (!__io_canceled && len > 0) { + if ((w = write(fd, buf, len)) < 0 ){ + if( errno == EINTR || errno == EAGAIN ) + continue; + return -1; + } + if (!w) + return 0; + len -= w; buf += w; t += w; + } + return t; +} + +static int create_snoop(char *file) +{ + struct btsnoop_hdr hdr; + int fd, len; + + fd = open(file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) + return fd; + + memcpy(hdr.id, btsnoop_id, sizeof(btsnoop_id)); + hdr.version = htonl(1); + hdr.type = htonl(1002); + + len = write(fd, &hdr, BTSNOOP_HDR_SIZE); + if (len < 0) { + close(fd); + return -EIO; + } + + if (len != BTSNOOP_HDR_SIZE) { + close(fd); + return -1; + } + + return fd; +} + +static int write_snoop(int fd, int type, int incoming, unsigned char *buf, int len) +{ + struct btsnoop_pkt pkt; + struct timeval tv; + uint32_t size = len; + uint64_t ts; + + if (fd < 0) + return -1; + + memset(&tv, 0, sizeof(tv)); + gettimeofday(&tv, NULL); + ts = (tv.tv_sec - 946684800ll) * 1000000ll + tv.tv_usec; + + pkt.size = htonl(size); + pkt.len = pkt.size; + pkt.flags = ntohl(incoming & 0x01); + pkt.drops = htonl(0); + pkt.ts = hton64(ts + 0x00E03AB44A676000ll); + + if (type == HCI_COMMAND_PKT || type == HCI_EVENT_PKT) + pkt.flags |= ntohl(0x02); + + write(fd, &pkt, BTSNOOP_PKT_SIZE); + write(fd, buf, size); + + return 0; +} + +static struct vhci_conn *conn_get_by_bdaddr(bdaddr_t *ba) +{ + register int i; + + for (i = 0; i < VHCI_MAX_CONN; i++) + if (!bacmp(&vconn[i]->dest, ba)) + return vconn[i]; + + return NULL; +} + +static void command_status(uint16_t ogf, uint16_t ocf, uint8_t status) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_cmd_status *cs; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_CMD_STATUS; + he->plen = EVT_CMD_STATUS_SIZE; + + cs = (void *) ptr; ptr += EVT_CMD_STATUS_SIZE; + + cs->status = status; + cs->ncmd = 1; + cs->opcode = htobs(cmd_opcode_pack(ogf, ocf)); + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s(%d)", + strerror(errno), errno); +} + +static void command_complete(uint16_t ogf, uint16_t ocf, int plen, void *data) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_cmd_complete *cc; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_CMD_COMPLETE; + he->plen = EVT_CMD_COMPLETE_SIZE + plen; + + cc = (void *) ptr; ptr += EVT_CMD_COMPLETE_SIZE; + + cc->ncmd = 1; + cc->opcode = htobs(cmd_opcode_pack(ogf, ocf)); + + if (plen) { + memcpy(ptr, data, plen); + ptr += plen; + } + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s(%d)", + strerror(errno), errno); +} + +static void connect_request(struct vhci_conn *conn) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_conn_request *cr; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_CONN_REQUEST; + he->plen = EVT_CONN_REQUEST_SIZE; + + cr = (void *) ptr; ptr += EVT_CONN_REQUEST_SIZE; + + bacpy(&cr->bdaddr, &conn->dest); + memset(&cr->dev_class, 0, sizeof(cr->dev_class)); + cr->link_type = ACL_LINK; + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s (%d)", + strerror(errno), errno); +} + +static void connect_complete(struct vhci_conn *conn) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_conn_complete *cc; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_CONN_COMPLETE; + he->plen = EVT_CONN_COMPLETE_SIZE; + + cc = (void *) ptr; ptr += EVT_CONN_COMPLETE_SIZE; + + bacpy(&cc->bdaddr, &conn->dest); + cc->status = 0x00; + cc->handle = htobs(conn->handle); + cc->link_type = ACL_LINK; + cc->encr_mode = 0x00; + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s (%d)", + strerror(errno), errno); +} + +static void disconn_complete(struct vhci_conn *conn) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_disconn_complete *dc; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_DISCONN_COMPLETE; + he->plen = EVT_DISCONN_COMPLETE_SIZE; + + dc = (void *) ptr; ptr += EVT_DISCONN_COMPLETE_SIZE; + + dc->status = 0x00; + dc->handle = htobs(conn->handle); + dc->reason = 0x00; + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s (%d)", + strerror(errno), errno); + + vdev.acl_cnt = 0; +} + +static void num_completed_pkts(struct vhci_conn *conn) +{ + uint8_t buf[HCI_MAX_FRAME_SIZE], *ptr = buf; + evt_num_comp_pkts *np; + hci_event_hdr *he; + + /* Packet type */ + *ptr++ = HCI_EVENT_PKT; + + /* Event header */ + he = (void *) ptr; ptr += HCI_EVENT_HDR_SIZE; + + he->evt = EVT_NUM_COMP_PKTS; + he->plen = EVT_NUM_COMP_PKTS_SIZE; + + np = (void *) ptr; ptr += EVT_NUM_COMP_PKTS_SIZE; + np->num_hndl = 1; + + *((uint16_t *) ptr) = htobs(conn->handle); ptr += 2; + *((uint16_t *) ptr) = htobs(vdev.acl_cnt); ptr += 2; + + write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf); + + if (write(vdev.fd, buf, ptr - buf) < 0) + syslog(LOG_ERR, "Can't send event: %s (%d)", + strerror(errno), errno); +} + +static int scan_enable(uint8_t *data) +{ + struct sockaddr_in sa; + GIOChannel *sk_io; + bdaddr_t ba; + int sk, opt; + + if (!(*data & SCAN_PAGE)) { + if (vdev.scan) { + g_io_channel_close(vdev.scan); + vdev.scan = NULL; + } + return 0; + } + + if (vdev.scan) + return 0; + + if ((sk = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); + return 1; + } + + opt = 1; + setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + baswap(&ba, &vdev.bdaddr); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = *(uint32_t *) &ba; + sa.sin_port = *(uint16_t *) &ba.b[4]; + if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + goto failed; + } + + if (listen(sk, 10)) { + syslog(LOG_ERR, "Can't listen on socket: %s (%d)", + strerror(errno), errno); + goto failed; + } + + sk_io = g_io_channel_unix_new(sk); + g_io_add_watch(sk_io, G_IO_IN | G_IO_NVAL, io_conn_ind, NULL); + vdev.scan = sk_io; + return 0; + +failed: + close(sk); + return 1; +} + +static void accept_connection(uint8_t *data) +{ + accept_conn_req_cp *cp = (void *) data; + struct vhci_conn *conn; + + if (!(conn = conn_get_by_bdaddr(&cp->bdaddr))) + return; + + connect_complete(conn); + + g_io_add_watch(conn->chan, G_IO_IN | G_IO_NVAL | G_IO_HUP, + io_acl_data, (gpointer) conn); +} + +static void close_connection(struct vhci_conn *conn) +{ + syslog(LOG_INFO, "Closing connection %s handle %d", + batostr(&conn->dest), conn->handle); + + g_io_channel_close(conn->chan); + + vconn[conn->handle - 1] = NULL; + disconn_complete(conn); + free(conn); +} + +static void disconnect(uint8_t *data) +{ + disconnect_cp *cp = (void *) data; + struct vhci_conn *conn; + uint16_t handle; + + handle = btohs(cp->handle); + + if (handle - 1 > VHCI_MAX_CONN) + return; + + if (!(conn = vconn[handle-1])) + return; + + close_connection(conn); +} + +static void create_connection(uint8_t *data) +{ + create_conn_cp *cp = (void *) data; + struct vhci_link_info info; + struct vhci_conn *conn; + struct sockaddr_in sa; + int h, sk, opt; + bdaddr_t ba; + + for (h = 0; h < VHCI_MAX_CONN; h++) + if (!vconn[h]) + goto do_connect; + + syslog(LOG_ERR, "Too many connections"); + return; + +do_connect: + if ((sk = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + syslog(LOG_ERR, "Can't create socket: %s (%d)", + strerror(errno), errno); + return; + } + + opt = 1; + setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + baswap(&ba, &vdev.bdaddr); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = INADDR_ANY; // *(uint32_t *) &ba; + sa.sin_port = 0; // *(uint16_t *) &ba.b[4]; + if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) { + syslog(LOG_ERR, "Can't bind socket: %s (%d)", + strerror(errno), errno); + close(sk); + return; + } + + baswap(&ba, &cp->bdaddr); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = *(uint32_t *) &ba; + sa.sin_port = *(uint16_t *) &ba.b[4]; + if (connect(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0) { + syslog(LOG_ERR, "Can't connect: %s (%d)", + strerror(errno), errno); + close(sk); + return; + } + + /* Send info */ + memset(&info, 0, sizeof(info)); + bacpy(&info.bdaddr, &vdev.bdaddr); + info.link_type = ACL_LINK; + info.role = 1; + write_n(sk, (void *) &info, sizeof(info)); + + if (!(conn = malloc(sizeof(*conn)))) { + syslog(LOG_ERR, "Can't alloc new connection: %s (%d)", + strerror(errno), errno); + close(sk); + return; + } + + memcpy((uint8_t *) &ba, (uint8_t *) &sa.sin_addr, 4); + memcpy((uint8_t *) &ba.b[4], (uint8_t *) &sa.sin_port, 2); + baswap(&conn->dest, &ba); + + vconn[h] = conn; + conn->handle = h + 1; + conn->chan = g_io_channel_unix_new(sk); + + connect_complete(conn); + g_io_add_watch(conn->chan, G_IO_IN | G_IO_NVAL | G_IO_HUP, + io_acl_data, (gpointer) conn); + return; +} + +static void inline hci_link_control(uint16_t ocf, int plen, uint8_t *data) +{ + uint8_t status; + + const uint16_t ogf = OGF_LINK_CTL; + + switch (ocf) { + case OCF_CREATE_CONN: + command_status(ogf, ocf, 0x00); + create_connection(data); + break; + + case OCF_ACCEPT_CONN_REQ: + command_status(ogf, ocf, 0x00); + accept_connection(data); + break; + + case OCF_DISCONNECT: + command_status(ogf, ocf, 0x00); + disconnect(data); + break; + + default: + status = 0x01; + command_complete(ogf, ocf, 1, &status); + break; + } +} + +static void inline hci_link_policy(uint16_t ocf, int plen, uint8_t *data) +{ + uint8_t status; + + const uint16_t ogf = OGF_INFO_PARAM; + + switch (ocf) { + default: + status = 0x01; + command_complete(ogf, ocf, 1, &status); + break; + } +} + +static void inline hci_host_control(uint16_t ocf, int plen, uint8_t *data) +{ + read_local_name_rp ln; + read_class_of_dev_rp cd; + read_inquiry_mode_rp im; + read_ext_inquiry_response_rp ir; + uint8_t status; + + const uint16_t ogf = OGF_HOST_CTL; + + switch (ocf) { + case OCF_RESET: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_SET_EVENT_FLT: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_CHANGE_LOCAL_NAME: + status = 0x00; + memcpy(vdev.name, data, sizeof(vdev.name)); + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_READ_LOCAL_NAME: + ln.status = 0x00; + memcpy(ln.name, vdev.name, sizeof(ln.name)); + command_complete(ogf, ocf, sizeof(ln), &ln); + break; + + case OCF_WRITE_CONN_ACCEPT_TIMEOUT: + case OCF_WRITE_PAGE_TIMEOUT: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_WRITE_SCAN_ENABLE: + status = scan_enable(data); + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_WRITE_AUTH_ENABLE: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_WRITE_ENCRYPT_MODE: + status = 0x00; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_READ_CLASS_OF_DEV: + cd.status = 0x00; + memcpy(cd.dev_class, vdev.dev_class, 3); + command_complete(ogf, ocf, sizeof(cd), &cd); + break; + + case OCF_WRITE_CLASS_OF_DEV: + status = 0x00; + memcpy(vdev.dev_class, data, 3); + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_READ_INQUIRY_MODE: + im.status = 0x00; + im.mode = vdev.inq_mode; + command_complete(ogf, ocf, sizeof(im), &im); + break; + + case OCF_WRITE_INQUIRY_MODE: + status = 0x00; + vdev.inq_mode = data[0]; + command_complete(ogf, ocf, 1, &status); + break; + + case OCF_READ_EXT_INQUIRY_RESPONSE: + ir.status = 0x00; + ir.fec = vdev.eir_fec; + memcpy(ir.data, vdev.eir_data, 240); + command_complete(ogf, ocf, sizeof(ir), &ir); + break; + + case OCF_WRITE_EXT_INQUIRY_RESPONSE: + status = 0x00; + vdev.eir_fec = data[0]; + memcpy(vdev.eir_data, data + 1, 240); + command_complete(ogf, ocf, 1, &status); + break; + + default: + status = 0x01; + command_complete(ogf, ocf, 1, &status); + break; + } +} + +static void inline hci_info_param(uint16_t ocf, int plen, uint8_t *data) +{ + read_local_version_rp lv; + read_local_features_rp lf; + read_local_ext_features_rp ef; + read_buffer_size_rp bs; + read_bd_addr_rp ba; + uint8_t status; + + const uint16_t ogf = OGF_INFO_PARAM; + + switch (ocf) { + case OCF_READ_LOCAL_VERSION: + lv.status = 0x00; + lv.hci_ver = 0x03; + lv.hci_rev = htobs(0x0000); + lv.lmp_ver = 0x03; + lv.manufacturer = htobs(29); + lv.lmp_subver = htobs(0x0000); + command_complete(ogf, ocf, sizeof(lv), &lv); + break; + + case OCF_READ_LOCAL_FEATURES: + lf.status = 0x00; + memcpy(lf.features, vdev.features, 8); + command_complete(ogf, ocf, sizeof(lf), &lf); + break; + + case OCF_READ_LOCAL_EXT_FEATURES: + ef.status = 0x00; + if (*data == 0) { + ef.page_num = 0; + ef.max_page_num = 0; + memcpy(ef.features, vdev.features, 8); + } else { + ef.page_num = *data; + ef.max_page_num = 0; + memset(ef.features, 0, 8); + } + command_complete(ogf, ocf, sizeof(ef), &ef); + break; + + case OCF_READ_BUFFER_SIZE: + bs.status = 0x00; + bs.acl_mtu = htobs(VHCI_ACL_MTU); + bs.sco_mtu = 0; + bs.acl_max_pkt = htobs(VHCI_ACL_MAX_PKT); + bs.sco_max_pkt = htobs(0); + command_complete(ogf, ocf, sizeof(bs), &bs); + break; + + case OCF_READ_BD_ADDR: + ba.status = 0x00; + bacpy(&ba.bdaddr, &vdev.bdaddr); + command_complete(ogf, ocf, sizeof(ba), &ba); + break; + + default: + status = 0x01; + command_complete(ogf, ocf, 1, &status); + break; + } +} + +static void hci_command(uint8_t *data) +{ + hci_command_hdr *ch; + uint8_t *ptr = data; + uint16_t ogf, ocf; + + ch = (hci_command_hdr *) ptr; + ptr += HCI_COMMAND_HDR_SIZE; + + ch->opcode = btohs(ch->opcode); + ogf = cmd_opcode_ogf(ch->opcode); + ocf = cmd_opcode_ocf(ch->opcode); + + switch (ogf) { + case OGF_LINK_CTL: + hci_link_control(ocf, ch->plen, ptr); + break; + + case OGF_LINK_POLICY: + hci_link_policy(ocf, ch->plen, ptr); + break; + + case OGF_HOST_CTL: + hci_host_control(ocf, ch->plen, ptr); + break; + + case OGF_INFO_PARAM: + hci_info_param(ocf, ch->plen, ptr); + break; + } +} + +static void hci_acl_data(uint8_t *data) +{ + hci_acl_hdr *ah = (void *) data; + struct vhci_conn *conn; + uint16_t handle; + int fd; + + handle = acl_handle(btohs(ah->handle)); + + if (handle > VHCI_MAX_CONN || !(conn = vconn[handle - 1])) { + syslog(LOG_ERR, "Bad connection handle %d", handle); + return; + } + + fd = g_io_channel_unix_get_fd(conn->chan); + if (write_n(fd, data, btohs(ah->dlen) + HCI_ACL_HDR_SIZE) < 0) { + close_connection(conn); + return; + } + + if (++vdev.acl_cnt > VHCI_ACL_MAX_PKT - 1) { + /* Send num of complete packets event */ + num_completed_pkts(conn); + vdev.acl_cnt = 0; + } +} + +static gboolean io_acl_data(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + struct vhci_conn *conn = (struct vhci_conn *) data; + unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; + hci_acl_hdr *ah; + uint16_t flags; + int len, fd; + + if (cond & G_IO_NVAL) + return FALSE; + + if (cond & G_IO_HUP) { + close_connection(conn); + return FALSE; + } + + fd = g_io_channel_unix_get_fd(chan); + + ptr = buf + 1; + if (read_n(fd, ptr, HCI_ACL_HDR_SIZE) <= 0) { + close_connection(conn); + return FALSE; + } + + ah = (void *) ptr; + ptr += HCI_ACL_HDR_SIZE; + + len = btohs(ah->dlen); + if (read_n(fd, ptr, len) <= 0) { + close_connection(conn); + return FALSE; + } + + buf[0] = HCI_ACLDATA_PKT; + + flags = acl_flags(btohs(ah->handle)); + ah->handle = htobs(acl_handle_pack(conn->handle, flags)); + len += HCI_ACL_HDR_SIZE + 1; + + write_snoop(vdev.dd, HCI_ACLDATA_PKT, 1, buf, len); + + write(vdev.fd, buf, len); + + return TRUE; +} + +static gboolean io_conn_ind(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + struct vhci_link_info info; + struct vhci_conn *conn; + struct sockaddr_in sa; + socklen_t len; + int sk, nsk, h; + + if (cond & G_IO_NVAL) + return FALSE; + + sk = g_io_channel_unix_get_fd(chan); + + len = sizeof(sa); + if ((nsk = accept(sk, (struct sockaddr *) &sa, &len)) < 0) + return TRUE; + + if (read_n(nsk, &info, sizeof(info)) < 0) { + syslog(LOG_ERR, "Can't read link info"); + return TRUE; + } + + if (!(conn = malloc(sizeof(*conn)))) { + syslog(LOG_ERR, "Can't alloc new connection"); + close(nsk); + return TRUE; + } + + bacpy(&conn->dest, &info.bdaddr); + + for (h = 0; h < VHCI_MAX_CONN; h++) + if (!vconn[h]) + goto accepted; + + syslog(LOG_ERR, "Too many connections"); + free(conn); + close(nsk); + return TRUE; + +accepted: + vconn[h] = conn; + conn->handle = h + 1; + conn->chan = g_io_channel_unix_new(nsk); + connect_request(conn); + + return TRUE; +} + +static gboolean io_hci_data(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; + int type; + gsize len; + GIOError err; + + ptr = buf; + + if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { + if (err == G_IO_ERROR_AGAIN) + return TRUE; + + syslog(LOG_ERR, "Read failed: %s (%d)", strerror(errno), errno); + g_main_quit(event_loop); + return FALSE; + } + + type = *ptr++; + + write_snoop(vdev.dd, type, 0, buf, len); + + switch (type) { + case HCI_COMMAND_PKT: + hci_command(ptr); + break; + + case HCI_ACLDATA_PKT: + hci_acl_data(ptr); + break; + + default: + syslog(LOG_ERR, "Unknown packet type 0x%2.2x", type); + break; + } + + return TRUE; +} + +static int getbdaddrbyname(char *str, bdaddr_t *ba) +{ + int i, n, len; + + len = strlen(str); + + /* Check address format */ + for (i = 0, n = 0; i < len; i++) + if (str[i] == ':') + n++; + + if (n == 5) { + /* BD address */ + baswap(ba, strtoba(str)); + return 0; + } + + if (n == 1) { + /* IP address + port */ + struct hostent *hent; + bdaddr_t b; + char *ptr; + + ptr = strchr(str, ':'); + *ptr++ = 0; + + if (!(hent = gethostbyname(str))) { + fprintf(stderr, "Can't resolve %s\n", str); + return -2; + } + + memcpy(&b, hent->h_addr, 4); + *(uint16_t *) (&b.b[4]) = htons(atoi(ptr)); + baswap(ba, &b); + + return 0; + } + + fprintf(stderr, "Invalid address format\n"); + + return -1; +} + +static void rewrite_bdaddr(unsigned char *buf, int len, bdaddr_t *bdaddr) +{ + hci_event_hdr *eh; + unsigned char *ptr = buf; + int type; + + if (!bdaddr) + return; + + if (!bacmp(bdaddr, BDADDR_ANY)) + return; + + type = *ptr++; + + switch (type) { + case HCI_EVENT_PKT: + eh = (hci_event_hdr *) ptr; + ptr += HCI_EVENT_HDR_SIZE; + + if (eh->evt == EVT_CMD_COMPLETE) { + evt_cmd_complete *cc = (void *) ptr; + + ptr += EVT_CMD_COMPLETE_SIZE; + + if (cc->opcode == htobs(cmd_opcode_pack(OGF_INFO_PARAM, + OCF_READ_BD_ADDR))) { + bacpy((bdaddr_t *) (ptr + 1), bdaddr); + } + } + break; + } +} + +static int run_proxy(int fd, int dev, bdaddr_t *bdaddr) +{ + unsigned char buf[HCI_MAX_FRAME_SIZE + 1]; + struct hci_dev_info di; + struct hci_filter flt; + struct pollfd p[2]; + int dd, err, len, need_raw; + + dd = hci_open_dev(dev); + if (dd < 0) { + syslog(LOG_ERR, "Can't open device hci%d: %s (%d)", + dev, strerror(errno), errno); + return 1; + } + + if (hci_devinfo(dev, &di) < 0) { + syslog(LOG_ERR, "Can't get device info for hci%d: %s (%d)", + dev, strerror(errno), errno); + hci_close_dev(dd); + return 1; + } + + need_raw = !hci_test_bit(HCI_RAW, &di.flags); + + hci_filter_clear(&flt); + hci_filter_all_ptypes(&flt); + hci_filter_all_events(&flt); + + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { + syslog(LOG_ERR, "Can't set filter for hci%d: %s (%d)", + dev, strerror(errno), errno); + hci_close_dev(dd); + return 1; + } + + if (need_raw) { + if (ioctl(dd, HCISETRAW, 1) < 0) { + syslog(LOG_ERR, "Can't set raw mode on hci%d: %s (%d)", + dev, strerror(errno), errno); + hci_close_dev(dd); + return 1; + } + } + + p[0].fd = fd; + p[0].events = POLLIN; + p[1].fd = dd; + p[1].events = POLLIN; + + while (!__io_canceled) { + p[0].revents = 0; + p[1].revents = 0; + err = poll(p, 2, 100); + if (err < 0) + break; + if (!err) + continue; + + if (p[0].revents & POLLIN) { + len = read(fd, buf, sizeof(buf)); + if (len > 0) { + rewrite_bdaddr(buf, len, bdaddr); + write(dd, buf, len); + } + } + + if (p[1].revents & POLLIN) { + len = read(dd, buf, sizeof(buf)); + if (len > 0) { + rewrite_bdaddr(buf, len, bdaddr); + write(fd, buf, len); + } + } + } + + if (need_raw) { + if (ioctl(dd, HCISETRAW, 0) < 0) + syslog(LOG_ERR, "Can't clear raw mode on hci%d: %s (%d)", + dev, strerror(errno), errno); + } + + hci_close_dev(dd); + + syslog(LOG_INFO, "Exit"); + + return 0; +} + +static void usage(void) +{ + printf("hciemu - HCI emulator ver %s\n", VERSION); + printf("Usage: \n"); + printf("\thciemu [-n] local_address\n"); +} + +static struct option main_options[] = { + { "device", 1, 0, 'd' }, + { "bdaddr", 1, 0, 'b' }, + { "snoop", 1, 0, 's' }, + { "nodetach", 0, 0, 'n' }, + { "help", 0, 0, 'h' }, + { 0 } +}; + +int main(int argc, char *argv[], char *env[]) +{ + struct sigaction sa; + GIOChannel *dev_io; + char *device = NULL, *snoop = NULL; + bdaddr_t bdaddr; + int fd, dd, opt, daemon, dofork, dev = -1; + + bacpy(&bdaddr, BDADDR_ANY); + + /* Configure default settings */ + daemon = 1; dofork = 1; + + while ((opt=getopt_long(argc, argv, "d:b:s:nh", main_options, NULL)) != EOF) { + switch(opt) { + case 'd': + device = strdup(optarg); + break; + + case 'b': + str2ba(optarg, &bdaddr); + break; + + case 's': + snoop = strdup(optarg); + break; + + case 'n': + daemon = 0; + break; + + case 'h': + default: + usage(); + exit(0); + } + } + + argc -= optind; + argv += optind; + optind = 0; + + if (argc < 1) { + usage(); + exit(1); + } + + if (strlen(argv[0]) > 3 && !strncasecmp(argv[0], "hci", 3)) { + dev = hci_devid(argv[0]); + if (dev < 0) { + perror("Invalid device"); + exit(1); + } + } else { + if (getbdaddrbyname(argv[0], &vdev.bdaddr) < 0) + exit(1); + } + + if (daemon) { + if (dofork && fork()) + exit(0); + + /* Direct stdin,stdout,stderr to '/dev/null' */ + fd = open("/dev/null", O_RDWR); + dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); + close(fd); + + setsid(); + + chdir("/"); + } + + /* Start logging to syslog and stderr */ + openlog("hciemu", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); + syslog(LOG_INFO, "HCI emulation daemon ver %s started", VERSION); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + io_init(); + + if (!device && dev >= 0) + device = strdup(GHCI_DEV); + + /* Open and create virtual HCI device */ + if (device) { + fd = open(device, O_RDWR); + if (fd < 0) { + syslog(LOG_ERR, "Can't open device %s: %s (%d)", + device, strerror(errno), errno); + free(device); + exit(1); + } + free(device); + } else { + fd = open(VHCI_DEV, O_RDWR); + if (fd < 0) { + fd = open(VHCI_UDEV, O_RDWR); + if (fd < 0) { + syslog(LOG_ERR, "Can't open device %s: %s (%d)", + VHCI_DEV, strerror(errno), errno); + exit(1); + } + } + } + + /* Create snoop file */ + if (snoop) { + dd = create_snoop(snoop); + if (dd < 0) + syslog(LOG_ERR, "Can't create snoop file %s: %s (%d)", + snoop, strerror(errno), errno); + free(snoop); + } else + dd = -1; + + /* Create event loop */ + event_loop = g_main_new(FALSE); + + if (dev >= 0) + return run_proxy(fd, dev, &bdaddr); + + /* Device settings */ + vdev.features[0] = 0xff; + vdev.features[1] = 0xff; + vdev.features[2] = 0x8f; + vdev.features[3] = 0xfe; + vdev.features[4] = 0x9b; + vdev.features[5] = 0xf9; + vdev.features[6] = 0x01; + vdev.features[7] = 0x80; + + memset(vdev.name, 0, sizeof(vdev.name)); + strncpy((char *) vdev.name, "BlueZ (Virtual HCI)", sizeof(vdev.name)); + + vdev.dev_class[0] = 0x00; + vdev.dev_class[1] = 0x00; + vdev.dev_class[2] = 0x00; + + vdev.inq_mode = 0x00; + vdev.eir_fec = 0x00; + memset(vdev.eir_data, 0, sizeof(vdev.eir_data)); + + vdev.fd = fd; + vdev.dd = dd; + + dev_io = g_io_channel_unix_new(fd); + g_io_add_watch(dev_io, G_IO_IN, io_hci_data, NULL); + + setpriority(PRIO_PROCESS, 0, -19); + + /* Start event processor */ + g_main_run(event_loop); + + close(fd); + + if (dd >= 0) + close(dd); + + syslog(LOG_INFO, "Exit"); + + return 0; +} -- cgit From 57580b1b9cd64d823f3843c556cabd9856b8f86f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 6 Dec 2005 20:52:03 +0000 Subject: Update manual page of bccmd tool --- tools/bccmd.8 | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/tools/bccmd.8 b/tools/bccmd.8 index 58e8814f..82727009 100644 --- a/tools/bccmd.8 +++ b/tools/bccmd.8 @@ -1,26 +1,45 @@ -.TH BCCMD 8 "Sep 30 2005" BlueZ "Linux System Administration" +.TH BCCMD 8 "Dec 6 2005" BlueZ "Linux System Administration" .SH NAME bccmd \- Utility for the CSR BCCMD interface .SH SYNOPSIS .B bccmd .br -.B bccmd [-i ] +.B bccmd [-t ] [-d ] [] +.br +.B bccmd [-h --help] .br - .SH DESCRIPTION -.LP .B bccmd issues BlueCore commands to .B Cambridge Silicon Radio -devices. If run without the argument, a short help page will be diaplayed. -.PP - +devices. If run without the argument, a short help page will be displayed. .SH OPTIONS .TP -.BI -i\ -Specify a particular device to operate on. If not specified, default is the first available device. +.BI -t\ +Specify the communication transport. Valid options are: +.RS +.TP +.BI HCI +Local device with Host Controller Interface (default). +.TP +.BI USB +Direct USB connection. +.TP +.BI BCSP +Blue Core Serial Protocol. +.TP +.BI H4 +H4 serial protocol. +.TP +.BI 3WIRE +3WIRE protocol (not implemented). +.SH +.TP +.BI -d\ +Specify a particular device to operate on. If not specified, default is the first available HCI device +or /dev/ttyS0 for serial transports. .SH COMMANDS .TP .BI builddef @@ -35,6 +54,9 @@ Get local Bluetooth clock .BI rand Get random number .TP +.BI buildname +Get the full build name +.TP .BI panicarg Get panic code argument .TP @@ -52,6 +74,34 @@ Disable TX on the device .TP .BI enabletx Enable TX on the device +.TP +.BI memtypes +Get memory types +.TP +.BI psget\ +Get value for PS key +.TP +.BI psset\ \ +Set value for PS key +.TP +.BI psclr\ +Clear value for PS key +.TP +.BI pslist +List all PS keys +.TP +.BI psread +Read all PS keys +.TP +.BI psload\ +Load all PS keys from PSR file +.TP +.BI pscheck\ +Check syntax of PSR file +.SH KEYS +bdaddr country devclass keymin keymax features commands version +remver hciextn mapsco baudrate hostintf anafreq anaftrim usbvid +usbpid dfupid bootmode .SH AUTHORS Written by Marcel Holtmann , man page by Adam Laurie -- cgit From 27454e3869df7f30ba170fefc17018fa07b5d194 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Dec 2005 09:04:58 +0000 Subject: Update the Silicon Wave init routine --- tools/hciattach.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/hciattach.c b/tools/hciattach.c index bcdad95b..d0e03cce 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -648,7 +648,7 @@ static int csr(int fd, struct uart_t *u, struct termios *ti) */ static int swave(int fd, struct uart_t *u, struct termios *ti) { - struct timespec tm = {0, 500000}; + struct timespec tm = { 0, 500000 }; char cmd[10], rsp[100]; int r; @@ -688,7 +688,7 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) } /* Send initialization command */ - if (write(fd, cmd, 9) != 9) { + if (write(fd, cmd, 10) != 10) { perror("Failed to write init command"); return -1; } @@ -720,15 +720,16 @@ static int swave(int fd, struct uart_t *u, struct termios *ti) return -1; } - // we probably got the reply. Now we must send the "soft reset": + // we probably got the reply. Now we must send the "soft reset" + // which is standard HCI RESET. + cmd[0] = HCI_COMMAND_PKT; // it's a command packet - cmd[1] = 0x0B; // OCF 0x0B = param access set - cmd[2] = 0xfc; // OGF bx111111 = vendor specific - cmd[3] = 0x01; // 1 byte of data following - cmd[4] = 0x03; // HCI Reset Subcommand - - // Send initialization command - if (write(fd, cmd, 5) != 5) { + cmd[1] = 0x03; + cmd[2] = 0x0c; + cmd[3] = 0x00; + + /* Send reset command */ + if (write(fd, cmd, 4) != 4) { perror("Can't write Silicon Wave reset cmd."); return -1; } -- cgit From a330124c26567659f373575e48d63852a96a18b3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Dec 2005 11:45:01 +0000 Subject: Use /var/lib/misc/oui.txt as default OUI file --- tools/oui.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/oui.c b/tools/oui.c index 13d6c2f5..b68ae04b 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -38,7 +38,7 @@ /* http://standards.ieee.org/regauth/oui/oui.txt */ -#define OUIFILE "/usr/share/misc/oui.txt" +#define OUIFILE "/var/lib/misc/oui.txt" char *ouitocomp(const char *oui) { @@ -49,8 +49,11 @@ char *ouitocomp(const char *oui) fd = open("oui.txt", O_RDONLY); if (fd < 0) { fd = open(OUIFILE, O_RDONLY); - if (fd < 0) - return NULL; + if (fd < 0) { + fd = open("/usr/share/misc/oui.txt", O_RDONLY); + if (fd < 0) + return NULL; + } } if (fstat(fd, &st) < 0) { -- cgit From 4312264fa42014771b188da1d61c3911026390e8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Dec 2005 09:09:33 +0000 Subject: Fix display of text strings --- tools/sdptool.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 6074ef77..2fcd0c7a 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -561,7 +561,6 @@ static void print_tree_attr(sdp_record_t *rec) static void print_raw_data(sdp_data_t *data, int indent) { struct uuid_def *def; - char *str; int i, hex; if (!data) @@ -661,25 +660,18 @@ static void print_raw_data(sdp_data_t *data, int indent) case SDP_TEXT_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: - str = data->val.str; - if (data->unitSize > strlen(str) + 1) { - hex = 0; - for (i = 0; i < data->unitSize - 1; i++) - if (!isprint(str[i])) { - hex = 1; - break; - } - if (str[data->unitSize - 1] != '\0') + hex = 0; + for (i = 0; i < data->unitSize; i++) + if (!isprint(data->val.str[i])) { hex = 1; - } else - hex = 0; - if (hex) { - printf("String"); - for (i = 0; i < data->unitSize; i++) - printf(" %02x", (unsigned char) str[i]); - printf("\n"); - } else - printf("String %s\n", str); + break; + } + for (i = 0; i < data->unitSize; i++) + if (hex) + printf(" %02x", (unsigned char) data->val.str[i]); + else + printf("%c", data->val.str[i]); + printf("\n"); break; case SDP_URL_STR8: case SDP_URL_STR16: -- cgit From b039c1a971aa2f4d4ca29b8453fbb2a360b5dbf7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Dec 2005 09:41:09 +0000 Subject: Reject connections from unknown devices --- hidd/main.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/hidd/main.c b/hidd/main.c index ebb9b745..3a41410c 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -231,7 +231,7 @@ static int request_encryption(bdaddr_t *src, bdaddr_t *dst) return err; } -static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int encrypt, int timeout) +static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int nocheck, int encrypt, int timeout) { struct hidp_connadd_req req; struct sockaddr_l2 addr; @@ -266,6 +266,9 @@ static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, if (!err) goto create; + if (!nocheck) + return -1; + if (!nosdp) { err = get_sdp_device_info(&src, &dst, &req); if (err < 0) @@ -316,7 +319,7 @@ error: return err; } -static void run_server(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int encrypt, int timeout) +static void run_server(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int nocheck, int encrypt, int timeout) { struct pollfd p[2]; short events; @@ -342,7 +345,7 @@ static void run_server(int ctl, int csk, int isk, uint8_t subclass, int nosdp, i ncsk = l2cap_accept(csk, NULL); nisk = l2cap_accept(isk, NULL); - err = create_device(ctl, ncsk, nisk, subclass, nosdp, encrypt, timeout); + err = create_device(ctl, ncsk, nisk, subclass, nosdp, nocheck, encrypt, timeout); if (err < 0) syslog(LOG_ERR, "HID create error %d (%s)", errno, strerror(errno)); @@ -457,7 +460,7 @@ connect: exit(1); } - err = create_device(ctl, csk, isk, subclass, 1, encrypt, timeout); + err = create_device(ctl, csk, isk, subclass, 1, 1, encrypt, timeout); if (err < 0) { fprintf(stderr, "HID create error %d (%s)\n", errno, strerror(errno)); @@ -604,6 +607,7 @@ static struct option main_options[] = { { "master", 0, 0, 'M' }, { "encrypt", 0, 0, 'E' }, { "nosdp", 0, 0, 'D' }, + { "nocheck", 0, 0, 'Z' }, { "show", 0, 0, 'l' }, { "list", 0, 0, 'l' }, { "server", 0, 0, 'd' }, @@ -629,11 +633,12 @@ int main(int argc, char *argv[]) char addr[18]; int log_option = LOG_NDELAY | LOG_PID; int opt, fd, ctl, csk, isk; - int mode = SHOW, daemon = 1, nosdp = 0, fakehid = 1, encrypt = 0, timeout = 30, lm = 0; + int mode = SHOW, daemon = 1, nosdp = 0, nocheck = 0; + int fakehid = 1, encrypt = 0, timeout = 30, lm = 0; bacpy(&bdaddr, BDADDR_ANY); - while ((opt = getopt_long(argc, argv, "+i:nt:b:MEDldsc:k:Ku:h", main_options, NULL)) != -1) { + while ((opt = getopt_long(argc, argv, "+i:nt:b:MEDZldsc:k:Ku:h", main_options, NULL)) != -1) { switch(opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) @@ -662,6 +667,9 @@ int main(int argc, char *argv[]) case 'D': nosdp = 1; break; + case 'Z': + nocheck = 1; + break; case 'l': mode = SHOW; break; @@ -776,7 +784,7 @@ int main(int argc, char *argv[]) sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); - run_server(ctl, csk, isk, subclass, nosdp, encrypt, timeout); + run_server(ctl, csk, isk, subclass, nosdp, nocheck, encrypt, timeout); syslog(LOG_INFO, "Exit"); -- cgit From d7cde36719252eaab14fad2d2c094bb6e7003059 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Dec 2005 11:43:09 +0000 Subject: Add support for the old RFCOMM based EPoX presenter --- hidd/Makefile.am | 4 +- hidd/fakehid.c | 296 ++++++++++++++++++++++++++++++- hidd/sdp.c | 71 ++++++-- hidd/uinput.h | 516 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 871 insertions(+), 16 deletions(-) create mode 100644 hidd/uinput.h diff --git a/hidd/Makefile.am b/hidd/Makefile.am index cc043457..ba01caeb 100644 --- a/hidd/Makefile.am +++ b/hidd/Makefile.am @@ -1,8 +1,8 @@ bin_PROGRAMS = hidd -hidd_SOURCES = main.c hidd.h sdp.c fakehid.c -hidd_LDADD = @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a +hidd_SOURCES = main.c hidd.h sdp.c uinput.h fakehid.c +hidd_LDADD = @BLUEZ_LIBS@ -lm $(top_builddir)/common/libtextfile.a AM_CFLAGS = @BLUEZ_CFLAGS@ diff --git a/hidd/fakehid.c b/hidd/fakehid.c index 1483f022..b9fbc200 100644 --- a/hidd/fakehid.c +++ b/hidd/fakehid.c @@ -27,6 +27,12 @@ #include #include +#include +#include +#include +#include +#include +#include #include #include @@ -34,16 +40,300 @@ #include #include "hidd.h" - -#include -#include +#include "uinput.h" #include +static void event(int fd, uint16_t type, uint16_t code, int32_t value) +{ + struct uinput_event event; + + if (fd <= fileno(stderr)) + return; + + memset(&event, 0, sizeof(event)); + event.type = type; + event.code = code; + event.value = value; + + write(fd, &event, sizeof(event)); +} + +static void func(int fd) +{ +} + +static void back(int fd) +{ +} + +static void next(int fd) +{ +} + +static void button(int fd, unsigned int button, int is_press) +{ + switch (button) { + case 1: + event(fd, EV_KEY, BTN_LEFT, is_press); + break; + case 3: + event(fd, EV_KEY, BTN_RIGHT, is_press); + break; + } + + event(fd, EV_SYN, SYN_REPORT, 0); +} + +static void move(int fd, unsigned int direction) +{ + double angle; + int32_t x, y; + + angle = (direction * 22.5) * 3.1415926 / 180; + x = (int) (sin(angle) * 8); + y = (int) (cos(angle) * -8); + + event(fd, EV_REL, REL_X, x); + event(fd, EV_REL, REL_Y, y); + + event(fd, EV_SYN, SYN_REPORT, 0); +} + +static void epox_decode(int fd, unsigned char event) +{ + switch (event) { + case 48: + func(fd); break; + case 55: + back(fd); break; + case 56: + next(fd); break; + case 53: + button(fd, 1, 1); break; + case 121: + button(fd, 1, 0); break; + case 113: + break; + case 54: + button(fd, 3, 1); break; + case 120: + button(fd, 3, 0); break; + case 112: + break; + case 51: + move(fd, 0); break; + case 97: + move(fd, 1); break; + case 65: + move(fd, 2); break; + case 98: + move(fd, 3); break; + case 50: + move(fd, 4); break; + case 99: + move(fd, 5); break; + case 67: + move(fd, 6); break; + case 101: + move(fd, 7); break; + case 52: + move(fd, 8); break; + case 100: + move(fd, 9); break; + case 66: + move(fd, 10); break; + case 102: + move(fd, 11); break; + case 49: + move(fd, 12); break; + case 103: + move(fd, 13); break; + case 57: + move(fd, 14); break; + case 104: + move(fd, 15); break; + case 69: + break; + default: + printf("Unknown event code %d\n", event); + break; + } +} + +static int uinput_create(int keyboard, int mouse) +{ + struct uinput_dev dev; + int fd, aux; + + fd = open("/dev/uinput", O_RDWR); + if (fd < 0) { + fd = open("/dev/input/uinput", O_RDWR); + if (fd < 0) { + fd = open("/dev/misc/uinput", O_RDWR); + if (fd < 0) { + fprintf(stderr, "Can't open input device: %s (%d)", + strerror(errno), errno); + return -1; + } + } + } + + memset(&dev, 0, sizeof(dev)); + strncpy(dev.name, "Bluetooth FakeHID", UINPUT_MAX_NAME_SIZE); + dev.id.bustype = BUS_BLUETOOTH; + dev.id.vendor = 0x0000; + dev.id.product = 0x0000; + dev.id.version = 0x0000; + + if (write(fd, &dev, sizeof(dev)) < 0) { + fprintf(stderr, "Can't write device information: %s (%d)", + strerror(errno), errno); + close(fd); + return -1; + } + + if (mouse) { + ioctl(fd, UI_SET_EVBIT, EV_REL); + + for (aux = REL_X; aux <= REL_MISC; aux++) + ioctl(fd, UI_SET_RELBIT, aux); + } + + if (keyboard) { + ioctl(fd, UI_SET_EVBIT, EV_KEY); + ioctl(fd, UI_SET_EVBIT, EV_LED); + ioctl(fd, UI_SET_EVBIT, EV_REP); + + for (aux = KEY_RESERVED; aux <= KEY_UNKNOWN; aux++) + ioctl(fd, UI_SET_KEYBIT, aux); + + //for (aux = LED_NUML; aux <= LED_MISC; aux++) + // ioctl(fd, UI_SET_LEDBIT, aux); + } + + if (mouse) { + ioctl(fd, UI_SET_EVBIT, EV_KEY); + + for (aux = BTN_LEFT; aux <= BTN_BACK; aux++) + ioctl(fd, UI_SET_KEYBIT, aux); + } + + ioctl(fd, UI_DEV_CREATE); + + return fd; +} + +static int rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) +{ + struct sockaddr_rc addr; + int sk; + + sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + if (sk < 0) { + fprintf(stderr, "Can't create socket: %s (%d)\n", + strerror(errno), errno); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, src); + + if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + fprintf(stderr, "Can't bind socket: %s (%d)\n", + strerror(errno), errno); + close(sk); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.rc_family = AF_BLUETOOTH; + bacpy(&addr.rc_bdaddr, dst); + addr.rc_channel = channel; + + if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + fprintf(stderr, "Can't connect: %s (%d)\n", + strerror(errno), errno); + close(sk); + return -1; + } + + return sk; +} + +static volatile sig_atomic_t __io_canceled = 0; + +static void sig_hup(int sig) +{ +} + +static void sig_term(int sig) +{ + __io_canceled = 1; +} + void epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) { + unsigned char buf[16]; + struct sigaction sa; + struct pollfd p; + char addr[18]; + int i, fd, sk, len; + + sk = rfcomm_connect(src, dst, channel); + if (sk < 0) + return; + + fd = uinput_create(1, 1); + if (fd < 0) { + close(sk); + return; + } + + ba2str(dst, addr); + + printf("Connected to %s on channel %d\n", addr, channel); + printf("Press CTRL-C for hangup\n"); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = sig_hup; + sigaction(SIGHUP, &sa, NULL); + + p.fd = sk; + p.events = POLLIN | POLLERR | POLLHUP; + + while (!__io_canceled) { + p.revents = 0; + if (poll(&p, 1, 100) < 1) + continue; + + len = read(sk, buf, sizeof(buf)); + if (len < 0) + break; + + for (i = 0; i < len; i++) + epox_decode(fd, buf[i]); + } + + printf("Disconnected\n"); + + ioctl(fd, UI_DEV_DESTROY); + + close(fd); + close(sk); } void headset_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) { + printf("Not implemented\n"); } diff --git a/hidd/sdp.c b/hidd/sdp.c index 285438e8..c86fb2ff 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -175,19 +175,21 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co search = sdp_list_append(NULL, &svclass); attrid = sdp_list_append(NULL, &range); - err = sdp_service_search_attr_req(s, search, SDP_ATTR_REQ_RANGE, attrid, &pnp_rsp); + err = sdp_service_search_attr_req(s, search, + SDP_ATTR_REQ_RANGE, attrid, &pnp_rsp); - sdp_list_free(search, 0); - sdp_list_free(attrid, 0); + sdp_list_free(search, NULL); + sdp_list_free(attrid, NULL); sdp_uuid16_create(&svclass, HID_SVCLASS_ID); search = sdp_list_append(NULL, &svclass); attrid = sdp_list_append(NULL, &range); - err = sdp_service_search_attr_req(s, search, SDP_ATTR_REQ_RANGE, attrid, &hid_rsp); + err = sdp_service_search_attr_req(s, search, + SDP_ATTR_REQ_RANGE, attrid, &hid_rsp); - sdp_list_free(search, 0); - sdp_list_free(attrid, 0); + sdp_list_free(search, NULL); + sdp_list_free(attrid, NULL); memset(&addr, 0, sizeof(addr)); addrlen = sizeof(addr); @@ -270,19 +272,66 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co int get_alternate_device_info(const bdaddr_t *src, const bdaddr_t *dst, uint16_t *uuid, uint8_t *channel) { + uint16_t attr = SDP_ATTR_PROTO_DESC_LIST; sdp_session_t *s; + sdp_list_t *search, *attrid, *rsp; + uuid_t svclass; + int err; s = sdp_connect(src, dst, SDP_RETRY_IF_BUSY | SDP_WAIT_ON_CLOSE); if (!s) return -1; + sdp_uuid16_create(&svclass, HEADSET_SVCLASS_ID); + search = sdp_list_append(NULL, &svclass); + attrid = sdp_list_append(NULL, &attr); + + err = sdp_service_search_attr_req(s, search, + SDP_ATTR_REQ_INDIVIDUAL, attrid, &rsp); + + sdp_list_free(search, NULL); + sdp_list_free(attrid, NULL); + + if (err <= 0) { + sdp_uuid16_create(&svclass, SERIAL_PORT_SVCLASS_ID); + search = sdp_list_append(NULL, &svclass); + attrid = sdp_list_append(NULL, &attr); + + err = sdp_service_search_attr_req(s, search, + SDP_ATTR_REQ_INDIVIDUAL, attrid, &rsp); + + sdp_list_free(search, NULL); + sdp_list_free(attrid, NULL); + + if (err < 0) { + sdp_close(s); + return err; + } + + if (uuid) + *uuid = SERIAL_PORT_SVCLASS_ID; + } else { + if (uuid) + *uuid = HEADSET_SVCLASS_ID; + } + sdp_close(s); - if (uuid) - *uuid = 0x0000; + for (; rsp; rsp = rsp->next) { + sdp_record_t *rec = (sdp_record_t *) rsp->data; + sdp_list_t *protos; + + if (!sdp_get_access_protos(rec, &protos)) { + uint8_t ch = sdp_get_proto_port(protos, RFCOMM_UUID); + if (ch > 0) { + if (channel) + *channel = ch; + return 0; + } + } - if (channel) - *channel = 0; + sdp_record_free(rec); + } - return 0; + return -EIO; } diff --git a/hidd/uinput.h b/hidd/uinput.h new file mode 100644 index 00000000..3a4d6860 --- /dev/null +++ b/hidd/uinput.h @@ -0,0 +1,516 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2003-2005 Marcel Holtmann + * + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __UINPUT_H +#define __UINPUT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* Events */ + +#define EV_SYN 0x00 +#define EV_KEY 0x01 +#define EV_REL 0x02 +#define EV_ABS 0x03 +#define EV_MSC 0x04 +#define EV_LED 0x11 +#define EV_SND 0x12 +#define EV_REP 0x14 +#define EV_FF 0x15 +#define EV_PWR 0x16 +#define EV_FF_STATUS 0x17 +#define EV_MAX 0x1f + +/* Synchronization events */ + +#define SYN_REPORT 0 +#define SYN_CONFIG 1 + +/* Keys and buttons */ + +#define KEY_RESERVED 0 +#define KEY_ESC 1 +#define KEY_1 2 +#define KEY_2 3 +#define KEY_3 4 +#define KEY_4 5 +#define KEY_5 6 +#define KEY_6 7 +#define KEY_7 8 +#define KEY_8 9 +#define KEY_9 10 +#define KEY_0 11 +#define KEY_MINUS 12 +#define KEY_EQUAL 13 +#define KEY_BACKSPACE 14 +#define KEY_TAB 15 +#define KEY_Q 16 +#define KEY_W 17 +#define KEY_E 18 +#define KEY_R 19 +#define KEY_T 20 +#define KEY_Y 21 +#define KEY_U 22 +#define KEY_I 23 +#define KEY_O 24 +#define KEY_P 25 +#define KEY_LEFTBRACE 26 +#define KEY_RIGHTBRACE 27 +#define KEY_ENTER 28 +#define KEY_LEFTCTRL 29 +#define KEY_A 30 +#define KEY_S 31 +#define KEY_D 32 +#define KEY_F 33 +#define KEY_G 34 +#define KEY_H 35 +#define KEY_J 36 +#define KEY_K 37 +#define KEY_L 38 +#define KEY_SEMICOLON 39 +#define KEY_APOSTROPHE 40 +#define KEY_GRAVE 41 +#define KEY_LEFTSHIFT 42 +#define KEY_BACKSLASH 43 +#define KEY_Z 44 +#define KEY_X 45 +#define KEY_C 46 +#define KEY_V 47 +#define KEY_B 48 +#define KEY_N 49 +#define KEY_M 50 +#define KEY_COMMA 51 +#define KEY_DOT 52 +#define KEY_SLASH 53 +#define KEY_RIGHTSHIFT 54 +#define KEY_KPASTERISK 55 +#define KEY_LEFTALT 56 +#define KEY_SPACE 57 +#define KEY_CAPSLOCK 58 +#define KEY_F1 59 +#define KEY_F2 60 +#define KEY_F3 61 +#define KEY_F4 62 +#define KEY_F5 63 +#define KEY_F6 64 +#define KEY_F7 65 +#define KEY_F8 66 +#define KEY_F9 67 +#define KEY_F10 68 +#define KEY_NUMLOCK 69 +#define KEY_SCROLLLOCK 70 +#define KEY_KP7 71 +#define KEY_KP8 72 +#define KEY_KP9 73 +#define KEY_KPMINUS 74 +#define KEY_KP4 75 +#define KEY_KP5 76 +#define KEY_KP6 77 +#define KEY_KPPLUS 78 +#define KEY_KP1 79 +#define KEY_KP2 80 +#define KEY_KP3 81 +#define KEY_KP0 82 +#define KEY_KPDOT 83 +#define KEY_103RD 84 +#define KEY_F13 85 +#define KEY_102ND 86 +#define KEY_F11 87 +#define KEY_F12 88 +#define KEY_F14 89 +#define KEY_F15 90 +#define KEY_F16 91 +#define KEY_F17 92 +#define KEY_F18 93 +#define KEY_F19 94 +#define KEY_F20 95 +#define KEY_KPENTER 96 +#define KEY_RIGHTCTRL 97 +#define KEY_KPSLASH 98 +#define KEY_SYSRQ 99 +#define KEY_RIGHTALT 100 +#define KEY_LINEFEED 101 +#define KEY_HOME 102 +#define KEY_UP 103 +#define KEY_PAGEUP 104 +#define KEY_LEFT 105 +#define KEY_RIGHT 106 +#define KEY_END 107 +#define KEY_DOWN 108 +#define KEY_PAGEDOWN 109 +#define KEY_INSERT 110 +#define KEY_DELETE 111 +#define KEY_MACRO 112 +#define KEY_MUTE 113 +#define KEY_VOLUMEDOWN 114 +#define KEY_VOLUMEUP 115 +#define KEY_POWER 116 +#define KEY_KPEQUAL 117 +#define KEY_KPPLUSMINUS 118 +#define KEY_PAUSE 119 +#define KEY_F21 120 +#define KEY_F22 121 +#define KEY_F23 122 +#define KEY_F24 123 +#define KEY_KPCOMMA 124 +#define KEY_LEFTMETA 125 +#define KEY_RIGHTMETA 126 +#define KEY_COMPOSE 127 + +#define KEY_STOP 128 +#define KEY_AGAIN 129 +#define KEY_PROPS 130 +#define KEY_UNDO 131 +#define KEY_FRONT 132 +#define KEY_COPY 133 +#define KEY_OPEN 134 +#define KEY_PASTE 135 +#define KEY_FIND 136 +#define KEY_CUT 137 +#define KEY_HELP 138 +#define KEY_MENU 139 +#define KEY_CALC 140 +#define KEY_SETUP 141 +#define KEY_SLEEP 142 +#define KEY_WAKEUP 143 +#define KEY_FILE 144 +#define KEY_SENDFILE 145 +#define KEY_DELETEFILE 146 +#define KEY_XFER 147 +#define KEY_PROG1 148 +#define KEY_PROG2 149 +#define KEY_WWW 150 +#define KEY_MSDOS 151 +#define KEY_COFFEE 152 +#define KEY_DIRECTION 153 +#define KEY_CYCLEWINDOWS 154 +#define KEY_MAIL 155 +#define KEY_BOOKMARKS 156 +#define KEY_COMPUTER 157 +#define KEY_BACK 158 +#define KEY_FORWARD 159 +#define KEY_CLOSECD 160 +#define KEY_EJECTCD 161 +#define KEY_EJECTCLOSECD 162 +#define KEY_NEXTSONG 163 +#define KEY_PLAYPAUSE 164 +#define KEY_PREVIOUSSONG 165 +#define KEY_STOPCD 166 +#define KEY_RECORD 167 +#define KEY_REWIND 168 +#define KEY_PHONE 169 +#define KEY_ISO 170 +#define KEY_CONFIG 171 +#define KEY_HOMEPAGE 172 +#define KEY_REFRESH 173 +#define KEY_EXIT 174 +#define KEY_MOVE 175 +#define KEY_EDIT 176 +#define KEY_SCROLLUP 177 +#define KEY_SCROLLDOWN 178 +#define KEY_KPLEFTPAREN 179 +#define KEY_KPRIGHTPAREN 180 + +#define KEY_INTL1 181 +#define KEY_INTL2 182 +#define KEY_INTL3 183 +#define KEY_INTL4 184 +#define KEY_INTL5 185 +#define KEY_INTL6 186 +#define KEY_INTL7 187 +#define KEY_INTL8 188 +#define KEY_INTL9 189 +#define KEY_LANG1 190 +#define KEY_LANG2 191 +#define KEY_LANG3 192 +#define KEY_LANG4 193 +#define KEY_LANG5 194 +#define KEY_LANG6 195 +#define KEY_LANG7 196 +#define KEY_LANG8 197 +#define KEY_LANG9 198 + +#define KEY_PLAYCD 200 +#define KEY_PAUSECD 201 +#define KEY_PROG3 202 +#define KEY_PROG4 203 +#define KEY_SUSPEND 205 +#define KEY_CLOSE 206 + +#define KEY_UNKNOWN 220 + +#define KEY_BRIGHTNESSDOWN 224 +#define KEY_BRIGHTNESSUP 225 + +#define BTN_MISC 0x100 +#define BTN_0 0x100 +#define BTN_1 0x101 +#define BTN_2 0x102 +#define BTN_3 0x103 +#define BTN_4 0x104 +#define BTN_5 0x105 +#define BTN_6 0x106 +#define BTN_7 0x107 +#define BTN_8 0x108 +#define BTN_9 0x109 + +#define BTN_MOUSE 0x110 +#define BTN_LEFT 0x110 +#define BTN_RIGHT 0x111 +#define BTN_MIDDLE 0x112 +#define BTN_SIDE 0x113 +#define BTN_EXTRA 0x114 +#define BTN_FORWARD 0x115 +#define BTN_BACK 0x116 +#define BTN_TASK 0x117 + +#define BTN_JOYSTICK 0x120 +#define BTN_TRIGGER 0x120 +#define BTN_THUMB 0x121 +#define BTN_THUMB2 0x122 +#define BTN_TOP 0x123 +#define BTN_TOP2 0x124 +#define BTN_PINKIE 0x125 +#define BTN_BASE 0x126 +#define BTN_BASE2 0x127 +#define BTN_BASE3 0x128 +#define BTN_BASE4 0x129 +#define BTN_BASE5 0x12a +#define BTN_BASE6 0x12b +#define BTN_DEAD 0x12f + +#define BTN_GAMEPAD 0x130 +#define BTN_A 0x130 +#define BTN_B 0x131 +#define BTN_C 0x132 +#define BTN_X 0x133 +#define BTN_Y 0x134 +#define BTN_Z 0x135 +#define BTN_TL 0x136 +#define BTN_TR 0x137 +#define BTN_TL2 0x138 +#define BTN_TR2 0x139 +#define BTN_SELECT 0x13a +#define BTN_START 0x13b +#define BTN_MODE 0x13c +#define BTN_THUMBL 0x13d +#define BTN_THUMBR 0x13e + +#define BTN_DIGI 0x140 +#define BTN_TOOL_PEN 0x140 +#define BTN_TOOL_RUBBER 0x141 +#define BTN_TOOL_BRUSH 0x142 +#define BTN_TOOL_PENCIL 0x143 +#define BTN_TOOL_AIRBRUSH 0x144 +#define BTN_TOOL_FINGER 0x145 +#define BTN_TOOL_MOUSE 0x146 +#define BTN_TOOL_LENS 0x147 +#define BTN_TOUCH 0x14a +#define BTN_STYLUS 0x14b +#define BTN_STYLUS2 0x14c +#define BTN_TOOL_DOUBLETAP 0x14d +#define BTN_TOOL_TRIPLETAP 0x14e + +#define BTN_WHEEL 0x150 +#define BTN_GEAR_DOWN 0x150 +#define BTN_GEAR_UP 0x151 + +#define KEY_MAX 0x1ff + +/* Relative axes */ + +#define REL_X 0x00 +#define REL_Y 0x01 +#define REL_Z 0x02 +#define REL_RX 0x03 +#define REL_RY 0x04 +#define REL_RZ 0x05 +#define REL_HWHEEL 0x06 +#define REL_DIAL 0x07 +#define REL_WHEEL 0x08 +#define REL_MISC 0x09 +#define REL_MAX 0x0f + +/* Absolute axes */ + +#define ABS_X 0x00 +#define ABS_Y 0x01 +#define ABS_Z 0x02 +#define ABS_RX 0x03 +#define ABS_RY 0x04 +#define ABS_RZ 0x05 +#define ABS_THROTTLE 0x06 +#define ABS_RUDDER 0x07 +#define ABS_WHEEL 0x08 +#define ABS_GAS 0x09 +#define ABS_BRAKE 0x0a +#define ABS_HAT0X 0x10 +#define ABS_HAT0Y 0x11 +#define ABS_HAT1X 0x12 +#define ABS_HAT1Y 0x13 +#define ABS_HAT2X 0x14 +#define ABS_HAT2Y 0x15 +#define ABS_HAT3X 0x16 +#define ABS_HAT3Y 0x17 +#define ABS_PRESSURE 0x18 +#define ABS_DISTANCE 0x19 +#define ABS_TILT_X 0x1a +#define ABS_TILT_Y 0x1b +#define ABS_TOOL_WIDTH 0x1c +#define ABS_VOLUME 0x20 +#define ABS_MISC 0x28 +#define ABS_MAX 0x3f + +/* Switch events */ + +#define SW_0 0x00 +#define SW_1 0x01 +#define SW_2 0x02 +#define SW_3 0x03 +#define SW_4 0x04 +#define SW_5 0x05 +#define SW_6 0x06 +#define SW_7 0x07 +#define SW_MAX 0x0f + +/* Misc events */ + +#define MSC_SERIAL 0x00 +#define MSC_PULSELED 0x01 +#define MSC_GESTURE 0x02 +#define MSC_RAW 0x03 +#define MSC_SCAN 0x04 +#define MSC_MAX 0x07 + +/* LEDs */ + +#define LED_NUML 0x00 +#define LED_CAPSL 0x01 +#define LED_SCROLLL 0x02 +#define LED_COMPOSE 0x03 +#define LED_KANA 0x04 +#define LED_SLEEP 0x05 +#define LED_SUSPEND 0x06 +#define LED_MUTE 0x07 +#define LED_MISC 0x08 +#define LED_MAIL 0x09 +#define LED_CHARGING 0x0a +#define LED_MAX 0x0f + +/* Autorepeat values */ + +#define REP_DELAY 0x00 +#define REP_PERIOD 0x01 +#define REP_MAX 0x01 + +/* Sounds */ + +#define SND_CLICK 0x00 +#define SND_BELL 0x01 +#define SND_TONE 0x02 +#define SND_MAX 0x07 + +/* Identifiers */ + +#define ID_BUS 0 +#define ID_VENDOR 1 +#define ID_PRODUCT 2 +#define ID_VERSION 3 + +#define BUS_PCI 0x01 +#define BUS_ISAPNP 0x02 +#define BUS_USB 0x03 +#define BUS_HIL 0x04 +#define BUS_BLUETOOTH 0x05 + +#define BUS_ISA 0x10 +#define BUS_I8042 0x11 +#define BUS_XTKBD 0x12 +#define BUS_RS232 0x13 +#define BUS_GAMEPORT 0x14 +#define BUS_PARPORT 0x15 +#define BUS_AMIGA 0x16 +#define BUS_ADB 0x17 +#define BUS_I2C 0x18 +#define BUS_HOST 0x19 +#define BUS_GSC 0x1A + +/* User input interface */ + +#define UINPUT_IOCTL_BASE 'U' + +#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1) +#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2) + +#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int) +#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int) +#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int) +#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int) +#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int) +#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int) +#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int) +#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int) +#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*) +#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int) + +#ifndef NBITS +#define NBITS(x) ((((x) - 1) / (sizeof(long) * 8)) + 1) +#endif + +#define UINPUT_MAX_NAME_SIZE 80 + +struct uinput_id { + uint16_t bustype; + uint16_t vendor; + uint16_t product; + uint16_t version; +}; + +struct uinput_dev { + char name[UINPUT_MAX_NAME_SIZE]; + struct uinput_id id; + int ff_effects_max; + int absmax[ABS_MAX + 1]; + int absmin[ABS_MAX + 1]; + int absfuzz[ABS_MAX + 1]; + int absflat[ABS_MAX + 1]; +}; + +struct uinput_event { + struct timeval time; + uint16_t type; + uint16_t code; + int32_t value; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __UINPUT_H */ -- cgit From 9f80ae2025e4d14059ac313b678e7457e5c506aa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Dec 2005 12:05:13 +0000 Subject: Support different device names --- hidd/fakehid.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hidd/fakehid.c b/hidd/fakehid.c index b9fbc200..61f33ce8 100644 --- a/hidd/fakehid.c +++ b/hidd/fakehid.c @@ -161,7 +161,7 @@ static void epox_decode(int fd, unsigned char event) } } -static int uinput_create(int keyboard, int mouse) +static int uinput_create(char *name, int keyboard, int mouse) { struct uinput_dev dev; int fd, aux; @@ -180,9 +180,12 @@ static int uinput_create(int keyboard, int mouse) } memset(&dev, 0, sizeof(dev)); - strncpy(dev.name, "Bluetooth FakeHID", UINPUT_MAX_NAME_SIZE); + + if (name) + strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE); + dev.id.bustype = BUS_BLUETOOTH; - dev.id.vendor = 0x0000; + dev.id.vendor = 0x0000; dev.id.product = 0x0000; dev.id.version = 0x0000; @@ -285,7 +288,7 @@ void epox_presenter(const bdaddr_t *src, const bdaddr_t *dst, uint8_t channel) if (sk < 0) return; - fd = uinput_create(1, 1); + fd = uinput_create("Bluetooth Presenter", 0, 1); if (fd < 0) { close(sk); return; -- cgit From 5e138ccd0d193206f602f6670ce60d2169ed0bc6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Dec 2005 14:08:02 +0000 Subject: Update changelog and bump version number --- ChangeLog | 14 ++++++++++++++ configure.in | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 111275bc..49c5d177 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +ver 2.23: + Update the new D-Bus interface. + Make dfutool ready for big endian architectures. + Add support for AVRCP specific service records. + Add support for writing complex BCCMD commands. + Add the new BCCMD interface utility. + Add MicroBCSP implementation from CSR. + Add HCI emulation tool. + Add fake HID support for old EPoX presenters. + Reject connections from unknown HID devices. + + Note: + This version needs at least bluez-libs-2.23 + ver 2.22: Remove D-Bus 0.23 support. Add initial version of the new D-Bus interface. diff --git a/configure.in b/configure.in index aa47db4b..1e7bc838 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.22) +AM_INIT_AUTOMAKE(bluez-utils, 2.23) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From 6ab0c763564fb55fc50f2f8ce4712fc718321635 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 13 Dec 2005 10:35:27 +0000 Subject: Fix display of text and data strings --- tools/sdptool.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 2fcd0c7a..b3124c58 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -666,11 +666,15 @@ static void print_raw_data(sdp_data_t *data, int indent) hex = 1; break; } - for (i = 0; i < data->unitSize; i++) - if (hex) + if (hex) { + printf("Data"); + for (i = 0; i < data->unitSize; i++) printf(" %02x", (unsigned char) data->val.str[i]); - else + } else { + printf("String "); + for (i = 0; i < data->unitSize; i++) printf("%c", data->val.str[i]); + } printf("\n"); break; case SDP_URL_STR8: -- cgit From 930a2e3369f14694bc7661a77cec279171a421a4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 13 Dec 2005 23:09:52 +0000 Subject: Update the D-Bus policy configuration file --- hcid/bluez-hcid.conf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hcid/bluez-hcid.conf b/hcid/bluez-hcid.conf index af3c49e7..72380aef 100644 --- a/hcid/bluez-hcid.conf +++ b/hcid/bluez-hcid.conf @@ -7,9 +7,11 @@ - + + + -- cgit From 69e97d91bc0636a9546836d2ec0ca629fdcb1718 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 15 Dec 2005 22:58:54 +0000 Subject: Update build definitions --- tools/csr.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/csr.c b/tools/csr.c index b28289a5..39293fa8 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -424,7 +424,7 @@ char *csr_builddeftostr(uint16_t def) case 0x000e: return "TRANSPORT_USER"; case 0x000f: - return "CHIP_BC02K"; + return "CHIP_BC02_KATO"; case 0x0010: return "TRANSPORT_NONE"; case 0x0012: @@ -446,15 +446,15 @@ char *csr_builddeftostr(uint16_t def) case 0x001a: return "COMPILER_GCC"; case 0x001b: - return "CHIP_BC02C"; + return "CHIP_BC02_CLOUSEAU"; case 0x001c: - return "CHIP_BC02T"; + return "CHIP_BC02_TOULOUSE"; case 0x001d: return "CHIP_BASE_BC3"; case 0x001e: - return "CHIP_BC3N"; + return "CHIP_BC3_NICKNACK"; case 0x001f: - return "CHIP_BC3K"; + return "CHIP_BC3_KALIMBA"; case 0x0020: return "INSTALL_HCI_MODULE"; case 0x0021: -- cgit From 96e7c3629715547f0632d4fb313923c16b64f049 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 18 Dec 2005 19:14:43 +0000 Subject: Include header file stdint.h --- tools/csr.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/csr.h b/tools/csr.h index 9cdc7225..d75e3995 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -21,6 +21,8 @@ * */ +#include + #define CSR_VARID_PS_CLR_ALL 0x000b /* valueless */ #define CSR_VARID_PS_FACTORY_SET 0x000c /* valueless */ #define CSR_VARID_PS_CLR_ALL_STORES 0x082d /* uint16 */ -- cgit From aaf086315704313db2fee31d2e4ce68926be53e5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 Dec 2005 23:42:19 +0000 Subject: Work around missing DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT declaration --- hcid/dbus.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hcid/dbus.c b/hcid/dbus.c index eb2e0578..daeb93bd 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -46,6 +46,10 @@ #include "hcid.h" #include "dbus.h" +#ifndef DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT +#define DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT 0x00 +#endif + static DBusConnection *connection; static int default_dev = -1; -- cgit From ddf0b3facf8bc26767185708582579a118aa8ed4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Dec 2005 00:08:09 +0000 Subject: Setup D-Bus for PIN agent if needed --- hcid/dbus.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index daeb93bd..e8c5ec41 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -460,12 +460,17 @@ static gboolean unregister_dbus_path(const char *path) void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) { - DBusMessage *message; + DBusMessage *message = NULL; DBusPendingCall *pending = NULL; struct pin_request *req; uint8_t *addr = (uint8_t *) &ci->bdaddr; dbus_bool_t out = ci->out; + if (!connection) { + if (!hcid_dbus_init()) + goto failed; + } + message = dbus_message_new_method_call(PINAGENT_SERVICE_NAME, PINAGENT_PATH, PINAGENT_INTERFACE, PIN_REQUEST); if (message == NULL) { @@ -497,7 +502,9 @@ void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci) return; failed: - dbus_message_unref(message); + if (message) + dbus_message_unref(message); + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); } -- cgit From 537efeed8fd5758a642afd3ca1df82f69a22d14b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Dec 2005 12:45:37 +0000 Subject: Add support for device scan property --- hcid/dbus-test | 24 +++-- hcid/dbus.c | 311 ++++++++++++++++++++++++++++++++++++++++++++++++-------- hcid/dbus.h | 3 +- hcid/hcid.h | 2 + hcid/security.c | 2 + 5 files changed, 291 insertions(+), 51 deletions(-) diff --git a/hcid/dbus-test b/hcid/dbus-test index 00cdfeda..926be2fc 100755 --- a/hcid/dbus-test +++ b/hcid/dbus-test @@ -14,6 +14,9 @@ dev_cmds = [ "Up", "Down", "SetProperty", "GetProperty", "Inquiry", "Connections", "Authenticate", "RoleSwitch" ] dev_setprop_bool = [ "auth", "encrypt", "discoverable", "connectable" ] dev_setprop_byte = [ "incmode" ] +dev_prop_filter = ["/org/bluez/Device/hci0", "/org/bluez/Device/hci1", + "/org/bluez/Device/hci2", "/org/bluez/Device/hci3", + "/org/bluez/Device/hci4", "/org/bluez/Device/hci5"] class Tester: exit_events = [] @@ -81,10 +84,10 @@ class Tester: self.dev.connect_to_signal('Up', self.dev_up) self.dev.connect_to_signal('Down', self.dev_down) - self.bus.add_signal_receiver(self.dev_name_changed, 'DeviceNameChanged', - 'org.bluez.Device', 'org.bluez', - '/org/bluez/Device/hci0') - + for path in dev_prop_filter: + self.bus.add_signal_receiver(self.dev_property_changed, + 'PropertyChanged','org.bluez.Device', + 'org.bluez',path) obj = self.bus.get_object('org.bluez', '%s/Controller' % self.dev_path) self.ctl = dbus.Interface(obj, 'org.bluez.Device.Controller') @@ -157,10 +160,17 @@ class Tester: print 'Down' @dbus.decorators.explicitly_pass_message - def dev_name_changed(*args, **keywords): - name = args[1] + def dev_property_changed(*args, **keywords): + property = args[1] + param = args[2] dbus_message = keywords["dbus_message"] - print 'Device %s name changed: %s' % (dbus_message.get_path(), name) + if property == 'name': + print 'Device %s name changed: %s' % (dbus_message.get_path(), param) + elif property == 'connectable': + print 'Device %s connectable scan property changed: %d' % (dbus_message.get_path(), param) + elif property == 'discoverable': + print 'Device %s discoverable scan property changed: %d' % (dbus_message.get_path(), param) + def signal_cb(self, sig, frame): print 'Caught signal, exiting' diff --git a/hcid/dbus.c b/hcid/dbus.c index e8c5ec41..c7d7f871 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -79,6 +79,7 @@ struct service_data { struct hci_dbus_data { uint16_t dev_id; uint16_t path_id; + uint32_t path_data; }; typedef int register_function_t(DBusConnection *conn, uint16_t id); @@ -136,6 +137,7 @@ static const bluez_error_t dbus_error_array[] = { { BLUEZ_EDBUS_NO_MEM, "No memory" }, { BLUEZ_EDBUS_CONN_NOT_FOUND, "Connection not found" }, { BLUEZ_EDBUS_UNKNOWN_PATH, "Unknown D-BUS path" }, + { BLUEZ_EDBUS_NOT_IMPLEMENTED, "Method not implemented" }, { 0, NULL } }; @@ -274,34 +276,36 @@ static const DBusObjectPathVTable obj_mgr_vtable = { */ static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data); static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data); -static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data); -static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data); -static DBusMessage* handle_device_set_propety_req_name(DBusMessage *msg, void *data); -static DBusMessage* handle_device_get_propety_req_name(DBusMessage *msg, void *data); +static DBusMessage* handle_device_set_property_req(DBusMessage *msg, void *data); +static DBusMessage* handle_device_get_property_req(DBusMessage *msg, void *data); +static DBusMessage* handle_device_set_property_req_name(DBusMessage *msg, void *data); +static DBusMessage* handle_device_get_property_req_name(DBusMessage *msg, void *data); +static DBusMessage* handle_device_set_property_req_pscan(DBusMessage *msg, void *data); +static DBusMessage* handle_device_set_property_req_iscan(DBusMessage *msg, void *data); static const struct service_data device_services[] = { { DEV_UP, handle_device_up_req, DEV_UP_SIGNATURE }, { DEV_DOWN, handle_device_down_req, DEV_DOWN_SIGNATURE }, - { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, - { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_STR }, - { DEV_SET_PROPERTY, handle_device_set_propety_req, DEV_SET_PROPERTY_SIGNATURE_BYTE }, - { DEV_GET_PROPERTY, handle_device_get_propety_req, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_SET_PROPERTY, handle_device_set_property_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, + { DEV_SET_PROPERTY, handle_device_set_property_req, DEV_SET_PROPERTY_SIGNATURE_STR }, + { DEV_SET_PROPERTY, handle_device_set_property_req, DEV_SET_PROPERTY_SIGNATURE_BYTE }, + { DEV_GET_PROPERTY, handle_device_get_property_req, DEV_GET_PROPERTY_SIGNATURE }, { NULL, NULL, NULL} }; static const struct service_data set_property_services[] = { { DEV_PROPERTY_AUTH, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, { DEV_PROPERTY_ENCRYPT, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, - { DEV_PROPERTY_PSCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, - { DEV_PROPERTY_ISCAN, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BOOL }, - { DEV_PROPERTY_NAME, handle_device_set_propety_req_name, DEV_SET_PROPERTY_SIGNATURE_STR }, + { DEV_PROPERTY_PSCAN, handle_device_set_property_req_pscan, DEV_SET_PROPERTY_SIGNATURE_BOOL }, + { DEV_PROPERTY_ISCAN, handle_device_set_property_req_iscan, DEV_SET_PROPERTY_SIGNATURE_BOOL }, + { DEV_PROPERTY_NAME, handle_device_set_property_req_name, DEV_SET_PROPERTY_SIGNATURE_STR }, { DEV_PROPERTY_INCMODE, handle_not_implemented_req, DEV_SET_PROPERTY_SIGNATURE_BYTE }, { NULL, NULL, NULL} }; static const struct service_data get_property_services[] = { { DEV_PROPERTY_DEV_INFO, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, - { DEV_PROPERTY_NAME, handle_device_get_propety_req_name, DEV_GET_PROPERTY_SIGNATURE }, + { DEV_PROPERTY_NAME, handle_device_get_property_req_name, DEV_GET_PROPERTY_SIGNATURE }, { DEV_PROPERTY_INCMODE, handle_not_implemented_req, DEV_GET_PROPERTY_SIGNATURE }, { NULL, NULL, NULL} }; @@ -947,12 +951,44 @@ gboolean hcid_dbus_register_device(uint16_t id) char *pptr = path; gboolean ret; DBusMessage *message = NULL; + int dd = -1; + read_scan_enable_rp rp; + struct hci_request rq; + struct hci_dbus_data* pdata; snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); + ret = register_dbus_path(path, DEVICE_PATH_ID, id, &obj_dev_vtable, FALSE); + + dd = hci_open_dev(id); + if (dd < 0) { + syslog(LOG_ERR, "HCI device open failed: hci%d", id); + rp.enable = SCAN_PAGE | SCAN_INQUIRY; + } else { + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_SCAN_ENABLE; + rq.rparam = &rp; + rq.rlen = READ_SCAN_ENABLE_RP_SIZE; + + if (hci_send_req(dd, &rq, 500) < 0) { + syslog(LOG_ERR, "Sending read scan enable command failed: %s (%d)", + strerror(errno), errno); + rp.enable = SCAN_PAGE | SCAN_INQUIRY; + } else if (rp.status) { + syslog(LOG_ERR, "Getting scan enable failed with status 0x%02x", + rp.status); + rp.enable = SCAN_PAGE | SCAN_INQUIRY; + } + } + + if (!dbus_connection_get_object_path_data(connection, path, (void*) &pdata)) + syslog(LOG_ERR, "Getting path data failed!"); + else + pdata->path_data = rp.enable; /* Keep the current scan status */ + message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE, BLUEZ_MGR_DEV_ADDED); - if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; @@ -970,12 +1006,13 @@ gboolean hcid_dbus_register_device(uint16_t id) dbus_connection_flush(connection); failed: - dbus_message_unref(message); - - ret = register_dbus_path(path, DEVICE_PATH_ID, id, &obj_dev_vtable, FALSE); - + if (message) + dbus_message_unref(message); + if (ret && default_dev < 0) default_dev = id; + if (dd >= 0) + close(dd); return ret; } @@ -1945,7 +1982,7 @@ failed: return reply; } -static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data) +static DBusMessage* handle_device_set_property_req(DBusMessage *msg, void *data) { const struct service_data *handlers = set_property_services; DBusMessageIter iter; @@ -1979,7 +2016,7 @@ static DBusMessage* handle_device_set_propety_req(DBusMessage *msg, void *data) return reply; } -static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data) +static DBusMessage* handle_device_get_property_req(DBusMessage *msg, void *data) { const struct service_data *handlers = get_property_services; DBusMessageIter iter; @@ -2005,7 +2042,36 @@ static DBusMessage* handle_device_get_propety_req(DBusMessage *msg, void *data) return reply; } -static DBusMessage* handle_device_set_propety_req_name(DBusMessage *msg, void *data) +static void send_property_changed_signal(const int devid, const char *prop_name, const int prop_type, void *value) +{ + DBusMessage *message = NULL; + char path[MAX_PATH_LENGTH]; + + snprintf(path, sizeof(path)-1, "%s/hci%d", DEVICE_PATH, devid); + path[MAX_PATH_LENGTH-1]='\0'; + + message = dbus_message_new_signal(path, DEVICE_INTERFACE, + BLUEZ_HCI_PROPERTY_CHANGED); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); + goto failed; + } + dbus_message_append_args(message, + DBUS_TYPE_STRING, &prop_name, + prop_type, value, + DBUS_TYPE_INVALID); + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS PropertChanged(%s) signal",prop_name); + goto failed; + } + +failed: + if (message) + dbus_message_unref(message); +} + +static DBusMessage* handle_device_set_property_req_name(DBusMessage *msg, void *data) { struct hci_dbus_data *dbus_data = data; DBusMessageIter iter; @@ -2066,8 +2132,6 @@ failed: void hcid_dbus_setname_complete(bdaddr_t *local) { - DBusMessage *message = NULL; - char path[MAX_PATH_LENGTH]; char *local_addr; bdaddr_t tmp; int id; @@ -2085,15 +2149,6 @@ void hcid_dbus_setname_complete(bdaddr_t *local) goto failed; } - snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); - - message = dbus_message_new_signal(path, DEVICE_INTERFACE, - BLUEZ_HCI_SET_NAME); - if (message == NULL) { - syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); - goto failed; - } - dd = hci_open_dev(id); memset(&rq, 0, sizeof(rq)); if (dd < 0) { @@ -2118,27 +2173,19 @@ void hcid_dbus_setname_complete(bdaddr_t *local) } strncpy(name,pname,sizeof(name)-1); - name[248]='\0'; + name[248] = '\0'; pname = name; - dbus_message_append_args(message, - DBUS_TYPE_STRING, &pname, - DBUS_TYPE_INVALID); - - if (dbus_connection_send(connection, message, NULL) == FALSE) { - syslog(LOG_ERR, "Can't send D-BUS NameChanged signal"); - goto failed; - } + send_property_changed_signal(id, DEV_PROPERTY_NAME, DBUS_TYPE_STRING, &pname); dbus_connection_flush(connection); failed: if (dd >= 0) close(dd); - dbus_message_unref(message); bt_free(local_addr); } -static DBusMessage* handle_device_get_propety_req_name(DBusMessage *msg, void *data) +static DBusMessage* handle_device_get_property_req_name(DBusMessage *msg, void *data) { struct hci_dbus_data *dbus_data = data; DBusMessage *reply = NULL; @@ -2194,6 +2241,184 @@ failed: return reply; } +static DBusMessage* write_scan_enable(DBusMessage *msg, void *data, gboolean ispscan) +{ + struct hci_dbus_data *dbus_data = data; + DBusMessageIter iter; + DBusMessage *reply = NULL; + int dd = -1; + read_scan_enable_rp rp; + uint8_t enable; + uint8_t status; + uint8_t scan_change, scan_keep; + struct hci_request rq; + gboolean prop_value; /* new requested value for the iscan or pscan */ + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_next(&iter); + dbus_message_iter_get_basic(&iter, &prop_value); + + dd = hci_open_dev(dbus_data->dev_id); + if (dd < 0) { + syslog(LOG_ERR, "HCI device open failed: hci%d", dbus_data->dev_id); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); + goto failed; + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_SCAN_ENABLE; + rq.rparam = &rp; + rq.rlen = READ_SCAN_ENABLE_RP_SIZE; + + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, "Sending read scan enable command failed: %s (%d)", + strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + + if (rp.status) { + syslog(LOG_ERR, "Getting scan enable failed with status 0x%02x", + rp.status); + reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + rp.status); + goto failed; + } + + if (ispscan) { /* Page scan */ + scan_change = SCAN_PAGE; + scan_keep = SCAN_INQUIRY; + } else { /* Inquiry scan */ + scan_change = SCAN_INQUIRY; + scan_keep = SCAN_PAGE; + } + + /* This is an optimization. We want to avoid overwrite the value + if the requested scan property will not change. */ + if (prop_value && !(rp.enable & scan_change)) + /* Enable the requested scan type (e.g. page scan). Keep the + the other type untouched. */ + enable = (rp.enable & scan_keep) | scan_change; + else if (!prop_value && (rp.enable & scan_change)) + /* Disable the requested scan type (e.g. page scan). Keep the + the other type untouched. */ + enable = (rp.enable & scan_keep); + else { /* Property not changed. Do nothing. Return ok. */ + reply = dbus_message_new_method_return(msg); + goto failed; + } + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_SCAN_ENABLE; + rq.cparam = &enable; + rq.clen = sizeof(enable); + rq.rparam = &status; + rq.rlen = sizeof(status); + + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, "Sending write scan enable command failed: %s (%d)", + strerror(errno), errno); + reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); + goto failed; + } + if (status) { + syslog(LOG_ERR, "Setting scan enable failed with status 0x%02x", rp.status); + reply = bluez_new_failure_msg(msg, BLUEZ_EBT_OFFSET + rp.status); + goto failed; + } + reply = dbus_message_new_method_return(msg); + +failed: + if (dd >= 0) + close(dd); + return reply; + +} + +void hcid_dbus_setscan_enable_complete(bdaddr_t *local) +{ + char *local_addr; + char path[MAX_PATH_LENGTH]; + bdaddr_t tmp; + int id; + int dd = -1; + gboolean se; + read_scan_enable_rp rp; + struct hci_request rq; + struct hci_dbus_data *pdata = NULL; + uint32_t old_data; + + baswap(&tmp, local); local_addr = batostr(&tmp); + id = hci_devid(local_addr); + if (id < 0) { + syslog(LOG_ERR, "No matching device id for %s", local_addr); + goto failed; + } + + snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); + + dd = hci_open_dev(id); + memset(&rq, 0, sizeof(rq)); + + if (dd < 0) { + syslog(LOG_ERR, "HCI device open failed: hci%d", id); + goto failed; + } + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_SCAN_ENABLE; + rq.rparam = &rp; + rq.rlen = READ_SCAN_ENABLE_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { + syslog(LOG_ERR, + "Sending read scan enable command failed: %s (%d)", + strerror(errno), errno); + goto failed; + } + if (rp.status) { + syslog(LOG_ERR, + "Getting scan enable failed with status 0x%02x", + rp.status); + goto failed; + } + + if (!dbus_connection_get_object_path_data(connection, path, (void*) &pdata)) { + syslog(LOG_ERR, "Getting path data failed!"); + goto failed; + } + + old_data = pdata->path_data; + pdata->path_data = rp.enable; + + /* If the new page scan flag is different from what we had, send a signal. */ + if((rp.enable & SCAN_PAGE) != (old_data & SCAN_PAGE)) { + se = (rp.enable & SCAN_PAGE); + send_property_changed_signal(id, DEV_PROPERTY_PSCAN, DBUS_TYPE_BOOLEAN, &se); + } + /* If the new inquity scan flag is different from what we had, send a signal. */ + if ((rp.enable & SCAN_INQUIRY) != (old_data & SCAN_INQUIRY)) { + se = (rp.enable & SCAN_INQUIRY); + send_property_changed_signal(id, DEV_PROPERTY_ISCAN, DBUS_TYPE_BOOLEAN, &se); + } + + dbus_connection_flush(connection); + +failed: + if (dd >= 0) + close(dd); + bt_free(local_addr); +} + +static DBusMessage* handle_device_set_property_req_pscan(DBusMessage *msg, void *data) +{ + return write_scan_enable(msg, data, TRUE); +} + +static DBusMessage* handle_device_set_property_req_iscan(DBusMessage *msg, void *data) +{ + return write_scan_enable(msg, data, FALSE); +} + static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data) { DBusMessageIter iter; @@ -2339,5 +2564,5 @@ static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data) syslog(LOG_INFO, "Not Implemented - path %s iface %s method %s", path, iface, method); - return NULL; + return bluez_new_failure_msg(msg, BLUEZ_EDBUS_NOT_IMPLEMENTED); } diff --git a/hcid/dbus.h b/hcid/dbus.h index 949f4b0d..aca14132 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -100,7 +100,7 @@ #define DEV_HCI_INTERFACE DEVICE_INTERFACE "." BLUEZ_HCI /* /org/bluez/Device signals */ -#define BLUEZ_HCI_SET_NAME "DeviceNameChanged" +#define BLUEZ_HCI_PROPERTY_CHANGED "PropertyChanged" /* Control interface signals */ #define BLUEZ_HCI_INQ_START "InquiryStart" @@ -227,6 +227,7 @@ #define BLUEZ_EDBUS_NO_MEM (0x05 + BLUEZ_EDBUS_OFFSET) #define BLUEZ_EDBUS_CONN_NOT_FOUND (0x06 + BLUEZ_EDBUS_OFFSET) #define BLUEZ_EDBUS_UNKNOWN_PATH (0x07 + BLUEZ_EDBUS_OFFSET) +#define BLUEZ_EDBUS_NOT_IMPLEMENTED (0x08 + BLUEZ_EDBUS_OFFSET) /* D-Bus error code, class BLUEZ_ESYSTEM_OFFSET */ #define BLUEZ_ESYSTEM_ENODEV (ENODEV + BLUEZ_ESYSTEM_OFFSET) diff --git a/hcid/hcid.h b/hcid/hcid.h index bac3ef26..3b15716e 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -135,6 +135,7 @@ void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer); void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason); void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status); void hcid_dbus_setname_complete(bdaddr_t *local); +void hcid_dbus_setscan_enable_complete(bdaddr_t *local); #else static inline void hcid_dbus_inquiry_start(bdaddr_t *local) {} static inline void hcid_dbus_inquiry_complete(bdaddr_t *local) {} @@ -145,6 +146,7 @@ static inline void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) {} static inline void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) {} static inline void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status) {} static inline void hcid_dbus_setname_complete(bdaddr_t *local) {} +static inline void hcid_dbus_setscan_enable_complete(bdaddr_t *local) {} #endif int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); diff --git a/hcid/security.c b/hcid/security.c index 76a8600d..eaaa7936 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -498,6 +498,8 @@ static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr) case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME): hcid_dbus_setname_complete(sba); break; + case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE): + hcid_dbus_setscan_enable_complete(sba); }; } -- cgit From f94e51848512064902c508cd8473dd6e1f1a0e5a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Dec 2005 16:58:53 +0000 Subject: Update changelog and bump version number --- ChangeLog | 8 ++++++++ configure.in | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 49c5d177..e31b5bda 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +ver 2.24: + Fix display of SDP text and data strings. + Add support for device scan property. + Update the D-Bus policy configuration file. + + Note: + This version needs at least bluez-libs-2.24 + ver 2.23: Update the new D-Bus interface. Make dfutool ready for big endian architectures. diff --git a/configure.in b/configure.in index 1e7bc838..14562143 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.23) +AM_INIT_AUTOMAKE(bluez-utils, 2.24) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From c96dc5deee19c9db3f15a352a5ec956e22f04d39 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Dec 2005 09:29:47 +0000 Subject: Another bunch of whitespace cleanups --- hcid/dbus.c | 114 +++++++++++++++++++++++++++++++++----------------------- hcid/security.c | 8 +++- 2 files changed, 73 insertions(+), 49 deletions(-) diff --git a/hcid/dbus.c b/hcid/dbus.c index c7d7f871..6f7e45dc 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -380,29 +380,32 @@ static void reply_handler_function(DBusPendingCall *call, void *user_data) syslog(LOG_ERR, "%s: %s", dbus_message_get_error_name(message), error_msg); hci_send_cmd(req->dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); - } else { - /* check signature */ - arg_type = dbus_message_iter_get_arg_type(&iter); - if (arg_type != DBUS_TYPE_STRING) { - syslog(LOG_ERR, "Wrong reply signature: expected PIN"); - hci_send_cmd(req->dev, OGF_LINK_CTL, - OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); - } else { - dbus_message_iter_get_basic(&iter, &pin); - len = strlen(pin); - - memset(&pr, 0, sizeof(pr)); - bacpy(&pr.bdaddr, &req->bda); - memcpy(pr.pin_code, pin, len); - pr.pin_len = len; - hci_send_cmd(req->dev, OGF_LINK_CTL, - OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); - } + + goto done; } - dbus_message_unref(message); + /* check signature */ + arg_type = dbus_message_iter_get_arg_type(&iter); + if (arg_type != DBUS_TYPE_STRING) { + syslog(LOG_ERR, "Wrong reply signature: expected PIN"); + hci_send_cmd(req->dev, OGF_LINK_CTL, + OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); + } else { + dbus_message_iter_get_basic(&iter, &pin); + len = strlen(pin); + + memset(&pr, 0, sizeof(pr)); + bacpy(&pr.bdaddr, &req->bda); + memcpy(pr.pin_code, pin, len); + pr.pin_len = len; + hci_send_cmd(req->dev, OGF_LINK_CTL, + OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); + } done: + if (message) + dbus_message_unref(message); + dbus_pending_call_unref(call); } @@ -673,7 +676,8 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) dbus_connection_flush(connection); failed: - dbus_message_unref(message); + if (message) + dbus_message_unref(message); bt_free(local_addr); bt_free(peer_addr); @@ -718,7 +722,8 @@ void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t statu dbus_connection_flush(connection); failed: - dbus_message_unref(message); + if (message) + dbus_message_unref(message); bt_free(local_addr); bt_free(peer_addr); @@ -771,7 +776,8 @@ void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t stat dbus_connection_flush(connection); failed: - dbus_message_unref(message); + if (message) + dbus_message_unref(message); bt_free(local_addr); bt_free(peer_addr); @@ -925,20 +931,21 @@ void hcid_dbus_exit(void) return; /* Unregister all paths in Device path hierarchy */ - if (dbus_connection_list_registered(connection, DEVICE_PATH, &children)) { - - for (; *children; children++) { - char dev_path[MAX_PATH_LENGTH]; + if (!dbus_connection_list_registered(connection, DEVICE_PATH, &children)) + goto done; - snprintf(dev_path, sizeof(dev_path), "%s/%s", DEVICE_PATH, *children); + for (; *children; children++) { + char dev_path[MAX_PATH_LENGTH]; - unregister_device_path(dev_path); - } + snprintf(dev_path, sizeof(dev_path), "%s/%s", DEVICE_PATH, *children); - if (*children) - dbus_free_string_array(children); + unregister_device_path(dev_path); } + if (*children) + dbus_free_string_array(children); + +done: unregister_dbus_path(DEVICE_PATH); unregister_dbus_path(MANAGER_PATH); @@ -986,7 +993,6 @@ gboolean hcid_dbus_register_device(uint16_t id) else pdata->path_data = rp.enable; /* Keep the current scan status */ - message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE, BLUEZ_MGR_DEV_ADDED); if (message == NULL) { @@ -1008,9 +1014,10 @@ gboolean hcid_dbus_register_device(uint16_t id) failed: if (message) dbus_message_unref(message); - + if (ret && default_dev < 0) default_dev = id; + if (dd >= 0) close(dd); @@ -1045,7 +1052,8 @@ gboolean hcid_dbus_unregister_device(uint16_t id) dbus_connection_flush(connection); failed: - dbus_message_unref(message); + if (message) + dbus_message_unref(message); ret = unregister_device_path(path); @@ -1090,7 +1098,8 @@ gboolean hcid_dbus_dev_up(uint16_t id) failed: /* if the signal can't be sent ignore the error */ - dbus_message_unref(message); + if (message) + dbus_message_unref(message); return TRUE; } @@ -1127,7 +1136,8 @@ gboolean hcid_dbus_dev_down(uint16_t id) failed: /* if the signal can't be sent ignore the error */ - dbus_message_unref(message); + if (message) + dbus_message_unref(message); return TRUE; } @@ -1232,6 +1242,7 @@ static void reconnect_timer_handler(int signum) if (hci_test_bit(HCI_UP, &dr->dev_opt)) hcid_dbus_dev_up(dr->dev_id); } + failed: if (sk >= 0) close(sk); @@ -2056,13 +2067,14 @@ static void send_property_changed_signal(const int devid, const char *prop_name, syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); goto failed; } + dbus_message_append_args(message, DBUS_TYPE_STRING, &prop_name, prop_type, value, DBUS_TYPE_INVALID); if (dbus_connection_send(connection, message, NULL) == FALSE) { - syslog(LOG_ERR, "Can't send D-BUS PropertChanged(%s) signal",prop_name); + syslog(LOG_ERR, "Can't send D-BUS PropertChanged(%s) signal", prop_name); goto failed; } @@ -2086,7 +2098,7 @@ static DBusMessage* handle_device_set_property_req_name(DBusMessage *msg, void * dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &str_name); - if(strlen(str_name) == 0) { + if (strlen(str_name) == 0) { syslog(LOG_ERR, "HCI change name failed - Invalid Name!"); reply = bluez_new_failure_msg(msg, BLUEZ_EDBUS_WRONG_PARAM); goto failed; @@ -2150,20 +2162,23 @@ void hcid_dbus_setname_complete(bdaddr_t *local) } dd = hci_open_dev(id); - memset(&rq, 0, sizeof(rq)); if (dd < 0) { syslog(LOG_ERR, "HCI device open failed: hci%d", id); + memset(&rq, 0, sizeof(rq)); } else { + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LOCAL_NAME; rq.rparam = &rp; rq.rlen = READ_LOCAL_NAME_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Sending getting name command failed: %s (%d)", strerror(errno), errno); rp.name[0] = '\0'; } + if (rp.status) { syslog(LOG_ERR, "Getting name failed with status 0x%02x", @@ -2172,7 +2187,7 @@ void hcid_dbus_setname_complete(bdaddr_t *local) } } - strncpy(name,pname,sizeof(name)-1); + strncpy(name, pname, sizeof(name) - 1); name[248] = '\0'; pname = name; @@ -2182,6 +2197,7 @@ void hcid_dbus_setname_complete(bdaddr_t *local) failed: if (dd >= 0) close(dd); + bt_free(local_addr); } @@ -2201,6 +2217,7 @@ static DBusMessage* handle_device_get_property_req_name(DBusMessage *msg, void * reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV); goto failed; } + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LOCAL_NAME; @@ -2359,22 +2376,23 @@ void hcid_dbus_setscan_enable_complete(bdaddr_t *local) snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id); dd = hci_open_dev(id); - memset(&rq, 0, sizeof(rq)); - if (dd < 0) { syslog(LOG_ERR, "HCI device open failed: hci%d", id); goto failed; } + + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_SCAN_ENABLE; rq.rparam = &rp; rq.rlen = READ_SCAN_ENABLE_RP_SIZE; + if (hci_send_req(dd, &rq, 100) < 0) { - syslog(LOG_ERR, - "Sending read scan enable command failed: %s (%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Sending read scan enable command failed: %s (%d)", + strerror(errno), errno); goto failed; } + if (rp.status) { syslog(LOG_ERR, "Getting scan enable failed with status 0x%02x", @@ -2406,6 +2424,7 @@ void hcid_dbus_setscan_enable_complete(bdaddr_t *local) failed: if (dd >= 0) close(dd); + bt_free(local_addr); } @@ -2530,7 +2549,8 @@ failed: * Section reserved to Manager D-Bus services * *****************************************************************/ -static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data) { +static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data) +{ char path[MAX_PATH_LENGTH]; char *pptr = path; DBusMessage *reply = NULL; @@ -2555,7 +2575,7 @@ failed: return reply; } -static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data) +static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data) { const char *path = dbus_message_get_path(msg); const char *iface = dbus_message_get_interface(msg); diff --git a/hcid/security.c b/hcid/security.c index eaaa7936..60204c45 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -117,6 +117,7 @@ static struct link_key *__get_link_key(int f, bdaddr_t *sba, bdaddr_t *dba) break; } } + return key; } @@ -131,7 +132,9 @@ static struct link_key *get_link_key(bdaddr_t *sba, bdaddr_t *dba) else if (errno != ENOENT) syslog(LOG_ERR, "Link key database open failed: %s (%d)", strerror(errno), errno); + close(f); + return key; } @@ -197,7 +200,7 @@ static void save_link_key(struct link_key *key) strerror(errno), errno); goto failed; } - + if (write_n(f, key, sizeof(*key)) < 0) { syslog(LOG_ERR, "Link key database write failed: %s (%d)", strerror(errno), errno); @@ -280,7 +283,9 @@ static int read_default_pin_code(void) hcid.pin_file, strerror(errno), errno); len = -1; } + fclose(f); + return len; } @@ -871,5 +876,4 @@ void init_security_data(void) } pairing = hcid.pairing; - return; } -- cgit From f2e48c44a7e4c9ee31b8ce2e302186f6047cfeab Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 13:28:56 +0000 Subject: Update copyright information --- README | 2 +- alsa/pcm_a2dp.c | 2 +- alsa/sbc.c | 2 +- alsa/sbc.h | 2 +- common/test_textfile.c | 2 +- common/textfile.c | 2 +- common/textfile.h | 2 +- cups/hcrp.c | 2 +- cups/main.c | 2 +- cups/sdp.c | 2 +- cups/spp.c | 2 +- daemon/main.c | 2 +- dund/dun.c | 2 +- dund/dund.h | 2 +- dund/lib.h | 2 +- dund/main.c | 2 +- dund/msdun.c | 2 +- dund/sdp.c | 2 +- extra/bcm203x.c | 2 +- fuse/main.c | 2 +- hcid/dbus.c | 2 +- hcid/dbus.h | 2 +- hcid/hcid.h | 2 +- hcid/kword.c | 2 +- hcid/kword.h | 2 +- hcid/lexer.l | 2 +- hcid/lib.c | 2 +- hcid/lib.h | 2 +- hcid/main.c | 2 +- hcid/parser.y | 2 +- hcid/security.c | 2 +- hcid/storage.c | 2 +- hidd/fakehid.c | 2 +- hidd/hidd.h | 2 +- hidd/main.c | 2 +- hidd/sdp.c | 2 +- hidd/uinput.h | 2 +- pand/bnep.c | 2 +- pand/main.c | 2 +- pand/pand.h | 2 +- pand/sdp.c | 2 +- rfcomm/kword.c | 2 +- rfcomm/kword.h | 2 +- rfcomm/lexer.l | 2 +- rfcomm/main.c | 2 +- rfcomm/parser.y | 2 +- sdpd/cstate.c | 2 +- sdpd/main.c | 2 +- sdpd/request.c | 2 +- sdpd/sdpd.h | 2 +- sdpd/service.c | 2 +- sdpd/servicedb.c | 2 +- test/attest.c | 2 +- test/bdaddr.c | 2 +- test/hciemu.c | 2 +- test/hstest.c | 2 +- test/l2test.c | 2 +- test/rctest.c | 2 +- test/scotest.c | 2 +- tools/avctrl.c | 2 +- tools/bccmd.c | 2 +- tools/ciptool.c | 2 +- tools/csr.c | 2 +- tools/csr.h | 2 +- tools/csr_3wire.c | 2 +- tools/csr_bcsp.c | 2 +- tools/csr_h4.c | 2 +- tools/csr_hci.c | 2 +- tools/csr_usb.c | 2 +- tools/dfu.c | 2 +- tools/dfu.h | 2 +- tools/dfutool.c | 2 +- tools/hciattach.c | 2 +- tools/hciconfig.c | 2 +- tools/hcisecfilter.c | 2 +- tools/hcitool.c | 2 +- tools/hid2hci.c | 2 +- tools/l2ping.c | 2 +- tools/oui.c | 2 +- tools/oui.h | 2 +- tools/ppporc.c | 2 +- tools/sdptool.c | 2 +- 82 files changed, 82 insertions(+), 82 deletions(-) diff --git a/README b/README index 0ae4eb5f..abd8bd4e 100644 --- a/README +++ b/README @@ -3,7 +3,7 @@ BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated Copyright (C) 2002-2003 Maxim Krasnyansky -Copyright (C) 2002-2005 Marcel Holtmann +Copyright (C) 2002-2006 Marcel Holtmann Bluetooth utilities diff --git a/alsa/pcm_a2dp.c b/alsa/pcm_a2dp.c index 6bd4d721..89a53211 100644 --- a/alsa/pcm_a2dp.c +++ b/alsa/pcm_a2dp.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This library is free software; you can redistribute it and/or diff --git a/alsa/sbc.c b/alsa/sbc.c index 9b9df4dd..c32665be 100644 --- a/alsa/sbc.c +++ b/alsa/sbc.c @@ -2,7 +2,7 @@ * * Bluetooth low-complexity, subband codec (SBC) library * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * Copyright (C) 2004-2005 Henryk Ploetz * * diff --git a/alsa/sbc.h b/alsa/sbc.h index ae1896ff..51243196 100644 --- a/alsa/sbc.h +++ b/alsa/sbc.h @@ -2,7 +2,7 @@ * * Bluetooth low-complexity, subband codec (SBC) library * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * Copyright (C) 2004-2005 Henryk Ploetz * * diff --git a/common/test_textfile.c b/common/test_textfile.c index 1c6be660..80761526 100644 --- a/common/test_textfile.c +++ b/common/test_textfile.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/common/textfile.c b/common/textfile.c index b2134562..906c230d 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/common/textfile.h b/common/textfile.h index 4f428ad0..803fc231 100644 --- a/common/textfile.h +++ b/common/textfile.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/cups/hcrp.c b/cups/hcrp.c index 2ee0e16c..c613b4fc 100644 --- a/cups/hcrp.c +++ b/cups/hcrp.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/cups/main.c b/cups/main.c index dce6145b..65216a07 100644 --- a/cups/main.c +++ b/cups/main.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/cups/sdp.c b/cups/sdp.c index 8d856499..6584f530 100644 --- a/cups/sdp.c +++ b/cups/sdp.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/cups/spp.c b/cups/spp.c index 3f3f1431..968cd61e 100644 --- a/cups/spp.c +++ b/cups/spp.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/daemon/main.c b/daemon/main.c index 8d8c2099..f23a1471 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/dund/dun.c b/dund/dun.c index 3de858d9..2a4a5cc6 100644 --- a/dund/dun.c +++ b/dund/dun.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/dund/dund.h b/dund/dund.h index 7ed9e23e..5a9a116d 100644 --- a/dund/dund.h +++ b/dund/dund.h @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/dund/lib.h b/dund/lib.h index 9d66bdb1..8cd51440 100644 --- a/dund/lib.h +++ b/dund/lib.h @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/dund/main.c b/dund/main.c index 32b7351a..4aedebd7 100644 --- a/dund/main.c +++ b/dund/main.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/dund/msdun.c b/dund/msdun.c index cba1bbfe..90c732ed 100644 --- a/dund/msdun.c +++ b/dund/msdun.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/dund/sdp.c b/dund/sdp.c index 54b40ca2..bf190422 100644 --- a/dund/sdp.c +++ b/dund/sdp.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/extra/bcm203x.c b/extra/bcm203x.c index 135d003f..008307c3 100644 --- a/extra/bcm203x.c +++ b/extra/bcm203x.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2001-2002 Maxim Krasnyansky - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/fuse/main.c b/fuse/main.c index 46bc4c25..fe8086aa 100644 --- a/fuse/main.c +++ b/fuse/main.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/dbus.c b/hcid/dbus.c index 6f7e45dc..f68ae732 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/dbus.h b/hcid/dbus.h index aca14132..da031108 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/hcid.h b/hcid/hcid.h index 3b15716e..c7aa0315 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/kword.c b/hcid/kword.c index 19b54566..0edf099c 100644 --- a/hcid/kword.c +++ b/hcid/kword.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/kword.h b/hcid/kword.h index 77f9b487..63ff5133 100644 --- a/hcid/kword.h +++ b/hcid/kword.h @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/lexer.l b/hcid/lexer.l index d9585959..fb73bbac 100644 --- a/hcid/lexer.l +++ b/hcid/lexer.l @@ -5,7 +5,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/lib.c b/hcid/lib.c index a0457ad4..e52e9b37 100644 --- a/hcid/lib.c +++ b/hcid/lib.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/lib.h b/hcid/lib.h index eb6154f6..74687fad 100644 --- a/hcid/lib.h +++ b/hcid/lib.h @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/main.c b/hcid/main.c index 5ff9fcf3..50cf86de 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/parser.y b/hcid/parser.y index dd90037f..948793cb 100644 --- a/hcid/parser.y +++ b/hcid/parser.y @@ -5,7 +5,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/security.c b/hcid/security.c index 60204c45..755db966 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hcid/storage.c b/hcid/storage.c index e18076dc..02c5dc0c 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hidd/fakehid.c b/hidd/fakehid.c index 61f33ce8..0d87335b 100644 --- a/hidd/fakehid.c +++ b/hidd/fakehid.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hidd/hidd.h b/hidd/hidd.h index ca9712aa..5e9fd311 100644 --- a/hidd/hidd.h +++ b/hidd/hidd.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hidd/main.c b/hidd/main.c index 3a41410c..cecd4bf0 100644 --- a/hidd/main.c +++ b/hidd/main.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hidd/sdp.c b/hidd/sdp.c index c86fb2ff..62e4ca3a 100644 --- a/hidd/sdp.c +++ b/hidd/sdp.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/hidd/uinput.h b/hidd/uinput.h index 3a4d6860..3e5890b9 100644 --- a/hidd/uinput.h +++ b/hidd/uinput.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/pand/bnep.c b/pand/bnep.c index 6c1d205b..3e7283f3 100644 --- a/pand/bnep.c +++ b/pand/bnep.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/pand/main.c b/pand/main.c index 576472b7..485a120d 100644 --- a/pand/main.c +++ b/pand/main.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/pand/pand.h b/pand/pand.h index 1e4509f9..d4a39fa4 100644 --- a/pand/pand.h +++ b/pand/pand.h @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/pand/sdp.c b/pand/sdp.c index 0edaf8f3..1b1343ae 100644 --- a/pand/sdp.c +++ b/pand/sdp.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/kword.c b/rfcomm/kword.c index 578a8435..c0d3583d 100644 --- a/rfcomm/kword.c +++ b/rfcomm/kword.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/kword.h b/rfcomm/kword.h index 9247e1aa..013b9c86 100644 --- a/rfcomm/kword.h +++ b/rfcomm/kword.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/lexer.l b/rfcomm/lexer.l index fb0b5e04..1a95e1b2 100644 --- a/rfcomm/lexer.l +++ b/rfcomm/lexer.l @@ -3,7 +3,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/main.c b/rfcomm/main.c index 48c09682..d4ed9a48 100644 --- a/rfcomm/main.c +++ b/rfcomm/main.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/rfcomm/parser.y b/rfcomm/parser.y index c0e3eda7..e22e3ef1 100644 --- a/rfcomm/parser.y +++ b/rfcomm/parser.y @@ -3,7 +3,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/sdpd/cstate.c b/sdpd/cstate.c index 6cb8abbd..d09e9423 100644 --- a/sdpd/cstate.c +++ b/sdpd/cstate.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/main.c b/sdpd/main.c index 0181657c..dd725c81 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/request.c b/sdpd/request.c index e0331683..9e3f966f 100644 --- a/sdpd/request.c +++ b/sdpd/request.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/sdpd.h b/sdpd/sdpd.h index 94bd9056..e73936c3 100644 --- a/sdpd/sdpd.h +++ b/sdpd/sdpd.h @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/service.c b/sdpd/service.c index 71b141bc..0bdc87fb 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/sdpd/servicedb.c b/sdpd/servicedb.c index d2c08493..7e8b5d19 100644 --- a/sdpd/servicedb.c +++ b/sdpd/servicedb.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * diff --git a/test/attest.c b/test/attest.c index 10aec939..59ab1d29 100644 --- a/test/attest.c +++ b/test/attest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2001-2005 Marcel Holtmann + * Copyright (C) 2001-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/bdaddr.c b/test/bdaddr.c index be1419d8..ede77049 100644 --- a/test/bdaddr.c +++ b/test/bdaddr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/hciemu.c b/test/hciemu.c index be033c2a..f6a35044 100644 --- a/test/hciemu.c +++ b/test/hciemu.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2000-2002 Maxim Krasnyansky - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/hstest.c b/test/hstest.c index bea4d3a4..cda9101c 100644 --- a/test/hstest.c +++ b/test/hstest.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/l2test.c b/test/l2test.c index f231587e..14d6d0e1 100644 --- a/test/l2test.c +++ b/test/l2test.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/rctest.c b/test/rctest.c index 724460c7..39ec51b7 100644 --- a/test/rctest.c +++ b/test/rctest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/test/scotest.c b/test/scotest.c index 169f39b7..281e34cb 100644 --- a/test/scotest.c +++ b/test/scotest.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/avctrl.c b/tools/avctrl.c index 06540ef5..c01e7d31 100644 --- a/tools/avctrl.c +++ b/tools/avctrl.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/bccmd.c b/tools/bccmd.c index 78018d48..62ffd0ce 100644 --- a/tools/bccmd.c +++ b/tools/bccmd.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/ciptool.c b/tools/ciptool.c index e30db09a..8f967858 100644 --- a/tools/ciptool.c +++ b/tools/ciptool.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr.c b/tools/csr.c index 39293fa8..eec6c0e6 100644 --- a/tools/csr.c +++ b/tools/csr.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr.h b/tools/csr.h index d75e3995..f1c63117 100644 --- a/tools/csr.h +++ b/tools/csr.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_3wire.c b/tools/csr_3wire.c index 322fb437..0999efc0 100644 --- a/tools/csr_3wire.c +++ b/tools/csr_3wire.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_bcsp.c b/tools/csr_bcsp.c index 2e1cea6e..77766114 100644 --- a/tools/csr_bcsp.c +++ b/tools/csr_bcsp.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_h4.c b/tools/csr_h4.c index 1e051903..8a3ff7fe 100644 --- a/tools/csr_h4.c +++ b/tools/csr_h4.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_hci.c b/tools/csr_hci.c index ebeb8aa7..4f33d0ae 100644 --- a/tools/csr_hci.c +++ b/tools/csr_hci.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/csr_usb.c b/tools/csr_usb.c index 617e7ccf..75354fd0 100644 --- a/tools/csr_usb.c +++ b/tools/csr_usb.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfu.c b/tools/dfu.c index 436b2e02..200426ff 100644 --- a/tools/dfu.c +++ b/tools/dfu.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfu.h b/tools/dfu.h index 54992e03..9cfe70fa 100644 --- a/tools/dfu.h +++ b/tools/dfu.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/dfutool.c b/tools/dfutool.c index eb087011..8d5e9194 100644 --- a/tools/dfutool.c +++ b/tools/dfutool.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciattach.c b/tools/hciattach.c index d0e03cce..6a806039 100644 --- a/tools/hciattach.c +++ b/tools/hciattach.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hciconfig.c b/tools/hciconfig.c index 47488546..703bdbd8 100644 --- a/tools/hciconfig.c +++ b/tools/hciconfig.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hcisecfilter.c b/tools/hcisecfilter.c index 1d557ce1..6114f57f 100644 --- a/tools/hcisecfilter.c +++ b/tools/hcisecfilter.c @@ -3,7 +3,7 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hcitool.c b/tools/hcitool.c index 9ae42a12..85404afc 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/hid2hci.c b/tools/hid2hci.c index 8a19a880..7e033755 100644 --- a/tools/hid2hci.c +++ b/tools/hid2hci.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2003-2005 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/l2ping.c b/tools/l2ping.c index 3b46675d..0fe3d11a 100644 --- a/tools/l2ping.c +++ b/tools/l2ping.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/oui.c b/tools/oui.c index b68ae04b..cc695a90 100644 --- a/tools/oui.c +++ b/tools/oui.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/oui.h b/tools/oui.h index 93cc7b01..c166038f 100644 --- a/tools/oui.h +++ b/tools/oui.h @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2005 Marcel Holtmann + * Copyright (C) 2004-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/ppporc.c b/tools/ppporc.c index e8275641..45e23549 100644 --- a/tools/ppporc.c +++ b/tools/ppporc.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/tools/sdptool.c b/tools/sdptool.c index b3124c58..689f724d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2005 Marcel Holtmann + * Copyright (C) 2002-2006 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * Copyright (C) 2002-2003 Jean Tourrilhes * -- cgit From 4fe03a99ce951164c711e7f2146f2bee6df44c64 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 13:31:18 +0000 Subject: Use %jx instead of %llx for uint64_t and int64_t --- tools/sdptool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 689f724d..8749e0b5 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -586,7 +586,7 @@ static void print_raw_data(sdp_data_t *data, int indent) printf("UINT32 0x%08x\n", data->val.uint32); break; case SDP_UINT64: - printf("UINT64 0x%016llx\n", data->val.uint64); + printf("UINT64 0x%016jx\n", data->val.uint64); break; case SDP_UINT128: printf("UINT128 ...\n"); @@ -601,7 +601,7 @@ static void print_raw_data(sdp_data_t *data, int indent) printf("INT32 %d\n", data->val.int32); break; case SDP_INT64: - printf("INT64 %lld\n", data->val.int64); + printf("INT64 %jd\n", data->val.int64); break; case SDP_INT128: printf("INT128 ...\n"); -- cgit From a0de58e012d1d85dcbef1c52eb082ea6c8a8e9de Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 15:26:43 +0000 Subject: Add UUID for N-Gage games --- tools/sdptool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index 8749e0b5..39583530 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2435,6 +2435,9 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) return 0; } +static unsigned char ngage_uuid[] = { 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; + struct { char *name; uint16_t class; @@ -2474,6 +2477,7 @@ struct { { "PALMOS", 0, add_palmos, palmos_uuid }, { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, + { "NGAGE", 0, NULL, ngage_uuid }, { 0 } }; -- cgit From b27690df2da69d959a78d95483217a0a5c529cfb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 21:03:23 +0000 Subject: Add UUID for Apple Macintosh Attributes --- tools/sdptool.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index 39583530..ea4e4d3d 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2438,6 +2438,9 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) static unsigned char ngage_uuid[] = { 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x02, 0xEE, 0x00, 0x00, 0x01 }; +static unsigned char apple_uuid[] = { 0xf0, 0x72, 0x2e, 0x20, 0x0f, 0x8b, 0x4e, 0x90, + 0x8c, 0xc2, 0x1b, 0x46, 0xf5, 0xf2, 0xef, 0xe2 }; + struct { char *name; uint16_t class; @@ -2478,6 +2481,7 @@ struct { { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, { "NGAGE", 0, NULL, ngage_uuid }, + { "APPLE", 0, NULL, apple_uuid }, { 0 } }; -- cgit From f83f040580da69b2e95ac817d308724bc35e75da Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 4 Jan 2006 00:05:22 +0000 Subject: dd definitions for Apple Agent --- tools/sdptool.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/sdptool.c b/tools/sdptool.c index ea4e4d3d..2b291aa5 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -314,6 +314,7 @@ static struct uuid_def uuid16_names[] = { { 0x1303, "VideoSource", NULL, 0 }, { 0x1304, "VideoSink", NULL, 0 }, { 0x1305, "VideoDistribution", NULL, 0 }, + { 0x2112, "AppleAgent", NULL, 0 }, }; static const int uuid16_max = sizeof(uuid16_names)/sizeof(struct uuid_def); @@ -2483,6 +2484,8 @@ struct { { "NGAGE", 0, NULL, ngage_uuid }, { "APPLE", 0, NULL, apple_uuid }, + { "ISYNC", APPLE_AGENT_SVCLASS_ID, NULL, }, + { 0 } }; -- cgit From b769dcbea87081a6e0010db03a97f163256cd372 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 4 Jan 2006 01:38:54 +0000 Subject: Add Apple attributes and iSync records --- tools/sdptool.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 2b291aa5..ae2925cc 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -2442,6 +2442,85 @@ static unsigned char ngage_uuid[] = { 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x10, static unsigned char apple_uuid[] = { 0xf0, 0x72, 0x2e, 0x20, 0x0f, 0x8b, 0x4e, 0x90, 0x8c, 0xc2, 0x1b, 0x46, 0xf5, 0xf2, 0xef, 0xe2 }; +static int add_apple(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root; + uuid_t root_uuid; + uint32_t attr783 = 0x00000000; + uint32_t attr785 = 0x00000002; + uint16_t attr786 = 0x1234; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_attr_add_new(&record, 0x0780, SDP_UUID128, (void *) apple_uuid); + sdp_attr_add_new(&record, 0x0781, SDP_TEXT_STR8, (void *) "Macmini"); + sdp_attr_add_new(&record, 0x0782, SDP_TEXT_STR8, (void *) "PowerMac10,1"); + sdp_attr_add_new(&record, 0x0783, SDP_UINT32, (void *) &attr783); + sdp_attr_add_new(&record, 0x0784, SDP_TEXT_STR8, (void *) "1.6.6f22"); + sdp_attr_add_new(&record, 0x0785, SDP_UINT32, (void *) &attr785); + sdp_attr_add_new(&record, 0x0786, SDP_UUID16, (void *) &attr786); + + sdp_set_info_attr(&record, "Apple Macintosh Attributes", NULL, NULL); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Apple attribute service registered\n"); + + return 0; +} + +static int add_isync(sdp_session_t *session, svc_info_t *si) +{ + sdp_record_t record; + sdp_list_t *root, *svclass, *proto; + uuid_t root_uuid, svclass_uuid, serial_uuid, l2cap_uuid, rfcomm_uuid; + uint8_t channel = si->channel? si->channel: 8; + + memset(&record, 0, sizeof(record)); + record.handle = 0xffffffff; + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto = sdp_list_append(NULL, sdp_list_append(NULL, &l2cap_uuid)); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto = sdp_list_append(proto, sdp_list_append( + sdp_list_append(NULL, &rfcomm_uuid), sdp_data_alloc(SDP_UINT8, &channel))); + + sdp_set_access_protos(&record, sdp_list_append(NULL, proto)); + + sdp_uuid16_create(&serial_uuid, SERIAL_PORT_SVCLASS_ID); + svclass = sdp_list_append(NULL, &serial_uuid); + + sdp_uuid16_create(&svclass_uuid, APPLE_AGENT_SVCLASS_ID); + svclass = sdp_list_append(svclass, &svclass_uuid); + + sdp_set_service_classes(&record, svclass); + + sdp_set_info_attr(&record, "AppleAgent", "Bluetooth acceptor", "Apple Computer Ltd."); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + return -1; + } + + printf("Apple iSync service registered\n"); + + return 0; +} + struct { char *name; uint16_t class; @@ -2482,9 +2561,9 @@ struct { { "NOKID", 0, add_nokiaid, nokid_uuid }, { "PCSUITE", 0, add_pcsuite, pcsuite_uuid }, { "NGAGE", 0, NULL, ngage_uuid }, - { "APPLE", 0, NULL, apple_uuid }, + { "APPLE", 0, add_apple, apple_uuid }, - { "ISYNC", APPLE_AGENT_SVCLASS_ID, NULL, }, + { "ISYNC", APPLE_AGENT_SVCLASS_ID, add_isync, }, { 0 } }; -- cgit From 88e399ec1d771872d9ee895875218a3d3aa2f6ec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 Jan 2006 12:59:57 +0000 Subject: Allow null-terminated strings --- tools/sdptool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index ae2925cc..b3876233 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -662,11 +662,14 @@ static void print_raw_data(sdp_data_t *data, int indent) case SDP_TEXT_STR16: case SDP_TEXT_STR32: hex = 0; - for (i = 0; i < data->unitSize; i++) + for (i = 0; i < data->unitSize; i++) { + if (i == (data->unitSize - 1) && data->val.str[i] == '\0') + break; if (!isprint(data->val.str[i])) { hex = 1; break; } + } if (hex) { printf("Data"); for (i = 0; i < data->unitSize; i++) -- cgit From ea30752670dc9a522c0ef29c431c3a4cefd9cc83 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Jan 2006 15:08:42 +0000 Subject: Fix service record registration --- sdpd/service.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/sdpd/service.c b/sdpd/service.c index 0bdc87fb..cd40541b 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -137,21 +137,25 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) // save image of PDU: we need it when clients request this attribute rec = extract_pdu_server(&req->device, p, 0xffffffff, &scanned); - if (!rec) { - sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *)rsp->data); - rsp->data_size = sizeof(uint16_t); - return -1; - } + if (!rec) + goto invalid; - rec->handle = sdp_next_handle(); - if (rec->handle < 0x10000) - return -1; + if (rec->handle == 0xffffffff) { + rec->handle = sdp_next_handle(); + if (rec->handle < 0x10000) + goto invalid; + } else { + if (sdp_record_find(rec->handle)) + goto invalid; + } sdp_record_add(&req->device, rec); if (!(req->flags & SDP_RECORD_PERSIST)) sdp_svcdb_set_collectable(rec, req->sock); + handle = sdp_data_alloc(SDP_UINT32, &rec->handle); sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, handle); + /* * if the browse group descriptor is NULL, * ensure that the record belongs to the ROOT group @@ -161,12 +165,20 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); sdp_pattern_add_uuid(rec, &uuid); } + update_db_timestamp(); /* Build a rsp buffer */ sdp_put_unaligned(htonl(rec->handle), (uint32_t *)rsp->data); rsp->data_size = sizeof(uint32_t); + return 0; + +invalid: + sdp_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *) rsp->data); + rsp->data_size = sizeof(uint16_t); + + return -1; } /* -- cgit From e9799abfdd2520e3adbd5c3a1d27a9e466361598 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Jan 2006 15:09:53 +0000 Subject: Add support for the Handsfree Audio Gateway service record --- tools/sdptool.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index b3876233..55d7f590 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -1303,7 +1303,6 @@ end: return ret; } - static int add_headset(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -1424,6 +1423,73 @@ end: return ret; } +static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, svclass_uuid, ga_svclass_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel: 3; + uint16_t u16 = 0x17; + sdp_data_t *channel, *features; + uint8_t netid = 0x01; // ???? profile document + sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + //record.handle = 0xffffffff; + record.handle = 0x10001; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&svclass_uuid, HANDSFREE_AGW_SVCLASS_ID); + svclass_id = sdp_list_append(0, &svclass_uuid); + sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, HANDSFREE_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + features = sdp_data_alloc(SDP_UINT16, &u16); + sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Voice Gateway", 0, 0); + + sdp_attr_add(&record, SDP_ATTR_EXTERNAL_NETWORK, network); + + if (sdp_record_register(session, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Handsfree AG service registered\n"); +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + return ret; +} + static int add_simaccess(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -2541,6 +2607,7 @@ struct { { "HS", HEADSET_SVCLASS_ID, add_headset }, { "HF", HANDSFREE_SVCLASS_ID, add_handsfree }, + { "HFAG", HANDSFREE_AGW_SVCLASS_ID, add_handsfree_ag}, { "SAP", SAP_SVCLASS_ID, add_simaccess }, { "NAP", NAP_SVCLASS_ID, add_nap }, -- cgit From fc073b9af90ff44efcbb318633d026e754f86907 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Jan 2006 16:19:28 +0000 Subject: Redirect stdin, stdout, stderr to /dev/null for daemon --- sdpd/main.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sdpd/main.c b/sdpd/main.c index dd725c81..685ffa8b 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -301,8 +302,16 @@ static int become_daemon(void) return 0; setsid(); } - for (fd = 0; fd < 3; fd++) - close(fd); + + fd = open("/dev/null", O_RDWR); + if (fd != -1) { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + + if (fd > STDERR_FILENO) + close(fd); + } chdir("/"); return 1; -- cgit From 3b5b20a3873b4d52041baf1cb11fbd0965ed39b8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 10:32:28 +0000 Subject: Make use of the daemon() function --- sdpd/main.c | 42 +++++++++--------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/sdpd/main.c b/sdpd/main.c index 685ffa8b..663200be 100644 --- a/sdpd/main.c +++ b/sdpd/main.c @@ -30,7 +30,6 @@ #include #include -#include #include #include #include @@ -290,33 +289,6 @@ static void sig_term(int sig) exit(0); } -static int become_daemon(void) -{ - int fd; - - if (getppid() != 1) { - signal(SIGTTOU, SIG_IGN); - signal(SIGTTIN, SIG_IGN); - signal(SIGTSTP, SIG_IGN); - if (fork()) - return 0; - setsid(); - } - - fd = open("/dev/null", O_RDWR); - if (fd != -1) { - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - - if (fd > STDERR_FILENO) - close(fd); - } - - chdir("/"); - return 1; -} - static inline void handle_request(int sk, uint8_t *data, int len) { struct sockaddr_l2 sa; @@ -411,7 +383,7 @@ static struct option main_options[] = { int main(int argc, char **argv) { - int daemon = 1; + int daemonize = 1; int master = 0; int public = 0; int opt; @@ -419,7 +391,7 @@ int main(int argc, char **argv) while ((opt = getopt_long(argc, argv, "nmp", main_options, NULL)) != -1) switch (opt) { case 'n': - daemon = 0; + daemonize = 0; break; case 'm': master = 1; @@ -431,10 +403,13 @@ int main(int argc, char **argv) usage(); exit(0); } + openlog("sdpd", LOG_PID | LOG_NDELAY, LOG_DAEMON); - - if (daemon && !become_daemon()) - return 0; + + if (daemonize && daemon(0, 0)) { + SDPERR("Server startup failed: %s (%d)", strerror(errno), errno); + return -1; + } argc -= optind; argv += optind; @@ -490,6 +465,7 @@ int main(int argc, char **argv) } else check_active(&mask, num); } + exit: sdp_svcdb_reset(); return 0; -- cgit From 7d71cc206923e2eedbd3192dcc5f0b3fd9f63cef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 10:36:43 +0000 Subject: Some whitespace cleanups --- sdpd/service.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sdpd/service.c b/sdpd/service.c index cd40541b..aa62a559 100644 --- a/sdpd/service.c +++ b/sdpd/service.c @@ -55,12 +55,12 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h *scanned = sdp_extract_seqtype(p, &dtd, &seqlen); p += *scanned; - lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *)(p + sizeof(uint8_t)))); + lookAheadAttrId = ntohs(sdp_get_unaligned((uint16_t *) (p + sizeof(uint8_t)))); SDPDBG("Look ahead attr id : %d\n", lookAheadAttrId); if (lookAheadAttrId == SDP_ATTR_RECORD_HANDLE) { - handle = ntohl(sdp_get_unaligned((uint32_t *)(p + + handle = ntohl(sdp_get_unaligned((uint32_t *) (p + sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t)))); SDPDBG("SvcRecHandle : 0x%x\n", handle); @@ -85,9 +85,9 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p, uint32_t h int attrValueLength = 0; SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, localExtractedLength); - dtd = *(uint8_t *)p; + dtd = *(uint8_t *) p; - attrId = ntohs(sdp_get_unaligned((uint16_t *)(p + attrSize))); + attrId = ntohs(sdp_get_unaligned((uint16_t *) (p + attrSize))); attrSize += sizeof(uint16_t); SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attrId); @@ -169,7 +169,7 @@ int service_register_req(sdp_req_t *req, sdp_buf_t *rsp) update_db_timestamp(); /* Build a rsp buffer */ - sdp_put_unaligned(htonl(rec->handle), (uint32_t *)rsp->data); + sdp_put_unaligned(htonl(rec->handle), (uint32_t *) rsp->data); rsp->data_size = sizeof(uint32_t); return 0; @@ -189,16 +189,16 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) sdp_record_t *orec; int status = 0, scanned = 0; uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); - uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *) p)); SDPDBG(""); SDPDBG("Svc Rec Handle: 0x%x\n", handle); - + p += sizeof(uint32_t); orec = sdp_record_find(handle); - + SDPDBG("SvcRecOld: 0x%x\n", (uint32_t)orec); if (orec) { @@ -220,7 +220,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) status = SDP_INVALID_RECORD_HANDLE; p = rsp->data; - sdp_put_unaligned(htons(status), (uint16_t *)p); + sdp_put_unaligned(htons(status), (uint16_t *) p); rsp->data_size = sizeof(uint16_t); return status; } @@ -231,7 +231,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp) int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) { uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t); - uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *) p)); sdp_record_t *rec; int status = 0; @@ -253,7 +253,7 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp) } p = rsp->data; - sdp_put_unaligned(htons(status), (uint16_t *)p); + sdp_put_unaligned(htons(status), (uint16_t *) p); rsp->data_size = sizeof(uint16_t); return status; -- cgit From aebaa2bd80065ac380237d2f52bc675e4d1462d1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 10:43:04 +0000 Subject: Add support for choosing a specific service record handle --- tools/sdptool.c | 365 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 216 insertions(+), 149 deletions(-) diff --git a/tools/sdptool.c b/tools/sdptool.c index 55d7f590..02db6e2c 100644 --- a/tools/sdptool.c +++ b/tools/sdptool.c @@ -747,7 +747,7 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha sdp_list_t *attrid_list; uint32_t range = 0x0000ffff; sdp_record_t *rec; - + /* Get the old SDP record */ attrid_list = sdp_list_append(NULL, &range); rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attrid_list); @@ -794,7 +794,7 @@ static int set_attrib(sdp_session_t *sess, uint32_t handle, uint16_t attrib, cha } static struct option set_options[] = { - { "help", 0,0, 'h' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -819,6 +819,7 @@ static int cmd_setattr(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -835,8 +836,10 @@ static int cmd_setattr(int argc, char **argv) sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); if (!sess) return -1; + status = set_attrib(sess, handle, attrib, argv[2]); sdp_close(sess); + return status; } @@ -912,13 +915,13 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri printf("Service Record update failed (%d).\n", errno); return -1; } - } else { + } else printf("Failed to create pSequenceHolder\n"); - } /* Cleanup */ for (i = 0; i < argc; i++) free(allocArray[i]); + free(dtdArray); free(valueArray); @@ -926,7 +929,7 @@ static int set_attribseq(sdp_session_t *session, uint32_t handle, uint16_t attri } static struct option seq_options[] = { - { "help", 0,0, 'h' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -952,6 +955,7 @@ static int cmd_setseq(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -971,8 +975,10 @@ static int cmd_setseq(int argc, char **argv) sess = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0); if (!sess) return -1; + status = set_attribseq(sess, handle, attrib, argc, argv); sdp_close(sess); + return status; } @@ -991,7 +997,7 @@ static void print_service_desc(void *value, void *user) char str[MAX_LEN_PROTOCOL_UUID_STR]; sdp_data_t *p = (sdp_data_t *)value, *s; int i = 0, proto = 0; - + for (; p; p = p->next, i++) { switch (p->dtd) { case SDP_UUID16: @@ -1106,10 +1112,10 @@ static void print_service_attr(sdp_record_t *rec) * Support for Service (de)registration */ typedef struct { + uint32_t handle; char *name; char *provider; char *desc; - unsigned int class; unsigned int profile; unsigned int channel; @@ -1135,12 +1141,12 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) uuid_t root_uuid, sp_uuid, l2cap, rfcomm; sdp_profile_desc_t profile; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 1; + uint8_t u8 = si->channel ? si->channel : 1; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1179,13 +1185,16 @@ static int add_sp(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Serial Port service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1196,12 +1205,12 @@ static int add_dun(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 1; + uint8_t u8 = si->channel ? si->channel : 2; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&rootu, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &rootu); sdp_set_browse_groups(&record, root); @@ -1237,7 +1246,68 @@ static int add_dun(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Dial-Up Networking service registered\n"); + +end: + sdp_data_free(channel); + sdp_list_free(proto[0], 0); + sdp_list_free(proto[1], 0); + sdp_list_free(apseq, 0); + sdp_list_free(aproto, 0); + + return ret; +} + +static int add_fax(sdp_session_t *session, svc_info_t *si) +{ + sdp_list_t *svclass_id, *pfseq, *apseq, *root; + uuid_t root_uuid, fax_uuid, tel_uuid, l2cap_uuid, rfcomm_uuid; + sdp_profile_desc_t profile; + sdp_list_t *aproto, *proto[2]; + sdp_record_t record; + uint8_t u8 = si->channel? si->channel : 3; + sdp_data_t *channel; + int ret = 0; + + memset((void *)&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(0, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&fax_uuid, FAX_SVCLASS_ID); + svclass_id = sdp_list_append(0, &fax_uuid); + sdp_uuid16_create(&tel_uuid, GENERIC_TELEPHONY_SVCLASS_ID); + svclass_id = sdp_list_append(svclass_id, &tel_uuid); + sdp_set_service_classes(&record, svclass_id); + + sdp_uuid16_create(&profile.uuid, FAX_PROFILE_ID); + profile.version = 0x0100; + pfseq = sdp_list_append(0, &profile); + sdp_set_profile_descs(&record, pfseq); + + sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); + proto[0] = sdp_list_append(0, &l2cap_uuid); + apseq = sdp_list_append(0, proto[0]); + + sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); + proto[1] = sdp_list_append(0, &rfcomm_uuid); + channel = sdp_data_alloc(SDP_UINT8, &u8); + proto[1] = sdp_list_append(proto[1], channel); + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(0, apseq); + sdp_set_access_protos(&record, aproto); + + sdp_set_info_attr(&record, "Fax", 0, 0); + + if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { + printf("Service Record registration failed\n"); + ret = -1; + goto end; + } + printf("Fax service registered\n"); end: sdp_data_free(channel); sdp_list_free(proto[0], 0); @@ -1254,12 +1324,12 @@ static int add_lan(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 2; + uint8_t u8 = si->channel ? si->channel : 4; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1293,13 +1363,16 @@ static int add_lan(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("LAN Access service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1310,12 +1383,12 @@ static int add_headset(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 5; + uint8_t u8 = si->channel ? si->channel : 5; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1351,13 +1424,16 @@ static int add_headset(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Headset service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1368,13 +1444,13 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 3; + uint8_t u8 = si->channel ? si->channel : 6; uint16_t u16 = 0x31; - sdp_data_t *channel, *features; + sdp_data_t *channel, *features; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1413,13 +1489,16 @@ static int add_handsfree(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Handsfree service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1430,16 +1509,15 @@ static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 3; + uint8_t u8 = si->channel ? si->channel : 7; uint16_t u16 = 0x17; sdp_data_t *channel, *features; uint8_t netid = 0x01; // ???? profile document sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - //record.handle = 0xffffffff; - record.handle = 0x10001; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1480,13 +1558,16 @@ static int add_handsfree_ag(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("Handsfree AG service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1497,13 +1578,13 @@ static int add_simaccess(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile; sdp_list_t *aproto, *proto[2]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 3; + uint8_t u8 = si->channel? si->channel : 8; uint16_t u16 = 0x31; sdp_data_t *channel, *features; int ret = 0; memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1552,64 +1633,6 @@ end: return ret; } -static int add_fax(sdp_session_t *session, svc_info_t *si) -{ - sdp_list_t *svclass_id, *pfseq, *apseq, *root; - uuid_t root_uuid, fax_uuid, tel_uuid, l2cap_uuid, rfcomm_uuid; - sdp_profile_desc_t profile; - sdp_list_t *aproto, *proto[2]; - sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 3; - sdp_data_t *channel; - int ret = 0; - - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; - sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); - root = sdp_list_append(0, &root_uuid); - sdp_set_browse_groups(&record, root); - - sdp_uuid16_create(&fax_uuid, FAX_SVCLASS_ID); - svclass_id = sdp_list_append(0, &fax_uuid); - sdp_uuid16_create(&tel_uuid, GENERIC_TELEPHONY_SVCLASS_ID); - svclass_id = sdp_list_append(svclass_id, &tel_uuid); - sdp_set_service_classes(&record, svclass_id); - - sdp_uuid16_create(&profile.uuid, FAX_PROFILE_ID); - profile.version = 0x0100; - pfseq = sdp_list_append(0, &profile); - sdp_set_profile_descs(&record, pfseq); - - sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); - proto[0] = sdp_list_append(0, &l2cap_uuid); - apseq = sdp_list_append(0, proto[0]); - - sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); - proto[1] = sdp_list_append(0, &rfcomm_uuid); - channel = sdp_data_alloc(SDP_UINT8, &u8); - proto[1] = sdp_list_append(proto[1], channel); - apseq = sdp_list_append(apseq, proto[1]); - - aproto = sdp_list_append(0, apseq); - sdp_set_access_protos(&record, aproto); - - sdp_set_info_attr(&record, "Fax", 0, 0); - - if (sdp_device_record_register(session, &interface, &record, SDP_RECORD_PERSIST) < 0) { - printf("Service Record registration failed\n"); - ret = -1; - goto end; - } - printf("Fax service registered\n"); -end: - sdp_data_free(channel); - sdp_list_free(proto[0], 0); - sdp_list_free(proto[1], 0); - sdp_list_free(apseq, 0); - sdp_list_free(aproto, 0); - return ret; -} - static int add_opush(sdp_session_t *session, svc_info_t *si) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; @@ -1617,7 +1640,7 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[3]; sdp_record_t record; - uint8_t chan = si->channel? si->channel: 4; + uint8_t chan = si->channel ? si->channel : 9; sdp_data_t *channel; uint8_t formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; //uint8_t formats[] = { 0xff }; @@ -1627,8 +1650,8 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) sdp_data_t *sflist; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1673,7 +1696,9 @@ static int add_opush(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("OBEX Object Push service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); @@ -1681,6 +1706,7 @@ end: sdp_list_free(proto[2], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1691,12 +1717,12 @@ static int add_ftp(sdp_session_t *session, svc_info_t *si) sdp_profile_desc_t profile[1]; sdp_list_t *aproto, *proto[3]; sdp_record_t record; - uint8_t u8 = si->channel? si->channel: 4; + uint8_t u8 = si->channel ? si->channel: 10; sdp_data_t *channel; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1734,7 +1760,9 @@ static int add_ftp(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("OBEX File Transfer service registered\n"); + end: sdp_data_free(channel); sdp_list_free(proto[0], 0); @@ -1742,6 +1770,7 @@ end: sdp_list_free(proto[2], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1756,8 +1785,8 @@ static int add_nap(sdp_session_t *session, svc_info_t *si) sdp_data_t *psm, *version; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1807,7 +1836,9 @@ static int add_nap(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("NAP service registered\n"); + end: sdp_data_free(version); sdp_data_free(psm); @@ -1815,6 +1846,7 @@ end: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1829,8 +1861,8 @@ static int add_gn(sdp_session_t *session, svc_info_t *si) sdp_data_t *psm, *version; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1866,7 +1898,9 @@ static int add_gn(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("GN service registered\n"); + end: sdp_data_free(version); sdp_data_free(psm); @@ -1874,6 +1908,7 @@ end: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1888,8 +1923,8 @@ static int add_panu(sdp_session_t *session, svc_info_t *si) sdp_data_t *psm, *version; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1928,7 +1963,9 @@ static int add_panu(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("PANU service registered\n"); + end: sdp_data_free(version); sdp_data_free(psm); @@ -1936,6 +1973,7 @@ end: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -1950,8 +1988,8 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) sdp_data_t *network = sdp_data_alloc(SDP_UINT8, &netid); int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -1985,13 +2023,16 @@ static int add_ctp(sdp_session_t *session, svc_info_t *si) ret = -1; goto end; } + printf("CTP service registered\n"); + end: sdp_list_free(proto[0], 0); sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); sdp_data_free(network); + return ret; } @@ -2006,8 +2047,8 @@ static int add_a2source(sdp_session_t *session, svc_info_t *si) uint16_t lp = 0x0019, ver = 0x0100; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2051,6 +2092,7 @@ done: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -2065,8 +2107,8 @@ static int add_a2sink(sdp_session_t *session, svc_info_t *si) uint16_t lp = 0x0019, ver = 0x0100; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2110,6 +2152,7 @@ done: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -2124,8 +2167,8 @@ static int add_avrct(sdp_session_t *session, svc_info_t *si) uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2172,6 +2215,7 @@ done: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -2186,8 +2230,8 @@ static int add_avrtg(sdp_session_t *session, svc_info_t *si) uint16_t lp = 0x0017, ver = 0x0100, feat = 0x000f; int ret = 0; - memset((void *)&record, 0, sizeof(sdp_record_t)); - record.handle = 0xffffffff; + memset(&record, 0, sizeof(sdp_record_t)); + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(0, &root_uuid); sdp_set_browse_groups(&record, root); @@ -2234,6 +2278,7 @@ done: sdp_list_free(proto[1], 0); sdp_list_free(apseq, 0); sdp_list_free(aproto, 0); + return ret; } @@ -2247,7 +2292,7 @@ static int add_sr1(sdp_session_t *session, svc_info_t *si) uuid_t root_uuid, svclass_uuid; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2277,10 +2322,10 @@ static int add_syncml(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid, obex_uuid; - uint8_t channel = si->channel? si->channel: 15; + uint8_t channel = si->channel ? si->channel: 15; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2322,10 +2367,10 @@ static int add_activesync(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; - uint8_t channel = si->channel? si->channel: 21; + uint8_t channel = si->channel ? si->channel: 21; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2364,10 +2409,10 @@ static int add_hotsync(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; - uint8_t channel = si->channel? si->channel: 22; + uint8_t channel = si->channel ? si->channel: 22; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2408,7 +2453,7 @@ static int add_palmos(sdp_session_t *session, svc_info_t *si) uuid_t root_uuid, svclass_uuid; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2440,7 +2485,7 @@ static int add_nokiaid(sdp_session_t *session, svc_info_t *si) sdp_data_t *version = sdp_data_alloc(SDP_UINT16, &verid); memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2471,10 +2516,10 @@ static int add_pcsuite(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid; - uint8_t channel = si->channel? si->channel: 14; + uint8_t channel = si->channel ? si->channel: 14; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2521,7 +2566,7 @@ static int add_apple(sdp_session_t *session, svc_info_t *si) uint16_t attr786 = 0x1234; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2552,10 +2597,10 @@ static int add_isync(sdp_session_t *session, svc_info_t *si) sdp_record_t record; sdp_list_t *root, *svclass, *proto; uuid_t root_uuid, svclass_uuid, serial_uuid, l2cap_uuid, rfcomm_uuid; - uint8_t channel = si->channel? si->channel: 8; + uint8_t channel = si->channel ? si->channel : 16; memset(&record, 0, sizeof(record)); - record.handle = 0xffffffff; + record.handle = si->handle; sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); @@ -2641,36 +2686,42 @@ struct { /* Add local service */ static int add_service(bdaddr_t *bdaddr, svc_info_t *si) { - int i; - sdp_session_t *sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); + sdp_session_t *sess; + int i, ret = -1; + + if (!si->name) + return -1; + sess = sdp_connect(&interface, BDADDR_LOCAL, SDP_RETRY_IF_BUSY); if (!sess) return -1; - if (si->name) - for (i = 0; service[i].name; i++) - if (!strcasecmp(service[i].name, si->name)) { - int ret = -1; - if (service[i].add) - ret = service[i].add(sess, si); - free(si->name); - sdp_close(sess); - return ret; - } + + for (i = 0; service[i].name; i++) + if (!strcasecmp(service[i].name, si->name)) { + if (service[i].add) + ret = service[i].add(sess, si); + goto done; + } + printf("Unknown service name: %s\n", si->name); + +done: free(si->name); sdp_close(sess); - return -1; + + return ret; } static struct option add_options[] = { - { "help", 0,0, 'h' }, - { "channel", 1,0, 'c' }, - { 0, 0, 0, 0} + { "help", 0, 0, 'h' }, + { "handle", 1, 0, 'r' }, + { "channel", 1, 0, 'c' }, + { 0, 0, 0, 0 } }; static char *add_help = "Usage:\n" - "\tadd [--channel=CHAN] service\n"; + "\tadd [--handle=RECORD_HANDLE --channel=CHANNEL] service\n"; static int cmd_add(int argc, char **argv) { @@ -2678,8 +2729,16 @@ static int cmd_add(int argc, char **argv) int opt; memset(&si, 0, sizeof(si)); + si.handle = 0xffffffff; + for_each_opt(opt, add_options, 0) { switch (opt) { + case 'r': + if (strncasecmp(optarg, "0x", 2)) + si.handle = atoi(optarg); + else + si.handle = strtol(optarg + 2, NULL, 16); + break; case 'c': si.channel = atoi(optarg); break; @@ -2688,6 +2747,7 @@ static int cmd_add(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -2724,6 +2784,7 @@ static int del_service(bdaddr_t *bdaddr, void *arg) attr = sdp_list_append(0, &range); rec = sdp_service_attr_req(sess, handle, SDP_ATTR_REQ_RANGE, attr); sdp_list_free(attr, 0); + if (!rec) { printf("Service Record not found.\n"); sdp_close(sess); @@ -2738,11 +2799,12 @@ static int del_service(bdaddr_t *bdaddr, void *arg) printf("Service Record deleted.\n"); sdp_close(sess); + return 0; } static struct option del_options[] = { - { "help", 0,0, 'h' }, + { "help", 0, 0, 'h' }, { 0, 0, 0, 0 } }; @@ -2761,6 +2823,7 @@ static int cmd_del(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -2917,6 +2980,7 @@ static int cmd_browse(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -2930,9 +2994,9 @@ static int cmd_browse(int argc, char **argv) } static struct option search_options[] = { - { "help", 0,0, 'h' }, - { "bdaddr", 1,0, 'b' }, - { "tree", 0,0, 't' }, + { "help", 0, 0, 'h' }, + { "bdaddr", 1, 0, 'b' }, + { "tree", 0, 0, 't' }, { "raw", 0, 0, 'r' }, { 0, 0, 0, 0} }; @@ -2946,7 +3010,7 @@ static char *search_help = * Search for a specific SDP service * * Note : we should support multiple services on the command line : - * sdptool search 0x0100 0x000f 0x1002 + * sdptool search 0x0100 0x000f 0x1002 * (this would search a service supporting both L2CAP and BNEP directly in * the top level browse group) */ @@ -2980,6 +3044,7 @@ static int cmd_search(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -2989,7 +3054,7 @@ static int cmd_search(int argc, char **argv) } /* Note : we need to find a way to support search combining - * multiple services - Jean II */ + * multiple services */ context.svc = strdup(argv[0]); if (!strncasecmp(context.svc, "0x", 2)) { int num; @@ -3026,7 +3091,6 @@ static int cmd_search(int argc, char **argv) /* * Show how to get a specific SDP record by its handle. * Not really useful to the user, just show how it can be done... - * Jean II */ static int get_service(bdaddr_t *bdaddr, struct search_context *context, int quite) { @@ -3046,6 +3110,7 @@ static int get_service(bdaddr_t *bdaddr, struct search_context *context, int qui rec = sdp_service_attr_req(session, context->handle, SDP_ATTR_REQ_RANGE, attrid); sdp_list_free(attrid, 0); sdp_close(session); + if (!rec) { if (!quite) { printf("Service get request failed.\n"); @@ -3112,6 +3177,7 @@ static int cmd_records(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -3177,6 +3243,7 @@ static int cmd_get(int argc, char **argv) return -1; } } + argc -= optind; argv += optind; @@ -3202,7 +3269,7 @@ static struct { { "add", cmd_add, "Add local service" }, { "del", cmd_del, "Delete local service" }, { "get", cmd_get, "Get local service" }, - { "setattr", cmd_setattr, "Set/Add attribute to a SDP record" }, + { "setattr", cmd_setattr, "Set/Add attribute to a SDP record" }, { "setseq", cmd_setseq, "Set/Add attribute sequence to a SDP record" }, { 0, 0, 0 } }; @@ -3277,5 +3344,5 @@ int main(int argc, char **argv) if (strncmp(command[i].cmd, argv[0], 4) == 0) return command[i].func(argc, argv); - return -1; + return 1; } -- cgit From 67d4c0b35c9708ad5d637bd868c76bc7bb99bf71 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 10:48:22 +0000 Subject: Add support for dialup/telephone connections --- dund/dund.1 | 3 +++ dund/dund.h | 1 + dund/main.c | 11 +++++++++-- dund/sdp.c | 8 +++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/dund/dund.1 b/dund/dund.1 index 895fc97a..09fb7f75 100644 --- a/dund/dund.1 +++ b/dund/dund.1 @@ -14,6 +14,9 @@ Show active DUN connections \fB\-\-listen\fR \fB\-s\fR Listen for DUN connections .TP +\fB\-\-dialup\fR \fB\-u\fR +Listen for dialup/telephone connections +.TP \fB\-\-connect\fR \fB\-c\fR Create DUN connection .TP diff --git a/dund/dund.h b/dund/dund.h index 5a9a116d..c8761dac 100644 --- a/dund/dund.h +++ b/dund/dund.h @@ -33,6 +33,7 @@ #define LANACCESS 0 #define MROUTER 1 #define ACTIVESYNC 2 +#define DIALUP 3 /* DUN functions */ int dun_init(void); diff --git a/dund/main.c b/dund/main.c index 4aedebd7..06055fde 100644 --- a/dund/main.c +++ b/dund/main.c @@ -398,10 +398,11 @@ static struct option main_lopts[] = { { "msdun", 2, 0, 'X' }, { "activesync", 0, 0, 'a' }, { "mrouter", 1, 0, 'm' }, + { "dialup", 1, 0, 'u' }, { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:i:lnp::DQ::AESMP:C::P:Xa"; +static char main_sopts[] = "hsc:k:Kr:i:lnp::DQ::AESMP:C::P:Xam:u"; static char main_help[] = "Bluetooth LAP (LAN Access over PPP) daemon version " VERSION " \n" @@ -410,6 +411,7 @@ static char main_help[] = "Options:\n" "\t--show --list -l Show active LAP connections\n" "\t--listen -s Listen for LAP connections\n" + "\t--dialup -u Pretend to be a dialup/telephone\n" "\t--connect -c Create LAP connection\n" "\t--mrouter -m Create mRouter connection\n" "\t--search -Q[duration] Search and connect\n" @@ -539,6 +541,11 @@ int main(int argc, char **argv) type = MROUTER; break; + case 'u': + mode = LISTEN; + type = DIALUP; + break; + case 'h': default: printf(main_help); @@ -599,7 +606,7 @@ int main(int argc, char **argv) fd = open("/dev/null", O_RDWR); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); close(fd); - + setsid(); chdir("/"); } diff --git a/dund/sdp.c b/dund/sdp.c index bf190422..f0ea08b5 100644 --- a/dund/sdp.c +++ b/dund/sdp.c @@ -98,6 +98,9 @@ int dun_sdp_register(bdaddr_t *device, uint8_t channel, int type) case ACTIVESYNC: sdp_uuid128_create(&dun, (void *) async_uuid); break; + case DIALUP: + sdp_uuid16_create(&dun, DIALUP_NET_SVCLASS_ID); + break; default: sdp_uuid16_create(&dun, LAN_ACCESS_SVCLASS_ID); break; @@ -106,7 +109,7 @@ int dun_sdp_register(bdaddr_t *device, uint8_t channel, int type) svclass = sdp_list_append(NULL, &dun); sdp_set_service_classes(record, svclass); - if (type == LANACCESS) { + if (type == LANACCESS || type == DIALUP) { sdp_uuid16_create(&profile[0].uuid, LAN_ACCESS_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(NULL, &profile[0]); @@ -120,6 +123,9 @@ int dun_sdp_register(bdaddr_t *device, uint8_t channel, int type) case ACTIVESYNC: sdp_set_info_attr(record, "ActiveSync", NULL, NULL); break; + case DIALUP: + sdp_set_info_attr(record, "Dialup Networking", NULL, NULL); + break; default: sdp_set_info_attr(record, "LAN Access Point", NULL, NULL); break; -- cgit From 454c7500c64ab132f44aebbd7086a9748e5c4436 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 10:52:35 +0000 Subject: Use MAP_PRIVATE instead of MAP_SHARED for textfile_put() --- common/textfile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/textfile.c b/common/textfile.c index 906c230d..ec445b1a 100644 --- a/common/textfile.c +++ b/common/textfile.c @@ -148,7 +148,7 @@ int textfile_put(char *pathname, char *key, char *value) goto unlock; } - map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, fd, 0); + map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_LOCKED, fd, 0); if (!map || map == MAP_FAILED) { err = errno; goto unlock; -- cgit From d9787e55f6d5153ed7825022297f51a9442434ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 23:16:38 +0000 Subject: Update changelog and bump version number --- ChangeLog | 14 ++++++++++++++ configure.in | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e31b5bda..ed357ec1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +ver 2.25: + Use %jx instead of %llx for uint64_t and int64_t. + Allow null-terminated text strings. + Add UUID for N-Gage games. + Add UUID for Apple Macintosh Attributes. + Add Apple attributes and iSync records. + Add definitions for Apple Agent. + Add support for the Handsfree Audio Gateway service. + Add support for choosing a specific record handle. + Add support for dialup/telephone connections. + + Note: + This version needs at least bluez-libs-2.25 + ver 2.24: Fix display of SDP text and data strings. Add support for device scan property. diff --git a/configure.in b/configure.in index 14562143..d21e98e1 100644 --- a/configure.in +++ b/configure.in @@ -1,7 +1,7 @@ AC_PREREQ(2.50) AC_INIT() -AM_INIT_AUTOMAKE(bluez-utils, 2.24) +AM_INIT_AUTOMAKE(bluez-utils, 2.25) AM_CONFIG_HEADER(config.h) AM_MAINTAINER_MODE -- cgit From da7aed3f3f9377f68a7aebe645ef4e8b1f6f1d92 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Jan 2006 17:45:51 +0000 Subject: Use the correct device for reading the local clock --- tools/hcitool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hcitool.c b/tools/hcitool.c index 85404afc..2ad26bfe 100644 --- a/tools/hcitool.c +++ b/tools/hcitool.c @@ -1973,7 +1973,7 @@ static void cmd_clock(int dev_id, int argc, char **argv) else bacpy(&bdaddr, BDADDR_ANY); - if (!bacmp(&bdaddr, BDADDR_ANY)) + if (dev_id < 0 && !bacmp(&bdaddr, BDADDR_ANY)) dev_id = hci_get_route(NULL); if (dev_id < 0) { -- cgit From 8064ef2f30e3327646e96e90c5b8815ba5622225 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 19 Jan 2006 15:00:50 +0000 Subject: Add missing break in switch statement --- hcid/security.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hcid/security.c b/hcid/security.c index 755db966..9364938f 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -505,6 +505,7 @@ static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr) break; case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE): hcid_dbus_setscan_enable_complete(sba); + break; }; } @@ -745,6 +746,7 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer case EVT_DISCONN_COMPLETE: disconn_complete(dev, &di->bdaddr, ptr); break; + case EVT_AUTH_COMPLETE: auth_complete(dev, &di->bdaddr, ptr); break; -- cgit From c0ac4b3ddff4543901155eb2d7c28952a694f686 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 20 Jan 2006 01:42:21 +0000 Subject: Include a devup script option --- pand/main.c | 118 +++++++++++++++++++++++++++++++++++------------------------- pand/pand.1 | 10 +++--- pand/pand.h | 4 --- 3 files changed, 76 insertions(+), 56 deletions(-) diff --git a/pand/main.c b/pand/main.c index 485a120d..c01bb6b6 100644 --- a/pand/main.c +++ b/pand/main.c @@ -48,19 +48,19 @@ #include "pand.h" -static uint16_t role = BNEP_SVC_PANU; /* Local role (ie service) */ -static uint16_t service = BNEP_SVC_NAP; /* Remote service */ - -static int detach = 1; -static int persist; -static int use_sdp = 1; -static int use_cache; -static int auth; -static int encrypt; -static int secure; -static int master; -static int cleanup; -static int search_duration = 10; +static uint16_t role = BNEP_SVC_PANU; /* Local role (ie service) */ +static uint16_t service = BNEP_SVC_NAP; /* Remote service */ + +static int detach = 1; +static int persist; +static int use_sdp = 1; +static int use_cache; +static int auth; +static int encrypt; +static int secure; +static int master; +static int cleanup; +static int search_duration = 10; static struct { int valid; @@ -70,10 +70,12 @@ static struct { static char netdev[16] = "bnep%d"; static char *pidfile = NULL; +static char *devupcmd = NULL; + static bdaddr_t src_addr = *BDADDR_ANY; static int src_dev = -1; -volatile int terminate; +static volatile int terminate; static void do_kill(char *dst); @@ -87,12 +89,13 @@ enum { static void run_devup(char *dev, char *dst, int sk, int nsk) { - char *argv[4], prog[40]; + char *argv[4]; struct sigaction sa; - sprintf(prog, "%s/%s", PAND_CONFIG_DIR, PAND_DEVUP_CMD); + if (!devupcmd) + return; - if (access(prog, R_OK | X_OK)) + if (access(devupcmd, R_OK | X_OK)) return; if (fork()) @@ -103,17 +106,19 @@ static void run_devup(char *dev, char *dst, int sk, int nsk) if (nsk >= 0) close(nsk); - + memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_DFL; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); - argv[0] = prog; + argv[0] = devupcmd; argv[1] = dev; argv[2] = dst; argv[3] = NULL; - execv(prog, argv); + + execv(devupcmd, argv); + exit(1); } @@ -131,7 +136,7 @@ static int do_listen(void) sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (sk < 0) { syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", - strerror(errno), errno); + strerror(errno), errno); return -1; } @@ -141,7 +146,8 @@ static int do_listen(void) l2a.l2_psm = htobs(BNEP_PSM); if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { - syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Bind failed. %s(%d)", + strerror(errno), errno); return -1; } @@ -150,14 +156,14 @@ static int do_listen(void) olen = sizeof(l2o); if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) { syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)", - strerror(errno), errno); + strerror(errno), errno); return -1; } l2o.imtu = l2o.omtu = BNEP_MTU; if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) { syslog(LOG_ERR, "Failed to set L2CAP options. %s(%d)", - strerror(errno), errno); + strerror(errno), errno); return -1; } @@ -173,7 +179,8 @@ static int do_listen(void) lm |= L2CAP_LM_SECURE; if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { - syslog(LOG_ERR, "Failed to set link mode. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Failed to set link mode. %s(%d)", + strerror(errno), errno); return -1; } @@ -184,7 +191,8 @@ static int do_listen(void) int nsk; nsk = accept(sk, (struct sockaddr *) &l2a, &alen); if (nsk < 0) { - syslog(LOG_ERR, "Accept failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Accept failed. %s(%d)", + strerror(errno), errno); continue; } @@ -192,7 +200,8 @@ static int do_listen(void) case 0: break; case -1: - syslog(LOG_ERR, "Fork failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Fork failed. %s(%d)", + strerror(errno), errno); default: close(nsk); continue; @@ -202,12 +211,13 @@ static int do_listen(void) char str[40]; ba2str(&l2a.l2_bdaddr, str); - syslog(LOG_INFO, "New connection from %s %s", str, netdev); + syslog(LOG_INFO, "New connection from %s %s", + str, netdev); run_devup(netdev, str, sk, nsk); } else { syslog(LOG_ERR, "Connection failed. %s(%d)", - strerror(errno), errno); + strerror(errno), errno); } close(nsk); @@ -233,7 +243,7 @@ static int w4_hup(int sk) if (errno == EINTR || errno == EAGAIN) continue; syslog(LOG_ERR, "Poll failed. %s(%d)", - strerror(errno), errno); + strerror(errno), errno); return 1; } @@ -269,7 +279,7 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (sk < 0) { syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", - strerror(errno), errno); + strerror(errno), errno); return -1; } @@ -285,8 +295,8 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) bacpy(&l2a.l2_bdaddr, &src_addr); if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) - syslog(LOG_ERR, "Bind failed. %s(%d)", - strerror(errno), errno); + syslog(LOG_ERR, "Bind failed. %s(%d)", + strerror(errno), errno); memset(&l2a, 0, sizeof(l2a)); l2a.l2_family = AF_BLUETOOTH; @@ -312,7 +322,7 @@ static int create_connection(char *dst, bdaddr_t *bdaddr) r = 0; } else { syslog(LOG_ERR, "Connect to %s failed. %s(%d)", - dst, strerror(errno), errno); + dst, strerror(errno), errno); r = 1; } @@ -365,7 +375,8 @@ static int do_connect(void) ii = NULL; n = hci_inquiry(src_dev, search_duration, 0, NULL, &ii, 0); if (n < 0) { - syslog(LOG_ERR, "Inquiry failed. %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Inquiry failed. %s(%d)", + strerror(errno), errno); continue; } @@ -406,29 +417,30 @@ static void do_kill(char *dst) bnep_kill_all_connections(); } -void sig_hup(int sig) +static void sig_hup(int sig) { return; } -void sig_term(int sig) +static void sig_term(int sig) { terminate = 1; } -int write_pidfile(void) +static int write_pidfile(void) { int fd; FILE *f; pid_t pid; - do { + do { fd = open(pidfile, O_WRONLY|O_TRUNC|O_CREAT|O_EXCL, 0644); if (fd == -1) { /* Try to open the file for read. */ fd = open(pidfile, O_RDONLY); if(fd == -1) { - syslog(LOG_ERR, "Could not read old pidfile: %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Could not read old pidfile: %s(%d)", + strerror(errno), errno); return -1; } @@ -440,7 +452,8 @@ int write_pidfile(void) */ f = fdopen(fd, "r"); if (!f) { - syslog(LOG_ERR, "Could not fdopen old pidfile: %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Could not fdopen old pidfile: %s(%d)", + strerror(errno), errno); close(fd); return -1; } @@ -469,17 +482,18 @@ int write_pidfile(void) f = fdopen(fd, "w"); if (!f) { - syslog(LOG_ERR, "Could not fdopen new pidfile: %s(%d)", strerror(errno), errno); + syslog(LOG_ERR, "Could not fdopen new pidfile: %s(%d)", + strerror(errno), errno); close(fd); unlink(pidfile); return -1; } + fprintf(f, "%d\n", getpid()); fclose(f); + return 0; } - - static struct option main_lopts[] = { { "help", 0, 0, 'h' }, @@ -503,11 +517,12 @@ static struct option main_lopts[] = { { "master", 0, 0, 'M' }, { "cache", 0, 0, 'C' }, { "pidfile", 1, 0, 'P' }, + { "devup", 1, 0, 'u' }, { "autozap", 0, 0, 'z' }, { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:d:e:i:lnp::DQ::AESMC::P:z"; +static char main_sopts[] = "hsc:k:Kr:d:e:i:lnp::DQ::AESMC::P:u:z"; static char main_help[] = "Bluetooth PAN daemon version " VERSION " \n" @@ -533,7 +548,8 @@ static char main_help[] = "\t--nodetach -n Do not become a daemon\n" "\t--persist -p[interval] Persist mode\n" "\t--cache -C[valid] Cache addresses\n" - "\t--pidfile -P Create PID file\n"; + "\t--pidfile -P Create PID file\n" + "\t--devup -u