From a48d8b4639f36e6fc2d7e87cac92e178674caaa1 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 8 Mar 2002 21:10:06 +0000 Subject: Initial revision --- src/Makefile.am | 10 + src/Makefile.in | 353 ++++++++++++++++++++++++++++++++ src/bluetooth.c | 164 +++++++++++++++ src/hci.c | 624 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1151 insertions(+) create mode 100644 src/Makefile.am create mode 100644 src/Makefile.in create mode 100644 src/bluetooth.c create mode 100644 src/hci.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 00000000..cc7b582b --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,10 @@ +# +# $Id$ +# + +lib_LTLIBRARIES = libbluetooth.la + +libbluetooth_la_SOURCES = bluetooth.c hci.c +libbluetooth_la_LDFLAGS = -version-info 1:0:0 + +CFLAGS += -I../include diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 00000000..6da2db02 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,353 @@ +# 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 = : +host_alias = @host_alias@ +host_triplet = @host@ +AR = @AR@ +AS = @AS@ +CC = @CC@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +EXEEXT = @EXEEXT@ +LD = @LD@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ + +lib_LTLIBRARIES = libbluetooth.la + +libbluetooth_la_SOURCES = bluetooth.c hci.c +libbluetooth_la_LDFLAGS = -version-info 1:0:0 + +CFLAGS = -I../include +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libbluetooth_la_LIBADD = +libbluetooth_la_OBJECTS = bluetooth.lo hci.lo +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +DEP_FILES = .deps/bluetooth.P .deps/hci.P +SOURCES = $(libbluetooth_la_SOURCES) +OBJECTS = $(libbluetooth_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .obj .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libbluetooth.la: $(libbluetooth_la_OBJECTS) $(libbluetooth_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libbluetooth_la_LDFLAGS) $(libbluetooth_la_OBJECTS) $(libbluetooth_la_LIBADD) $(LIBS) + +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 = src + +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 src/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-libLTLIBRARIES +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLTLIBRARIES +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) + + +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-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags mostlyclean-depend \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ + clean-depend clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-depend \ + distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + 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-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool 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/src/bluetooth.c b/src/bluetooth.c new file mode 100644 index 00000000..6dfccf44 --- /dev/null +++ b/src/bluetooth.c @@ -0,0 +1,164 @@ +/* + 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 + +void baswap(bdaddr_t *dst, bdaddr_t *src) +{ + register unsigned char * d = (unsigned char *)dst; + register unsigned char * s = (unsigned char *)src; + register int i; + for(i=0; i<6; i++) + d[i] = s[5-i]; +} + +char * batostr(bdaddr_t *ba) +{ + static char str[2][18]; + static int i = 1; + + i ^= 1; + sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", + ba->b[0], ba->b[1], ba->b[2], + ba->b[3], ba->b[4], ba->b[5]); + return str[i]; +} + +bdaddr_t * strtoba(char *str) +{ + static unsigned char ba[2][sizeof(bdaddr_t)]; + static int i = 1; + register char *ptr = str; + register int x; + + i ^= 1; + for(x=0; x<6; x++){ + ba[i][x] = (uint8_t) strtol(ptr, NULL, 16); + if( x!=5 && !(ptr=strchr(ptr,':')) ) + ptr = ":00:00:00:00:00"; + ptr++; + } + return (bdaddr_t *) ba[i]; +} + +int ba2str(bdaddr_t *ba, char *str) +{ + return sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", + ba->b[0], ba->b[1], ba->b[2], + ba->b[3], ba->b[4], ba->b[5]); +} + +int str2ba(char *str, bdaddr_t *ba) +{ + unsigned char *b = (void *) ba; + char *ptr = str; + register int x; + + for (x=0; x < 6; x++) { + b[x] = (uint8_t) strtol(ptr, NULL, 16); + if (x!=5 && !(ptr=strchr(ptr, ':'))) + ptr = ":00:00:00:00:00"; + ptr++; + } + return 0; +} + +/* Bluetooth error codes to Unix errno mapping */ +int bterr(uint16_t code) +{ + switch(code) { + case 0: + return 0; + case 0x01: + return EBADRQC; + case 0x02: + return ENOTCONN; + case 0x03: + return EIO; + case 0x04: + return EHOSTDOWN; + case 0x05: + return EACCES; + case 0x06: + return EINVAL; + case 0x07: + return ENOMEM; + case 0x08: + return ETIMEDOUT; + case 0x09: + return EMLINK; + case 0x0a: + return EMLINK; + case 0x0b: + return EALREADY; + case 0x0c: + return EBUSY; + case 0x0d: + case 0x0e: + case 0x0f: + return ECONNREFUSED; + case 0x10: + return ETIMEDOUT; + case 0x11: + case 0x27: + case 0x29: + case 0x20: + return EOPNOTSUPP; + case 0x12: + return EINVAL; + case 0x13: + case 0x14: + case 0x15: + return ECONNRESET; + case 0x16: + return ECONNABORTED; + case 0x17: + return ELOOP; + case 0x18: + return EACCES; + case 0x1a: + return EPROTONOSUPPORT; + case 0x1b: + return ECONNREFUSED; + case 0x19: + case 0x1e: + case 0x23: + case 0x24: + case 0x25: + return EPROTO; + default: + return ENOSYS; + } +} diff --git a/src/hci.c b/src/hci.c new file mode 100644 index 00000000..e9693d3e --- /dev/null +++ b/src/hci.c @@ -0,0 +1,624 @@ +/* + 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 + +typedef struct { + char *str; unsigned int val; +} hci_map; + +static char * hci_uint2str(hci_map *m, unsigned int val) +{ + static char str[50]; + char *ptr = str; + + *ptr = 0; + while (m->str) { + if ((unsigned int) m->val & val) + ptr += sprintf(ptr, "%s ", m->str); + m++; + } + return str; +} + +int hci_str2uint(hci_map *map, char *str, unsigned int *val) +{ + char *t, *ptr; + hci_map *m; + int set; + + if (!str) + return 0; + + str = ptr = strdup(str); + *val = set = 0; + + while ((t=strsep(&ptr, ","))) { + for (m=map; m->str; m++) { + if (!strcasecmp(m->str,t)) { + *val |= (unsigned int) m->val; + set = 1; + } + } + } + free(str); + + return set; +} + +char *hci_dtypetostr(int type) +{ + switch (type) { + case HCI_VHCI: + return "VHCI"; + case HCI_USB: + return "USB "; + case HCI_PCCARD: + return "PCCARD"; + case HCI_UART: + return "UART"; + default: + return "UKNW"; + } +} + +/* HCI dev flags mapping */ +hci_map dev_flags_map[] = { + { "UP", HCI_UP }, + { "INIT", HCI_INIT }, + { "RUNNING", HCI_RUNNING }, + { "RAW", HCI_RAW }, + { "PSCAN", HCI_PSCAN }, + { "ISCAN", HCI_ISCAN }, + { "IQUIRY", HCI_INQUIRY }, + { "AUTH", HCI_AUTH }, + { "ENCRYPT", HCI_ENCRYPT }, + { NULL } +}; +char *hci_dflagstostr(uint32_t flags) +{ + static char str[50]; + char *ptr = str; + hci_map *m = dev_flags_map; + + *ptr = 0; + + if (!hci_test_bit(HCI_UP, &flags)) + ptr += sprintf(ptr, "DOWN "); + + while (m->str) { + if (hci_test_bit(m->val, &flags)) + ptr += sprintf(ptr, "%s ", m->str); + m++; + } + return str; +} + +/* HCI packet type mapping */ +hci_map pkt_type_map[] = { + { "DM1", HCI_DM1 }, + { "DM3", HCI_DM3 }, + { "DM5", HCI_DM5 }, + { "DH1", HCI_DH1 }, + { "DH3", HCI_DH3 }, + { "DH5", HCI_DH5 }, + { "HV1", HCI_HV1 }, + { "HV2", HCI_HV2 }, + { "HV3", HCI_HV3 }, + { NULL } +}; +char *hci_ptypetostr(unsigned int ptype) +{ + return hci_uint2str(pkt_type_map, ptype); +} +int hci_strtoptype(char *str, unsigned int *val) +{ + return hci_str2uint(pkt_type_map, str, val); +} + +/* Link policy mapping */ +hci_map link_policy_map[] = { + { "NONE", 0 }, + { "RSWITCH", HCI_LP_RSWITCH }, + { "HOLD", HCI_LP_HOLD }, + { "SNIFF", HCI_LP_SNIFF }, + { "PARK", HCI_LP_PARK }, + { NULL } +}; +char *hci_lptostr(unsigned int lp) +{ + return hci_uint2str(link_policy_map, lp); +} +int hci_strtolp(char *str, unsigned int *val) +{ + return hci_str2uint(link_policy_map, str, val); +} + +/* Link mode mapping */ +hci_map link_mode_map[] = { + { "NONE", 0 }, + { "ACCEPT", HCI_LM_ACCEPT }, + { "MASTER", HCI_LM_MASTER }, + { "AUTH", HCI_LM_AUTH }, + { "ENCRYPT", HCI_LM_ENCRYPT}, + { "TRUSTED", HCI_LM_TRUSTED}, + { NULL } +}; +char *hci_lmtostr(unsigned int lm) +{ + static char str[50]; + + str[0] = 0; + if (!(lm & HCI_LM_MASTER)) + strcpy(str, "SLAVE "); + + strcat(str, hci_uint2str(link_mode_map, lm)); + return str; +} +int hci_strtolm(char *str, unsigned int *val) +{ + return hci_str2uint(link_mode_map, str, val); +} + +/* HCI functions that do not require open device */ + +int hci_devinfo(int dev_id, struct hci_dev_info *di) +{ + int s, err; + + s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (s < 0) + return s; + + di->dev_id = dev_id; + err = ioctl(s, HCIGETDEVINFO, (void *) di); + close(s); + + return err; +} + +inquiry_info *hci_inquiry(int dev_id, int len, int *num_rsp, uint8_t *lap, long flags) +{ + struct hci_inquiry_req *ir; + char *buf, *ptr; + int s, err, size; + + if (!*num_rsp) + *num_rsp = 200; // enough ? + + size = sizeof(*ir) + (sizeof(inquiry_info) * (*num_rsp)); + if (!(buf = malloc(size))) + return NULL; + + ir = (void *)buf; + ir->dev_id = dev_id; + ir->num_rsp = *num_rsp; + ir->length = len; + ir->flags = flags; + + if (lap) { + memcpy(ir->lap, lap, 3); + } else { + ir->lap[0] = 0x33; + ir->lap[1] = 0x8b; + ir->lap[2] = 0x9e; + } + + if ((s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) + goto failed; + if (ioctl(s, HCIINQUIRY, (unsigned long)buf) < 0) + goto failed; + + size = sizeof(inquiry_info) * ir->num_rsp; + if (!(ptr = malloc(size))) + goto failed; + + memcpy(ptr, buf + sizeof(*ir), size); + *num_rsp = ir->num_rsp; + + free(buf); + close(s); + return (void *) ptr; + +failed: + err = errno; + free(buf); + close(s); + errno = err; + return NULL; +} + +/* Open HCI device. + * Returns device descriptor (dd). */ +int hci_open_dev(int dev_id) +{ + struct sockaddr_hci a; + int dd, err; + + /* Create HCI socket */ + dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (dd < 0) + return dd; + + /* Bind socket to the HCI device */ + a.hci_family = AF_BLUETOOTH; + a.hci_dev = dev_id; + if (bind(dd, (struct sockaddr *)&a, sizeof(a)) < 0) + goto failed; + + return dd; + +failed: + err = errno; + close(dd); + errno = err; + return -1; +} + +int hci_close_dev(int dd) +{ + return close(dd); +} + +/* HCI functions that require open device + * dd - Device descriptor returned by hci_dev_open. */ + +int hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) +{ + uint8_t type = HCI_COMMAND_PKT; + hci_command_hdr hc; + struct iovec iv[3]; + int ivn; + + hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); + hc.plen= plen; + + iv[0].iov_base = &type; + iv[0].iov_len = 1; + iv[1].iov_base = &hc; + iv[1].iov_len = HCI_COMMAND_HDR_SIZE; + ivn = 2; + + if (plen) { + iv[2].iov_base = param; + iv[2].iov_len = plen; + ivn = 3; + } + + while (writev(dd, iv, ivn) < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + return -1; + } + return 0; +} + +int hci_send_req(int dd, struct hci_request *r, int to) +{ + unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr; + uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + struct hci_filter nf, of; + hci_event_hdr *hdr; + int err, len, try; + + len = sizeof(of); + if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &len) < 0) + return -1; + + hci_filter_clear(&nf); + hci_filter_set_ptype(HCI_EVENT_PKT, &nf); + hci_filter_set_event(EVT_CMD_STATUS, &nf); + hci_filter_set_event(EVT_CMD_COMPLETE, &nf); + hci_filter_set_event(r->event, &nf); + hci_filter_set_opcode(opcode, &nf); + if (setsockopt(dd, SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) + return -1; + + if (hci_send_cmd(dd, r->ogf, r->ocf, r->clen, r->cparam) < 0) + goto failed; + + try = 10; + while (try--) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + + if (to) { + struct pollfd p; + int n; + + p.fd = dd; p.events = POLLIN; + while ((n = poll(&p, 1, to)) < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + goto failed; + } + + if (!n) { + errno = ETIMEDOUT; + goto failed; + } + + to -= 10; + if (to < 0) to = 0; + + } + + while ((len = read(dd, buf, sizeof(buf))) < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + goto failed; + } + + hdr = (void *)(buf + 1); + ptr = buf + (1 + HCI_EVENT_HDR_SIZE); + len -= (1 + HCI_EVENT_HDR_SIZE); + + switch (hdr->evt) { + case EVT_CMD_STATUS: + cs = (void *)ptr; + + if (cs->opcode != opcode) + continue; + + if (cs->status) { + errno = EIO; + goto failed; + } + break; + + case EVT_CMD_COMPLETE: + cc = (void *)ptr; + + if (cc->opcode != opcode) + continue; + + ptr += EVT_CMD_COMPLETE_SIZE; + len -= EVT_CMD_COMPLETE_SIZE; + + r->rlen = MIN(len, r->rlen); + memcpy(r->rparam, ptr, r->rlen); + goto done; + + default: + if (hdr->evt != r->event) + break; + + r->rlen = MIN(len, r->rlen); + memcpy(r->rparam, ptr, r->rlen); + goto done; + } + } + errno = ETIMEDOUT; + +failed: + err = errno; + setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of)); + errno = err; + return -1; + +done: + setsockopt(dd, SOL_HCI, HCI_FILTER, &of, sizeof(of)); + return 0; +} + +int hci_create_connection(int dd, bdaddr_t *ba, int ptype, int rswitch, int to) +{ + evt_conn_complete rp; + create_conn_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, ba); + cp.pkt_type = ptype; + cp.role_switch = rswitch; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_CREATE_CONN; + rq.event = EVT_CONN_COMPLETE; + rq.cparam = &cp; + rq.clen = CREATE_CONN_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CONN_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return rp.handle; +} + +int hci_disconnect(int dd, int hndl, int res, int to) +{ + evt_disconn_complete rp; + disconnect_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = hndl; + cp.reason = res; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.event = EVT_DISCONN_COMPLETE; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_DISCONN_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + return 0; +} + +int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +{ + evt_remote_name_req_complete rn; + remote_name_req_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, ba); + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_REMOTE_NAME_REQ; + rq.cparam = &cp; + rq.clen = REMOTE_NAME_REQ_CP_SIZE; + rq.event = EVT_REMOTE_NAME_REQ_COMPLETE; + rq.rparam = &rn; + rq.rlen = EVT_REMOTE_NAME_REQ_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rn.status) { + errno = EIO; + return -1; + } + + rn.name[247] = '\0'; + strncpy(name, rn.name, len); + return 0; +} + +int hci_read_remote_features(int dd, int hndl, uint8_t *features, int to) +{ + evt_read_remote_features_complete rp; + read_remote_features_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = hndl; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_READ_REMOTE_FEATURES; + rq.event = EVT_READ_REMOTE_FEATURES_COMPLETE; + rq.cparam = &cp; + rq.clen = READ_REMOTE_FEATURES_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(features, rp.features, 8); + return 0; +} + +int hci_read_remote_version(int dd, int hndl, struct hci_version *ver, int to) +{ + evt_read_remote_version_complete rp; + read_remote_version_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = hndl; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_READ_REMOTE_VERSION; + rq.event = EVT_READ_REMOTE_VERSION_COMPLETE; + rq.cparam = &cp; + rq.clen = READ_REMOTE_VERSION_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + ver->manufacturer = btohs(rp.manufacturer); + ver->lmp_ver = rp.lmp_ver; + ver->lmp_subver = btohs(rp.lmp_subver); + return 0; +} + +int hci_read_local_version(int dd, struct hci_version *ver, int to) +{ + read_local_version_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; + rq.cparam = NULL; + rq.clen = 0; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + + if (hci_send_req(dd, &rq, 1000) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + ver->manufacturer = btohs(rp.manufacturer); + ver->hci_ver = rp.lmp_ver; + ver->hci_rev = btohs(rp.hci_rev); + ver->lmp_ver = rp.lmp_ver; + ver->lmp_subver = btohs(rp.lmp_subver); + + return 0; +} -- cgit From 9ff2c721bb4ff84ad15e4593404bf47941315337 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 19 Mar 2002 17:35:54 +0000 Subject: Added hci_local_name function. --- src/hci.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index e9693d3e..1e20243b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -503,6 +503,29 @@ int hci_disconnect(int dd, int hndl, int res, int to) return 0; } +int hci_local_name(int dd, int len, char *name, int to) +{ + read_local_name_rp rp; + struct hci_request 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, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + rp.name[247] = '\0'; + strncpy(name, rp.name, len); + return 0; +} + int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) { evt_remote_name_req_complete rn; -- cgit From a51747b602f9cd03c7431788f80431c1710f5827 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 21 Mar 2002 23:20:32 +0000 Subject: Additional strtoXX and XXtostr functions. --- src/bluetooth.c | 216 +++++++++++++++++++++++++++++++++++++++----------------- src/hci.c | 82 ++++++++++++++++++--- 2 files changed, 227 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 6dfccf44..b202f280 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -96,69 +96,159 @@ int str2ba(char *str, bdaddr_t *ba) } /* Bluetooth error codes to Unix errno mapping */ -int bterr(uint16_t code) +int bt_error(uint16_t code) { - switch(code) { - case 0: - return 0; - case 0x01: - return EBADRQC; - case 0x02: - return ENOTCONN; - case 0x03: - return EIO; - case 0x04: - return EHOSTDOWN; - case 0x05: - return EACCES; - case 0x06: - return EINVAL; - case 0x07: - return ENOMEM; - case 0x08: - return ETIMEDOUT; - case 0x09: - return EMLINK; - case 0x0a: - return EMLINK; - case 0x0b: - return EALREADY; - case 0x0c: - return EBUSY; - case 0x0d: - case 0x0e: - case 0x0f: - return ECONNREFUSED; - case 0x10: - return ETIMEDOUT; - case 0x11: - case 0x27: - case 0x29: - case 0x20: - return EOPNOTSUPP; - case 0x12: - return EINVAL; - case 0x13: - case 0x14: - case 0x15: - return ECONNRESET; - case 0x16: - return ECONNABORTED; - case 0x17: - return ELOOP; - case 0x18: - return EACCES; - case 0x1a: - return EPROTONOSUPPORT; - case 0x1b: - return ECONNREFUSED; - case 0x19: - case 0x1e: - case 0x23: - case 0x24: - case 0x25: - return EPROTO; - default: - return ENOSYS; + switch (code) { + case 0: + return 0; + case 0x01: + return EBADRQC; + case 0x02: + return ENOTCONN; + case 0x03: + return EIO; + case 0x04: + return EHOSTDOWN; + case 0x05: + return EACCES; + case 0x06: + return EINVAL; + case 0x07: + return ENOMEM; + case 0x08: + return ETIMEDOUT; + case 0x09: + return EMLINK; + case 0x0a: + return EMLINK; + case 0x0b: + return EALREADY; + case 0x0c: + return EBUSY; + case 0x0d: + case 0x0e: + case 0x0f: + return ECONNREFUSED; + case 0x10: + return ETIMEDOUT; + case 0x11: + case 0x27: + case 0x29: + case 0x20: + return EOPNOTSUPP; + case 0x12: + return EINVAL; + case 0x13: + case 0x14: + case 0x15: + return ECONNRESET; + case 0x16: + return ECONNABORTED; + case 0x17: + return ELOOP; + case 0x18: + return EACCES; + case 0x1a: + return EPROTONOSUPPORT; + case 0x1b: + return ECONNREFUSED; + case 0x19: + case 0x1e: + case 0x23: + case 0x24: + case 0x25: + return EPROTO; + default: + return ENOSYS; + } +} + +char *bt_compidtostr(int compid) +{ + switch (compid) { + case 0: + return "Ericsson Mobile Comunications"; + case 1: + return "Nokia Mobile Phones"; + case 2: + return "Intel Corp."; + case 3: + return "IBM Corp."; + case 4: + return "Toshiba Corp."; + case 5: + return "3Com"; + case 6: + return "Microsoft"; + case 7: + return "Lucent"; + case 8: + return "Motorola"; + case 9: + return "Infineon Technologies AG"; + case 10: + return "Cambridge Silicon Radio"; + case 11: + return "Silicon Wave"; + case 12: + return "Digianswer A/S"; + case 13: + return "Texas Instruments Inc."; + case 14: + return "Parthus Technologies Inc."; + case 15: + return "Broadcom Corporation"; + case 16: + return "Mitel Semiconductor"; + case 17: + return "Widcomm, Inc."; + case 18: + return "Telencomm Inc."; + case 19: + return "Atmel Corporation"; + case 20: + return "Mitsubishi Electric Corporation"; + case 21: + return "RTX Telecom A/S"; + case 22: + return "KC Technology Inc."; + case 23: + return "Newlogic"; + case 24: + return "Transilica, Inc."; + case 25: + return "Rohde & Schwartz GmbH & Co. KG"; + case 26: + return "TTPCom Limited"; + case 27: + return "Signia Technologies, Inc."; + case 28: + return "Conexant Systems Inc."; + case 29: + return "Qualcomm"; + case 30: + return "Inventel"; + case 31: + return "AVM Berlin"; + case 32: + return "BandSpeed, Inc."; + case 33: + return "Mansella Ltd"; + case 34: + return "NEC Corporation"; + case 35: + return "WavePlus Technology Co., Ltd."; + case 36: + return "Alcatel"; + case 37: + return "Philips Semiconductors"; + case 38: + return "C Technologies"; + case 39: + return "Open Interface"; + case 65535: + return "internal use"; + default: + return "not assigned"; } } diff --git a/src/hci.c b/src/hci.c index 1e20243b..cd65a296 100644 --- a/src/hci.c +++ b/src/hci.c @@ -51,7 +51,7 @@ typedef struct { char *str; unsigned int val; } hci_map; -static char * hci_uint2str(hci_map *m, unsigned int val) +static char *hci_bit2str(hci_map *m, unsigned int val) { static char str[50]; char *ptr = str; @@ -65,7 +65,7 @@ static char * hci_uint2str(hci_map *m, unsigned int val) return str; } -int hci_str2uint(hci_map *map, char *str, unsigned int *val) +static int hci_str2bit(hci_map *map, char *str, unsigned int *val) { char *t, *ptr; hci_map *m; @@ -90,6 +90,46 @@ int hci_str2uint(hci_map *map, char *str, unsigned int *val) return set; } +static char *hci_uint2str(hci_map *m, unsigned int val) +{ + static char str[50]; + char *ptr = str; + + *ptr = 0; + while (m->str) { + if ((unsigned int) m->val == val) { + ptr += sprintf(ptr, "%s", m->str); + break; + } + m++; + } + return str; +} + +static int hci_str2uint(hci_map *map, char *str, unsigned int *val) +{ + char *t, *ptr; + hci_map *m; + int set = 0; + + if (!str) + return 0; + + str = ptr = strdup(str); + + while ((t=strsep(&ptr, ","))) { + for (m=map; m->str; m++) { + if (!strcasecmp(m->str,t)) { + *val = (unsigned int) m->val; set = 1; + break; + } + } + } + free(str); + + return set; +} + char *hci_dtypetostr(int type) { switch (type) { @@ -153,11 +193,11 @@ hci_map pkt_type_map[] = { }; char *hci_ptypetostr(unsigned int ptype) { - return hci_uint2str(pkt_type_map, ptype); + return hci_bit2str(pkt_type_map, ptype); } int hci_strtoptype(char *str, unsigned int *val) { - return hci_str2uint(pkt_type_map, str, val); + return hci_str2bit(pkt_type_map, str, val); } /* Link policy mapping */ @@ -171,11 +211,11 @@ hci_map link_policy_map[] = { }; char *hci_lptostr(unsigned int lp) { - return hci_uint2str(link_policy_map, lp); + return hci_bit2str(link_policy_map, lp); } int hci_strtolp(char *str, unsigned int *val) { - return hci_str2uint(link_policy_map, str, val); + return hci_str2bit(link_policy_map, str, val); } /* Link mode mapping */ @@ -196,12 +236,38 @@ char *hci_lmtostr(unsigned int lm) if (!(lm & HCI_LM_MASTER)) strcpy(str, "SLAVE "); - strcat(str, hci_uint2str(link_mode_map, lm)); + strcat(str, hci_bit2str(link_mode_map, lm)); return str; } int hci_strtolm(char *str, unsigned int *val) { - return hci_str2uint(link_mode_map, str, val); + return hci_str2bit(link_mode_map, str, val); +} + +/* Version mapping */ +hci_map ver_map[] = { + { "1.0b", 0x00 }, + { "1.1", 0x01 }, + { NULL } +}; +char *hci_vertostr(unsigned int ver) +{ + char *str = hci_uint2str(ver_map, ver); + return *str ? str : "n/a"; +} +int hci_strtover(char *str, unsigned int *ver) +{ + return hci_str2uint(ver_map, str, ver); +} + +char *lmp_vertostr(unsigned int ver) +{ + char *str = hci_uint2str(ver_map, ver); + return *str ? str : "n/a"; +} +int lmp_strtover(char *str, unsigned int *ver) +{ + return hci_str2uint(ver_map, str, ver); } /* HCI functions that do not require open device */ -- cgit From 0a6472fe170438016c23c71d9129e627f26cd398 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Mar 2002 19:45:46 +0000 Subject: Fixed compiler options and warnings. Proper parameter types. Cleanup. --- src/Makefile.am | 2 +- src/Makefile.in | 3 ++- src/hci.c | 24 +++++++++++++----------- 3 files changed, 16 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index cc7b582b..b1c657e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,4 +7,4 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c libbluetooth_la_LDFLAGS = -version-info 1:0:0 -CFLAGS += -I../include +AM_CFLAGS = -I../include diff --git a/src/Makefile.in b/src/Makefile.in index 6da2db02..530d0757 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -85,7 +85,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c libbluetooth_la_LDFLAGS = -version-info 1:0:0 -CFLAGS = -I../include +AM_CFLAGS = -I../include mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LTLIBRARIES = $(lib_LTLIBRARIES) @@ -97,6 +97,7 @@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ libbluetooth_la_LIBADD = libbluetooth_la_OBJECTS = bluetooth.lo hci.lo +CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) diff --git a/src/hci.c b/src/hci.c index cd65a296..3e1dd52e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -511,7 +511,7 @@ done: return 0; } -int hci_create_connection(int dd, bdaddr_t *ba, int ptype, int rswitch, int to) +int hci_create_connection(int dd, bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) { evt_conn_complete rp; create_conn_cp cp; @@ -519,8 +519,9 @@ int hci_create_connection(int dd, bdaddr_t *ba, int ptype, int rswitch, int to) memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); - cp.pkt_type = ptype; - cp.role_switch = rswitch; + cp.pkt_type = ptype; + cp.clock_offset = clkoffset; + cp.role_switch = rswitch; rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_CREATE_CONN; @@ -538,18 +539,19 @@ int hci_create_connection(int dd, bdaddr_t *ba, int ptype, int rswitch, int to) return -1; } - return rp.handle; + *handle = rp.handle; + return 0; } -int hci_disconnect(int dd, int hndl, int res, int to) +int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) { evt_disconn_complete rp; disconnect_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = hndl; - cp.reason = res; + cp.handle = handle; + cp.reason = reason; rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_DISCONNECT; @@ -622,14 +624,14 @@ int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) return 0; } -int hci_read_remote_features(int dd, int hndl, uint8_t *features, int to) +int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) { evt_read_remote_features_complete rp; read_remote_features_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = hndl; + cp.handle = handle; rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_FEATURES; @@ -651,14 +653,14 @@ int hci_read_remote_features(int dd, int hndl, uint8_t *features, int to) return 0; } -int hci_read_remote_version(int dd, int hndl, struct hci_version *ver, int to) +int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, int to) { evt_read_remote_version_complete rp; read_remote_version_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = hndl; + cp.handle = handle; rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_VERSION; -- cgit From 87f8b3bc7c1967cef913de6b23bbdebb8f98d19e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 25 Mar 2002 19:12:16 +0000 Subject: Fix static allocations. --- src/bluetooth.c | 45 +++++++++++++++++++++++---------------------- src/hci.c | 34 ++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index b202f280..add25594 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -44,33 +44,34 @@ void baswap(bdaddr_t *dst, bdaddr_t *src) d[i] = s[5-i]; } -char * batostr(bdaddr_t *ba) +char *batostr(bdaddr_t *ba) { - static char str[2][18]; - static int i = 1; + char *str = malloc(18); + if (!str) + return NULL; - i ^= 1; - sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", + sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", ba->b[0], ba->b[1], ba->b[2], ba->b[3], ba->b[4], ba->b[5]); - return str[i]; + return str; } -bdaddr_t * strtoba(char *str) +bdaddr_t *strtoba(char *str) { - static unsigned char ba[2][sizeof(bdaddr_t)]; - static int i = 1; - register char *ptr = str; - register int x; - - i ^= 1; - for(x=0; x<6; x++){ - ba[i][x] = (uint8_t) strtol(ptr, NULL, 16); - if( x!=5 && !(ptr=strchr(ptr,':')) ) + char *ptr = str; + int i; + + uint8_t *ba = malloc(sizeof(bdaddr_t)); + if (!ba) + return NULL; + + for(i=0; i<6; i++){ + ba[i] = (uint8_t) strtol(ptr, NULL, 16); + if( i!=5 && !(ptr=strchr(ptr,':')) ) ptr = ":00:00:00:00:00"; ptr++; } - return (bdaddr_t *) ba[i]; + return (bdaddr_t *) ba; } int ba2str(bdaddr_t *ba, char *str) @@ -82,13 +83,13 @@ int ba2str(bdaddr_t *ba, char *str) int str2ba(char *str, bdaddr_t *ba) { - unsigned char *b = (void *) ba; + uint8_t *b = (void *) ba; char *ptr = str; - register int x; + int i; - for (x=0; x < 6; x++) { - b[x] = (uint8_t) strtol(ptr, NULL, 16); - if (x!=5 && !(ptr=strchr(ptr, ':'))) + for (i=0; i < 6; i++) { + b[i] = (uint8_t) strtol(ptr, NULL, 16); + if (i!=5 && !(ptr=strchr(ptr, ':'))) ptr = ":00:00:00:00:00"; ptr++; } diff --git a/src/hci.c b/src/hci.c index 3e1dd52e..fb7a2780 100644 --- a/src/hci.c +++ b/src/hci.c @@ -53,9 +53,12 @@ typedef struct { static char *hci_bit2str(hci_map *m, unsigned int val) { - static char str[50]; + char *str = malloc(50); char *ptr = str; + if (!str) + return NULL; + *ptr = 0; while (m->str) { if ((unsigned int) m->val & val) @@ -71,10 +74,10 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) hci_map *m; int set; + str = ptr = strdup(str); if (!str) return 0; - str = ptr = strdup(str); *val = set = 0; while ((t=strsep(&ptr, ","))) { @@ -92,9 +95,12 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) static char *hci_uint2str(hci_map *m, unsigned int val) { - static char str[50]; + char *str = malloc(50); char *ptr = str; + if (!str) + return NULL; + *ptr = 0; while (m->str) { if ((unsigned int) m->val == val) { @@ -161,10 +167,13 @@ hci_map dev_flags_map[] = { }; char *hci_dflagstostr(uint32_t flags) { - static char str[50]; + char *str = malloc(50); char *ptr = str; hci_map *m = dev_flags_map; + if (!str) + return NULL; + *ptr = 0; if (!hci_test_bit(HCI_UP, &flags)) @@ -230,13 +239,22 @@ hci_map link_mode_map[] = { }; char *hci_lmtostr(unsigned int lm) { - static char str[50]; + char *s, *str = malloc(50); + if (!str) + return NULL; - str[0] = 0; + *str = 0; if (!(lm & HCI_LM_MASTER)) strcpy(str, "SLAVE "); - strcat(str, hci_bit2str(link_mode_map, lm)); + s = hci_bit2str(link_mode_map, lm); + if (!s) { + free(str); + return NULL; + } + + strcat(str, s); + free(s); return str; } int hci_strtolm(char *str, unsigned int *val) @@ -706,7 +724,7 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) } ver->manufacturer = btohs(rp.manufacturer); - ver->hci_ver = rp.lmp_ver; + ver->hci_ver = rp.hci_ver; ver->hci_rev = btohs(rp.hci_rev); ver->lmp_ver = rp.lmp_ver; ver->lmp_subver = btohs(rp.lmp_subver); -- cgit From b442a036129e5bfe44eb95ef036bdb13f2eba009 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 26 Mar 2002 19:25:05 +0000 Subject: Check for null string in strtobit. --- src/hci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index fb7a2780..544607b9 100644 --- a/src/hci.c +++ b/src/hci.c @@ -74,8 +74,7 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) hci_map *m; int set; - str = ptr = strdup(str); - if (!str) + if (!str || !(str = ptr = strdup(str))) return 0; *val = set = 0; -- cgit From 21efc9d87640fa0d9b78a311677e316590515171 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 28 Mar 2002 23:11:53 +0000 Subject: Swap address in str2ba and ba2str. --- src/bluetooth.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index add25594..97a1cf57 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -76,14 +76,16 @@ bdaddr_t *strtoba(char *str) int ba2str(bdaddr_t *ba, char *str) { + uint8_t b[6]; + + baswap((bdaddr_t *)b, ba); return sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - ba->b[0], ba->b[1], ba->b[2], - ba->b[3], ba->b[4], ba->b[5]); + b[0], b[1], b[2], b[3], b[4], b[5]); } int str2ba(char *str, bdaddr_t *ba) { - uint8_t *b = (void *) ba; + uint8_t b[6]; char *ptr = str; int i; @@ -93,6 +95,7 @@ int str2ba(char *str, bdaddr_t *ba) ptr = ":00:00:00:00:00"; ptr++; } + baswap(ba, (bdaddr_t *)b); return 0; } -- cgit From a8d4b5143b9fc3ee47a5f59180d8a92c5f742115 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 29 Mar 2002 21:34:01 +0000 Subject: Cleanup. --- src/Makefile.am | 2 +- src/Makefile.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index b1c657e0..22dd8aac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,4 +7,4 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c libbluetooth_la_LDFLAGS = -version-info 1:0:0 -AM_CFLAGS = -I../include +INCLUDES = -I../include diff --git a/src/Makefile.in b/src/Makefile.in index 530d0757..0335d393 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -85,7 +85,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c libbluetooth_la_LDFLAGS = -version-info 1:0:0 -AM_CFLAGS = -I../include +INCLUDES = -I../include mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_CLEAN_FILES = LTLIBRARIES = $(lib_LTLIBRARIES) -- cgit From 00012f0fe236ff884d28c12781398183dac51b7f Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 10 Apr 2002 18:20:36 +0000 Subject: hci_req initialization fixes. --- src/hci.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 544607b9..a3ffe28b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -593,10 +593,12 @@ int hci_local_name(int dd, int len, char *name, int to) read_local_name_rp rp; struct hci_request rq; - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_LOCAL_NAME; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_NAME; + rq.cparam = NULL; + rq.clen = 0; rq.rparam = &rp; - rq.rlen = READ_LOCAL_NAME_RP_SIZE; + rq.rlen = READ_LOCAL_NAME_RP_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -620,8 +622,8 @@ int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); - 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.event = EVT_REMOTE_NAME_REQ_COMPLETE; @@ -706,13 +708,12 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) read_local_version_rp rp; struct hci_request rq; - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_INFO_PARAM; - rq.ocf = OCF_READ_LOCAL_VERSION; + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_VERSION; rq.cparam = NULL; - rq.clen = 0; + rq.clen = 0; rq.rparam = &rp; - rq.rlen = READ_LOCAL_VERSION_RP_SIZE; + rq.rlen = READ_LOCAL_VERSION_RP_SIZE; if (hci_send_req(dd, &rq, 1000) < 0) return -1; -- cgit From 8dab9b0bcab616bde55a3a137bd6fb8818ced4a5 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 11 Apr 2002 16:56:10 +0000 Subject: Added LMP features to sting translation function and table. --- src/hci.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index a3ffe28b..af494c15 100644 --- a/src/hci.c +++ b/src/hci.c @@ -53,7 +53,7 @@ typedef struct { static char *hci_bit2str(hci_map *m, unsigned int val) { - char *str = malloc(50); + char *str = malloc(120); char *ptr = str; if (!str) @@ -287,6 +287,71 @@ int lmp_strtover(char *str, unsigned int *ver) return hci_str2uint(ver_map, str, ver); } +/* LMP features mapping */ +hci_map lmp_features_map[][9] = { + { /* byte 0 */ + { "<3-slot packets>", LMP_3SLOT }, + { "<5-slot packets>", LMP_5SLOT }, + { "", LMP_ENCRYPT }, + { "", LMP_SOFFSET }, + { "", LMP_TACCURACY}, + { "", LMP_RSWITCH }, + { "", LMP_HOLD }, + { "", LMP_SNIFF }, + { NULL } + }, + { /* byte 1 */ + { "", LMP_PARK }, + { "", LMP_RSSI }, + { "", LMP_QUALITY }, + { "", LMP_SCO }, + { "", LMP_HV2 }, + { "", LMP_HV3 }, + { "", LMP_ULAW }, + { "", LMP_ALAW }, + { NULL } + }, + { /* byte 2 */ + { "", LMP_CVSD }, + { "", LMP_PSCHEME }, + { "", LMP_PCONTROL }, + { "", LMP_TRSP_SCO }, + { NULL } + }, + {{ NULL }} +}; + +char *lmp_featurestostr(uint8_t *features, char *pref, int width) +{ + char *ptr, *str = malloc(400); + int i, w; + + if (!str) + return NULL; + + ptr = str; *ptr = 0; + + if (pref) + ptr += sprintf(ptr, "%s", pref); + + for(i=0, w=0; lmp_features_map[i][0].str; i++) { + hci_map *m; + + m = lmp_features_map[i]; + while (m->str) { + if ((unsigned int) m->val & (unsigned int) features[i]) + ptr += sprintf(ptr, "%s ", m->str); + m++; + + w = (w + 1) & width; + if (!w) + ptr += sprintf(ptr, "\n%s", pref); + } + } + + return str; +} + /* HCI functions that do not require open device */ int hci_devinfo(int dev_id, struct hci_dev_info *di) -- cgit From 083ac35c0e178f548da930e91fe4154a4993af0e Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 11 Apr 2002 18:19:58 +0000 Subject: Added hci_class_of_dev function. hci_req initialization cleanup. --- src/hci.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index af494c15..9418eb42 100644 --- a/src/hci.c +++ b/src/hci.c @@ -605,6 +605,7 @@ int hci_create_connection(int dd, bdaddr_t *ba, uint16_t ptype, uint16_t clkoffs cp.clock_offset = clkoffset; cp.role_switch = rswitch; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_CREATE_CONN; rq.event = EVT_CONN_COMPLETE; @@ -635,6 +636,7 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) cp.handle = handle; cp.reason = reason; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_DISCONNECT; rq.event = EVT_DISCONN_COMPLETE; @@ -658,10 +660,9 @@ int hci_local_name(int dd, int len, char *name, int to) read_local_name_rp rp; struct hci_request rq; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LOCAL_NAME; - rq.cparam = NULL; - rq.clen = 0; rq.rparam = &rp; rq.rlen = READ_LOCAL_NAME_RP_SIZE; @@ -687,6 +688,7 @@ int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_REMOTE_NAME_REQ; rq.cparam = &cp; @@ -717,6 +719,7 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) memset(&cp, 0, sizeof(cp)); cp.handle = handle; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_FEATURES; rq.event = EVT_READ_REMOTE_FEATURES_COMPLETE; @@ -746,6 +749,7 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in memset(&cp, 0, sizeof(cp)); cp.handle = handle; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_VERSION; rq.event = EVT_READ_REMOTE_VERSION_COMPLETE; @@ -773,10 +777,9 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) read_local_version_rp rp; struct hci_request rq; + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_INFO_PARAM; rq.ocf = OCF_READ_LOCAL_VERSION; - rq.cparam = NULL; - rq.clen = 0; rq.rparam = &rp; rq.rlen = READ_LOCAL_VERSION_RP_SIZE; @@ -796,3 +799,26 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) return 0; } + +int hci_class_of_dev(int dd, uint8_t *class, int to) +{ + read_class_of_dev_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + 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(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(class, rp.dev_class, 3); + return 0; +} -- cgit From e6564963d4e3c7efe92e30c00fa289dd5a964f28 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 15 Apr 2002 16:55:14 +0000 Subject: lmp_featuretostr fixes --- src/hci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 9418eb42..6af14864 100644 --- a/src/hci.c +++ b/src/hci.c @@ -339,13 +339,13 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) m = lmp_features_map[i]; while (m->str) { - if ((unsigned int) m->val & (unsigned int) features[i]) + if ((unsigned int) m->val & (unsigned int) features[i]) { ptr += sprintf(ptr, "%s ", m->str); + w = (w + 1) & width; + if (!w) + ptr += sprintf(ptr, "\n%s", pref ? pref : ""); + } m++; - - w = (w + 1) & width; - if (!w) - ptr += sprintf(ptr, "\n%s", pref); } } -- cgit From d61a1930cd52b112516c0442a9b75d8461a6031a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 13 May 2002 19:00:25 +0000 Subject: more company ids --- src/bluetooth.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 97a1cf57..622464f8 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -250,6 +250,12 @@ char *bt_compidtostr(int compid) return "C Technologies"; case 39: return "Open Interface"; + case 40: + return "R F Micro Devices"; + case 41: + return "Hitachi Ltd"; + case 42: + return "Symbol Technologies, Inc."; case 65535: return "internal use"; default: -- cgit From 8e9ea9b77e3c4eaf1f1813cfa1e275c7b7ef219a Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 17 May 2002 01:09:28 +0000 Subject: Fix "make dist" --- src/Makefile.in | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/Makefile.in b/src/Makefile.in index 0335d393..d0a7b1ed 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -61,8 +61,12 @@ 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@ AS = @AS@ CC = @CC@ -- cgit From bf19cd7953fbc8cc916b9514d8f11fc8557f0cec Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 17 May 2002 17:12:30 +0000 Subject: Add hci_devba function --- src/hci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 6af14864..426eb91e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -369,6 +369,22 @@ int hci_devinfo(int dev_id, struct hci_dev_info *di) return err; } +int hci_devba(int dev_id, bdaddr_t *ba) +{ + struct hci_dev_info di; + + if (hci_devinfo(dev_id, &di)) + return -1; + + if (!hci_test_bit(HCI_UP, &di.flags)) { + errno = ENETDOWN; + return -1; + } + + bacpy(ba, &di.bdaddr); + return 0; +} + inquiry_info *hci_inquiry(int dev_id, int len, int *num_rsp, uint8_t *lap, long flags) { struct hci_inquiry_req *ir; -- cgit From 4bbdd73f337a0e1f76597c93bb3bda99cea4a550 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 23 May 2002 20:26:01 +0000 Subject: Build env cleanup. Remove auto generated files from CVS. Working 'make distcheck'. --- src/Makefile.am | 2 +- src/Makefile.in | 358 -------------------------------------------------------- 2 files changed, 1 insertion(+), 359 deletions(-) delete mode 100644 src/Makefile.in (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 22dd8aac..6359a2b0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,4 +7,4 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c libbluetooth_la_LDFLAGS = -version-info 1:0:0 -INCLUDES = -I../include +INCLUDES = -I$(top_srcdir)/include diff --git a/src/Makefile.in b/src/Makefile.in deleted file mode 100644 index d0a7b1ed..00000000 --- a/src/Makefile.in +++ /dev/null @@ -1,358 +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@ -AS = @AS@ -CC = @CC@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -EXEEXT = @EXEEXT@ -LD = @LD@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -MAKEINFO = @MAKEINFO@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -RANLIB = @RANLIB@ -STRIP = @STRIP@ -VERSION = @VERSION@ - -lib_LTLIBRARIES = libbluetooth.la - -libbluetooth_la_SOURCES = bluetooth.c hci.c -libbluetooth_la_LDFLAGS = -version-info 1:0:0 - -INCLUDES = -I../include -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -LTLIBRARIES = $(lib_LTLIBRARIES) - - -DEFS = @DEFS@ -I. -I$(srcdir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -libbluetooth_la_LIBADD = -libbluetooth_la_OBJECTS = bluetooth.lo hci.lo -CFLAGS = @CFLAGS@ -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -DIST_COMMON = Makefile.am Makefile.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -DEP_FILES = .deps/bluetooth.P .deps/hci.P -SOURCES = $(libbluetooth_la_SOURCES) -OBJECTS = $(libbluetooth_la_OBJECTS) - -all: all-redirect -.SUFFIXES: -.SUFFIXES: .S .c .lo .o .obj .s -$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - - -mostlyclean-libLTLIBRARIES: - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - -distclean-libLTLIBRARIES: - -maintainer-clean-libLTLIBRARIES: - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(libdir) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - if test -f $$p; then \ - echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ - $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ - else :; fi; \ - done - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ - done - -# FIXME: We should only use cygpath when building on Windows, -# and only if it is available. -.c.obj: - $(COMPILE) -c `cygpath -w $<` - -.s.o: - $(COMPILE) -c $< - -.S.o: - $(COMPILE) -c $< - -mostlyclean-compile: - -rm -f *.o core *.core - -rm -f *.$(OBJEXT) - -clean-compile: - -distclean-compile: - -rm -f *.tab.c - -maintainer-clean-compile: - -.s.lo: - $(LIBTOOL) --mode=compile $(COMPILE) -c $< - -.S.lo: - $(LIBTOOL) --mode=compile $(COMPILE) -c $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -maintainer-clean-libtool: - -libbluetooth.la: $(libbluetooth_la_OBJECTS) $(libbluetooth_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libbluetooth_la_LDFLAGS) $(libbluetooth_la_OBJECTS) $(libbluetooth_la_LIBADD) $(LIBS) - -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 = src - -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 src/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-libLTLIBRARIES -install-exec: install-exec-am - -install-data-am: -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: uninstall-libLTLIBRARIES -uninstall: uninstall-am -all-am: Makefile $(LTLIBRARIES) -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - $(mkinstalldirs) $(DESTDIR)$(libdir) - - -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-libLTLIBRARIES mostlyclean-compile \ - mostlyclean-libtool mostlyclean-tags mostlyclean-depend \ - mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ - clean-depend clean-generic mostlyclean-am - -clean: clean-am - -distclean-am: distclean-libLTLIBRARIES distclean-compile \ - distclean-libtool distclean-tags distclean-depend \ - distclean-generic clean-am - -rm -f libtool - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ - maintainer-clean-compile maintainer-clean-libtool \ - 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-libLTLIBRARIES distclean-libLTLIBRARIES \ -clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ -uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ -distclean-compile clean-compile maintainer-clean-compile \ -mostlyclean-libtool distclean-libtool clean-libtool \ -maintainer-clean-libtool 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 00b68045e890dccbf09bed06727f0453daa27b90 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 4 Jun 2002 00:13:33 +0000 Subject: Additional comp ids --- src/bluetooth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 622464f8..6c09c4d9 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -256,6 +256,10 @@ char *bt_compidtostr(int compid) return "Hitachi Ltd"; case 42: return "Symbol Technologies, Inc."; + case 43: + return "Tenovis"; + case 44: + return "Macronix International Co. Ltd."; case 65535: return "internal use"; default: -- cgit From 4837bd7e9ba55361aeca45610a160dd107d5be2f Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 16:46:54 +0000 Subject: Fix inquiry function to return errors and accept user buffers. New functions hci_for_each_dev and hci_get_route. --- src/hci.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 426eb91e..bc645686 100644 --- a/src/hci.c +++ b/src/hci.c @@ -354,6 +354,59 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) /* HCI functions that do not require open device */ +int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg) +{ + struct hci_dev_list_req *dl; + struct hci_dev_req *dr; + int dev_id = -1; + int s, i; + + s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (s < 0) + return -1; + + dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); + if (!dl) { + close(s); + return -1; + } + + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(s, HCIGETDEVLIST, (void *)dl)) + goto done; + + for (i=0; i < dl->dev_num; i++, dr++) { + if (hci_test_bit(flag, &dr->dev_opt)) + if (!func || func(s, dr->dev_id, arg)) { + dev_id = dr->dev_id; + break; + } + } + +done: + close(s); + free(dl); + return dev_id; +} + +static int __other_bdaddr(int s, int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + return 0; + return bacmp((bdaddr_t *)arg, &di.bdaddr); +} + +int hci_get_route(bdaddr_t *bdaddr) +{ + if (bdaddr) + return hci_for_each_dev(HCI_UP, __other_bdaddr, (long) bdaddr); + else + return hci_for_each_dev(HCI_UP, NULL, 0); +} + int hci_devinfo(int dev_id, struct hci_dev_info *di) { int s, err; @@ -385,22 +438,33 @@ int hci_devba(int dev_id, bdaddr_t *ba) return 0; } -inquiry_info *hci_inquiry(int dev_id, int len, int *num_rsp, uint8_t *lap, long flags) +int hci_inquiry(int dev_id, int len, int nrsp, uint8_t *lap, inquiry_info **ii, long flags) { struct hci_inquiry_req *ir; - char *buf, *ptr; - int s, err, size; + void *buf; + int s, err; - if (!*num_rsp) - *num_rsp = 200; // enough ? + if (nrsp <= 0) + nrsp = 200; // enough ? - size = sizeof(*ir) + (sizeof(inquiry_info) * (*num_rsp)); - if (!(buf = malloc(size))) - return NULL; + if (dev_id < 0 && (dev_id = hci_get_route(NULL)) < 0) { + errno = ENODEV; + return -1; + } + + s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (s < 0) + return -1; + + buf = malloc(sizeof(*ir) + (sizeof(inquiry_info) * (nrsp))); + if (!buf) { + close(s); + return -1; + } - ir = (void *)buf; + ir = buf; ir->dev_id = dev_id; - ir->num_rsp = *num_rsp; + ir->num_rsp = nrsp; ir->length = len; ir->flags = flags; @@ -412,28 +476,23 @@ inquiry_info *hci_inquiry(int dev_id, int len, int *num_rsp, uint8_t *lap, long ir->lap[2] = 0x9e; } - if ((s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0) - goto failed; - if (ioctl(s, HCIINQUIRY, (unsigned long)buf) < 0) - goto failed; - - size = sizeof(inquiry_info) * ir->num_rsp; - if (!(ptr = malloc(size))) - goto failed; + err = ioctl(s, HCIINQUIRY, (unsigned long) buf); + close(s); - memcpy(ptr, buf + sizeof(*ir), size); - *num_rsp = ir->num_rsp; + if (!err) { + int size = sizeof(inquiry_info) * ir->num_rsp; - free(buf); - close(s); - return (void *) ptr; + if (!*ii) + *ii = (void *) malloc(size); -failed: - err = errno; + if (*ii) { + memcpy((void *) *ii, buf + sizeof(*ir), size); + err = ir->num_rsp; + } else + err = -1; + } free(buf); - close(s); - errno = err; - return NULL; + return err; } /* Open HCI device. @@ -838,3 +897,4 @@ int hci_class_of_dev(int dd, uint8_t *class, int to) memcpy(class, rp.dev_class, 3); return 0; } + -- cgit From d316a5fbab4a41ce3f8321eef407db9c53b57e85 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 18:15:13 +0000 Subject: Added hci_devid function. --- src/hci.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index bc645686..f72ef760 100644 --- a/src/hci.c +++ b/src/hci.c @@ -399,6 +399,14 @@ static int __other_bdaddr(int s, int dev_id, long arg) return bacmp((bdaddr_t *)arg, &di.bdaddr); } +static int __same_bdaddr(int s, int dev_id, long arg) +{ + struct hci_dev_info di = {dev_id: dev_id}; + if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + return 0; + return !bacmp((bdaddr_t *)arg, &di.bdaddr); +} + int hci_get_route(bdaddr_t *bdaddr) { if (bdaddr) @@ -407,6 +415,11 @@ int hci_get_route(bdaddr_t *bdaddr) return hci_for_each_dev(HCI_UP, NULL, 0); } +int hci_devid(bdaddr_t *bdaddr) +{ + return hci_for_each_dev(HCI_UP, __same_bdaddr, (long) bdaddr); +} + int hci_devinfo(int dev_id, struct hci_dev_info *di) { int s, err; -- cgit From 9942261d0febb9ef243ffe810421451e97925e68 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 18:32:44 +0000 Subject: improved hci_devid --- src/hci.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index f72ef760..c0be8df2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -415,9 +415,20 @@ int hci_get_route(bdaddr_t *bdaddr) return hci_for_each_dev(HCI_UP, NULL, 0); } -int hci_devid(bdaddr_t *bdaddr) +int hci_devid(char *str) { - return hci_for_each_dev(HCI_UP, __same_bdaddr, (long) bdaddr); + bdaddr_t ba; + int id = -1; + + if (!strncmp(str, "hci", 3) && strlen(str) >= 4) { + id = atoi(str + 3); + if (hci_devba(id, &ba) < 0) + return -1; + } else { + str2ba(str, &ba); + id = hci_for_each_dev(HCI_UP, __same_bdaddr, (long) &ba); + } + return id; } int hci_devinfo(int dev_id, struct hci_dev_info *di) -- cgit From e549aca0820bd58dc7b714f365ff0c46a941dc65 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 18 Jun 2002 18:48:36 +0000 Subject: Return correct error if adds was not found. --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index c0be8df2..1424ddcd 100644 --- a/src/hci.c +++ b/src/hci.c @@ -425,6 +425,7 @@ int hci_devid(char *str) if (hci_devba(id, &ba) < 0) return -1; } else { + errno = ENODEV; str2ba(str, &ba); id = hci_for_each_dev(HCI_UP, __same_bdaddr, (long) &ba); } -- cgit From afdbc9e8fe53fdf5c4a5c78e379d604e92a61480 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 25 Jun 2002 04:03:54 +0000 Subject: new comp ids --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 6c09c4d9..d769e2b9 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -260,6 +260,8 @@ char *bt_compidtostr(int compid) return "Tenovis"; case 44: return "Macronix International Co. Ltd."; + case 45: + return "GCT Semiconductor"; case 65535: return "internal use"; default: -- cgit From 8ee9bf3777ff4f57ec1e170174e2fcb6e1f870f7 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Tue, 2 Jul 2002 18:34:22 +0000 Subject: more compids --- src/bluetooth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index d769e2b9..7097ebf0 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -262,6 +262,10 @@ char *bt_compidtostr(int compid) return "Macronix International Co. Ltd."; case 45: return "GCT Semiconductor"; + case 46: + return "Norwood Systems"; + case 47: + return "MewTel Technology Inc."; case 65535: return "internal use"; default: -- cgit From 803bf105508009f7efc87276a539dda244527690 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 21 Aug 2002 16:38:15 +0000 Subject: implement hci_{read, write}_current_iac_lap() --- src/hci.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 1424ddcd..40a19fb2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -923,3 +923,42 @@ int hci_class_of_dev(int dd, uint8_t *class, int to) return 0; } +int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) +{ + read_current_iac_lap_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_CURRENT_IAC_LAP; + rq.rparam = &rp; + rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; + if (0 > hci_send_req(dd, &rq, to)) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + *num_iac = rp.num_current_iac; + memcpy(lap, rp.lap, 3*rp.num_current_iac); + return 0; +} + +int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) +{ + write_current_iac_lap_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.num_current_iac = num_iac; + memcpy(&cp.lap, lap, 3*num_iac); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; + rq.cparam = &cp; + rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + if (0 > hci_send_req(dd, &rq, to)) + return -1; + return 0; +} -- cgit From 9aa01920bf2e6f3b9b23b44d7c5e48dadc2f8da8 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2002 09:19:29 +0000 Subject: implement hci_{read, write}_class_of_dev() --- src/hci.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 40a19fb2..6b60477a 100644 --- a/src/hci.c +++ b/src/hci.c @@ -900,7 +900,7 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) return 0; } -int hci_class_of_dev(int dd, uint8_t *class, int to) +int hci_read_class_of_dev(int dd, uint8_t *cls, int to) { read_class_of_dev_rp rp; struct hci_request rq; @@ -919,10 +919,26 @@ int hci_class_of_dev(int dd, uint8_t *class, int to) return -1; } - memcpy(class, rp.dev_class, 3); + memcpy(cls, rp.dev_class, 3); return 0; } +int hci_write_class_of_dev(int dd, uint32_t cls, int to) +{ + write_class_of_dev_cp cp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + cp.dev_class[0] = cls & 0xff; + cp.dev_class[1] = (cls >> 8) & 0xff; + cp.dev_class[2] = (cls >> 16) & 0xff; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CLASS_OF_DEV; + rq.cparam = &cp; + rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; + return hci_send_req(dd, &rq, 1000); +} + int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) { read_current_iac_lap_rp rp; -- cgit From e329c9ff80a76cb34ff616bce80df0d161731d0b Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2002 10:04:18 +0000 Subject: hci_write_local_name() --- src/hci.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 6b60477a..7f2c1745 100644 --- a/src/hci.c +++ b/src/hci.c @@ -755,7 +755,7 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) return 0; } -int hci_local_name(int dd, int len, char *name, int to) +int hci_read_local_name(int dd, int len, char *name, int to) { read_local_name_rp rp; struct hci_request rq; @@ -779,7 +779,24 @@ int hci_local_name(int dd, int len, char *name, int to) return 0; } -int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +int hci_write_local_name(int dd, char *name, int to) +{ + change_local_name_cp cp; + struct hci_request rq; + + strncpy(cp.name, name, sizeof(cp.name)); + memset(&rq, 0, sizeof(rq)); + 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(dd, &rq, to) < 0) + return -1; + return 0; +} + +int hci_read_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; -- cgit From 66d1c38bdf157527c00cf7bde69e1de7bdd3ea28 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Thu, 22 Aug 2002 17:17:57 +0000 Subject: resurrect hci_local_name(); fix whitespace --- src/hci.c | 113 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 59 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 7f2c1745..a9d3268d 100644 --- a/src/hci.c +++ b/src/hci.c @@ -755,6 +755,11 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) return 0; } +int hci_local_name(int dd, int len, char *name, int to) +{ + return hci_read_local_name(dd, len, name, to); +} + int hci_read_local_name(int dd, int len, char *name, int to) { read_local_name_rp rp; @@ -781,19 +786,19 @@ int hci_read_local_name(int dd, int len, char *name, int to) int hci_write_local_name(int dd, char *name, int to) { - change_local_name_cp cp; - struct hci_request rq; + change_local_name_cp cp; + struct hci_request rq; - strncpy(cp.name, name, sizeof(cp.name)); - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_CHANGE_LOCAL_NAME; - rq.cparam = &cp; - rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; + strncpy(cp.name, name, sizeof(cp.name)); + memset(&rq, 0, sizeof(rq)); + 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(dd, &rq, to) < 0) - return -1; - return 0; + if (hci_send_req(dd, &rq, to) < 0) + return -1; + return 0; } int hci_read_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) @@ -942,56 +947,56 @@ int hci_read_class_of_dev(int dd, uint8_t *cls, int to) int hci_write_class_of_dev(int dd, uint32_t cls, int to) { - write_class_of_dev_cp cp; - struct hci_request rq; + write_class_of_dev_cp cp; + struct hci_request rq; - memset(&rq, 0, sizeof(rq)); - cp.dev_class[0] = cls & 0xff; - cp.dev_class[1] = (cls >> 8) & 0xff; - cp.dev_class[2] = (cls >> 16) & 0xff; - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CLASS_OF_DEV; - rq.cparam = &cp; - rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; - return hci_send_req(dd, &rq, 1000); + memset(&rq, 0, sizeof(rq)); + cp.dev_class[0] = cls & 0xff; + cp.dev_class[1] = (cls >> 8) & 0xff; + cp.dev_class[2] = (cls >> 16) & 0xff; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CLASS_OF_DEV; + rq.cparam = &cp; + rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; + return hci_send_req(dd, &rq, 1000); } int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) { - read_current_iac_lap_rp rp; - struct hci_request rq; - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_CURRENT_IAC_LAP; - rq.rparam = &rp; - rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; - if (0 > hci_send_req(dd, &rq, to)) - return -1; - if (rp.status) { - errno = EIO; - return -1; - } - *num_iac = rp.num_current_iac; - memcpy(lap, rp.lap, 3*rp.num_current_iac); - return 0; + read_current_iac_lap_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_CURRENT_IAC_LAP; + rq.rparam = &rp; + rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; + if (0 > hci_send_req(dd, &rq, to)) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + *num_iac = rp.num_current_iac; + memcpy(lap, rp.lap, 3*rp.num_current_iac); + return 0; } int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) { - write_current_iac_lap_cp cp; - struct hci_request rq; - - memset(&cp, 0, sizeof(cp)); - cp.num_current_iac = num_iac; - memcpy(&cp.lap, lap, 3*num_iac); - - memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; - rq.cparam = &cp; - rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; - if (0 > hci_send_req(dd, &rq, to)) - return -1; - return 0; + write_current_iac_lap_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.num_current_iac = num_iac; + memcpy(&cp.lap, lap, 3*num_iac); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; + rq.cparam = &cp; + rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + if (0 > hci_send_req(dd, &rq, to)) + return -1; + return 0; } -- cgit From 8a3e9d619f548c665569e8c835ed82313db3759b Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Mon, 16 Sep 2002 17:32:47 +0000 Subject: update --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 6359a2b0..794d67d2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,6 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c -libbluetooth_la_LDFLAGS = -version-info 1:0:0 +libbluetooth_la_LDFLAGS = -version-info 1:1:0 INCLUDES = -I$(top_srcdir)/include -- cgit From 96cd06b189af2a09bde5d752552f58fd495d5646 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Wed, 18 Sep 2002 00:37:04 +0000 Subject: resurrect hci_remote_name() --- src/hci.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index a9d3268d..af0ffd65 100644 --- a/src/hci.c +++ b/src/hci.c @@ -801,6 +801,11 @@ int hci_write_local_name(int dd, char *name, int to) return 0; } +int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +{ + return hci_read_remote_name(dd, ba, len, name, to); +} + int hci_read_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) { evt_remote_name_req_complete rn; -- cgit From 79cd53450eeb6555077f7ede0b5e02a23d7bebe8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 22 Sep 2002 23:59:17 +0000 Subject: Add HCI_PCI to the device types --- src/hci.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index af0ffd65..dcc24666 100644 --- a/src/hci.c +++ b/src/hci.c @@ -146,6 +146,10 @@ char *hci_dtypetostr(int type) return "PCCARD"; case HCI_UART: return "UART"; + case HCI_RS232: + return "RS232"; + case HCI_PCI: + return "PCI"; default: return "UKNW"; } -- cgit From 9b62711dfb2f6fa13d6ddc02a713ba5960926c66 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 17 Oct 2002 14:49:27 +0000 Subject: Add new company identifiers --- src/bluetooth.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 7097ebf0..7bd06ff0 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -266,6 +266,12 @@ char *bt_compidtostr(int compid) return "Norwood Systems"; case 47: return "MewTel Technology Inc."; + case 48: + return "ST Microelectronics"; + case 49: + return "Synopsys"; + case 50: + return "Red-M (Communications) Ltd"; case 65535: return "internal use"; default: -- cgit From a1e51b622a5d7dad098ed0b856c37c18da495692 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Fri, 22 Nov 2002 21:54:27 +0000 Subject: Fix hci_for_each_dev() to work on big endian machines. --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index dcc24666..89d481b4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -369,7 +369,7 @@ int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg if (s < 0) return -1; - dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) + sizeof(uint16_t)); + dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); if (!dl) { close(s); return -1; -- cgit From 7e64d607acb1f9701381d09ccdeca0793f127592 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 28 Nov 2002 21:26:59 +0000 Subject: Add new company identifiers --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 7bd06ff0..b60b0191 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -272,6 +272,8 @@ char *bt_compidtostr(int compid) return "Synopsys"; case 50: return "Red-M (Communications) Ltd"; + case 51: + return "Commil Ltd"; case 65535: return "internal use"; default: -- cgit From a0a3d96eed5f186278ea931953d4bcb6cd99cc7a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 2 Dec 2002 20:24:17 +0000 Subject: Fix a typo --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 89d481b4..42de36e5 100644 --- a/src/hci.c +++ b/src/hci.c @@ -163,7 +163,7 @@ hci_map dev_flags_map[] = { { "RAW", HCI_RAW }, { "PSCAN", HCI_PSCAN }, { "ISCAN", HCI_ISCAN }, - { "IQUIRY", HCI_INQUIRY }, + { "INQUIRY", HCI_INQUIRY }, { "AUTH", HCI_AUTH }, { "ENCRYPT", HCI_ENCRYPT }, { NULL } -- cgit From d6cbeb4c61f5dc0c0d04dd022139b44f81964b18 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 15 Dec 2002 13:18:53 +0000 Subject: Support for voice setting --- src/hci.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 42de36e5..b8bbc0c2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -970,6 +970,43 @@ int hci_write_class_of_dev(int dd, uint32_t cls, int to) return hci_send_req(dd, &rq, 1000); } +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; +} + +int hci_write_voice_setting(int dd, uint16_t vs, int to) +{ + write_voice_setting_cp cp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + cp.voice_setting = vs; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_VOICE_SETTING; + rq.cparam = &cp; + rq.clen = WRITE_VOICE_SETTING_CP_SIZE; + return hci_send_req(dd, &rq, 1000); +} + int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) { read_current_iac_lap_rp rp; -- cgit From 6a1cfd82efe91f0dc81ca4e3ea50e8c2077f415e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 24 Jan 2003 09:41:07 +0000 Subject: Don't ignore the timeout parameter --- src/hci.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index b8bbc0c2..ddc15672 100644 --- a/src/hci.c +++ b/src/hci.c @@ -914,7 +914,7 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) rq.rparam = &rp; rq.rlen = READ_LOCAL_VERSION_RP_SIZE; - if (hci_send_req(dd, &rq, 1000) < 0) + if (hci_send_req(dd, &rq, to) < 0) return -1; if (rp.status) { @@ -967,7 +967,7 @@ int hci_write_class_of_dev(int dd, uint32_t cls, int to) rq.ocf = OCF_WRITE_CLASS_OF_DEV; rq.cparam = &cp; rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; - return hci_send_req(dd, &rq, 1000); + return hci_send_req(dd, &rq, to); } int hci_read_voice_setting(int dd, uint16_t *vs, int to) @@ -1004,7 +1004,7 @@ int hci_write_voice_setting(int dd, uint16_t vs, int to) rq.ocf = OCF_WRITE_VOICE_SETTING; rq.cparam = &cp; rq.clen = WRITE_VOICE_SETTING_CP_SIZE; - return hci_send_req(dd, &rq, 1000); + return hci_send_req(dd, &rq, to); } int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) @@ -1017,14 +1017,17 @@ int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) rq.ocf = OCF_READ_CURRENT_IAC_LAP; rq.rparam = &rp; rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; - if (0 > hci_send_req(dd, &rq, to)) + + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; } + *num_iac = rp.num_current_iac; - memcpy(lap, rp.lap, 3*rp.num_current_iac); + memcpy(lap, rp.lap, rp.num_current_iac * 3); return 0; } @@ -1035,14 +1038,12 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) memset(&cp, 0, sizeof(cp)); cp.num_current_iac = num_iac; - memcpy(&cp.lap, lap, 3*num_iac); + memcpy(&cp.lap, lap, num_iac * 3); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; rq.cparam = &cp; rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; - if (0 > hci_send_req(dd, &rq, to)) - return -1; - return 0; + return hci_send_req(dd, &rq, to); } -- cgit From 805b906186b0a5ea0ce77824b4a7c659b6b7b598 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 3 Feb 2003 17:39:11 +0000 Subject: use error codes --- src/bluetooth.c | 69 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index b60b0191..4548b121 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -105,62 +105,61 @@ int bt_error(uint16_t code) switch (code) { case 0: return 0; - case 0x01: + case HCI_UNKNOWN_COMMAND: return EBADRQC; - case 0x02: + case HCI_NO_CONNECTION: return ENOTCONN; - case 0x03: + case HCI_HARDWARE_FAILURE: return EIO; - case 0x04: + case HCI_PAGE_TIMEOUT: return EHOSTDOWN; - case 0x05: + case HCI_AUTHENTICATION_FAILURE: return EACCES; - case 0x06: + case HCI_KEY_MISSING: return EINVAL; - case 0x07: + case HCI_MEMORY_FULL: return ENOMEM; - case 0x08: + case HCI_CONNECTION_TIMEOUT: return ETIMEDOUT; - case 0x09: + case HCI_MAX_NUMBER_OF_CONNECTIONS: + case HCI_MAX_NUMBER_OF_SCO_CONNECTIONS: return EMLINK; - case 0x0a: - return EMLINK; - case 0x0b: + case HCI_ACL_CONNECTION_EXISTS: return EALREADY; - case 0x0c: + case HCI_COMMAND_DISALLOWED: return EBUSY; - case 0x0d: - case 0x0e: - case 0x0f: + case HCI_REJECTED_LIMITED_RESOURCES: + case HCI_REJECTED_SECURITY: + case HCI_REJECTED_PERSONAL: return ECONNREFUSED; - case 0x10: + case HCI_HOST_TIMEOUT: return ETIMEDOUT; - case 0x11: - case 0x27: - case 0x29: - case 0x20: + case HCI_UNSUPPORTED_FEATURE: + case HCI_QOS_NOT_SUPPORTED: + case HCI_PAIRING_NOT_SUPPORTED: + case HCI_UNSUPPORTED_LMP_PARAMETER_VALUE: return EOPNOTSUPP; - case 0x12: + case HCI_INVALID_PARAMETERS: return EINVAL; - case 0x13: - case 0x14: - case 0x15: + case HCI_OE_USER_ENDED_CONNECTION: + case HCI_OE_LOW_RESOURCES: + case HCI_OE_POWER_OFF: return ECONNRESET; - case 0x16: + case HCI_CONNECTION_TERMINATED: return ECONNABORTED; - case 0x17: + case HCI_REPEATED_ATTEMPTS: return ELOOP; - case 0x18: + case HCI_PAIRING_NOT_ALLOWED: return EACCES; - case 0x1a: + case HCI_UNSUPPORTED_REMOTE_FEATURE: return EPROTONOSUPPORT; - case 0x1b: + case HCI_SCO_OFFSET_REJECTED: return ECONNREFUSED; - case 0x19: - case 0x1e: - case 0x23: - case 0x24: - case 0x25: + case HCI_UNKNOWN_LMP_PDU: + case HCI_INVALID_LMP_PARAMETERS: + case HCI_LMP_ERROR_TRANSACTION_COLLISION: + case HCI_LMP_PDU_NOT_ALLOWED: + case HCI_ENCRYPTION_MODE_NOT_ACCEPTED: return EPROTO; default: return ENOSYS; -- cgit From 109bfa547ab9e24672472371e2183dcec24d0058 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 11 Feb 2003 10:22:23 +0000 Subject: add const to fn sigs; fns to auth and enc links --- src/bluetooth.c | 18 +++++++++--------- src/hci.c | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 42 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 4548b121..bc0eb238 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -35,16 +35,16 @@ #include #include -void baswap(bdaddr_t *dst, bdaddr_t *src) +void baswap(bdaddr_t *dst, const bdaddr_t *src) { - register unsigned char * d = (unsigned char *)dst; - register unsigned char * s = (unsigned char *)src; + register unsigned char *d = (unsigned char *)dst; + register const unsigned char *s = (const unsigned char *)src; register int i; for(i=0; i<6; i++) d[i] = s[5-i]; } -char *batostr(bdaddr_t *ba) +char *batostr(const bdaddr_t *ba) { char *str = malloc(18); if (!str) @@ -56,9 +56,9 @@ char *batostr(bdaddr_t *ba) return str; } -bdaddr_t *strtoba(char *str) +bdaddr_t *strtoba(const char *str) { - char *ptr = str; + const char *ptr = str; int i; uint8_t *ba = malloc(sizeof(bdaddr_t)); @@ -74,7 +74,7 @@ bdaddr_t *strtoba(char *str) return (bdaddr_t *) ba; } -int ba2str(bdaddr_t *ba, char *str) +int ba2str(const bdaddr_t *ba, char *str) { uint8_t b[6]; @@ -83,10 +83,10 @@ int ba2str(bdaddr_t *ba, char *str) b[0], b[1], b[2], b[3], b[4], b[5]); } -int str2ba(char *str, bdaddr_t *ba) +int str2ba(const char *str, bdaddr_t *ba) { uint8_t b[6]; - char *ptr = str; + const char *ptr = str; int i; for (i=0; i < 6; i++) { diff --git a/src/hci.c b/src/hci.c index ddc15672..abcfb447 100644 --- a/src/hci.c +++ b/src/hci.c @@ -419,7 +419,7 @@ int hci_get_route(bdaddr_t *bdaddr) return hci_for_each_dev(HCI_UP, NULL, 0); } -int hci_devid(char *str) +int hci_devid(const char *str) { bdaddr_t ba; int id = -1; @@ -467,7 +467,7 @@ int hci_devba(int dev_id, bdaddr_t *ba) return 0; } -int hci_inquiry(int dev_id, int len, int nrsp, uint8_t *lap, inquiry_info **ii, long flags) +int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info **ii, long flags) { struct hci_inquiry_req *ir; void *buf; @@ -697,7 +697,7 @@ done: return 0; } -int hci_create_connection(int dd, bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) +int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) { evt_conn_complete rp; create_conn_cp cp; @@ -788,7 +788,7 @@ int hci_read_local_name(int dd, int len, char *name, int to) return 0; } -int hci_write_local_name(int dd, char *name, int to) +int hci_write_local_name(int dd, const char *name, int to) { change_local_name_cp cp; struct hci_request rq; @@ -805,12 +805,12 @@ int hci_write_local_name(int dd, char *name, int to) return 0; } -int hci_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +int hci_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to) { return hci_read_remote_name(dd, ba, len, name, to); } -int hci_read_remote_name(int dd, bdaddr_t *ba, int len, char *name, int to) +int hci_read_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; @@ -1047,3 +1047,30 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; return hci_send_req(dd, &rq, to); } + +int hci_authenticate_link(int dd, uint16_t handle, int to) +{ + auth_requested_cp cp; + struct hci_request rq; + + cp.handle = handle; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_AUTH_REQUESTED; + rq.cparam = &cp; + rq.clen = AUTH_REQUESTED_CP_SIZE; + return hci_send_req(dd, &rq, to); +} + +int hci_encrypt_link(int dd, uint16_t handle, int on, int to) +{ + set_conn_encrypt_cp cp; + struct hci_request rq; + + cp.handle = handle; + cp.encrypt = on; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.cparam = &cp; + rq.clen = SET_CONN_ENCRYPT_CP_SIZE; + return hci_send_req(dd, &rq, to); +} -- cgit From dcaa587850c70d3a8efaf39a756207062e6a7ed6 Mon Sep 17 00:00:00 2001 From: Max Krasnyansky Date: Thu, 20 Mar 2003 19:30:29 +0000 Subject: New version. --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 794d67d2..ac3e7279 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,6 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c -libbluetooth_la_LDFLAGS = -version-info 1:1:0 +libbluetooth_la_LDFLAGS = -version-info 1:2:0 INCLUDES = -I$(top_srcdir)/include -- cgit From 8ab4acd91521e11b769c8b1d2c89a40cf9077396 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 21 Mar 2003 14:13:46 +0000 Subject: Use R1 for default value of pscan_rep_mode --- src/hci.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index abcfb447..312c748e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -703,11 +703,12 @@ int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t c create_conn_cp cp; struct hci_request rq; - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.bdaddr, ba); - cp.pkt_type = ptype; - cp.clock_offset = clkoffset; - cp.role_switch = rswitch; + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, ba); + cp.pkt_type = ptype; + cp.pscan_rep_mode = 0x01; + cp.clock_offset = clkoffset; + cp.role_switch = rswitch; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; -- cgit From bfcbbde6d7baebca27c6e93f02f6279e5f36c866 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 21 Mar 2003 14:26:12 +0000 Subject: Use R1 for default value of pscan_rep_mode --- src/hci.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 312c748e..5c58b129 100644 --- a/src/hci.c +++ b/src/hci.c @@ -800,7 +800,7 @@ int hci_write_local_name(int dd, const char *name, int to) rq.ocf = OCF_CHANGE_LOCAL_NAME; rq.cparam = &cp; rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; - + if (hci_send_req(dd, &rq, to) < 0) return -1; return 0; @@ -819,6 +819,7 @@ int hci_read_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); + cp.pscan_rep_mode = 0x01; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; @@ -847,10 +848,10 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) evt_read_remote_features_complete rp; read_remote_features_cp cp; struct hci_request rq; - + memset(&cp, 0, sizeof(cp)); cp.handle = handle; - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_FEATURES; @@ -859,15 +860,15 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) rq.clen = READ_REMOTE_FEATURES_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE; - + if (hci_send_req(dd, &rq, to) < 0) return -1; - + if (rp.status) { errno = EIO; return -1; } - + memcpy(features, rp.features, 8); return 0; } @@ -877,10 +878,10 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in evt_read_remote_version_complete rp; read_remote_version_cp cp; struct hci_request rq; - + memset(&cp, 0, sizeof(cp)); cp.handle = handle; - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_READ_REMOTE_VERSION; @@ -889,15 +890,15 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in rq.clen = READ_REMOTE_VERSION_CP_SIZE; rq.rparam = &rp; rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE; - + if (hci_send_req(dd, &rq, to) < 0) return -1; - + if (rp.status) { errno = EIO; return -1; } - + ver->manufacturer = btohs(rp.manufacturer); ver->lmp_ver = rp.lmp_ver; ver->lmp_subver = btohs(rp.lmp_subver); @@ -928,7 +929,6 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) ver->hci_rev = btohs(rp.hci_rev); ver->lmp_ver = rp.lmp_ver; ver->lmp_subver = btohs(rp.lmp_subver); - return 0; } -- cgit From 1c9576607a611e033e0bac0f56d91146c120a16d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Mar 2003 08:00:36 +0000 Subject: Support for reading the clock offset --- src/hci.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 5c58b129..9a5c7dfe 100644 --- a/src/hci.c +++ b/src/hci.c @@ -905,6 +905,36 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in return 0; } +int hci_read_clock_offset(int dd, uint16_t handle, uint16_t *clkoffset, int to) +{ + evt_read_clock_offset_complete rp; + read_clock_offset_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_READ_CLOCK_OFFSET; + rq.event = EVT_READ_CLOCK_OFFSET_COMPLETE; + rq.cparam = &cp; + rq.clen = READ_CLOCK_OFFSET_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *clkoffset = rp.clock_offset; + return 0; +} + int hci_read_local_version(int dd, struct hci_version *ver, int to) { read_local_version_rp rp; -- cgit From 6cd70af01a46b7e543c50d0646b877c38b3257f4 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 19 May 2003 17:47:22 +0000 Subject: fix auth and encrypt --- src/hci.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 9a5c7dfe..e6cf48c4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1082,6 +1082,7 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) int hci_authenticate_link(int dd, uint16_t handle, int to) { auth_requested_cp cp; + evt_auth_complete rp; struct hci_request rq; cp.handle = handle; @@ -1089,12 +1090,22 @@ int hci_authenticate_link(int dd, uint16_t handle, int to) rq.ocf = OCF_AUTH_REQUESTED; rq.cparam = &cp; rq.clen = AUTH_REQUESTED_CP_SIZE; - return hci_send_req(dd, &rq, to); + rq.rparam = &rp; + rq.event = EVT_AUTH_COMPLETE; + rq.rlen = EVT_AUTH_COMPLETE_SIZE; + if (hci_send_req(dd, &rq, to) < 0) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } int hci_encrypt_link(int dd, uint16_t handle, int on, int to) { set_conn_encrypt_cp cp; + evt_encrypt_change rp; struct hci_request rq; cp.handle = handle; @@ -1103,5 +1114,14 @@ int hci_encrypt_link(int dd, uint16_t handle, int on, int to) rq.ocf = OCF_SET_CONN_ENCRYPT; rq.cparam = &cp; rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - return hci_send_req(dd, &rq, to); + rq.event = EVT_ENCRYPT_CHANGE; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; + rq.rparam = &rp; + if (hci_send_req(dd, &rq, to) < 0) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } -- cgit From 2c375c1f2c5cff353e2f767ac14f8251452392e9 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Tue, 20 May 2003 11:33:53 +0000 Subject: add role switch --- src/hci.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index e6cf48c4..6d313d21 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1125,3 +1125,27 @@ int hci_encrypt_link(int dd, uint16_t handle, int on, int to) } return 0; } + +int hci_switch_role(int dd, bdaddr_t peer, int role, int to) +{ + switch_role_cp cp; + evt_role_change rp; + struct hci_request rq; + + cp.bdaddr = peer; + cp.role = role; + 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, to) < 0) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + return 0; +} -- cgit From c12c507c9a494cd70e82b01c9856d92ebf36f165 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 26 May 2003 13:10:49 +0000 Subject: Add new company identifiers --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index bc0eb238..baaf9f7c 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -273,6 +273,8 @@ char *bt_compidtostr(int compid) return "Red-M (Communications) Ltd"; case 51: return "Commil Ltd"; + case 52: + return "Computer Access Technology Corporation (CATC)"; case 65535: return "internal use"; default: -- cgit From 8095772fc06beb7d21bb02c0cc0a2157734e5919 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jun 2003 14:04:01 +0000 Subject: Add new company identifiers --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index baaf9f7c..f2c13a24 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -275,6 +275,8 @@ char *bt_compidtostr(int compid) return "Commil Ltd"; case 52: return "Computer Access Technology Corporation (CATC)"; + case 53: + return "Eclipse (HQ Espana) S.L."; case 65535: return "internal use"; default: -- cgit From 78410fbc646a08b98487096e93e7bde4189314ae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jun 2003 13:09:02 +0000 Subject: Add functions for park mode --- src/hci.c | 226 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 143 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 6d313d21..676b8af8 100644 --- a/src/hci.c +++ b/src/hci.c @@ -39,9 +39,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -699,9 +699,9 @@ done: int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) { - evt_conn_complete rp; - create_conn_cp cp; - struct hci_request rq; + evt_conn_complete rp; + create_conn_cp cp; + struct hci_request rq; memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); @@ -711,21 +711,21 @@ int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t c cp.role_switch = rswitch; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_CREATE_CONN; - rq.event = EVT_CONN_COMPLETE; - rq.cparam = &cp; - rq.clen = CREATE_CONN_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_CONN_COMPLETE_SIZE; - - if (hci_send_req(dd, &rq, to) < 0) - return -1; - - if (rp.status) { - errno = EIO; - return -1; - } + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_CREATE_CONN; + rq.event = EVT_CONN_COMPLETE; + rq.cparam = &cp; + rq.clen = CREATE_CONN_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CONN_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } *handle = rp.handle; return 0; @@ -733,31 +733,31 @@ int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t c int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) { - evt_disconn_complete rp; - disconnect_cp cp; - struct hci_request rq; + evt_disconn_complete rp; + disconnect_cp cp; + struct hci_request rq; - memset(&cp, 0, sizeof(cp)); - cp.handle = handle; - cp.reason = reason; + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.reason = reason; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_DISCONNECT; - rq.event = EVT_DISCONN_COMPLETE; - rq.cparam = &cp; - rq.clen = DISCONNECT_CP_SIZE; - rq.rparam = &rp; - rq.rlen = EVT_DISCONN_COMPLETE_SIZE; - - if (hci_send_req(dd, &rq, to) < 0) - return -1; - - if (rp.status) { - errno = EIO; - return -1; - } - return 0; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_DISCONNECT; + rq.event = EVT_DISCONN_COMPLETE; + rq.cparam = &cp; + rq.clen = DISCONNECT_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_DISCONN_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } int hci_local_name(int dd, int len, char *name, int to) @@ -775,7 +775,7 @@ int hci_read_local_name(int dd, int len, char *name, int to) rq.ocf = OCF_READ_LOCAL_NAME; rq.rparam = &rp; rq.rlen = READ_LOCAL_NAME_RP_SIZE; - + if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -796,10 +796,10 @@ int hci_write_local_name(int dd, const char *name, int to) strncpy(cp.name, name, sizeof(cp.name)); memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_CHANGE_LOCAL_NAME; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_CHANGE_LOCAL_NAME; rq.cparam = &cp; - rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; + rq.clen = CHANGE_LOCAL_NAME_CP_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -862,11 +862,11 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) rq.rlen = EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE; if (hci_send_req(dd, &rq, to) < 0) - return -1; + return -1; if (rp.status) { - errno = EIO; - return -1; + errno = EIO; + return -1; } memcpy(features, rp.features, 8); @@ -955,10 +955,10 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) } ver->manufacturer = btohs(rp.manufacturer); - ver->hci_ver = rp.hci_ver; - ver->hci_rev = btohs(rp.hci_rev); - ver->lmp_ver = rp.lmp_ver; - ver->lmp_subver = btohs(rp.lmp_subver); + ver->hci_ver = rp.hci_ver; + ver->hci_rev = btohs(rp.hci_rev); + ver->lmp_ver = rp.lmp_ver; + ver->lmp_subver = btohs(rp.lmp_subver); return 0; } @@ -994,10 +994,10 @@ int hci_write_class_of_dev(int dd, uint32_t cls, int to) cp.dev_class[0] = cls & 0xff; cp.dev_class[1] = (cls >> 8) & 0xff; cp.dev_class[2] = (cls >> 16) & 0xff; - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CLASS_OF_DEV; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CLASS_OF_DEV; rq.cparam = &cp; - rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; + rq.clen = WRITE_CLASS_OF_DEV_CP_SIZE; return hci_send_req(dd, &rq, to); } @@ -1020,8 +1020,8 @@ int hci_read_voice_setting(int dd, uint16_t *vs, int to) return -1; } - *vs = rp.voice_setting; - return 0; + *vs = rp.voice_setting; + return 0; } int hci_write_voice_setting(int dd, uint16_t vs, int to) @@ -1031,10 +1031,10 @@ int hci_write_voice_setting(int dd, uint16_t vs, int to) memset(&rq, 0, sizeof(rq)); cp.voice_setting = vs; - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_VOICE_SETTING; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_VOICE_SETTING; rq.cparam = &cp; - rq.clen = WRITE_VOICE_SETTING_CP_SIZE; + rq.clen = WRITE_VOICE_SETTING_CP_SIZE; return hci_send_req(dd, &rq, to); } @@ -1044,10 +1044,10 @@ int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) struct hci_request rq; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_CURRENT_IAC_LAP; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_CURRENT_IAC_LAP; rq.rparam = &rp; - rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; + rq.rlen = READ_CURRENT_IAC_LAP_RP_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -1072,10 +1072,10 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) memcpy(&cp.lap, lap, num_iac * 3); memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; rq.cparam = &cp; - rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; return hci_send_req(dd, &rq, to); } @@ -1086,13 +1086,13 @@ int hci_authenticate_link(int dd, uint16_t handle, int to) struct hci_request rq; cp.handle = handle; - 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.event = EVT_AUTH_COMPLETE; - rq.rlen = EVT_AUTH_COMPLETE_SIZE; + rq.event = EVT_AUTH_COMPLETE; + rq.rlen = EVT_AUTH_COMPLETE_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; if (rp.status) { @@ -1108,14 +1108,14 @@ int hci_encrypt_link(int dd, uint16_t handle, int on, int to) evt_encrypt_change rp; struct hci_request rq; - cp.handle = handle; + cp.handle = handle; cp.encrypt = on; - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_ENCRYPT; rq.cparam = &cp; - rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - rq.event = EVT_ENCRYPT_CHANGE; - rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; + rq.clen = SET_CONN_ENCRYPT_CP_SIZE; + rq.event = EVT_ENCRYPT_CHANGE; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; rq.rparam = &rp; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -1133,19 +1133,79 @@ int hci_switch_role(int dd, bdaddr_t peer, int role, int to) struct hci_request rq; cp.bdaddr = peer; - cp.role = role; - rq.ogf = OGF_LINK_POLICY; - rq.ocf = OCF_SWITCH_ROLE; + cp.role = role; + 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, to) < 0) + return -1; + if (rp.status) { + errno = EIO; + return -1; + } + return 0; +} + +int hci_park_mode (int dd, uint16_t handle, uint16_t max_interval, uint16_t min_interval, int to) +{ + park_mode_cp cp; + evt_mode_change rp; + struct hci_request rq; + + memset(&cp, 0, sizeof (cp)); + cp.handle = handle; + cp.max_interval = max_interval; + cp.min_interval = min_interval; + + memset(&rq, 0, sizeof (rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_PARK_MODE; + rq.event = EVT_MODE_CHANGE; rq.cparam = &cp; - rq.clen = SWITCH_ROLE_CP_SIZE; + rq.clen = PARK_MODE_CP_SIZE; rq.rparam = &rp; - rq.rlen = EVT_ROLE_CHANGE_SIZE; - rq.event = EVT_ROLE_CHANGE; + rq.rlen = EVT_MODE_CHANGE_SIZE; + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; } + + return 0; +} + +int hci_exit_park_mode(int dd, uint16_t handle, int to) +{ + exit_park_mode_cp cp; + evt_mode_change rp; + struct hci_request rq; + + memset(&cp, 0, sizeof (cp)); + cp.handle = handle; + + memset (&rq, 0, sizeof (rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_EXIT_PARK_MODE; + rq.event = EVT_MODE_CHANGE; + rq.cparam = &cp; + rq.clen = EXIT_PARK_MODE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_MODE_CHANGE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } -- cgit From 5624d6cc20e5fb63d4b34b672b2421eb38b849e5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jun 2003 21:17:37 +0000 Subject: Add functions for park mode --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 676b8af8..b01dec97 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1150,7 +1150,7 @@ int hci_switch_role(int dd, bdaddr_t peer, int role, int to) return 0; } -int hci_park_mode (int dd, uint16_t handle, uint16_t max_interval, uint16_t min_interval, int to) +int hci_park_mode(int dd, uint16_t handle, uint16_t max_interval, uint16_t min_interval, int to) { park_mode_cp cp; evt_mode_change rp; -- cgit From 9b910ddd11031c344408cc11b50116f0d5631231 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 18 Jul 2003 01:51:09 +0000 Subject: Add new company identifiers --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index f2c13a24..97688efc 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -277,6 +277,8 @@ char *bt_compidtostr(int compid) return "Computer Access Technology Corporation (CATC)"; case 53: return "Eclipse (HQ Espana) S.L."; + case 54: + return "Renesas Technology Corp."; case 65535: return "internal use"; default: -- cgit From 349d081b82323130f0648eeac5329fa53610d3f1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 25 Jul 2003 12:57:59 +0000 Subject: Add new company identifiers --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 97688efc..af56573b 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -279,6 +279,8 @@ char *bt_compidtostr(int compid) return "Eclipse (HQ Espana) S.L."; case 54: return "Renesas Technology Corp."; + case 55: + return "Mobilian Corporation"; case 65535: return "internal use"; default: -- cgit From 1ebb5e939840d4be143d086eaa68a1c281084561 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 13 Aug 2003 15:48:33 +0000 Subject: Add new company identifiers --- src/bluetooth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index af56573b..fedeb384 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -281,6 +281,10 @@ char *bt_compidtostr(int compid) return "Renesas Technology Corp."; case 55: return "Mobilian Corporation"; + case 56: + return "Terax"; + case 57: + return "Integrated System Solution Corp."; case 65535: return "internal use"; default: -- cgit From bdcb3c69d6ad2a308c0b636e0a697f1f261d97b9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 14 Aug 2003 16:50:33 +0000 Subject: Remove useless white space --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index b01dec97..f22fcbfc 100644 --- a/src/hci.c +++ b/src/hci.c @@ -141,7 +141,7 @@ char *hci_dtypetostr(int type) case HCI_VHCI: return "VHCI"; case HCI_USB: - return "USB "; + return "USB"; case HCI_PCCARD: return "PCCARD"; case HCI_UART: -- cgit From 2f6b4e4f5e4da2cea6af279b262f81e9d52e78e4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 3 Sep 2003 10:50:40 +0000 Subject: Add link manager version parameter for Bluetooth 1.2 --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index f22fcbfc..818c04e5 100644 --- a/src/hci.c +++ b/src/hci.c @@ -269,6 +269,7 @@ int hci_strtolm(char *str, unsigned int *val) hci_map ver_map[] = { { "1.0b", 0x00 }, { "1.1", 0x01 }, + { "1.2", 0x02 }, { NULL } }; char *hci_vertostr(unsigned int ver) -- cgit From 3d29835ef69b00fa3ed92702727ea2f737f37af2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Sep 2003 17:55:45 +0000 Subject: Add new company identifiers --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index fedeb384..9c4536fc 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -285,6 +285,8 @@ char *bt_compidtostr(int compid) return "Terax"; case 57: return "Integrated System Solution Corp."; + case 58: + return "Matsushita Electric Industrial Co., Ltd."; case 65535: return "internal use"; default: -- cgit From aac33d6b2e0c3c7b021478feb320afd8c812bda9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 18 Nov 2003 11:36:20 +0000 Subject: Add decoding of Bluetooth 1.2 features --- src/hci.c | 68 ++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 818c04e5..61bdd1a6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -295,32 +295,60 @@ int lmp_strtover(char *str, unsigned int *ver) /* LMP features mapping */ hci_map lmp_features_map[][9] = { { /* byte 0 */ - { "<3-slot packets>", LMP_3SLOT }, - { "<5-slot packets>", LMP_5SLOT }, - { "", LMP_ENCRYPT }, - { "", LMP_SOFFSET }, - { "", LMP_TACCURACY}, - { "", LMP_RSWITCH }, - { "", LMP_HOLD }, - { "", LMP_SNIFF }, + { "<3-slot packets>", LMP_3SLOT }, + { "<5-slot packets>", LMP_5SLOT }, + { "", LMP_ENCRYPT }, + { "", LMP_SOFFSET }, + { "", LMP_TACCURACY }, + { "", LMP_RSWITCH }, + { "", LMP_HOLD }, + { "", LMP_SNIFF }, { NULL } }, { /* byte 1 */ - { "", LMP_PARK }, - { "", LMP_RSSI }, - { "", LMP_QUALITY }, - { "", LMP_SCO }, - { "", LMP_HV2 }, - { "", LMP_HV3 }, - { "", LMP_ULAW }, - { "", LMP_ALAW }, + { "", LMP_PARK }, + { "", LMP_RSSI }, + { "", LMP_QUALITY }, + { "", LMP_SCO }, + { "", LMP_HV2 }, + { "", LMP_HV3 }, + { "", LMP_ULAW }, + { "", LMP_ALAW }, { NULL } }, { /* byte 2 */ - { "", LMP_CVSD }, - { "", LMP_PSCHEME }, - { "", LMP_PCONTROL }, - { "", LMP_TRSP_SCO }, + { "", LMP_CVSD }, + { "", LMP_PSCHEME }, + { "", LMP_PCONTROL }, + { "", LMP_TRSP_SCO }, + { "",LMP_BCAST_ENC }, + { NULL } + }, + { /* byte 3 */ + { "", LMP_ENH_ISCAN }, + { "", LMP_ILACE_ISCAN }, + { "", LMP_ILACE_PSCAN }, + { "",LMP_RSSI_INQ }, + { "", LMP_ESCO }, + { NULL } + }, + { /* byte 4 */ + { "", LMP_EV4 }, + { "", LMP_EV5 }, + { "", LMP_AFH_CAP_SLV }, + { "", LMP_AFH_CLS_SLV }, + { NULL } + }, + { /* byte 5 */ + { "", LMP_AFH_CAP_MST }, + { "",LMP_AFH_CLS_MST }, + { NULL } + }, + { /* byte 6 */ + { NULL } + }, + { /* byte 7 */ + { "",LMP_EXT_FEAT }, { NULL } }, {{ NULL }} -- cgit From 6b5b6093a75df05d27571d192d4ef2fb56bfc6e2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 20 Nov 2003 08:50:42 +0000 Subject: Fix lmp_featurestostr() --- src/hci.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 61bdd1a6..8100d227 100644 --- a/src/hci.c +++ b/src/hci.c @@ -293,7 +293,7 @@ int lmp_strtover(char *str, unsigned int *ver) } /* LMP features mapping */ -hci_map lmp_features_map[][9] = { +hci_map lmp_features_map[8][9] = { { /* byte 0 */ { "<3-slot packets>", LMP_3SLOT }, { "<5-slot packets>", LMP_5SLOT }, @@ -351,7 +351,6 @@ hci_map lmp_features_map[][9] = { { "",LMP_EXT_FEAT }, { NULL } }, - {{ NULL }} }; char *lmp_featurestostr(uint8_t *features, char *pref, int width) @@ -367,7 +366,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) if (pref) ptr += sprintf(ptr, "%s", pref); - for(i=0, w=0; lmp_features_map[i][0].str; i++) { + for(i=0, w=0; i<8; i++) { hci_map *m; m = lmp_features_map[i]; @@ -381,7 +380,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) m++; } } - + return str; } -- cgit From 4831ff2d35f407ddff185c2d6350355556244101 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 17 Dec 2003 14:28:36 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index ac3e7279..2388a753 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,6 +5,6 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c -libbluetooth_la_LDFLAGS = -version-info 1:2:0 +libbluetooth_la_LDFLAGS = -version-info 1:3:0 INCLUDES = -I$(top_srcdir)/include -- cgit From a1b95e6f01957e2e5c3a9950a6da307e9ada285b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 24 Dec 2003 11:58:54 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 9c4536fc..a2aae586 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -287,6 +287,8 @@ char *bt_compidtostr(int compid) return "Integrated System Solution Corp."; case 58: return "Matsushita Electric Industrial Co., Ltd."; + case 59: + return "Gennum Corporation"; case 65535: return "internal use"; default: -- cgit From 382615bc4b30d8204bdad79643f98cf19656b2a3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 31 Jan 2004 00:55:32 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index a2aae586..1607c04f 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -289,6 +289,8 @@ char *bt_compidtostr(int compid) return "Matsushita Electric Industrial Co., Ltd."; case 59: return "Gennum Corporation"; + case 60: + return "Research In Motion"; case 65535: return "internal use"; default: -- cgit From 542fc57346fbb329934152f446f58cc61a5d5d00 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 16:37:55 +0000 Subject: Add SDP library code --- src/Makefile.am | 9 +- src/sdp.c | 3076 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 3082 insertions(+), 3 deletions(-) create mode 100644 src/sdp.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 2388a753..6c6b9fc4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,9 +2,12 @@ # $Id$ # -lib_LTLIBRARIES = libbluetooth.la +lib_LTLIBRARIES = libbluetooth.la libsdp.la -libbluetooth_la_SOURCES = bluetooth.c hci.c -libbluetooth_la_LDFLAGS = -version-info 1:3:0 +libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c +libbluetooth_la_LDFLAGS = -version-info 1:4:0 + +libsdp_la_SOURCES = +libsdp_la_LDFLAGS = -version-info 2:2:0 INCLUDES = -I$(top_srcdir)/include diff --git a/src/sdp.c b/src/sdp.c new file mode 100644 index 00000000..4ffb0d93 --- /dev/null +++ b/src/sdp.c @@ -0,0 +1,3076 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky + + Based on an 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 + +#include +#include +#include +#include +#include +#include +#include + +#define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB" + +static uint128_t *bluetooth_base_uuid = NULL; + +/* Message structure. */ +struct tupla { + int index; + char *str; +}; + +static struct tupla Protocol[] = { + { SDP_UUID, "SDP" }, + { RFCOMM_UUID, "RFCOMM" }, + { TCS_BIN_UUID, "TCS-BIN" }, + { L2CAP_UUID, "L2CAP" }, + { IP_UUID, "IP" }, + { UDP_UUID, "UDP" }, + { TCP_UUID, "TCP" }, + { TCS_AT_UUID, "TCS-AT" }, + { OBEX_UUID, "OBEX" }, + { FTP_UUID, "FTP" }, + { HTTP_UUID, "HTTP" }, + { WSP_UUID, "WSP" }, + { BNEP_UUID, "BNEP" }, + { 0 } +}; + +static struct tupla ServiceClass[] = { + { SDP_SERVER_SVCLASS_ID, "SDP Server" }, + { BROWSE_GRP_DESC_SVCLASS_ID, "Browse Group Descriptor" }, + { PUBLIC_BROWSE_GROUP, "Public Browse Group" }, + { SERIAL_PORT_SVCLASS_ID, "Serial Port" }, + { LAN_ACCESS_SVCLASS_ID, "LAN Access Using PPP" }, + { DIALUP_NET_SVCLASS_ID, "Dialup Networking" }, + { IRMC_SYNC_SVCLASS_ID, "IrMCSync" }, + { OBEX_OBJPUSH_SVCLASS_ID, "OBEX Object Push" }, + { OBEX_FILETRANS_SVCLASS_ID, "OBEX File Transfer" }, + { IRMC_SYNC_CMD_SVCLASS_ID, "IrMCSync Command" }, + { HEADSET_SVCLASS_ID, "Headset" }, + { CORDLESS_TELEPHONY_SVCLASS_ID,"Cordless Telephony" }, + { INTERCOM_SVCLASS_ID, "Intercom" }, + { FAX_SVCLASS_ID, "Fax" }, + { HEADSET_AGW_SVCLASS_ID, "Headset Audio Gateway" }, + { PNP_INFO_SVCLASS_ID, "PnP Information" }, + { GENERIC_NETWORKING_SVCLASS_ID,"Generic Networking" }, + { GENERIC_FILETRANS_SVCLASS_ID, "Generic File Transfer" }, + { GENERIC_AUDIO_SVCLASS_ID, "Generic Audio" }, + { GENERIC_TELEPHONY_SVCLASS_ID, "Generic Telephony" }, + { PANU_SVCLASS_ID, "PAN user" }, + { NAP_SVCLASS_ID, "Network access point" }, + { GN_SVCLASS_ID, "PAN group network" }, + { 0 } +}; + +static struct tupla Profile[] = { + { SERIAL_PORT_PROFILE_ID, "Serial Port" }, + { LAN_ACCESS_PROFILE_ID, "LAN Access Using PPP" }, + { DIALUP_NET_PROFILE_ID, "Dialup Networking" }, + { IRMC_SYNC_PROFILE_ID, "IrMCSync" }, + { OBEX_OBJPUSH_PROFILE_ID, "OBEX Object Push" }, + { OBEX_FILETRANS_PROFILE_ID, "OBEX File Transfer" }, + { IRMC_SYNC_CMD_PROFILE_ID, "IrMCSync Command" }, + { HEADSET_PROFILE_ID, "Headset" }, + { CORDLESS_TELEPHONY_PROFILE_ID, "Cordless Telephony" }, + { INTERCOM_PROFILE_ID, "Intercom" }, + { FAX_PROFILE_ID, "Fax" }, + { HEADSET_AGW_PROFILE_ID, "Headset Audio Gateway" }, + { PANU_PROFILE_ID, "PAN user" }, + { NAP_PROFILE_ID, "PAN access point" }, + { GN_PROFILE_ID, "PAN group network" }, + { 0 } +}; + +static char *string_lookup(struct tupla *pt0, int index) +{ + struct tupla *pt; + for (pt = pt0; pt->index; pt++) + if (pt->index == index) + return pt->str; + return ""; +} + +/* + * Prints into a string the Protocol UUID + * coping a maximum of n characters. + */ +static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t n) +{ + char *str2; + + if (!uuid) { + snprintf(str, n, "NULL"); + return -2; + } + switch (uuid->type) { + case SDP_UUID16: + str2 = string_lookup(message, uuid->value.uuid16); + snprintf(str, n, str2); + break; + case SDP_UUID32: + snprintf(str, n, "Error: This is uuid32"); + return -3; + case SDP_UUID128: + snprintf(str, n, "Error: This is uuid128"); + return -4; + default: + snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); + return -1; + } + return 0; +} + +int sdp_proto_uuid2strn(const uuid_t *uuid, char *str, size_t n) +{ + return uuid2str(Protocol, uuid, str, n); +} + +int sdp_svclass_uuid2strn(const uuid_t *uuid, char *str, size_t n) +{ + return uuid2str(ServiceClass, uuid, str, n); +} + +int sdp_profile_uuid2strn(const uuid_t *uuid, char *str, size_t n) +{ + return uuid2str(Profile, uuid, str, n); +} + +/* + * convert the UUID to string, copying a maximum of n characters. + */ +int sdp_uuid2strn(const uuid_t *uuid, char *str, size_t n) +{ + if (!uuid) { + snprintf(str, n, "NULL"); + return -2; + } + switch (uuid->type) { + case SDP_UUID16: + snprintf(str, n, "%.4x", uuid->value.uuid16); + break; + case SDP_UUID32: + snprintf(str, n, "%.8x", uuid->value.uuid32); + break; + case 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); + + snprintf(str, n, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x", + ntohl(data0), ntohs(data1), + ntohs(data2), ntohs(data3), + ntohl(data4), ntohs(data5)); + } + break; + default: + snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); + return -1; // Enum type of UUID not set + } + return 0; +} + +#ifdef SDP_DEBUG +/* + * Function prints the UUID in hex as per defined syntax - + * + * 4bytes-2bytes-2bytes-2bytes-6bytes + * + * There is some ugly code, including hardcoding, but + * that is just the way it is converting 16 and 32 bit + * UUIDs to 128 bit as defined in the SDP doc + */ +void sdp_uuid_print(const uuid_t *uuid) +{ + if (uuid == NULL) { + SDPERR("Null passed to print UUID\n"); + return; + } + if (uuid->type == SDP_UUID16) { + SDPDBG(" uint16_t : 0x%.4x\n", uuid->value.uuid16); + } else if (uuid->type == SDP_UUID32) { + SDPDBG(" uint32_t : 0x%.8x\n", 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); + + SDPDBG(" uint128_t : 0x%.8x-", ntohl(data0)); + SDPDBG("%.4x-", ntohs(data1)); + SDPDBG("%.4x-", ntohs(data2)); + SDPDBG("%.4x-", ntohs(data3)); + SDPDBG("%.8x", ntohl(data4)); + SDPDBG("%.4x\n", ntohs(data5)); + } else + SDPERR("Enum type of UUID not set\n"); +} +#endif + +sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) +{ + sdp_data_t *seq; + int len = 0; + sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + + if (!d) + return NULL; + + memset(d, 0, sizeof(sdp_data_t)); + d->dtd = dtd; + d->unitSize = sizeof(uint8_t); + + switch (dtd) { + case SDP_DATA_NIL: + break; + case SDP_UINT8: + d->val.uint8 = *(uint8_t *)value; + d->unitSize += sizeof(uint8_t); + break; + case SDP_INT8: + case SDP_BOOL: + d->val.int8 = *(int8_t *)value; + d->unitSize += sizeof(int8_t); + break; + case SDP_UINT16: + d->val.uint16 = sdp_get_unaligned((uint16_t *)value); + d->unitSize += sizeof(uint16_t); + break; + case SDP_INT16: + d->val.int16 = sdp_get_unaligned((int16_t *)value); + d->unitSize += sizeof(int16_t); + break; + case SDP_UINT32: + d->val.uint32 = sdp_get_unaligned((uint32_t *)value); + d->unitSize += sizeof(uint32_t); + break; + case SDP_INT32: + d->val.int32 = sdp_get_unaligned((int32_t *)value); + d->unitSize += sizeof(int32_t); + break; + case SDP_INT64: + d->val.int64 = sdp_get_unaligned((int64_t *)value); + d->unitSize += sizeof(int64_t); + break; + case SDP_UINT64: + d->val.uint64 = sdp_get_unaligned((uint64_t *)value); + d->unitSize += sizeof(uint64_t); + break; + case SDP_UINT128: + memcpy(&d->val.uint128.data, value, sizeof(uint128_t)); + d->unitSize += sizeof(uint128_t); + break; + case SDP_INT128: + memcpy(&d->val.int128.data, value, sizeof(uint128_t)); + d->unitSize += sizeof(uint128_t); + break; + case SDP_UUID16: + sdp_uuid16_create(&d->val.uuid, sdp_get_unaligned((uint16_t *)value)); + d->unitSize += sizeof(uint16_t); + break; + case SDP_UUID32: + sdp_uuid32_create(&d->val.uuid, sdp_get_unaligned((uint32_t *)value)); + d->unitSize += sizeof(uint32_t); + break; + case SDP_UUID128: + sdp_uuid128_create(&d->val.uuid, value); + d->unitSize += sizeof(uint128_t); + break; + case SDP_URL_STR8: + case SDP_TEXT_STR8: + case SDP_URL_STR16: + case SDP_TEXT_STR16: + if (!value) + goto out_error; + + len = strlen(value); + d->unitSize += len; + if (len <= USHRT_MAX) { + d->val.str = (char *)malloc(len + 1); + if (!d->val.str) + goto out_error; + + strcpy(d->val.str, value); + if (len <= UCHAR_MAX) { + d->unitSize += sizeof(uint8_t); + if (dtd != SDP_URL_STR8 && dtd != SDP_TEXT_STR8) { + if (dtd == SDP_URL_STR16) + dtd = SDP_URL_STR8; + else + dtd = SDP_TEXT_STR8; + } + } else { + d->unitSize += sizeof(uint16_t); + if (dtd == SDP_TEXT_STR8) + dtd = SDP_TEXT_STR16; + else + dtd = SDP_URL_STR16; + } + } else { + SDPERR("Strings of size > USHRT_MAX not supported\n"); + goto out_error; + } + break; + case SDP_URL_STR32: + case SDP_TEXT_STR32: + SDPERR("Strings of size > USHRT_MAX not supported\n"); + break; + case SDP_ALT8: + case SDP_ALT16: + case SDP_ALT32: + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + if (dtd == SDP_ALT8 || dtd == SDP_SEQ8) + d->unitSize += sizeof(uint8_t); + else if (dtd == SDP_ALT16 || dtd == SDP_SEQ16) + d->unitSize += sizeof(uint16_t); + else if (dtd == SDP_ALT32 || dtd == SDP_SEQ32) + d->unitSize += sizeof(uint32_t); + seq = (sdp_data_t *)value; + d->val.dataseq = seq; + for (; seq; seq = seq->next) + d->unitSize += seq->unitSize; + break; + default: + goto out_error; + } + return d; + +out_error: + free(d); + return NULL; +} + +sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d) +{ + if (seq) { + sdp_data_t *p; + for (p = seq; p->next; p = p->next); + p->next = d; + } else + seq = d; + d->next = NULL; + return seq; +} + +sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len) +{ + sdp_data_t *curr = NULL, *seq = NULL; + int i; + + for (i = 0; i < len; i++) { + sdp_data_t *data; + uint8_t dtd = *(uint8_t *)dtds[i]; + if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32) + data = (sdp_data_t *)values[i]; + else + data = sdp_data_alloc(dtd, values[i]); + if (!data) + return NULL; + if (curr) + curr->next = data; + else + seq = data; + curr = data; + } + return sdp_data_alloc(SDP_SEQ8, seq); +} + +int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d) +{ + sdp_data_t *p = sdp_data_get(rec, attr); + + if (p) + return -1; + d->attrId = attr; + rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func); + return 0; +} + +void sdp_attr_remove(sdp_record_t *rec, uint16_t attr) +{ + sdp_data_t *d = sdp_data_get(rec, attr); + if (d) + rec->attrlist = sdp_list_remove(rec->attrlist, d); +} + +void sdp_set_seq_len(char *ptr, int length) +{ + uint8_t dtd = *(uint8_t *)ptr++; + + switch (dtd) { + case SDP_SEQ8: + case SDP_ALT8: + case SDP_TEXT_STR8: + case SDP_URL_STR8: + *(uint8_t *)ptr = (uint8_t)length; + break; + case SDP_SEQ16: + case SDP_ALT16: + case SDP_TEXT_STR16: + case SDP_URL_STR16: + sdp_put_unaligned(htons(length), (uint16_t *)ptr); + break; + case SDP_SEQ32: + case SDP_ALT32: + case SDP_TEXT_STR32: + case SDP_URL_STR32: + sdp_put_unaligned(htons(length), (uint32_t *)ptr); + break; + } +} + +int sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd) +{ + int orig = buf->data_size; + uint8_t *p = buf->data + buf->data_size; + + *p++ = dtd; + buf->data_size += sizeof(uint8_t); + switch (dtd) { + case SDP_SEQ8: + case SDP_TEXT_STR8: + case SDP_URL_STR8: + case SDP_ALT8: + buf->data_size += sizeof(uint8_t); + break; + case SDP_SEQ16: + case SDP_TEXT_STR16: + case SDP_URL_STR16: + case SDP_ALT16: + buf->data_size += sizeof(uint16_t); + break; + case SDP_SEQ32: + case SDP_TEXT_STR32: + case SDP_URL_STR32: + case SDP_ALT32: + buf->data_size += sizeof(uint32_t); + break; + } + return buf->data_size - orig; +} + +void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr) +{ + uint8_t *p = buf->data; + + // data type for attr + *p++ = SDP_UINT16; + buf->data_size = sizeof(uint8_t); + sdp_put_unaligned(htons(attr), (uint16_t *)p); + p += sizeof(uint16_t); + buf->data_size += sizeof(uint16_t); +} + +static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata) +{ + sdp_data_t *d; + int n = 0; + + for (d = sdpdata->val.dataseq; d; d = d->next) + n += sdp_gen_pdu(buf, d); + return n; +} + +int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) +{ + int pdu_size = 0, data_size = 0; + unsigned char *src = NULL, is_seq = 0, is_alt = 0; + uint8_t dtd = d->dtd; + uint16_t u16; + uint32_t u32; + uint64_t u64; + uint128_t u128; + char *seqp = buf->data + buf->data_size; + + pdu_size = sdp_set_data_type(buf, dtd); + switch (dtd) { + case SDP_DATA_NIL: + break; + case SDP_UINT8: + src = &d->val.uint8; + data_size = sizeof(uint8_t); + break; + case SDP_UINT16: + u16 = htons(d->val.uint16); + src = (unsigned char *)&u16; + data_size = sizeof(uint16_t); + break; + case SDP_UINT32: + u32 = htonl(d->val.uint32); + src = (unsigned char *)&u32; + data_size = sizeof(uint32_t); + break; + case SDP_UINT64: + u64 = hton64(d->val.uint64); + src = (unsigned char *)&u64; + data_size = sizeof(uint64_t); + break; + case SDP_UINT128: + hton128(&d->val.uint128, &u128); + src = (unsigned char *)&u128; + data_size = sizeof(uint128_t); + break; + case SDP_INT8: + case SDP_BOOL: + src = (unsigned char *)&d->val.int8; + data_size = sizeof(int8_t); + break; + case SDP_INT16: + u16 = htons(d->val.int16); + src = (unsigned char *)&u16; + data_size = sizeof(int16_t); + break; + case SDP_INT32: + u32 = htonl(d->val.int32); + src = (unsigned char *)&u32; + data_size = sizeof(int32_t); + break; + case SDP_INT64: + u64 = hton64(d->val.int64); + src = (unsigned char *)&u64; + data_size = sizeof(int64_t); + break; + case SDP_INT128: + hton128(&d->val.int128, &u128); + src = (unsigned char *)&u128; + data_size = sizeof(uint128_t); + break; + case SDP_TEXT_STR8: + case SDP_URL_STR8: + case SDP_TEXT_STR16: + case SDP_TEXT_STR32: + case SDP_URL_STR16: + case SDP_URL_STR32: + src = (unsigned char *)d->val.str; + data_size = strlen(d->val.str); + sdp_set_seq_len(seqp, data_size); + break; + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + is_seq = 1; + data_size = get_data_size(buf, d); + sdp_set_seq_len(seqp, data_size); + break; + case SDP_ALT8: + case SDP_ALT16: + case SDP_ALT32: + is_alt = 1; + data_size = get_data_size(buf, d); + sdp_set_seq_len(seqp, data_size); + break; + case SDP_UUID16: + u16 = htons(d->val.uuid.value.uuid16); + src = (unsigned char *)&u16; + data_size = sizeof(uint16_t); + break; + case SDP_UUID32: + u32 = htonl(d->val.uuid.value.uuid32); + src = (unsigned char *)&u32; + data_size = sizeof(uint32_t); + break; + case SDP_UUID128: + src = (unsigned char *)&d->val.uuid.value.uuid128; + data_size = sizeof(uint128_t); + break; + default: + break; + } + if (!is_seq && !is_alt) { + if (src && buf) { + memcpy(buf->data + buf->data_size, src, data_size); + buf->data_size += data_size; + } else if (dtd != SDP_DATA_NIL) + SDPDBG("Gen PDU : Cant copy from NULL source or dest\n"); + } + pdu_size += data_size; + return pdu_size; +} + +static void sdp_attr_pdu(void *value, void *udata) +{ + sdp_append_to_pdu((sdp_buf_t *)udata, (sdp_data_t *)value); +} + +int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf) +{ + buf->data = (char *)malloc(SDP_PDU_CHUNK_SIZE); + if (buf->data) { + buf->buf_size = SDP_PDU_CHUNK_SIZE; + buf->data_size = 0; + memset(buf->data, 0, buf->buf_size); + sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf); + return 0; + } + return -1; +} + +void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d) +{ + sdp_data_t *p = sdp_data_get(rec, attr); + + if (p) { + rec->attrlist = sdp_list_remove(rec->attrlist, p); + sdp_data_free(p); + } + d->attrId = attr; + rec->attrlist = sdp_list_insert_sorted(rec->attrlist, (void *)d, sdp_attrid_comp_func); +} + +int sdp_attrid_comp_func(const void *key1, const void *key2) +{ + const sdp_data_t *d1 = (const sdp_data_t *)key1; + const sdp_data_t *d2 = (const sdp_data_t *)key2; + + if (d1 && d2) + return d1->attrId - d2->attrId; + return 0; +} + +static void data_seq_free(sdp_data_t *seq) +{ + sdp_data_t *d = seq->val.dataseq; + + while (d) { + sdp_data_t *next = d->next; + sdp_data_free(d); + d = next; + } +} + +void sdp_data_free(sdp_data_t *d) +{ + switch (d->dtd) { + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + data_seq_free(d); + break; + case SDP_URL_STR8: + case SDP_URL_STR16: + case SDP_URL_STR32: + case SDP_TEXT_STR8: + case SDP_TEXT_STR16: + case SDP_TEXT_STR32: + free(d->val.str); + break; + } + free(d); +} + +static sdp_data_t *extract_int(const void *p, int *len) +{ + sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + + SDPDBG("Extracting integer\n"); + memset(d, 0, sizeof(sdp_data_t)); + d->dtd = *(uint8_t *)p; + p += sizeof(uint8_t); + *len += sizeof(uint8_t); + + switch (d->dtd) { + case SDP_DATA_NIL: + break; + case SDP_BOOL: + case SDP_INT8: + case SDP_UINT8: + *len += sizeof(uint8_t); + d->val.uint8 = *(uint8_t *)p; + break; + case SDP_INT16: + case SDP_UINT16: + *len += sizeof(uint16_t); + d->val.uint16 = ntohs(sdp_get_unaligned((uint16_t *)p)); + break; + case SDP_INT32: + case SDP_UINT32: + *len += sizeof(uint32_t); + d->val.uint32 = ntohl(sdp_get_unaligned((uint32_t *)p)); + break; + case SDP_INT64: + case SDP_UINT64: + *len += sizeof(uint64_t); + d->val.uint64 = ntoh64(sdp_get_unaligned((uint64_t *)p)); + break; + case SDP_INT128: + case SDP_UINT128: + *len += sizeof(uint128_t); + ntoh128((uint128_t *)p, &d->val.uint128); + break; + default: + free(d); + d = NULL; + } + return d; +} + +static sdp_data_t *extract_uuid(const void *p, int *len, sdp_record_t *rec) +{ + sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + + SDPDBG("Extracting UUID"); + memset(d, 0, sizeof(sdp_data_t)); + if (0 > sdp_uuid_extract(p, &d->val.uuid, len)) { + free(d); + return NULL; + } + d->dtd = *(uint8_t *)p; + sdp_pattern_add_uuid(rec, &d->val.uuid); + return d; +} + +/* + * Extract strings from the PDU (could be service description and similar info) + */ +static sdp_data_t *extract_str(const void *p, int *len) +{ + char *s; + int n; + sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + + memset(d, 0, sizeof(sdp_data_t)); + d->dtd = *(uint8_t *)p; + p += sizeof(uint8_t); + *len += sizeof(uint8_t); + + switch (d->dtd) { + case SDP_TEXT_STR8: + case SDP_URL_STR8: + n = *(uint8_t *)p; + p += sizeof(uint8_t); + *len += sizeof(uint8_t) + n; + break; + case SDP_TEXT_STR16: + case SDP_URL_STR16: + n = ntohs(sdp_get_unaligned((uint16_t *)p)); + p += sizeof(uint16_t); + *len += sizeof(uint16_t) + n; + break; + default: + SDPERR("Sizeof text string > UINT16_MAX\n"); + free(d); + return 0; + } + + s = (char *)malloc(n + 1); + memset(s, 0, n + 1); + strncpy(s, p, n); + + SDPDBG("Len : %d\n", n); + SDPDBG("Str : %s\n", s); + + d->val.str = s; + return d; +} + +static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec) +{ + int seqlen, n = 0; + sdp_data_t *curr, *prev; + sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + + SDPDBG("Extracting SEQ"); + memset(d, 0, sizeof(sdp_data_t)); + *len = sdp_extract_seqtype(p, &d->dtd, &seqlen); + SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen); + + if (*len == 0) + return d; + + p += *len; + curr = prev = NULL; + while (n < seqlen) { + int attrlen = 0; + curr = sdp_extract_attr(p, &attrlen, rec); + if (curr == NULL) + break; + + if (prev) + prev->next = curr; + else + d->val.dataseq = curr; + prev = curr; + p += attrlen; + n += attrlen; + + SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen); + } + + *len += n; + return d; +} + +sdp_data_t *sdp_extract_attr(const char *p, int *size, sdp_record_t *rec) +{ + sdp_data_t *elem; + int n = 0; + uint8_t dtd = *(const uint8_t *)p; + + SDPDBG("extract_attr: dtd=0x%x", dtd); + switch (dtd) { + case SDP_DATA_NIL: + 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: + elem = extract_int(p, &n); + break; + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + elem = extract_uuid(p, &n, rec); + break; + case SDP_TEXT_STR8: + case SDP_TEXT_STR16: + case SDP_TEXT_STR32: + case SDP_URL_STR8: + case SDP_URL_STR16: + case SDP_URL_STR32: + elem = extract_str(p, &n); + break; + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + case SDP_ALT8: + case SDP_ALT16: + case SDP_ALT32: + elem = extract_seq(p, &n, rec); + break; + default: + SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd); + return NULL; + } + *size += n; + return elem; +} + +#ifdef SDP_DEBUG +static void attr_print_func(void *value, void *userData) +{ + sdp_data_t *d = (sdp_data_t *)value; + + SDPDBG("=====================================\n"); + SDPDBG("ATTRIBUTE IDENTIFIER : 0x%x\n", d->attrId); + SDPDBG("ATTRIBUTE VALUE PTR : 0x%x\n", (uint32_t)value); + if (d) + sdp_data_print(d); + else + SDPDBG("NULL value\n"); + SDPDBG("=====================================\n"); +} + +void sdp_print_service_attr(sdp_list_t *svcAttrList) +{ + sdp_list_foreach(svcAttrList, attr_print_func, NULL); +} +#endif + +sdp_record_t *sdp_extract_pdu(const char *buf, int *scanned) +{ + int extracted = 0, seqlen = 0; + uint8_t dtd; + uint16_t attr; + sdp_record_t *rec = sdp_record_alloc(); + const char *p = buf; + + *scanned = sdp_extract_seqtype(buf, &dtd, &seqlen); + p += *scanned; + rec->attrlist = NULL; + while (extracted < seqlen) { + int n = sizeof(uint8_t), attrlen = 0; + sdp_data_t *data = NULL; + + SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, extracted); + dtd = *(uint8_t *)p; + attr = ntohs(sdp_get_unaligned((uint16_t *)(p+n))); + n += sizeof(uint16_t); + + SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr); + + data = sdp_extract_attr(p+n, &attrlen, rec); + + SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen); + + n += attrlen; + if (data == NULL) { + SDPDBG("Terminating extraction of attributes"); + break; + } + if (attr == SDP_ATTR_RECORD_HANDLE) + rec->handle = data->val.uint32; + extracted += n; + p += n; + sdp_attr_replace(rec, attr, data); + SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d", + seqlen, extracted); + } +#ifdef SDP_DEBUG + SDPDBG("Successful extracting of Svc Rec attributes\n"); + sdp_print_service_attr(rec->attrlist); +#endif + *scanned += seqlen; + return rec; +} + +#ifdef SDP_DEBUG +static void print_dataseq(sdp_data_t *p) +{ + sdp_data_t *d; + + for (d = p; d; d = d->next) + sdp_data_print(d); +} +#endif + +void sdp_record_print(const sdp_record_t *rec) +{ + sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); + if (d) + printf("Service Name: %s\n", d->val.str); + d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); + if (d) + printf("Service Description: %s\n", d->val.str); + d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY); + if (d) + printf("Service Provider: %s\n", d->val.str); +} + +#ifdef SDP_DEBUG +void sdp_data_print(sdp_data_t *d) +{ + switch (d->dtd) { + case SDP_DATA_NIL: + SDPDBG("NIL\n"); + 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: + SDPDBG("Integer : 0x%x\n", d->val.uint32); + break; + case SDP_UUID16: + case SDP_UUID32: + case SDP_UUID128: + SDPDBG("UUID\n"); + sdp_uuid_print(&d->val.uuid); + break; + case SDP_TEXT_STR8: + case SDP_TEXT_STR16: + case SDP_TEXT_STR32: + SDPDBG("Text : %s\n", d->val.str); + break; + case SDP_URL_STR8: + case SDP_URL_STR16: + case SDP_URL_STR32: + SDPDBG("URL : %s\n", d->val.str); + break; + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + print_dataseq(d->val.dataseq); + break; + case SDP_ALT8: + case SDP_ALT16: + case SDP_ALT32: + SDPDBG("Data Sequence Alternates\n"); + print_dataseq(d->val.dataseq); + break; + } +} +#endif + +sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId) +{ + if (rec->attrlist) { + sdp_data_t sdpTemplate; + sdp_list_t *p; + + sdpTemplate.attrId = attrId; + p = sdp_list_find(rec->attrlist, &sdpTemplate, sdp_attrid_comp_func); + if (p) + return (sdp_data_t *)p->data; + } + return 0; +} + +/* + * Extract the sequence type and its length, and return offset into buf + * or 0 on failure. + */ +int sdp_extract_seqtype(const char *buf, uint8_t *dtdp, int *size) +{ + uint8_t dtd = *(uint8_t *)buf; + int scanned = sizeof(uint8_t); + + buf += sizeof(uint8_t); + *dtdp = dtd; + switch (dtd) { + case SDP_SEQ8: + case SDP_ALT8: + *size = *(uint8_t *)buf; + scanned += sizeof(uint8_t); + break; + case SDP_SEQ16: + case SDP_ALT16: + *size = ntohs(sdp_get_unaligned((uint16_t *)buf)); + scanned += sizeof(uint16_t); + break; + case SDP_SEQ32: + case SDP_ALT32: + *size = ntohl(sdp_get_unaligned((uint32_t *)buf)); + scanned += sizeof(uint32_t); + break; + default: + SDPERR("Unknown sequence type, aborting\n"); + return 0; + } + return scanned; +} + +int sdp_send_req(sdp_session_t *session, char *buf, int size) +{ + int sent = 0; + + while (sent < size) { + int n = send(session->sock, buf + sent, size - sent, 0); + if (n < 0) + return -1; + sent += n; + } + return 0; +} + +int sdp_read_rsp(sdp_session_t *session, char *buf, int size) +{ + fd_set readFds; + struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 }; + + FD_SET(session->sock, &readFds); + SDPDBG("Waiting for response\n"); + if (0 == select(session->sock + 1, &readFds, NULL, NULL, &timeout)) { + SDPERR("Client timed out\n"); + errno = ETIMEDOUT; + return -1; + } + return recv(session->sock, buf, size, 0); +} + +/* + * generic send request, wait for response method. + */ +int sdp_send_req_w4_rsp(sdp_session_t *session, char *reqbuf, char *rspbuf, int reqsize, int *rspsize) +{ + int n; + sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)reqbuf; + sdp_pdu_hdr_t *rsphdr = (sdp_pdu_hdr_t *)rspbuf; + + SDPDBG(""); + if (0 > sdp_send_req(session, reqbuf, reqsize)) { + SDPERR("Error sending data:%s", strerror(errno)); + return -1; + } + n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE); + if (0 > n) + return -1; + SDPDBG("Read : %d\n", n); + if (n == 0 || reqhdr->tid != rsphdr->tid) { + errno = EPROTO; + return -1; + } + *rspsize = n; + return 0; +} + +/* + * singly-linked lists (after openobex implementation) + */ +sdp_list_t *sdp_list_append(sdp_list_t *p, void *d) +{ + sdp_list_t *q, *n = (sdp_list_t *)malloc(sizeof(sdp_list_t)); + + if (!n) + return 0; + + n->data = d; + n->next = 0; + + if (!p) + return n; + + for (q = p; q->next; q = q->next); + q->next = n; + + return p; +} + +sdp_list_t *sdp_list_remove(sdp_list_t *list, void *d) +{ + sdp_list_t *p, *q; + + for (q = 0, p = list; p; q = p, p = p->next) + if (p->data == d) { + if (q) + q->next = p->next; + else + list = p->next; + free(p); + break; + } + + return list; +} + +sdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d, sdp_comp_func_t f) +{ + sdp_list_t *q, *p, *n; + + n = (sdp_list_t *)malloc(sizeof(sdp_list_t)); + if (!n) + return 0; + n->data = d; + for (q = 0, p = list; p; q = p, p = p->next) + if (f(p->data, d) >= 0) + break; + // insert between q and p; if !q insert at head + if (q) + q->next = n; + else + list = n; + n->next = p; + return list; +} + +/* + * Every element of the list points to things which need + * to be free()'d. This method frees the list's contents + */ +void sdp_list_free(sdp_list_t *list, sdp_free_func_t f) +{ + sdp_list_t *next; + while (list) { + next = list->next; + if (f) + f(list->data); + free(list); + list = next; + } +} + +static inline int __find_port(sdp_data_t *seq, int proto) +{ + if (!seq || !seq->next) + return 0; + + if (SDP_IS_UUID(seq->dtd) && sdp_uuid_to_proto(&seq->val.uuid) == proto) { + seq = seq->next; + switch (seq->dtd) { + case SDP_UINT8: + return seq->val.uint8; + case SDP_UINT16: + return seq->val.uint16; + } + } + return 0; +} + +int sdp_get_proto_port(const sdp_list_t *list, int proto) +{ + if (proto != L2CAP_UUID && proto != RFCOMM_UUID) { + errno = EINVAL; + return -1; + } + + for (; list; list = list->next) { + sdp_list_t *p; + for (p = list->data; p; p = p->next) { + sdp_data_t *seq = (sdp_data_t *) p->data; + int port = __find_port(seq, proto); + if (port) + return port; + } + } + return 0; +} + +sdp_data_t *sdp_get_proto_desc(sdp_list_t *list, int proto) +{ + for (; list; list = list->next) { + sdp_list_t *p; + for (p = list->data; p; p = p->next) { + sdp_data_t *seq = (sdp_data_t *) p->data; + if (SDP_IS_UUID(seq->dtd) && + sdp_uuid_to_proto(&seq->val.uuid) == proto) + return seq->next; + } + } + return NULL; +} + +int sdp_get_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_PROTO_DESC_LIST); + if (pdlist == NULL) { + errno = ENODATA; + return -1; + } + SDPDBG("AP type : 0%x\n", pdlist->dtd); + + 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_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **seqp) +{ + sdp_data_t *sdpdata = sdp_data_get(rec, attr); + + *seqp = NULL; + if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) { + sdp_data_t *d; + for (d = sdpdata->val.dataseq; d; d = d->next) { + uuid_t *u = (uuid_t *)malloc(sizeof(uuid_t)); + memset((char *)u, 0, sizeof(uuid_t)); + if (d->dtd >= SDP_UUID16 && d->dtd <= SDP_UUID128) { + *u = d->val.uuid; + *seqp = sdp_list_append(*seqp, u); + } else + goto fail; + } + return 0; + } +fail: + sdp_list_free(*seqp, free); + errno = EINVAL; + return -1; +} + +int sdp_set_uuidseq_attr(sdp_record_t *rec, uint16_t aid, sdp_list_t *seq) +{ + int status = 0, i, len; + void **dtds, **values; + uint8_t uuid16 = SDP_UUID16; + uint8_t uuid32 = SDP_UUID32; + uint8_t uuid128 = SDP_UUID128; + sdp_list_t *p; + + len = sdp_list_len(seq); + if (!seq || len == 0) + return -1; + dtds = (void **)malloc(len * sizeof(void *)); + values = (void **)malloc(len * sizeof(void *)); + for (p = seq, i = 0; i < len; i++, p = p->next) { + uuid_t *uuid = (uuid_t *)p->data; + if (uuid) + switch (uuid->type) { + case SDP_UUID16: + dtds[i] = &uuid16; + values[i] = &uuid->value.uuid16; + break; + case SDP_UUID32: + dtds[i] = &uuid32; + values[i] = &uuid->value.uuid32; + break; + case SDP_UUID128: + dtds[i] = &uuid128; + values[i] = &uuid->value.uuid128; + break; + default: + status = -1; + break; + } + else { + status = -1; + break; + } + } + if (status == 0) { + sdp_data_t *data = sdp_seq_alloc(dtds, values, len); + sdp_attr_replace(rec, aid, data); + sdp_pattern_add_uuidseq(rec, seq); + } + free(dtds); + free(values); + return status; +} + +int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq) +{ + sdp_lang_attr_t *lang; + sdp_data_t *sdpdata, *curr_data; + + *langSeq = NULL; + sdpdata = sdp_data_get(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST); + if (sdpdata == NULL) { + errno = ENODATA; + return -1; + } + curr_data = sdpdata->val.dataseq; + while (curr_data) { + sdp_data_t *pCode = curr_data; + sdp_data_t *pEncoding = pCode->next; + sdp_data_t *pOffset = pEncoding->next; + if (pCode && pEncoding && pOffset) { + lang = (sdp_lang_attr_t *)malloc(sizeof(sdp_lang_attr_t)); + lang->code_ISO639 = pCode->val.uint16; + lang->encoding = pEncoding->val.uint16; + lang->base_offset = pOffset->val.uint16; + SDPDBG("code_ISO639 : 0x%02x\n", lang->code_ISO639); + SDPDBG("encoding : 0x%02x\n", lang->encoding); + SDPDBG("base_offfset : 0x%02x\n", lang->base_offset); + *langSeq = sdp_list_append(*langSeq, lang); + } + curr_data = pOffset->next; + } + return 0; +} + +int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq) +{ + sdp_profile_desc_t *profDesc; + sdp_data_t *sdpdata, *seq; + + *profDescSeq = NULL; + sdpdata = sdp_data_get(rec, SDP_ATTR_PFILE_DESC_LIST); + if (!sdpdata || !sdpdata->val.dataseq) { + errno = ENODATA; + return -1; + } + for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) { + sdp_data_t *uuid = seq->val.dataseq; + sdp_data_t *pVnum = seq->val.dataseq->next; + if (uuid && pVnum) { + profDesc = (sdp_profile_desc_t *)malloc(sizeof(sdp_profile_desc_t)); + profDesc->uuid = uuid->val.uuid; + profDesc->version = pVnum->val.uint16; +#ifdef SDP_DEBUG + sdp_uuid_print(&profDesc->uuid); + SDPDBG("Vnum : 0x%04x\n", profDesc->version); +#endif + *profDescSeq = sdp_list_append(*profDescSeq, profDesc); + } + } + return 0; +} + +int sdp_get_server_ver(const sdp_record_t *rec, sdp_list_t **u16) +{ + sdp_data_t *d, *curr; + + *u16 = NULL; + d = sdp_data_get(rec, SDP_ATTR_VERSION_NUM_LIST); + if (d == NULL) { + errno = ENODATA; + return -1; + } + for (curr = d->val.dataseq; curr; curr = curr->next) + *u16 = sdp_list_append(*u16, &curr->val.uint16); + return 0; +} + +/* flexible extraction of basic attributes - Jean II */ +/* How do we expect caller to extract predefined data sequences? */ +int sdp_get_int_attr(const sdp_record_t *rec, uint16_t attrid, int *value) +{ + sdp_data_t *sdpdata = sdp_data_get(rec, attrid); + + if (sdpdata) + /* Verify that it is what the caller expects */ + if (sdpdata->dtd == SDP_BOOL || sdpdata->dtd == SDP_UINT8 || + sdpdata->dtd == SDP_UINT16 || sdpdata->dtd == SDP_UINT32 || + sdpdata->dtd == SDP_INT8 || sdpdata->dtd == SDP_INT16 || + sdpdata->dtd == SDP_INT32) { + *value = sdpdata->val.uint32; + return 0; + } + errno = EINVAL; + return -1; +} + +int sdp_get_string_attr(const sdp_record_t *rec, uint16_t attrid, char *value, int valuelen) +{ + sdp_data_t *sdpdata = sdp_data_get(rec, attrid); + if (sdpdata) + /* Verify that it is what the caller expects */ + if (sdpdata->dtd == SDP_TEXT_STR8 || sdpdata->dtd == SDP_TEXT_STR16 || sdpdata->dtd == SDP_TEXT_STR32) + if (strlen(sdpdata->val.str) < valuelen) { + strcpy(value, sdpdata->val.str); + return 0; + } + errno = EINVAL; + return -1; +} + +#define get_basic_attr(attrID, pAttrValue, fieldName) \ + sdp_data_t *data = sdp_data_get(rec, attrID); \ + if (data) { \ + *pAttrValue = data->val.fieldName; \ + return 0; \ + } \ + errno = EINVAL; \ + return -1; + +int sdp_get_service_id(const sdp_record_t *rec, uuid_t *uuid) +{ + get_basic_attr(SDP_ATTR_SERVICE_ID, uuid, uuid); +} + +int sdp_get_group_id(const sdp_record_t *rec, uuid_t *uuid) +{ + get_basic_attr(SDP_ATTR_GROUP_ID, uuid, uuid); +} + +int sdp_get_record_state(const sdp_record_t *rec, uint32_t *svcRecState) +{ + get_basic_attr(SDP_ATTR_RECORD_STATE, svcRecState, uint32); +} + +int sdp_get_service_avail(const sdp_record_t *rec, uint8_t *svcAvail) +{ + get_basic_attr(SDP_ATTR_SERVICE_AVAILABILITY, svcAvail, uint8); +} + +int sdp_get_service_ttl(const sdp_record_t *rec, uint32_t *svcTTLInfo) +{ + get_basic_attr(SDP_ATTR_SVCINFO_TTL, svcTTLInfo, uint32); +} + +int sdp_get_database_state(const sdp_record_t *rec, uint32_t *svcDBState) +{ + get_basic_attr(SDP_ATTR_SVCDB_STATE, svcDBState, uint32); +} + +/* + * NOTE that none of the setXXX() functions below will + * actually update the SDP server, unless the + * {register, update}sdp_record_t() function is invoked. + */ + +int sdp_attr_add_new(sdp_record_t *rec, uint16_t attr, uint8_t dtd, const void *value) +{ + sdp_data_t *d = sdp_data_alloc(dtd, value); + if (d) { + sdp_attr_replace(rec, attr, d); + return 0; + } + return -1; +} + +/* + * Set the information attributes of the service + * pointed to by rec. The attributes are + * service name, description and provider name + */ +void sdp_set_info_attr(sdp_record_t *rec, const char *name, const char *prov, const char *desc) +{ + if (name) + sdp_attr_add_new(rec, SDP_ATTR_SVCNAME_PRIMARY, SDP_TEXT_STR8, (void *)name); + if (prov) + sdp_attr_add_new(rec, SDP_ATTR_PROVNAME_PRIMARY, SDP_TEXT_STR8, (void *)prov); + if (desc) + sdp_attr_add_new(rec, SDP_ATTR_SVCDESC_PRIMARY, SDP_TEXT_STR8, (void *)desc); +} + +static sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto) +{ + sdp_data_t *seq = NULL; + void *dtds[10], *values[10]; + void **seqDTDs, **seqs; + int i, seqlen; + sdp_list_t *p; + + seqlen = sdp_list_len(proto); + seqDTDs = (void **)malloc(seqlen * sizeof(void *)); + seqs = (void **)malloc(seqlen * sizeof(void *)); + for (i = 0, p = proto; p; p = p->next, i++) { + sdp_list_t *elt = (sdp_list_t *)p->data; + sdp_data_t *s; + int pslen = 0; + for (; elt && pslen < sizeof(dtds); elt = elt->next, pslen++) { + sdp_data_t *d = (sdp_data_t *)elt->data; + dtds[pslen] = &d->dtd; + switch (d->dtd) { + case SDP_UUID16: + values[pslen] = &((uuid_t *)d)->value.uuid16; + break; + case SDP_UUID32: + values[pslen] = &((uuid_t *)d)->value.uuid32; + break; + case SDP_UUID128: + values[pslen] = &((uuid_t *)d)->value.uuid128; + break; + case SDP_UINT8: + values[pslen] = &d->val.uint8; + break; + case SDP_UINT16: + values[pslen] = &d->val.uint16; + break; + case SDP_SEQ8: + case SDP_SEQ16: + case SDP_SEQ32: + values[pslen] = d; + break; + // FIXME: more + } + } + s = sdp_seq_alloc(dtds, values, pslen); + if (s) { + seqDTDs[i] = &s->dtd; + seqs[i] = s; + } + } + seq = sdp_seq_alloc(seqDTDs, seqs, seqlen); + free(seqDTDs); + free(seqs); + return seq; +} + +/* + * sets the access protocols of the service specified + * to the value specified in "access_proto" + * + * Note that if there are alternate mechanisms by + * which the service is accessed, then they should + * be specified as sequences + * + * Using a value of NULL for accessProtocols has + * effect of removing this attribute (if previously set) + * + * This function replaces the existing sdp_access_proto_t + * structure (if any) with the new one specified. + * + * returns 0 if successful or -1 if there is a failure. + */ +int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap) +{ + const sdp_list_t *p; + sdp_data_t *protos = 0; + + for (p = ap; p; p = p->next) { + sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *)p->data); + protos = sdp_seq_append(protos, seq); + } + sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos); + return 0; +} + +/* + * set the "LanguageBase" attributes of the service record + * record to the value specified in "langAttrList". + * + * "langAttrList" is a linked list of "sdp_lang_attr_t" + * objects, one for each language in which user visible + * attributes are present in the service record. + * + * Using a value of NULL for langAttrList has + * effect of removing this attribute (if previously set) + * + * This function replaces the exisiting sdp_lang_attr_t + * structure (if any) with the new one specified. + * + * returns 0 if successful or -1 if there is a failure. + */ +int sdp_set_lang_attr(sdp_record_t *rec, const sdp_list_t *seq) +{ + uint8_t uint16 = SDP_UINT16; + int status = 0, i = 0, seqlen = sdp_list_len(seq); + void **dtds = (void **)malloc(3 * seqlen * sizeof(void *)); + void **values = (void **)malloc(3 * seqlen * sizeof(void *)); + const sdp_list_t *p; + + for (p = seq; p; p = p->next) { + sdp_lang_attr_t *lang = (sdp_lang_attr_t *)p->data; + if (!lang) { + status = -1; + break; + } + dtds[i] = &uint16; + values[i] = &lang->code_ISO639; + i++; + dtds[i] = &uint16; + values[i] = &lang->encoding; + i++; + dtds[i] = &uint16; + values[i] = &lang->base_offset; + i++; + } + if (status == 0) { + sdp_data_t *seq = sdp_seq_alloc(dtds, values, 3 * seqlen); + sdp_attr_add(rec, SDP_ATTR_LANG_BASE_ATTR_ID_LIST, seq); + } + free(dtds); + free(values); + return status; +} + +/* + * set the "ServiceID" attribute of the service. + * + * This is the UUID of the service. + * + * returns 0 if successful or -1 if there is a failure. + */ +void sdp_set_service_id(sdp_record_t *rec, uuid_t uuid) +{ + switch (uuid.type) { + case SDP_UUID16: + sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID16, &uuid.value.uuid16); + break; + case SDP_UUID32: + sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID32, &uuid.value.uuid32); + break; + case SDP_UUID128: + sdp_attr_add_new(rec, SDP_ATTR_SERVICE_ID, SDP_UUID128, &uuid.value.uuid128); + break; + } + sdp_pattern_add_uuid(rec, &uuid); +} + +/* + * set the GroupID attribute of the service record defining a group. + * + * This is the UUID of the group. + * + * returns 0 if successful or -1 if there is a failure. + */ +void sdp_set_group_id(sdp_record_t *rec, uuid_t uuid) +{ + switch (uuid.type) { + case SDP_UUID16: + sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID16, &uuid.value.uuid16); + break; + case SDP_UUID32: + sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID32, &uuid.value.uuid32); + break; + case SDP_UUID128: + sdp_attr_add_new(rec, SDP_ATTR_GROUP_ID, SDP_UUID128, &uuid.value.uuid128); + break; + } + sdp_pattern_add_uuid(rec, &uuid); +} + +/* + * set the ProfileDescriptorList attribute of the service record + * pointed to by record to the value specified in "profileDesc". + * + * Each element in the list is an object of type + * sdp_profile_desc_t which is a definition of the + * Bluetooth profile that this service conforms to. + * + * Using a value of NULL for profileDesc has + * effect of removing this attribute (if previously set) + * + * This function replaces the exisiting ProfileDescriptorList + * structure (if any) with the new one specified. + * + * returns 0 if successful or -1 if there is a failure. + */ +int sdp_set_profile_descs(sdp_record_t *rec, const sdp_list_t *profiles) +{ + int status = 0; + uint8_t uuid16 = SDP_UUID16; + uint8_t uuid32 = SDP_UUID32; + uint8_t uuid128 = SDP_UUID128; + uint8_t uint16 = SDP_UINT16; + int i = 0, seqlen = sdp_list_len(profiles); + void **seqDTDs = (void **)malloc(seqlen * sizeof(void *)); + void **seqs = (void **)malloc(seqlen * sizeof(void *)); + const sdp_list_t *p; + + for (p = profiles; p; p = p->next) { + sdp_data_t *seq; + void *dtds[2], *values[2]; + sdp_profile_desc_t *profile = (sdp_profile_desc_t *)p->data; + if (!profile) { + status = -1; + break; + } + switch (profile->uuid.type) { + case SDP_UUID16: + dtds[0] = &uuid16; + values[0] = &profile->uuid.value.uuid16; + break; + case SDP_UUID32: + dtds[0] = &uuid32; + values[0] = &profile->uuid.value.uuid32; + break; + case SDP_UUID128: + dtds[0] = &uuid128; + values[0] = &profile->uuid.value.uuid128; + break; + default: + status = -1; + break; + } + dtds[1] = &uint16; + values[1] = &profile->version; + seq = sdp_seq_alloc(dtds, values, 2); + if (seq) { + seqDTDs[i] = &seq->dtd; + seqs[i] = seq; + sdp_pattern_add_uuid(rec, &profile->uuid); + } + i++; + } + if (status == 0) { + sdp_data_t *pAPSeq = sdp_seq_alloc(seqDTDs, seqs, seqlen); + sdp_attr_add(rec, SDP_ATTR_PFILE_DESC_LIST, pAPSeq); + } + free(seqDTDs); + free(seqs); + return status; +} + +/* + * sets various URL attributes of the service + * pointed to by record. The URL include + * + * client: a URL to the client's + * platform specific (WinCE, PalmOS) executable + * code that can be used to access this service. + * + * doc: a URL pointing to service documentation + * + * icon: a URL to an icon that can be used to represent + * this service. + * + * Note that you need to pass NULL for any URLs + * that you don't want to set or remove + */ +void sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc, const char *icon) +{ + sdp_attr_add_new(rec, SDP_ATTR_CLNT_EXEC_URL, SDP_URL_STR8, client); + sdp_attr_add_new(rec, SDP_ATTR_DOC_URL, SDP_URL_STR8, doc); + sdp_attr_add_new(rec, SDP_ATTR_ICON_URL, SDP_URL_STR8, icon); +} + +/* + * The code in this function is executed only once per + * thread. We compute the actual bit value of the Bluetooth + * base UUID which is a string defined in bt_std_values.h + * and is assumed to be of the standard form with "-" separators. + * + * The algorithm however converts the string to 4 unsigned longs + * using the strtoul() and assigns the values in sequence to + * the 128bit value + */ +uint128_t *sdp_create_base_uuid(void) +{ + char baseStr[128]; + int delim = '-'; + unsigned long dataLongValue; + char *delimPtr; + char *dataPtr; + char temp[10]; + int toBeCopied; + char *data; + + if (bluetooth_base_uuid == NULL) { + strcpy(baseStr, BASE_UUID); + bluetooth_base_uuid = (uint128_t *)malloc(sizeof(uint128_t)); + data = bluetooth_base_uuid->data; + memset(data, '\0', sizeof(uint128_t)); + memset(temp, '\0', 10); + dataPtr = baseStr; + delimPtr = NULL; + delimPtr = strchr(dataPtr, delim); + toBeCopied = delimPtr - dataPtr; + if (toBeCopied != 8) { + SDPDBG("To be copied(1) : %d\n", toBeCopied); + return NULL; + } + strncpy(temp, dataPtr, toBeCopied); + dataLongValue = htonl(strtoul(temp, NULL, 16)); + memcpy(&data[0], &dataLongValue, 4); + + /* + * Get the next 4 bytes (note that there is a "-" + * between them now) + */ + memset(temp, '\0', 10); + dataPtr = delimPtr + 1; + delimPtr = strchr(dataPtr, delim); + toBeCopied = delimPtr - dataPtr; + if (toBeCopied != 4) { + SDPDBG("To be copied(2) : %d\n", toBeCopied); + return NULL; + } + strncpy(temp, dataPtr, toBeCopied); + dataPtr = delimPtr + 1; + delimPtr = strchr(dataPtr, delim); + toBeCopied = delimPtr - dataPtr; + if (toBeCopied != 4) { + SDPDBG("To be copied(3) : %d\n", toBeCopied); + return NULL; + } + strncat(temp, dataPtr, toBeCopied); + dataLongValue = htonl(strtoul(temp, NULL, 16)); + memcpy(&data[4], &dataLongValue, 4); + + /* + * Get the last 4 bytes (note that there are 6 bytes + * after the last separator, which is truncated (2+4) + */ + memset(temp, '\0', 10); + dataPtr = delimPtr + 1; + dataPtr = delimPtr + 1; + delimPtr = strchr(dataPtr, delim); + toBeCopied = delimPtr - dataPtr; + if (toBeCopied != 4) { + SDPDBG("To be copied(4) : %d\n", toBeCopied); + return NULL; + } + strncpy(temp, dataPtr, toBeCopied); + strncat(temp, (delimPtr + 1), 4); + dataLongValue = htonl(strtoul(temp, NULL, 16)); + memcpy(&data[8], &dataLongValue, 4); + dataLongValue = htonl(strtoul(delimPtr + 5, NULL, 16)); + memcpy(&data[12], &dataLongValue, 4); + } + return bluetooth_base_uuid; +} + +uuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val) +{ + memset(u, 0, sizeof(uuid_t)); + u->type = SDP_UUID16; + u->value.uuid16 = val; + return u; +} + +uuid_t *sdp_uuid32_create(uuid_t *u, uint32_t val) +{ + memset(u, 0, sizeof(uuid_t)); + u->type = SDP_UUID32; + u->value.uuid32 = val; + return u; +} + +uuid_t *sdp_uuid128_create(uuid_t *u, const void *val) +{ + memset(u, 0, sizeof(uuid_t)); + u->type = SDP_UUID128; + memcpy(&u->value.uuid128, val, sizeof(uint128_t)); + return u; +} + +/* + * UUID comparison function + * returns 0 if uuidValue1 == uuidValue2 else -1 + */ +int sdp_uuid16_cmp(const void *p1, const void *p2) +{ + const uuid_t *u1 = (const uuid_t *)p1; + const uuid_t *u2 = (const uuid_t *)p2; + return memcmp(&u1->value.uuid16, &u2->value.uuid16, sizeof(uint16_t)); +} + +/* + * UUID comparison function + * returns 0 if uuidValue1 == uuidValue2 else -1 + */ +int sdp_uuid128_cmp(const void *p1, const void *p2) +{ + const uuid_t *u1 = (const uuid_t *)p1; + const uuid_t *u2 = (const uuid_t *)p2; + return memcmp(&u1->value.uuid128, &u2->value.uuid128, sizeof(uint128_t)); +} + +/* + * 128 to 16 bit and 32 to 16 bit UUID conversion functions + * yet to be implemented. Note that the input is in NBO in + * both 32 and 128 bit UUIDs and conversion is needed + */ +void sdp_uuid16_to_uuid128(uuid_t *uuid128, uuid_t *uuid16) +{ + /* + * We have a 16 bit value, which needs to be added to + * bytes 3 and 4 (at indices 2 and 3) of the Bluetooth base + */ + unsigned short data1; + + // allocate a 128bit UUID and init to the Bluetooth base UUID + uint128_t *pBTBase128Bit = sdp_create_base_uuid(); + uuid128->value.uuid128 = *pBTBase128Bit; + uuid128->type = SDP_UUID128; + + // extract bytes 2 and 3 of 128bit BT base UUID + memcpy(&data1, &pBTBase128Bit->data[2], 2); + + // add the given UUID (16 bits) + data1 += htons(uuid16->value.uuid16); + + // set bytes 2 and 3 of the 128 bit value + memcpy(&uuid128->value.uuid128.data[2], &data1, 2); +} + +void sdp_uuid32_to_uuid128(uuid_t *uuid128, uuid_t *uuid32) +{ + /* + * We have a 32 bit value, which needs to be added to + * bytes 1->4 (at indices 0 thru 3) of the Bluetooth base + */ + unsigned int data0; + + // allocate a 128bit UUID and init to the Bluetooth base UUID + uint128_t *pBTBase128Bit = sdp_create_base_uuid(); + uuid128->value.uuid128 = *pBTBase128Bit; + uuid128->type = SDP_UUID128; + + // extract first 4 bytes + memcpy(&data0, &pBTBase128Bit->data[0], 4); + + // add the given UUID (32bits) + data0 += htonl(uuid32->value.uuid32); + + // set the 4 bytes of the 128 bit value + memcpy(&uuid128->value.uuid128.data[0], &data0, 4); +} + +uuid_t *sdp_uuid_to_uuid128(uuid_t *uuid) +{ + uuid_t *uuid128 = (uuid_t *)malloc(sizeof(uuid_t)); + memset(uuid128, 0, sizeof(uuid_t)); + switch (uuid->type) { + case SDP_UUID128: + *uuid128 = *uuid; + break; + case SDP_UUID32: + sdp_uuid32_to_uuid128(uuid128, uuid); + break; + case SDP_UUID16: + sdp_uuid16_to_uuid128(uuid128, uuid); + break; + } + return uuid128; +} + +/* + * converts a 128-bit uuid to a 16/32-bit one if possible + * returns true if uuid contains a 16/32-bit UUID at exit + */ +int sdp_uuid128_to_uuid(uuid_t *uuid) +{ + extern uint128_t *sdp_create_base_uuid(); + int i; + uint128_t *b = sdp_create_base_uuid(); + uint128_t *u = &uuid->value.uuid128; + uint32_t data; + + if (uuid->type != SDP_UUID128) + return 1; + + for (i = 4; i < sizeof(b->data); i++) + if (b->data[i] != u->data[i]) + return 0; + + memcpy(&data, u->data, 4); + data = htonl(data); + if (data <= 0xffff) { + uuid->type = SDP_UUID16; + uuid->value.uuid16 = (uint16_t)data; + } else { + uuid->type = SDP_UUID32; + uuid->value.uuid32 = data; + } + return 1; +} + +/* + * convert a UUID to the 16-bit short-form + */ +int sdp_uuid_to_proto(uuid_t *uuid) +{ + uuid_t u = *uuid; + if (sdp_uuid128_to_uuid(&u) && u.type == SDP_UUID16) + return u.value.uuid16; + return 0; +} + +int sdp_uuid_extract(const char *p, uuid_t *uuid, int *scanned) +{ + uint8_t type = *(const uint8_t *)p; + + if (!SDP_IS_UUID(type)) { + SDPERR("Unknown data type : %d expecting a svc UUID\n", type); + return -1; + } + p += sizeof(uint8_t); + *scanned += sizeof(uint8_t); + if (type == SDP_UUID16) { + sdp_uuid16_create(uuid, ntohs(sdp_get_unaligned((uint16_t *)p))); + *scanned += sizeof(uint16_t); + p += sizeof(uint16_t); + } else if (type == SDP_UUID32) { + sdp_uuid32_create(uuid, ntohl(sdp_get_unaligned((uint32_t *)p))); + *scanned += sizeof(uint32_t); + p += sizeof(uint32_t); + } else { + sdp_uuid128_create(uuid, p); + *scanned += sizeof(uint128_t); + p += sizeof(uint128_t); + } + return 0; +} + +/* + * This function appends data to the PDU buffer "dst" from source "src". + * The data length is also computed and set. + * Should the PDU length exceed 2^8, then sequence type is + * set accordingly and the data is memmove()'d. + */ +void sdp_append_to_buf(sdp_buf_t *dst, char *data, int len) +{ + char *p = dst->data; + uint8_t dtd = *(uint8_t *)p; + + SDPDBG("Append src size: %d\n", len); + SDPDBG("Append dst size: %d\n", dst->data_size); + SDPDBG("Dst buffer size: %d\n", dst->buf_size); + if (dst->data_size + len > dst->buf_size) { + int need = SDP_PDU_CHUNK_SIZE * ((len / SDP_PDU_CHUNK_SIZE) + 1); + dst->data = (char *)realloc(dst->data, dst->buf_size + need); + + SDPDBG("Realloc'ing : %d\n", need); + + if (dst->data == NULL) { + SDPERR("Realloc fails \n"); + } + dst->buf_size += need; + } + if (dst->data_size == 0 && dtd == 0) { + // create initial sequence + *(uint8_t *)p = SDP_SEQ8; + p += sizeof(uint8_t); + dst->data_size += sizeof(uint8_t); + // reserve space for sequence size + p += sizeof(uint8_t); + dst->data_size += sizeof(uint8_t); + } + + memcpy(dst->data + dst->data_size, data, len); + dst->data_size += len; + + dtd = *(uint8_t *)dst->data; + if (dst->data_size > UCHAR_MAX && dtd == SDP_SEQ8) { + short offset = sizeof(uint8_t) + sizeof(uint8_t); + memmove(dst->data + offset + 1, dst->data + offset, dst->data_size - offset); + p = dst->data; + *(uint8_t *)p = SDP_SEQ16; + p += sizeof(uint8_t); + dst->data_size += 1; + } + p = dst->data; + dtd = *(uint8_t *)p; + p += sizeof(uint8_t); + switch (dtd) { + case SDP_SEQ8: + *(uint8_t *)p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t); + break; + case SDP_SEQ16: + sdp_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *)p); + break; + case SDP_SEQ32: + sdp_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *)p); + break; + } +} + +void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) +{ + char buf[SDP_SEQ_PDUFORM_SIZE]; + sdp_buf_t append; + + append.data = buf; + append.buf_size = sizeof(buf); + append.data_size = 0; + sdp_set_attrid(&append, d->attrId); + sdp_gen_pdu(&append, d); + sdp_append_to_buf(pdu, append.data, append.data_size); +} + +/* + * Registers an sdp record. + * + * It is incorrect to call this method on a record that + * has been already registered with the server. + * + * Returns a non-null value (a pointer) to a service + * record if successful, else -1 setting errno + */ +int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags) +{ + char *p; + int status = 0; + char *req, *rsp; + int reqsize, rspsize; + sdp_pdu_hdr_t *reqhdr, *rsphdr; + sdp_buf_t pdu; + + SDPDBG(""); + + if (!session->local) { + errno = EREMOTE; + return -1; + } + req = (char *)malloc(SDP_REQ_BUFFER_SIZE); + rsp = (char *)malloc(SDP_RSP_BUFFER_SIZE); + if (req == NULL || rsp == NULL) { + status = -1; + errno = ENOMEM; + goto end; + } + reqhdr = (sdp_pdu_hdr_t *)req; + reqhdr->pdu_id = SDP_SVC_REGISTER_REQ; + reqhdr->tid = htons(sdp_gen_tid(session)); + reqsize = sizeof(sdp_pdu_hdr_t) + 1; + p = req + sizeof(sdp_pdu_hdr_t); + *p++ = flags; + if (0 > sdp_gen_record_pdu(rec, &pdu)) { + status = -1; + errno = ENOMEM; + goto end; + } + memcpy(p, pdu.data, pdu.data_size); + free(pdu.data); + reqsize += pdu.data_size; + reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); + + status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize); + if (status < 0) + goto end; + rsphdr = (sdp_pdu_hdr_t *)rsp; + p = rsp + sizeof(sdp_pdu_hdr_t); + if (rsphdr->pdu_id == SDP_SVC_REGISTER_RSP) { + uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); + rec->handle = handle; + sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); + } +end: + if (req) + free(req); + if (rsp) + free(rsp); + return status; +} + +/* + * unregister a service record + */ +int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) +{ + char *p; + int status = 0; + char *reqbuf, *rspbuf; + int reqsize = 0, rspsize = 0; + sdp_pdu_hdr_t *reqhdr, *rsphdr; + uint32_t handle = 0; + + SDPDBG(""); + + handle = rec->handle; + if (handle == SDP_SERVER_RECORD_HANDLE) { + errno = EINVAL; + return -1; + } + if (!session->local) { + errno = EREMOTE; + return -1; + } + reqbuf = (char *)malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = (char *)malloc(SDP_RSP_BUFFER_SIZE); + if (!reqbuf || !rspbuf) { + errno = ENOMEM; + status = -1; + goto end; + } + reqhdr = (sdp_pdu_hdr_t *)reqbuf; + reqhdr->pdu_id = SDP_SVC_REMOVE_REQ; + reqhdr->tid = htons(sdp_gen_tid(session)); + + p = reqbuf + sizeof(sdp_pdu_hdr_t); + reqsize = sizeof(sdp_pdu_hdr_t); + sdp_put_unaligned(htonl(handle), (uint32_t *)p); + reqsize += sizeof(uint32_t); + + reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); + status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); + if (status == 0) { + rsphdr = (sdp_pdu_hdr_t *)rspbuf; + p = rspbuf + sizeof(sdp_pdu_hdr_t); + status = sdp_get_unaligned((uint16_t *)p); + if (status == 0 && rsphdr->pdu_id == SDP_SVC_REMOVE_RSP) { + SDPDBG("Removing local copy\n"); + sdp_record_free(rec); + } + } +end: + if (reqbuf) + free(reqbuf); + if (rspbuf) + free(rspbuf); + return status; +} + +/* + * modify an existing service record + */ +int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) +{ + char *p; + int status = 0; + char *reqbuf, *rspbuf; + int reqsize, rspsize; + sdp_pdu_hdr_t *reqhdr, *rsphdr; + uint32_t handle; + sdp_buf_t pdu; + + SDPDBG(""); + handle = rec->handle; + + if (handle == SDP_SERVER_RECORD_HANDLE) { + errno = EINVAL; + return -1; + } + if (!session->local) { + errno = EREMOTE; + return -1; + } + reqbuf = (char *)malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = (char *)malloc(SDP_RSP_BUFFER_SIZE); + if (!reqbuf || !rspbuf) { + errno = ENOMEM; + status = -1; + goto end; + } + reqhdr = (sdp_pdu_hdr_t *)reqbuf; + reqhdr->pdu_id = SDP_SVC_UPDATE_REQ; + reqhdr->tid = htons(sdp_gen_tid(session)); + + p = (char *)(reqbuf + sizeof(sdp_pdu_hdr_t)); + reqsize = sizeof(sdp_pdu_hdr_t); + + sdp_put_unaligned(htonl(handle), (uint32_t *)p); + reqsize += sizeof(uint32_t); + p += sizeof(uint32_t); + + if (0 > sdp_gen_record_pdu(rec, &pdu)) { + errno = ENOMEM; + status = -1; + goto end; + } + memcpy(p, pdu.data, pdu.data_size); + reqsize += pdu.data_size; + + reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); + status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); + + SDPDBG("Send req status : %d\n", status); + + if (status == 0) { + rsphdr = (sdp_pdu_hdr_t *)rspbuf; + p = rspbuf + sizeof(sdp_pdu_hdr_t); + status = sdp_get_unaligned((uint16_t *)p); + } +end: + if (reqbuf) + free(reqbuf); + if (rspbuf) + free(rspbuf); + return status; +} + +sdp_record_t *sdp_record_alloc() +{ + sdp_record_t *rec = (sdp_record_t *)malloc(sizeof(sdp_record_t)); + memset((void *)rec, 0, sizeof(sdp_record_t)); + rec->handle = 0xffffffff; + return rec; +} + +/* + * Free the contents of a service record + */ +void sdp_record_free(sdp_record_t *rec) +{ + sdp_list_free(rec->attrlist, (sdp_free_func_t)sdp_data_free); + sdp_list_free(rec->pattern, free); + free(rec); +} + +void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid) +{ + uuid_t *uuid128 = sdp_uuid_to_uuid128(uuid); + + SDPDBG("SvcRec : 0x%lx\n", (unsigned long)rec); + SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern)); + SDPDBG("Trying to add : 0x%lx\n", (unsigned long)uuid128); + + if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL) + rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp); + else + free(uuid128); + + SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern)); +} + +void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq) +{ + for (; seq; seq = seq->next) { + uuid_t *uuid = (uuid_t *)seq->data; + sdp_pattern_add_uuid(rec, uuid); + } +} + +/* + * Extract a sequence of service record handles from a PDU buffer + * and add the entries to a sdp_list_t. Note that the service record + * handles are not in "data element sequence" form, but just like + * an array of service handles + */ +static void extract_record_handle_seq(char *pdu, sdp_list_t **seq, int count, int *scanned) +{ + sdp_list_t *pSeq = *seq; + char *pdata = pdu; + int n; + + for (n = 0; n < count; n++) { + uint32_t *pSvcRec = (uint32_t *) malloc(sizeof(uint32_t)); + *pSvcRec = ntohl(sdp_get_unaligned((uint32_t *)pdata)); + pSeq = sdp_list_append(pSeq, pSvcRec); + pdata += sizeof(uint32_t); + *scanned += sizeof(uint32_t); + } + *seq = pSeq; +} +/* + * Generate the attribute sequence pdu form + * from sdp_list_t elements. Return length of attr seq + */ +static int gen_dataseq_pdu(char *dst, const sdp_list_t *seq, uint8_t dtd) +{ + sdp_data_t *dataseq; + void **types, **values; + sdp_buf_t buf; + int i, seqlen = sdp_list_len(seq); + + // Fill up the value and the dtd arrays + SDPDBG(""); + + memset(&buf, 0, sizeof(sdp_buf_t)); + buf.data = (char *)malloc(SDP_UUID_SEQ_SIZE); + buf.buf_size = SDP_UUID_SEQ_SIZE; + + SDPDBG("Seq length : %d\n", seqlen); + + types = malloc(seqlen * sizeof(void *)); + values = malloc(seqlen * sizeof(void *)); + for (i = 0; i < seqlen; i++) { + void *data = seq->data; + types[i] = &dtd; + if (SDP_IS_UUID(dtd)) + data = &((uuid_t *)data)->value; + values[i] = data; + seq = seq->next; + } + + dataseq = sdp_seq_alloc(types, values, seqlen); + SDPDBG("Data Seq : 0x%p\n", seq); + seqlen = sdp_gen_pdu(&buf, dataseq); + SDPDBG("Copying : %d\n", buf.data_size); + memcpy(dst, buf.data, buf.data_size); + + sdp_data_free(dataseq); + + free(types); + free(values); + free(buf.data); + return seqlen; +} + +static int gen_searchseq_pdu(char *dst, const sdp_list_t *seq) +{ + uuid_t *uuid = (uuid_t *)seq->data; + return gen_dataseq_pdu(dst, seq, uuid->type); +} + +static int gen_attridseq_pdu(char *dst, const sdp_list_t *seq, uint8_t dataType) +{ + return gen_dataseq_pdu(dst, seq, dataType); +} + +static int copy_cstate(char *pdata, const sdp_cstate_t *cstate) +{ + if (cstate) { + *pdata++ = cstate->length; + memcpy(pdata, cstate->data, cstate->length); + return cstate->length + 1; + } + *pdata = 0; + return 1; +} + +/* + * This is a service search request. + * + * INPUT : + * + * sdp_list_t *search_list + * Singly linked list containing elements of the search + * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16) + * of the service to be searched + * + * uint16_t max_rec_num + * A 16 bit integer which tells the service, the maximum + * entries that the client can handle in the response. The + * server is obliged not to return > max_rec_num entries + * + * OUTPUT : + * + * int return value + * 0: + * The request completed successfully. This does not + * mean the requested services were found + * -1: + * On any failure and sets errno + * + * sdp_list_t **rsp_list + * This variable is set on a successful return if there are + * non-zero service handles. It is a singly linked list of + * service records (sdp_record_t *) + * + * uint16_t *handleCount + * This is a pointer to a 16 bit integer, which is set to + * indicate the number of service record handles present in + * rec_list + */ +int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, + uint16_t max_rec_num, sdp_list_t **rsp) +{ + int status = 0; + int reqsize = 0, _reqsize; + int rspsize = 0, rsplen; + int seqlen = 0; + int scanned, total_rec_count, rec_count; + char *pdata, *_pdata; + char *reqbuf, *rspbuf; + sdp_pdu_hdr_t *reqhdr, *rsphdr; + sdp_cstate_t *cstate = NULL; + + reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = malloc(SDP_RSP_BUFFER_SIZE); + if (!reqbuf || !rspbuf) { + errno = ENOMEM; + status = -1; + goto end; + } + reqhdr = (sdp_pdu_hdr_t *)reqbuf; + reqhdr->pdu_id = SDP_SVC_SEARCH_REQ; + pdata = reqbuf + sizeof(sdp_pdu_hdr_t); + reqsize = sizeof(sdp_pdu_hdr_t); + + // add service class IDs for search + seqlen = gen_searchseq_pdu(pdata, search); + + SDPDBG("Data seq added : %d\n", seqlen); + + // set the length and increment the pointer + reqsize += seqlen; + pdata += seqlen; + + // specify the maximum svc rec count that client expects + sdp_put_unaligned(htons(max_rec_num), (uint16_t *)pdata); + reqsize += sizeof(uint16_t); + pdata += sizeof(uint16_t); + + _reqsize = reqsize; + _pdata = pdata; + *rsp = NULL; + + do { + // Add continuation state or NULL (first time) + reqsize = _reqsize + copy_cstate(_pdata, cstate); + + // Set the request header's param length + reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); + + reqhdr->tid = htons(sdp_gen_tid(session)); + /* + * Send the request, wait for response and if + * no error, set the appropriate values and return + */ + status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); + if (status < 0) + goto end; + + rsplen = 0; + rsphdr = (sdp_pdu_hdr_t *)rspbuf; + rsplen = ntohs(rsphdr->plen); + + if (rsphdr->pdu_id == SDP_ERROR_RSP) { + SDPDBG("Status : 0x%x\n", rsphdr->pdu_id); + status = -1; + goto end; + } + scanned = 0; + pdata = rspbuf + sizeof(sdp_pdu_hdr_t); + + // net service record match count + total_rec_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + pdata += sizeof(uint16_t); + scanned += sizeof(uint16_t); + rec_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + pdata += sizeof(uint16_t); + scanned += sizeof(uint16_t); + + SDPDBG("Total svc count: %d\n", total_rec_count); + SDPDBG("Current svc count: %d\n", rec_count); + SDPDBG("ResponseLength: %d\n", rsplen); + + if (!rec_count) { + status = -1; + goto end; + } + extract_record_handle_seq(pdata, rsp, rec_count, &scanned); + SDPDBG("BytesScanned : %d\n", scanned); + + if (rsplen > scanned) { + uint8_t cstate_len; + + pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned; + cstate_len = *(uint8_t *)pdata; + if (cstate_len > 0) { + cstate = (sdp_cstate_t *)pdata; + SDPDBG("Cont state length: %d\n", cstate_len); + } else + cstate = NULL; + } + } while (cstate); + + end: + if (reqbuf) + free(reqbuf); + if (rspbuf) + free(rspbuf); + + return status; +} + +/* + * This is a service attribute request. + * + * INPUT : + * + * uint32_t handle + * The handle of the service for which the attribute(s) are + * requested + * + * sdp_attrreq_type_t reqtype + * Attribute identifiers are 16 bit unsigned integers specified + * in one of 2 ways described below : + * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers + * They are the actual attribute identifiers in ascending order + * + * SDP_ATTR_REQ_RANGE - 32bit identifier range + * The high-order 16bits is the start of range + * the low-order 16bits are the end of range + * 0x0000 to 0xFFFF gets all attributes + * + * sdp_list_t *attrid + * Singly linked list containing attribute identifiers desired. + * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) + * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) + * + * OUTPUT : + * return sdp_record_t * + * 0: + * On any error and sets errno + * !0: + * The service record + */ +sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, + sdp_attrreq_type_t reqtype, const sdp_list_t *attrids) +{ + int status = 0; + int reqsize = 0, _reqsize; + int rspsize = 0, rsp_count; + int attr_list_len = 0; + int seqlen = 0; + char *pdata, *_pdata; + char *reqbuf, *rspbuf; + sdp_pdu_hdr_t *reqhdr, *rsphdr; + sdp_cstate_t *cstate = NULL; + uint8_t cstate_len = 0; + sdp_buf_t rsp_concat_buf; + sdp_record_t *rec = 0; + + if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) { + errno = EINVAL; + return 0; + } + + reqbuf = (char *)malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = (char *)malloc(SDP_RSP_BUFFER_SIZE); + if (!reqbuf || !rspbuf) { + errno = ENOMEM; + status = -1; + goto end; + } + memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t)); + reqhdr = (sdp_pdu_hdr_t *)reqbuf; + reqhdr->pdu_id = SDP_SVC_ATTR_REQ; + + pdata = reqbuf + sizeof(sdp_pdu_hdr_t); + reqsize = sizeof(sdp_pdu_hdr_t); + + // add the service record handle + sdp_put_unaligned(htonl(handle), (uint32_t *)pdata); + reqsize += sizeof(uint32_t); + pdata += sizeof(uint32_t); + + // specify the response limit + sdp_put_unaligned(htons(65535), (uint16_t *)pdata); + reqsize += sizeof(uint16_t); + pdata += sizeof(uint16_t); + + // get attr seq PDU form + seqlen = gen_attridseq_pdu(pdata, attrids, + reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32); + if (seqlen == -1) { + errno = EINVAL; + status = -1; + goto end; + } + pdata += seqlen; + reqsize += seqlen; + SDPDBG("Attr list length : %d\n", seqlen); + + // save before Continuation State + _pdata = pdata; + _reqsize = reqsize; + + do { + // add NULL continuation state + reqsize = _reqsize + copy_cstate(_pdata, cstate); + + // set the request header's param length + reqhdr->tid = htons(sdp_gen_tid(session)); + reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); + + status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); + if (status < 0) + goto end; + rsp_count = 0; + rsphdr = (sdp_pdu_hdr_t *)rspbuf; + if (rsphdr->pdu_id == SDP_ERROR_RSP) { + SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id); + status = -1; + goto end; + } + pdata = rspbuf + sizeof(sdp_pdu_hdr_t); + rsp_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + attr_list_len += rsp_count; + pdata += sizeof(uint16_t); + + // if continuation state set need to re-issue request before parsing + cstate_len = *(uint8_t *)(pdata + rsp_count); + + SDPDBG("Response id : %d\n", rsphdr->pdu_id); + SDPDBG("Attrlist byte count : %d\n", rsp_count); + SDPDBG("sdp_cstate_t length : %d\n", cstate_len); + + /* + * a split response: concatenate intermediate responses + * and the last one (which has cstate_len == 0) + */ + if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { + char *targetPtr = NULL; + + cstate = cstate_len > 0? (sdp_cstate_t *)(pdata + rsp_count): 0; + + // build concatenated response buffer + rsp_concat_buf.data = (char *)realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); + rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; + targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; + memcpy(targetPtr, pdata, rsp_count); + rsp_concat_buf.data_size += rsp_count; + } + } while (cstate); + + if (attr_list_len > 0) { + int scanned = 0; + if (rsp_concat_buf.data_size != 0) + pdata = rsp_concat_buf.data; + rec = sdp_extract_pdu(pdata, &scanned); + + if (!rec) + status = -1; + } + + end: + if (reqbuf) + free(reqbuf); + if (rsp_concat_buf.data) + free(rsp_concat_buf.data); + if (rspbuf) + free(rspbuf); + return rec; +} + +/* + * This is a service search request combined with the service + * attribute request. First a service class match is done and + * for matching service, requested attributes are extracted + * + * INPUT : + * + * sdp_list_t *search + * Singly linked list containing elements of the search + * pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16) + * of the service to be searched + * + * AttributeSpecification attrSpec + * Attribute identifiers are 16 bit unsigned integers specified + * in one of 2 ways described below : + * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers + * They are the actual attribute identifiers in ascending order + * + * SDP_ATTR_REQ_RANGE - 32bit identifier range + * The high-order 16bits is the start of range + * the low-order 16bits are the end of range + * 0x0000 to 0xFFFF gets all attributes + * + * sdp_list_t *attrids + * Singly linked list containing attribute identifiers desired. + * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) + * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) + * + * OUTPUT : + * int return value + * 0: + * The request completed successfully. This does not + * mean the requested services were found + * -1: + * On any error and sets errno + * + * sdp_list_t **rsp + * This variable is set on a successful return to point to + * service(s) found. Each element of this list is of type + * sdp_record_t* (of the services which matched the search list) + */ +int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrids, sdp_list_t **rsp) +{ + int status = 0; + int reqsize = 0, _reqsize; + int rspsize = 0; + int seqlen = 0, attr_list_len = 0; + int rsp_count = 0, cstate_len = 0; + char *pdata, *_pdata; + char *reqbuf, *rspbuf; + sdp_pdu_hdr_t *reqhdr, *rsphdr; + uint8_t dataType; + sdp_list_t *rec_list = NULL; + sdp_buf_t rsp_concat_buf; + sdp_cstate_t *cstate = NULL; + + if (reqtype != SDP_ATTR_REQ_INDIVIDUAL && reqtype != SDP_ATTR_REQ_RANGE) { + errno = EINVAL; + return -1; + } + reqbuf = (char *)malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = (char *)malloc(SDP_RSP_BUFFER_SIZE); + if (!reqbuf || !rspbuf) { + errno = ENOMEM; + status = -1; + goto end; + } + + memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t)); + reqhdr = (sdp_pdu_hdr_t *)reqbuf; + reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ; + + // generate PDU + pdata = reqbuf + sizeof(sdp_pdu_hdr_t); + reqsize = sizeof(sdp_pdu_hdr_t); + + // add service class IDs for search + seqlen = gen_searchseq_pdu(pdata, search); + + SDPDBG("Data seq added : %d\n", seqlen); + + // now set the length and increment the pointer + reqsize += seqlen; + pdata += seqlen; + + sdp_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *)pdata); + reqsize += sizeof(uint16_t); + pdata += sizeof(uint16_t); + + SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN); + + // get attr seq PDU form + seqlen = gen_attridseq_pdu(pdata, attrids, + reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16: SDP_UINT32); + if (seqlen == -1) { + status = EINVAL; + goto end; + } + pdata += seqlen; + SDPDBG("Attr list length : %d\n", seqlen); + reqsize += seqlen; + *rsp = 0; + + // save before Continuation State + _pdata = pdata; + _reqsize = reqsize; + + do { + reqhdr->tid = htons(sdp_gen_tid(session)); + + // add continuation state (can be null) + reqsize = _reqsize + copy_cstate(_pdata, cstate); + + // set the request header's param length + reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); + rsphdr = (sdp_pdu_hdr_t *)rspbuf; + status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); + if (status < 0) { + SDPDBG("Status : 0x%x\n", rsphdr->pdu_id); + goto end; + } + + if (rsphdr->pdu_id == SDP_ERROR_RSP) { + status = -1; + goto end; + } + + pdata = rspbuf + sizeof(sdp_pdu_hdr_t); + rsp_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + attr_list_len += rsp_count; + pdata += sizeof(uint16_t); // pdata points to attribute list + cstate_len = *(uint8_t *)(pdata + rsp_count); + + SDPDBG("Attrlist byte count : %d\n", attr_list_len); + SDPDBG("Response byte count : %d\n", rsp_count); + SDPDBG("Cstate length : %d\n", cstate_len); + /* + * This is a split response, need to concatenate intermediate + * responses and the last one which will have cstate_len == 0 + */ + if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { + char *targetPtr = NULL; + + cstate = cstate_len > 0? (sdp_cstate_t *)(pdata + rsp_count): 0; + + // build concatenated response buffer + rsp_concat_buf.data = (char *)realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); + targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; + rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; + memcpy(targetPtr, pdata, rsp_count); + rsp_concat_buf.data_size += rsp_count; + } + } while (cstate); + + if (attr_list_len > 0) { + int scanned = 0; + + if (rsp_concat_buf.data_size != 0) + pdata = rsp_concat_buf.data; + + /* + * Response is a sequence of sequence(s) for one or + * more data element sequence(s) representing services + * for which attributes are returned + */ + scanned = sdp_extract_seqtype(pdata, &dataType, &seqlen); + + SDPDBG("Bytes scanned : %d\n", scanned); + SDPDBG("Seq length : %d\n", seqlen); + + if (scanned && seqlen) { + pdata += scanned; + do { + int recsize = 0; + sdp_record_t *rec = sdp_extract_pdu(pdata, &recsize); + if (rec == NULL) { + SDPERR("SVC REC is null\n"); + status = -1; + goto end; + } + scanned += recsize; + pdata += recsize; + + SDPDBG("Loc seq length : %d\n", recsize); + SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle); + SDPDBG("Bytes scanned : %d\n", scanned); + SDPDBG("Attrlist byte count : %d\n", attr_list_len); + rec_list = sdp_list_append(rec_list, rec); + } while (scanned < attr_list_len); + + SDPDBG("Successful scan of service attr lists\n"); + *rsp = rec_list; + } + } + end: + if (rsp_concat_buf.data) + free(rsp_concat_buf.data); + if (reqbuf) + free(reqbuf); + if (rspbuf) + free(rspbuf); + return status; +} + +/* + * Find devices in the piconet. + */ +int sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *found) +{ + int n = hci_inquiry(-1, 10, num_dev, NULL, &ii, 0); + if (n < 0) { + SDPERR("Inquiry failed:%s", strerror(errno)); + return -1; + } + *found = n; + return 0; +} + +int sdp_close(sdp_session_t *session) +{ + int ret = close(session->sock); + free(session); + return ret; +} + +static inline int sdp_is_local(const bdaddr_t *device) +{ + return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0; +} + +sdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t flags) +{ + sdp_session_t *session = malloc(sizeof(sdp_session_t)); + if (!session) + return session; + memset(session, 0, sizeof(*session)); + session->flags = flags; + if (sdp_is_local(dst)) { + struct sockaddr_un sa; + + // create local unix connection + session->sock = socket(PF_UNIX, SOCK_STREAM, 0); + session->local = 1; + if (session->sock >= 0) { + sa.sun_family = AF_UNIX; + strcpy(sa.sun_path, SDP_UNIX_PATH); + if (connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)) == 0) + return session; + } + } else { + struct sockaddr_l2 sa; + + // create L2CAP connection + session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + session->local = 0; + if (session->sock >= 0) { + sa.l2_family = AF_BLUETOOTH; + sa.l2_psm = 0; + if (bacmp(src, BDADDR_ANY) != 0) { + sa.l2_bdaddr = *src; + if (0 > bind(session->sock, (struct sockaddr *)&sa, sizeof(sa))) + goto fail; + } + sa.l2_psm = htobs(SDP_PSM); + sa.l2_bdaddr = *dst; + do + if (connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)) == 0) + return session; + while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY)); + } + } +fail: + if (session->sock >= 0) + close(session->sock); + free(session); + return 0; +} -- cgit From 4d97c2497c2bee809432ea3e48676fa61538bbef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 16:48:38 +0000 Subject: Use R2 for default value of pscan_rep_mode --- src/hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 8100d227..3778f064 100644 --- a/src/hci.c +++ b/src/hci.c @@ -734,7 +734,7 @@ int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t c memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); cp.pkt_type = ptype; - cp.pscan_rep_mode = 0x01; + cp.pscan_rep_mode = 0x02; cp.clock_offset = clkoffset; cp.role_switch = rswitch; @@ -847,7 +847,7 @@ int hci_read_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, ba); - cp.pscan_rep_mode = 0x01; + cp.pscan_rep_mode = 0x02; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; -- cgit From 51e671b116fe121053444c4817e38ad07e9586f8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 31 Mar 2004 19:50:46 +0000 Subject: Use $(top_builddir) as include root directory --- src/Makefile.am | 2 +- src/bluetooth.c | 4 ++-- src/hci.c | 6 +++--- src/sdp.c | 14 +++++++------- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 6c6b9fc4..17fdbf6d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,4 +10,4 @@ libbluetooth_la_LDFLAGS = -version-info 1:4:0 libsdp_la_SOURCES = libsdp_la_LDFLAGS = -version-info 2:2:0 -INCLUDES = -I$(top_srcdir)/include +INCLUDES = -I$(top_builddir)/include diff --git a/src/bluetooth.c b/src/bluetooth.c index 1607c04f..a57809d7 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -32,8 +32,8 @@ #include #include -#include -#include +#include +#include void baswap(bdaddr_t *dst, const bdaddr_t *src) { diff --git a/src/hci.c b/src/hci.c index 3778f064..1530f395 100644 --- a/src/hci.c +++ b/src/hci.c @@ -43,9 +43,9 @@ #include #include -#include -#include -#include +#include +#include +#include typedef struct { char *str; unsigned int val; diff --git a/src/sdp.c b/src/sdp.c index 4ffb0d93..b793f64f 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -38,13 +38,13 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB" -- cgit From ff3922238b4258eb2f9f9458589d3cecd177f7bc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 10:18:22 +0000 Subject: Store additional unitSize for strings --- src/sdp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index b793f64f..0fec56f7 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -810,14 +810,15 @@ static sdp_data_t *extract_str(const void *p, int *len) return 0; } - s = (char *)malloc(n + 1); + s = malloc(n + 1); memset(s, 0, n + 1); - strncpy(s, p, n); + memcpy(s, p, n); SDPDBG("Len : %d\n", n); SDPDBG("Str : %s\n", s); d->val.str = s; + d->unitSize = n; return d; } -- cgit From b5705586036d2aefa5b75ebe26ed64445a4d79be Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 1 Apr 2004 14:02:12 +0000 Subject: Add string representation for HID and CIP --- src/sdp.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 0fec56f7..cbc68193 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -70,6 +70,8 @@ static struct tupla Protocol[] = { { HTTP_UUID, "HTTP" }, { WSP_UUID, "WSP" }, { BNEP_UUID, "BNEP" }, + { HIDP_UUID, "HIDP" }, + { CMTP_UUID, "CMTP" }, { 0 } }; @@ -97,6 +99,8 @@ static struct tupla ServiceClass[] = { { PANU_SVCLASS_ID, "PAN user" }, { NAP_SVCLASS_ID, "Network access point" }, { GN_SVCLASS_ID, "PAN group network" }, + { HID_SVCLASS_ID, "Human Interface Device" }, + { CIP_SVCLASS_ID, "Common ISDN Access" }, { 0 } }; @@ -116,6 +120,8 @@ static struct tupla Profile[] = { { PANU_PROFILE_ID, "PAN user" }, { NAP_PROFILE_ID, "PAN access point" }, { GN_PROFILE_ID, "PAN group network" }, + { HID_SVCLASS_ID, "Human Interface Device" }, + { CIP_SVCLASS_ID, "Common ISDN Access" }, { 0 } }; -- cgit From 764abe23a0d4ede999f1f34ee0e310c0eeaaff79 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Apr 2004 05:11:38 +0000 Subject: Update copyright information --- src/bluetooth.c | 76 ++++++++++++++------------- src/hci.c | 155 +++++++++++++++++++++++++++++++------------------------- src/sdp.c | 61 +++++++++++----------- 3 files changed, 159 insertions(+), 133 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index a57809d7..61a632a5 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -1,31 +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. -*/ - /* + * + * 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 @@ -37,10 +43,10 @@ void baswap(bdaddr_t *dst, const bdaddr_t *src) { - register unsigned char *d = (unsigned char *)dst; - register const unsigned char *s = (const unsigned char *)src; + register unsigned char *d = (unsigned char *) dst; + register const unsigned char *s = (const unsigned char *) src; register int i; - for(i=0; i<6; i++) + for (i = 0; i < 6; i++) d[i] = s[5-i]; } @@ -51,7 +57,7 @@ char *batostr(const bdaddr_t *ba) return NULL; sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - ba->b[0], ba->b[1], ba->b[2], + ba->b[0], ba->b[1], ba->b[2], ba->b[3], ba->b[4], ba->b[5]); return str; } @@ -65,9 +71,9 @@ bdaddr_t *strtoba(const char *str) if (!ba) return NULL; - for(i=0; i<6; i++){ + for(i = 0; i < 6; i++) { ba[i] = (uint8_t) strtol(ptr, NULL, 16); - if( i!=5 && !(ptr=strchr(ptr,':')) ) + if (i != 5 && !(ptr = strchr(ptr,':'))) ptr = ":00:00:00:00:00"; ptr++; } @@ -78,9 +84,9 @@ int ba2str(const bdaddr_t *ba, char *str) { uint8_t b[6]; - baswap((bdaddr_t *)b, ba); + baswap((bdaddr_t *) b, ba); return sprintf(str, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - b[0], b[1], b[2], b[3], b[4], b[5]); + b[0], b[1], b[2], b[3], b[4], b[5]); } int str2ba(const char *str, bdaddr_t *ba) @@ -89,13 +95,13 @@ int str2ba(const char *str, bdaddr_t *ba) const char *ptr = str; int i; - for (i=0; i < 6; i++) { + for (i = 0; i < 6; i++) { b[i] = (uint8_t) strtol(ptr, NULL, 16); - if (i!=5 && !(ptr=strchr(ptr, ':'))) + if (i != 5 && !(ptr = strchr(ptr, ':'))) ptr = ":00:00:00:00:00"; ptr++; } - baswap(ba, (bdaddr_t *)b); + baswap(ba, (bdaddr_t *) b); return 0; } diff --git a/src/hci.c b/src/hci.c index 1530f395..e2184cbb 100644 --- a/src/hci.c +++ b/src/hci.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 @@ -64,7 +71,7 @@ static char *hci_bit2str(hci_map *m, unsigned int val) if ((unsigned int) m->val & val) ptr += sprintf(ptr, "%s ", m->str); m++; - } + } return str; } @@ -79,14 +86,14 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) *val = set = 0; - while ((t=strsep(&ptr, ","))) { - for (m=map; m->str; m++) { - if (!strcasecmp(m->str,t)) { + while ((t = strsep(&ptr, ","))) { + for (m = map; m->str; m++) { + if (!strcasecmp(m->str, t)) { *val |= (unsigned int) m->val; set = 1; } } - } + } free(str); return set; @@ -107,7 +114,7 @@ static char *hci_uint2str(hci_map *m, unsigned int val) break; } m++; - } + } return str; } @@ -122,14 +129,14 @@ static int hci_str2uint(hci_map *map, char *str, unsigned int *val) str = ptr = strdup(str); - while ((t=strsep(&ptr, ","))) { - for (m=map; m->str; m++) { + while ((t = strsep(&ptr, ","))) { + for (m = map; m->str; m++) { if (!strcasecmp(m->str,t)) { *val = (unsigned int) m->val; set = 1; break; } } - } + } free(str); return set; @@ -156,7 +163,7 @@ char *hci_dtypetostr(int type) } /* HCI dev flags mapping */ -hci_map dev_flags_map[] = { +static hci_map dev_flags_map[] = { { "UP", HCI_UP }, { "INIT", HCI_INIT }, { "RUNNING", HCI_RUNNING }, @@ -168,6 +175,7 @@ hci_map dev_flags_map[] = { { "ENCRYPT", HCI_ENCRYPT }, { NULL } }; + char *hci_dflagstostr(uint32_t flags) { char *str = malloc(50); @@ -191,7 +199,7 @@ char *hci_dflagstostr(uint32_t flags) } /* HCI packet type mapping */ -hci_map pkt_type_map[] = { +static hci_map pkt_type_map[] = { { "DM1", HCI_DM1 }, { "DM3", HCI_DM3 }, { "DM5", HCI_DM5 }, @@ -203,17 +211,19 @@ hci_map pkt_type_map[] = { { "HV3", HCI_HV3 }, { NULL } }; + char *hci_ptypetostr(unsigned int ptype) { return hci_bit2str(pkt_type_map, ptype); } + int hci_strtoptype(char *str, unsigned int *val) { return hci_str2bit(pkt_type_map, str, val); } /* Link policy mapping */ -hci_map link_policy_map[] = { +static hci_map link_policy_map[] = { { "NONE", 0 }, { "RSWITCH", HCI_LP_RSWITCH }, { "HOLD", HCI_LP_HOLD }, @@ -221,17 +231,19 @@ hci_map link_policy_map[] = { { "PARK", HCI_LP_PARK }, { NULL } }; + char *hci_lptostr(unsigned int lp) { return hci_bit2str(link_policy_map, lp); } + int hci_strtolp(char *str, unsigned int *val) { return hci_str2bit(link_policy_map, str, val); } /* Link mode mapping */ -hci_map link_mode_map[] = { +static hci_map link_mode_map[] = { { "NONE", 0 }, { "ACCEPT", HCI_LM_ACCEPT }, { "MASTER", HCI_LM_MASTER }, @@ -240,6 +252,7 @@ hci_map link_mode_map[] = { { "TRUSTED", HCI_LM_TRUSTED}, { NULL } }; + char *hci_lmtostr(unsigned int lm) { char *s, *str = malloc(50); @@ -260,23 +273,26 @@ char *hci_lmtostr(unsigned int lm) free(s); return str; } + int hci_strtolm(char *str, unsigned int *val) { return hci_str2bit(link_mode_map, str, val); } /* Version mapping */ -hci_map ver_map[] = { +static hci_map ver_map[] = { { "1.0b", 0x00 }, { "1.1", 0x01 }, { "1.2", 0x02 }, { NULL } }; + char *hci_vertostr(unsigned int ver) { char *str = hci_uint2str(ver_map, ver); return *str ? str : "n/a"; } + int hci_strtover(char *str, unsigned int *ver) { return hci_str2uint(ver_map, str, ver); @@ -287,13 +303,14 @@ char *lmp_vertostr(unsigned int ver) char *str = hci_uint2str(ver_map, ver); return *str ? str : "n/a"; } + int lmp_strtover(char *str, unsigned int *ver) { return hci_str2uint(ver_map, str, ver); } /* LMP features mapping */ -hci_map lmp_features_map[8][9] = { +static hci_map lmp_features_map[8][9] = { { /* byte 0 */ { "<3-slot packets>", LMP_3SLOT }, { "<5-slot packets>", LMP_5SLOT }, @@ -341,7 +358,7 @@ hci_map lmp_features_map[8][9] = { }, { /* byte 5 */ { "", LMP_AFH_CAP_MST }, - { "",LMP_AFH_CLS_MST }, + { "",LMP_AFH_CLS_MST }, { NULL } }, { /* byte 6 */ @@ -366,7 +383,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) if (pref) ptr += sprintf(ptr, "%s", pref); - for(i=0, w=0; i<8; i++) { + for (i = 0, w = 0; i < 8; i++) { hci_map *m; m = lmp_features_map[i]; @@ -386,7 +403,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) /* HCI functions that do not require open device */ -int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg) +int hci_for_each_dev(int flag, int (*func)(int s, int dev_id, long arg), long arg) { struct hci_dev_list_req *dl; struct hci_dev_req *dr; @@ -402,13 +419,13 @@ int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg close(s); return -1; } - + dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; if (ioctl(s, HCIGETDEVLIST, (void *)dl)) goto done; - + for (i=0; i < dl->dev_num; i++, dr++) { if (hci_test_bit(flag, &dr->dev_opt)) if (!func || func(s, dr->dev_id, arg)) { @@ -417,7 +434,7 @@ int hci_for_each_dev(int flag, int(*func)(int s, int dev_id, long arg), long arg } } -done: +done: close(s); free(dl); return dev_id; @@ -426,17 +443,17 @@ done: static int __other_bdaddr(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void *) &di)) return 0; - return bacmp((bdaddr_t *)arg, &di.bdaddr); + return bacmp((bdaddr_t *) arg, &di.bdaddr); } static int __same_bdaddr(int s, int dev_id, long arg) { struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(s, HCIGETDEVINFO, (void*) &di)) + if (ioctl(s, HCIGETDEVINFO, (void *) &di)) return 0; - return !bacmp((bdaddr_t *)arg, &di.bdaddr); + return !bacmp((bdaddr_t *) arg, &di.bdaddr); } int hci_get_route(bdaddr_t *bdaddr) @@ -502,7 +519,7 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info int s, err; if (nrsp <= 0) - nrsp = 200; // enough ? + nrsp = 200; /* enough ? */ if (dev_id < 0 && (dev_id = hci_get_route(NULL)) < 0) { errno = ENODEV; @@ -563,11 +580,11 @@ int hci_open_dev(int dev_id) dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (dd < 0) return dd; - + /* Bind socket to the HCI device */ a.hci_family = AF_BLUETOOTH; a.hci_dev = dev_id; - if (bind(dd, (struct sockaddr *)&a, sizeof(a)) < 0) + if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0) goto failed; return dd; @@ -645,7 +662,7 @@ int hci_send_req(int dd, struct hci_request *r, int to) while (try--) { evt_cmd_complete *cc; evt_cmd_status *cs; - + if (to) { struct pollfd p; int n; @@ -661,7 +678,7 @@ int hci_send_req(int dd, struct hci_request *r, int to) errno = ETIMEDOUT; goto failed; } - + to -= 10; if (to < 0) to = 0; @@ -673,17 +690,17 @@ int hci_send_req(int dd, struct hci_request *r, int to) goto failed; } - hdr = (void *)(buf + 1); + hdr = (void *) (buf + 1); ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); switch (hdr->evt) { case EVT_CMD_STATUS: - cs = (void *)ptr; - + cs = (void *) ptr; + if (cs->opcode != opcode) continue; - + if (cs->status) { errno = EIO; goto failed; @@ -691,11 +708,11 @@ int hci_send_req(int dd, struct hci_request *r, int to) break; case EVT_CMD_COMPLETE: - cc = (void *)ptr; + cc = (void *) ptr; if (cc->opcode != opcode) continue; - + ptr += EVT_CMD_COMPLETE_SIZE; len -= EVT_CMD_COMPLETE_SIZE; @@ -706,7 +723,7 @@ int hci_send_req(int dd, struct hci_request *r, int to) default: if (hdr->evt != r->event) break; - + r->rlen = MIN(len, r->rlen); memcpy(r->rparam, ptr, r->rlen); goto done; @@ -994,21 +1011,21 @@ int hci_read_class_of_dev(int dd, uint8_t *cls, int to) { read_class_of_dev_rp rp; struct hci_request rq; - + memset(&rq, 0, sizeof(rq)); 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(dd, &rq, to) < 0) return -1; - + if (rp.status) { errno = EIO; return -1; } - + memcpy(cls, rp.dev_class, 3); return 0; } @@ -1070,7 +1087,7 @@ int hci_read_current_iac_lap(int dd, uint8_t *num_iac, uint8_t *lap, int to) { read_current_iac_lap_rp rp; struct hci_request rq; - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_CURRENT_IAC_LAP; @@ -1094,11 +1111,11 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) { write_current_iac_lap_cp cp; struct hci_request rq; - + memset(&cp, 0, sizeof(cp)); cp.num_current_iac = num_iac; memcpy(&cp.lap, lap, num_iac * 3); - + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; diff --git a/src/sdp.c b/src/sdp.c index cbc68193..6740e9d6 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -1,35 +1,38 @@ -/* - BlueZ - Bluetooth protocol stack for Linux - Copyright (C) 2000-2001 Qualcomm Incorporated - - Written 2000,2001 by Maxim Krasnyansky - - Based on an 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 +#include +#endif + #include #include #include -- cgit From 40f6099fd4ffe323a369dd63652570404f4ddc02 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 11:40:10 +0000 Subject: Add bit numbers to the features table --- src/hci.c | 82 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index e2184cbb..2c19b78d 100644 --- a/src/hci.c +++ b/src/hci.c @@ -311,61 +311,61 @@ int lmp_strtover(char *str, unsigned int *ver) /* LMP features mapping */ static hci_map lmp_features_map[8][9] = { - { /* byte 0 */ - { "<3-slot packets>", LMP_3SLOT }, - { "<5-slot packets>", LMP_5SLOT }, - { "", LMP_ENCRYPT }, - { "", LMP_SOFFSET }, - { "", LMP_TACCURACY }, - { "", LMP_RSWITCH }, - { "", LMP_HOLD }, - { "", LMP_SNIFF }, + { /* Byte 0 */ + { "<3-slot packets>", LMP_3SLOT }, /* Bit 0 */ + { "<5-slot packets>", LMP_5SLOT }, /* Bit 1 */ + { "", LMP_ENCRYPT }, /* Bit 2 */ + { "", LMP_SOFFSET }, /* Bit 3 */ + { "", LMP_TACCURACY }, /* Bit 4 */ + { "", LMP_RSWITCH }, /* Bit 5 */ + { "", LMP_HOLD }, /* Bit 6 */ + { "", LMP_SNIFF }, /* Bit 7 */ { NULL } }, - { /* byte 1 */ - { "", LMP_PARK }, - { "", LMP_RSSI }, - { "", LMP_QUALITY }, - { "", LMP_SCO }, - { "", LMP_HV2 }, - { "", LMP_HV3 }, - { "", LMP_ULAW }, - { "", LMP_ALAW }, + { /* Byte 1 */ + { "", LMP_PARK }, /* Bit 0 */ + { "", LMP_RSSI }, /* Bit 1 */ + { "", LMP_QUALITY }, /* Bit 2 */ + { "", LMP_SCO }, /* Bit 3 */ + { "", LMP_HV2 }, /* Bit 4 */ + { "", LMP_HV3 }, /* Bit 5 */ + { "", LMP_ULAW }, /* Bit 6 */ + { "", LMP_ALAW }, /* Bit 7 */ { NULL } }, - { /* byte 2 */ - { "", LMP_CVSD }, - { "", LMP_PSCHEME }, - { "", LMP_PCONTROL }, - { "", LMP_TRSP_SCO }, - { "",LMP_BCAST_ENC }, + { /* Byte 2 */ + { "", LMP_CVSD }, /* Bit 0 */ + { "", LMP_PSCHEME }, /* Bit 1 */ + { "", LMP_PCONTROL }, /* Bit 2 */ + { "", LMP_TRSP_SCO }, /* Bit 3 */ + { "",LMP_BCAST_ENC }, /* Bit 7 */ { NULL } }, - { /* byte 3 */ - { "", LMP_ENH_ISCAN }, - { "", LMP_ILACE_ISCAN }, - { "", LMP_ILACE_PSCAN }, - { "",LMP_RSSI_INQ }, - { "", LMP_ESCO }, + { /* Byte 3 */ + { "", LMP_ENH_ISCAN }, /* Bit 3 */ + { "", LMP_ILACE_ISCAN }, /* Bit 4 */ + { "", LMP_ILACE_PSCAN }, /* Bit 5 */ + { "",LMP_RSSI_INQ }, /* Bit 6 */ + { "", LMP_ESCO }, /* Bit 7 */ { NULL } }, - { /* byte 4 */ - { "", LMP_EV4 }, - { "", LMP_EV5 }, - { "", LMP_AFH_CAP_SLV }, - { "", LMP_AFH_CLS_SLV }, + { /* Byte 4 */ + { "", LMP_EV4 }, /* Bit 0 */ + { "", LMP_EV5 }, /* Bit 1 */ + { "", LMP_AFH_CAP_SLV }, /* Bit 3 */ + { "", LMP_AFH_CLS_SLV }, /* Bit 4 */ { NULL } }, - { /* byte 5 */ - { "", LMP_AFH_CAP_MST }, - { "",LMP_AFH_CLS_MST }, + { /* Byte 5 */ + { "", LMP_AFH_CAP_MST }, /* Bit 3 */ + { "",LMP_AFH_CLS_MST }, /* Bit 4 */ { NULL } }, - { /* byte 6 */ + { /* Byte 6 */ { NULL } }, - { /* byte 7 */ - { "",LMP_EXT_FEAT }, + { /* Byte 7 */ + { "",LMP_EXT_FEAT }, /* Bit 7 */ { NULL } }, }; -- cgit From 6caf64335ab07e1bd138e11a1823ba9baa209fef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Apr 2004 12:09:53 +0000 Subject: Add features and packet types from EDR prototyping specification --- src/hci.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 2c19b78d..f1e278cb 100644 --- a/src/hci.c +++ b/src/hci.c @@ -200,15 +200,35 @@ char *hci_dflagstostr(uint32_t flags) /* HCI packet type mapping */ static hci_map pkt_type_map[] = { - { "DM1", HCI_DM1 }, - { "DM3", HCI_DM3 }, - { "DM5", HCI_DM5 }, - { "DH1", HCI_DH1 }, - { "DH3", HCI_DH3 }, - { "DH5", HCI_DH5 }, - { "HV1", HCI_HV1 }, - { "HV2", HCI_HV2 }, - { "HV3", HCI_HV3 }, + { "DM1", HCI_DM1 }, + { "DM3", HCI_DM3 }, + { "DM5", HCI_DM5 }, + { "DH1", HCI_DH1 }, + { "DH3", HCI_DH3 }, + { "DH5", HCI_DH5 }, + { "HV1", HCI_HV1 }, + { "HV2", HCI_HV2 }, + { "HV3", HCI_HV3 }, + { "2-DH1", HCI_2DH1 }, + { "2-DH3", HCI_2DH3 }, + { "2-DH5", HCI_2DH5 }, + { "3-DH1", HCI_3DH1 }, + { "3-DH3", HCI_3DH3 }, + { "3-DH5", HCI_3DH5 }, + { NULL } +}; + +static hci_map sco_ptype_map[] = { + { "HV1", 0x0001 }, + { "HV2", 0x0002 }, + { "HV3", 0x0004 }, + { "EV3", HCI_EV3 }, + { "EV4", HCI_EV4 }, + { "EV5", HCI_EV5 }, + { "2-EV3", HCI_2EV3 }, + { "2-EV5", HCI_2EV5 }, + { "3-EV3", HCI_3EV3 }, + { "3-EV5", HCI_3EV5 }, { NULL } }; @@ -222,6 +242,16 @@ int hci_strtoptype(char *str, unsigned int *val) return hci_str2bit(pkt_type_map, str, val); } +char *hci_scoptypetostr(unsigned int ptype) +{ + return hci_bit2str(sco_ptype_map, ptype); +} + +int hci_strtoscoptype(char *str, unsigned int *val) +{ + return hci_str2bit(sco_ptype_map, str, val); +} + /* Link policy mapping */ static hci_map link_policy_map[] = { { "NONE", 0 }, @@ -342,6 +372,8 @@ static hci_map lmp_features_map[8][9] = { { NULL } }, { /* Byte 3 */ + { "", LMP_EDR_ACL_2M }, /* Bit 1 */ + { "", LMP_EDR_ACL_3M }, /* Bit 2 */ { "", LMP_ENH_ISCAN }, /* Bit 3 */ { "", LMP_ILACE_ISCAN }, /* Bit 4 */ { "", LMP_ILACE_PSCAN }, /* Bit 5 */ @@ -354,11 +386,16 @@ static hci_map lmp_features_map[8][9] = { { "", LMP_EV5 }, /* Bit 1 */ { "", LMP_AFH_CAP_SLV }, /* Bit 3 */ { "", LMP_AFH_CLS_SLV }, /* Bit 4 */ + { "<3-slot EDR ACL>", LMP_EDR_3SLOT }, /* Bit 7 */ { NULL } }, { /* Byte 5 */ + { "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */ { "", LMP_AFH_CAP_MST }, /* Bit 3 */ { "",LMP_AFH_CLS_MST }, /* Bit 4 */ + { "", LMP_EDR_ESCO_2M }, /* Bit 5 */ + { "", LMP_EDR_ESCO_3M }, /* Bit 6 */ + { "<3-slot EDR eSCO>", LMP_EDR_3S_ESCO }, /* Bit 7 */ { NULL } }, { /* Byte 6 */ -- cgit From 9717723fd7bdc64648c258967911d0932248cf1f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Apr 2004 14:10:03 +0000 Subject: Better display of decoded LMP features --- src/hci.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index f1e278cb..5acbe7cd 100644 --- a/src/hci.c +++ b/src/hci.c @@ -409,8 +409,8 @@ static hci_map lmp_features_map[8][9] = { char *lmp_featurestostr(uint8_t *features, char *pref, int width) { - char *ptr, *str = malloc(400); - int i, w; + char *off, *ptr, *str = malloc(400); + int i; if (!str) return NULL; @@ -420,16 +420,19 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) if (pref) ptr += sprintf(ptr, "%s", pref); - for (i = 0, w = 0; i < 8; i++) { + off = ptr; + + for (i = 0; i < 8; i++) { hci_map *m; m = lmp_features_map[i]; while (m->str) { if ((unsigned int) m->val & (unsigned int) features[i]) { - ptr += sprintf(ptr, "%s ", m->str); - w = (w + 1) & width; - if (!w) + if (strlen(off) + strlen(m->str) > width - 1) { ptr += sprintf(ptr, "\n%s", pref ? pref : ""); + off = ptr; + } + ptr += sprintf(ptr, "%s ", m->str); } m++; } -- cgit From 233bd39dee08afc5176b203e6348184da56d7bff Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 May 2004 21:40:30 +0000 Subject: Add sdp_get_add_access_protos() function --- src/sdp.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 6740e9d6..75c8edcb 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -1310,6 +1310,30 @@ int sdp_get_access_protos(const sdp_record_t *rec, sdp_list_t **pap) return 0; } +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; + } + SDPDBG("AP type : 0%x\n", pdlist->dtd); + + 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_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **seqp) { sdp_data_t *sdpdata = sdp_data_get(rec, attr); -- cgit From 2d0aca374edda17c9dfb547679b8f03feacf616e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 8 May 2004 18:17:29 +0000 Subject: Update company identifiers --- src/bluetooth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 61a632a5..1cd247d6 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -176,7 +176,7 @@ char *bt_compidtostr(int compid) { switch (compid) { case 0: - return "Ericsson Mobile Comunications"; + return "Ericsson Technology Licensing"; case 1: return "Nokia Mobile Phones"; case 2: @@ -212,7 +212,7 @@ char *bt_compidtostr(int compid) case 17: return "Widcomm, Inc."; case 18: - return "Telencomm Inc."; + return "Zeevo, Inc."; case 19: return "Atmel Corporation"; case 20: -- cgit From 15f0222e04e33cbfc622007d6bac851e44477dd9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 8 May 2004 20:22:26 +0000 Subject: Update library version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 17fdbf6d..73b6854f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libsdp.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:4:0 +libbluetooth_la_LDFLAGS = -version-info 1:7:0 libsdp_la_SOURCES = libsdp_la_LDFLAGS = -version-info 2:2:0 -- cgit From a315030f93449c55905df6b0b8b85f2c6260b838 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Jul 2004 15:58:33 +0000 Subject: Update library version number and remove dummy libsdp --- src/Makefile.am | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 73b6854f..119b3762 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,12 +2,9 @@ # $Id$ # -lib_LTLIBRARIES = libbluetooth.la libsdp.la +lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:7:0 - -libsdp_la_SOURCES = -libsdp_la_LDFLAGS = -version-info 2:2:0 +libbluetooth_la_LDFLAGS = -version-info 1:8:0 INCLUDES = -I$(top_builddir)/include -- cgit From 3429ef600fcef09e96408f8b476ead6cb519cf83 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Jul 2004 13:30:34 +0000 Subject: Make use of MAINTAINERCLEANFILES --- src/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 119b3762..46985678 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,3 +8,5 @@ libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c libbluetooth_la_LDFLAGS = -version-info 1:8:0 INCLUDES = -I$(top_builddir)/include + +MAINTAINERCLEANFILES = Makefile.in -- cgit From a8efcfa5ca81ef29e4d56dac70761d9b9ffc9708 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 22 Jul 2004 18:08:49 +0000 Subject: UUID32 values can also be used as protocol identifiers --- src/sdp.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 75c8edcb..9cb2230a 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2069,14 +2069,14 @@ int sdp_uuid128_to_uuid(uuid_t *uuid) uint128_t *b = sdp_create_base_uuid(); uint128_t *u = &uuid->value.uuid128; uint32_t data; - + if (uuid->type != SDP_UUID128) return 1; - + for (i = 4; i < sizeof(b->data); i++) if (b->data[i] != u->data[i]) return 0; - + memcpy(&data, u->data, 4); data = htonl(data); if (data <= 0xffff) { @@ -2095,8 +2095,14 @@ int sdp_uuid128_to_uuid(uuid_t *uuid) int sdp_uuid_to_proto(uuid_t *uuid) { uuid_t u = *uuid; - if (sdp_uuid128_to_uuid(&u) && u.type == SDP_UUID16) - return u.value.uuid16; + if (sdp_uuid128_to_uuid(&u)) { + switch (u.type) { + case SDP_UUID16: + return u.value.uuid16; + case SDP_UUID32: + return u.value.uuid32; + } + } return 0; } -- cgit From 1590d5be4605667ca2b405172d99a65c814723b2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 Jul 2004 13:35:42 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 46985678..4bca9333 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:8:0 +libbluetooth_la_LDFLAGS = -version-info 1:9:0 INCLUDES = -I$(top_builddir)/include -- cgit From c64da0295f5260a07d56dfd6df14d7369859164a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 13 Aug 2004 13:48:14 +0000 Subject: Update library version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 4bca9333..414c7b53 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:9:0 +libbluetooth_la_LDFLAGS = -version-info 1:10:0 INCLUDES = -I$(top_builddir)/include -- cgit From a867781820a4b7a85031c54fe38399c33affdb9c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 6 Oct 2004 17:39:53 +0000 Subject: Add support for the kernel security manager --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 5acbe7cd..43baa7b7 100644 --- a/src/hci.c +++ b/src/hci.c @@ -173,6 +173,7 @@ static hci_map dev_flags_map[] = { { "INQUIRY", HCI_INQUIRY }, { "AUTH", HCI_AUTH }, { "ENCRYPT", HCI_ENCRYPT }, + { "SECMGR", HCI_SECMGR }, { NULL } }; -- cgit From 735e59b37803748fea1077de064b285f78de1c10 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 13 Oct 2004 12:03:16 +0000 Subject: Add SIM Access types --- src/sdp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 9cb2230a..971644ba 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -104,6 +104,7 @@ static struct tupla ServiceClass[] = { { GN_SVCLASS_ID, "PAN group network" }, { HID_SVCLASS_ID, "Human Interface Device" }, { CIP_SVCLASS_ID, "Common ISDN Access" }, + { SAP_SVCLASS_ID, "SIM Access" }, { 0 } }; @@ -123,8 +124,9 @@ static struct tupla Profile[] = { { PANU_PROFILE_ID, "PAN user" }, { NAP_PROFILE_ID, "PAN access point" }, { GN_PROFILE_ID, "PAN group network" }, - { HID_SVCLASS_ID, "Human Interface Device" }, - { CIP_SVCLASS_ID, "Common ISDN Access" }, + { HID_PROFILE_ID, "Human Interface Device" }, + { CIP_PROFILE_ID, "Common ISDN Access" }, + { SAP_PROFILE_ID, "SIM Access" }, { 0 } }; -- cgit From cc0deab6cac822b062e1c6ab7322d1e1d75d463e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 06:44:47 +0000 Subject: Cleanup the API to prevent endian bugs --- src/hci.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 43baa7b7..ffa453f3 100644 --- a/src/hci.c +++ b/src/hci.c @@ -537,7 +537,7 @@ int hci_devinfo(int dev_id, struct hci_dev_info *di) return err; } -int hci_devba(int dev_id, bdaddr_t *ba) +int hci_devba(int dev_id, bdaddr_t *bdaddr) { struct hci_dev_info di; @@ -549,7 +549,7 @@ int hci_devba(int dev_id, bdaddr_t *ba) return -1; } - bacpy(ba, &di.bdaddr); + bacpy(bdaddr, &di.bdaddr); return 0; } @@ -783,14 +783,14 @@ done: return 0; } -int hci_create_connection(int dd, const bdaddr_t *ba, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) +int hci_create_connection(int dd, const bdaddr_t *bdaddr, uint16_t ptype, uint16_t clkoffset, uint8_t rswitch, uint16_t *handle, int to) { evt_conn_complete rp; create_conn_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - bacpy(&cp.bdaddr, ba); + bacpy(&cp.bdaddr, bdaddr); cp.pkt_type = ptype; cp.pscan_rep_mode = 0x02; cp.clock_offset = clkoffset; @@ -892,19 +892,19 @@ int hci_write_local_name(int dd, const char *name, int to) return 0; } -int hci_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to) +int hci_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) { - return hci_read_remote_name(dd, ba, len, name, to); + return hci_read_remote_name(dd, bdaddr, len, name, to); } -int hci_read_remote_name(int dd, const bdaddr_t *ba, int len, char *name, int to) +int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - bacpy(&cp.bdaddr, ba); + bacpy(&cp.bdaddr, bdaddr); cp.pscan_rep_mode = 0x02; memset(&rq, 0, sizeof(rq)); @@ -1121,6 +1121,7 @@ int hci_write_voice_setting(int dd, uint16_t vs, int to) rq.ocf = OCF_WRITE_VOICE_SETTING; rq.cparam = &cp; rq.clen = WRITE_VOICE_SETTING_CP_SIZE; + return hci_send_req(dd, &rq, to); } @@ -1162,6 +1163,7 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; rq.cparam = &cp; rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + return hci_send_req(dd, &rq, to); } @@ -1179,32 +1181,37 @@ int hci_authenticate_link(int dd, uint16_t handle, int to) rq.rparam = &rp; rq.event = EVT_AUTH_COMPLETE; rq.rlen = EVT_AUTH_COMPLETE_SIZE; + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; } + return 0; } -int hci_encrypt_link(int dd, uint16_t handle, int on, int to) +int hci_encrypt_link(int dd, uint16_t handle, uint8_t encrypt, int to) { set_conn_encrypt_cp cp; evt_encrypt_change rp; struct hci_request rq; cp.handle = handle; - cp.encrypt = on; - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_SET_CONN_ENCRYPT; - rq.cparam = &cp; - rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - rq.event = EVT_ENCRYPT_CHANGE; - rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; - rq.rparam = &rp; + cp.encrypt = encrypt; + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.cparam = &cp; + rq.clen = SET_CONN_ENCRYPT_CP_SIZE; + rq.event = EVT_ENCRYPT_CHANGE; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; + rq.rparam = &rp; + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; @@ -1212,13 +1219,13 @@ int hci_encrypt_link(int dd, uint16_t handle, int on, int to) return 0; } -int hci_switch_role(int dd, bdaddr_t peer, int role, int to) +int hci_switch_role(int dd, bdaddr_t *bdaddr, uint8_t role, int to) { switch_role_cp cp; evt_role_change rp; struct hci_request rq; - cp.bdaddr = peer; + bacpy(&cp.bdaddr, bdaddr); cp.role = role; rq.ogf = OGF_LINK_POLICY; rq.ocf = OCF_SWITCH_ROLE; @@ -1227,12 +1234,15 @@ int hci_switch_role(int dd, bdaddr_t peer, int role, int to) rq.rparam = &rp; rq.rlen = EVT_ROLE_CHANGE_SIZE; rq.event = EVT_ROLE_CHANGE; + if (hci_send_req(dd, &rq, to) < 0) return -1; + if (rp.status) { errno = EIO; return -1; } + return 0; } -- cgit From 1a04074615c182634202f03fd74a73f62107b93c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Oct 2004 07:36:45 +0000 Subject: Add functions for reading and writing the inquiry mode --- src/hci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index ffa453f3..3ab433f0 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1305,3 +1305,54 @@ int hci_exit_park_mode(int dd, uint16_t handle, int to) return 0; } + +int hci_read_inquiry_mode(int dd, uint8_t *mode, int to) +{ + read_inquiry_mode_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + 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, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *mode = rp.mode; + return 0; +} + +int hci_write_inquiry_mode(int dd, uint8_t mode, int to) +{ + write_inquiry_mode_cp cp; + write_inquiry_mode_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.mode = mode; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQUIRY_MODE; + rq.cparam = &cp; + rq.clen = WRITE_INQUIRY_MODE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_INQUIRY_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} -- cgit From 11cc772e89c75f5bf58fd887befac4b88a25c91c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 26 Oct 2004 02:18:45 +0000 Subject: Add more audio/video profile translations --- src/sdp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 971644ba..28fffc6f 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -74,6 +74,8 @@ static struct tupla Protocol[] = { { WSP_UUID, "WSP" }, { BNEP_UUID, "BNEP" }, { HIDP_UUID, "HIDP" }, + { AVCTP_UUID, "AVCTP" }, + { AVDTP_UUID, "AVDTP" }, { CMTP_UUID, "CMTP" }, { 0 } }; @@ -91,6 +93,8 @@ static struct tupla ServiceClass[] = { { IRMC_SYNC_CMD_SVCLASS_ID, "IrMCSync Command" }, { HEADSET_SVCLASS_ID, "Headset" }, { CORDLESS_TELEPHONY_SVCLASS_ID,"Cordless Telephony" }, + { AUDIO_SOURCE_SVCLASS_ID, "Audio Source" }, + { AUDIO_SINK_SVCLASS_ID, "Audio Sink" }, { INTERCOM_SVCLASS_ID, "Intercom" }, { FAX_SVCLASS_ID, "Fax" }, { HEADSET_AGW_SVCLASS_ID, "Headset Audio Gateway" }, @@ -118,6 +122,7 @@ static struct tupla Profile[] = { { IRMC_SYNC_CMD_PROFILE_ID, "IrMCSync Command" }, { HEADSET_PROFILE_ID, "Headset" }, { CORDLESS_TELEPHONY_PROFILE_ID, "Cordless Telephony" }, + { ADVANCED_AUDIO_PROFILE_ID, "Advanced Audio" }, { INTERCOM_PROFILE_ID, "Intercom" }, { FAX_PROFILE_ID, "Fax" }, { HEADSET_AGW_PROFILE_ID, "Headset Audio Gateway" }, -- cgit From a01d0b2417283b208e951db3a950cc0374b44b61 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 26 Oct 2004 13:36:41 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 1cd247d6..22957c7f 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -297,6 +297,8 @@ char *bt_compidtostr(int compid) return "Gennum Corporation"; case 60: return "Research In Motion"; + case 61: + return "IPextreme, Inc."; case 65535: return "internal use"; default: -- cgit From 1eccad4e5bd6f163a44e7b6e772993db5a37cf69 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 26 Oct 2004 21:30:57 +0000 Subject: Correct typo in comment --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 3ab433f0..d3892bbc 100644 --- a/src/hci.c +++ b/src/hci.c @@ -643,7 +643,7 @@ int hci_close_dev(int dd) } /* HCI functions that require open device - * dd - Device descriptor returned by hci_dev_open. */ + * dd - Device descriptor returned by hci_open_dev. */ int hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) { -- cgit From e32d72e13f1ad2b8fb9d97f99e9c2bd5f94771f9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 28 Oct 2004 10:38:41 +0000 Subject: Delete comment for a no long used parameter --- src/sdp.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 28fffc6f..05cb4e97 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2565,11 +2565,6 @@ static int copy_cstate(char *pdata, const sdp_cstate_t *cstate) * This variable is set on a successful return if there are * non-zero service handles. It is a singly linked list of * service records (sdp_record_t *) - * - * uint16_t *handleCount - * This is a pointer to a 16 bit integer, which is set to - * indicate the number of service record handles present in - * rec_list */ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num, sdp_list_t **rsp) -- cgit From 599e9c7e04dd55654ba8664ef2eba467ea0de277 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 2 Nov 2004 11:04:19 +0000 Subject: Fix bug where htonl() should be used instead of htons() --- src/sdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 05cb4e97..e6035bf0 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -488,7 +488,7 @@ void sdp_set_seq_len(char *ptr, int length) case SDP_ALT32: case SDP_TEXT_STR32: case SDP_URL_STR32: - sdp_put_unaligned(htons(length), (uint32_t *)ptr); + sdp_put_unaligned(htonl(length), (uint32_t *)ptr); break; } } -- cgit From 9427f5dc51c6962692eecd7250f2a1130dbc49ad Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 4 Nov 2004 11:21:34 +0000 Subject: Add hci_change_link_key() function --- src/hci.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index d3892bbc..23f890a6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1174,12 +1174,13 @@ int hci_authenticate_link(int dd, uint16_t handle, int to) struct hci_request rq; cp.handle = handle; + rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_AUTH_REQUESTED; + rq.event = EVT_AUTH_COMPLETE; rq.cparam = &cp; rq.clen = AUTH_REQUESTED_CP_SIZE; rq.rparam = &rp; - rq.event = EVT_AUTH_COMPLETE; rq.rlen = EVT_AUTH_COMPLETE_SIZE; if (hci_send_req(dd, &rq, to) < 0) @@ -1201,13 +1202,14 @@ int hci_encrypt_link(int dd, uint16_t handle, uint8_t encrypt, int to) cp.handle = handle; cp.encrypt = encrypt; + rq.ogf = OGF_LINK_CTL; rq.ocf = OCF_SET_CONN_ENCRYPT; + rq.event = EVT_ENCRYPT_CHANGE; rq.cparam = &cp; rq.clen = SET_CONN_ENCRYPT_CP_SIZE; - rq.event = EVT_ENCRYPT_CHANGE; - rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; rq.rparam = &rp; + rq.rlen = EVT_ENCRYPT_CHANGE_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -1216,6 +1218,34 @@ int hci_encrypt_link(int dd, uint16_t handle, uint8_t encrypt, int to) errno = EIO; return -1; } + + return 0; +} + +int hci_change_link_key(int dd, uint16_t handle, int to) +{ + change_conn_link_key_cp cp; + evt_change_conn_link_key_complete rp; + struct hci_request rq; + + cp.handle = handle; + + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_CHANGE_CONN_LINK_KEY; + rq.event = EVT_CHANGE_CONN_LINK_KEY_COMPLETE; + rq.cparam = &cp; + rq.clen = CHANGE_CONN_LINK_KEY_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + return 0; } -- cgit From 52e03fab5cb877505e6a4c391b5b0456726ed162 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 8 Nov 2004 13:37:59 +0000 Subject: Add version identifier for Bluetooth 2.0 --- src/hci.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 23f890a6..5895563e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -312,9 +312,10 @@ int hci_strtolm(char *str, unsigned int *val) /* Version mapping */ static hci_map ver_map[] = { - { "1.0b", 0x00 }, - { "1.1", 0x01 }, - { "1.2", 0x02 }, + { "1.0b", 0x00 }, + { "1.1", 0x01 }, + { "1.2", 0x02 }, + { "2.0", 0x03 }, { NULL } }; -- cgit From 34fb9e62566cddafd8d4fea40e368434859ae25a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 8 Nov 2004 21:51:52 +0000 Subject: Change HCI_KEY_MISSING to HCI_PIN_OR_KEY_MISSING --- src/bluetooth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 22957c7f..00639d2d 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -121,7 +121,7 @@ int bt_error(uint16_t code) return EHOSTDOWN; case HCI_AUTHENTICATION_FAILURE: return EACCES; - case HCI_KEY_MISSING: + case HCI_PIN_OR_KEY_MISSING: return EINVAL; case HCI_MEMORY_FULL: return ENOMEM; -- cgit From c3b2524a78dc4d27025f6cd3c8f4c56f5de012ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 00:05:01 +0000 Subject: Add the missing HCI error codes --- src/bluetooth.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 00639d2d..20a1aee6 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -133,19 +133,25 @@ int bt_error(uint16_t code) case HCI_ACL_CONNECTION_EXISTS: return EALREADY; case HCI_COMMAND_DISALLOWED: + case HCI_TRANSACTION_COLLISION: + case HCI_ROLE_SWITCH_PENDING: return EBUSY; case HCI_REJECTED_LIMITED_RESOURCES: - case HCI_REJECTED_SECURITY: case HCI_REJECTED_PERSONAL: + case HCI_QOS_REJECTED: return ECONNREFUSED; case HCI_HOST_TIMEOUT: return ETIMEDOUT; case HCI_UNSUPPORTED_FEATURE: case HCI_QOS_NOT_SUPPORTED: case HCI_PAIRING_NOT_SUPPORTED: + case HCI_CLASSIFICATION_NOT_SUPPORTED: case HCI_UNSUPPORTED_LMP_PARAMETER_VALUE: + case HCI_PARAMETER_OUT_OF_RANGE: + case HCI_QOS_UNACCEPTABLE_PARAMETER: return EOPNOTSUPP; case HCI_INVALID_PARAMETERS: + case HCI_SLOT_VIOLATION: return EINVAL; case HCI_OE_USER_ENDED_CONNECTION: case HCI_OE_LOW_RESOURCES: @@ -155,7 +161,9 @@ int bt_error(uint16_t code) return ECONNABORTED; case HCI_REPEATED_ATTEMPTS: return ELOOP; + case HCI_REJECTED_SECURITY: case HCI_PAIRING_NOT_ALLOWED: + case HCI_INSUFFICIENT_SECURITY: return EACCES; case HCI_UNSUPPORTED_REMOTE_FEATURE: return EPROTONOSUPPORT; -- cgit From 0bae50cd5c691f338f6fa820a8b803a45c0de181 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 21:33:17 +0000 Subject: Add hci_{read|write}_afh_mode() functions --- src/hci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 5895563e..9ebd5a23 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1387,3 +1387,54 @@ int hci_write_inquiry_mode(int dd, uint8_t mode, int to) return 0; } + +int hci_read_afh_mode(int dd, uint8_t *mode, int to) +{ + read_afh_mode_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + 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, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *mode = rp.mode; + return 0; +} + +int hci_write_afh_mode(int dd, uint8_t mode, int to) +{ + write_afh_mode_cp cp; + write_afh_mode_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.mode = mode; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_AFH_MODE; + rq.cparam = &cp; + rq.clen = WRITE_AFH_MODE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_AFH_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} -- cgit From 213febe584cdd8c7b5fd2defc2d56f0c84677e51 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 22:29:55 +0000 Subject: Add hci_read_afh_map() function --- src/hci.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 9ebd5a23..ee8dce2f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1438,3 +1438,29 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } + +int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int to) +{ + read_afh_map_rp rp; + struct hci_request rq; + + 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, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *mode = rp.mode; + memcpy(map, rp.map, 10); + return 0; +} -- cgit From 0792c0b319112503dd5129f05536f3c6ae4c746c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 9 Nov 2004 22:52:40 +0000 Subject: Add hci_set_afh_classification() function --- src/hci.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index ee8dce2f..19ee3c4c 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1439,6 +1439,34 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } +int hci_set_afh_classification(int dd, uint8_t *map, int to) +{ + set_afh_classification_cp cp; + set_afh_classification_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + memcpy(cp.map, map, 10); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_SET_AFH_CLASSIFICATION; + rq.cparam = &cp; + rq.clen = SET_AFH_CLASSIFICATION_CP_SIZE; + rq.rparam = &rp; + rq.rlen = SET_AFH_CLASSIFICATION_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int to) { read_afh_map_rp rp; -- cgit From 9dbfdb30dc538930eadd36df65917b1e68f7558a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 11 Nov 2004 18:03:20 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 414c7b53..fad7b418 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:10:0 +libbluetooth_la_LDFLAGS = -version-info 1:11:0 INCLUDES = -I$(top_builddir)/include -- cgit From 0ea7064b34d9f03e9aa7d8abeb7c0e6bcc8a37ac Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 29 Nov 2004 03:48:21 +0000 Subject: Add service classes and profile ids for WAP --- src/sdp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index e6035bf0..a830cf8b 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -98,6 +98,8 @@ static struct tupla ServiceClass[] = { { INTERCOM_SVCLASS_ID, "Intercom" }, { FAX_SVCLASS_ID, "Fax" }, { HEADSET_AGW_SVCLASS_ID, "Headset Audio Gateway" }, + { WAP_SVCLASS_ID, "WAP" }, + { WAP_CLIENT_SVCLASS_ID, "WAP Client" }, { PNP_INFO_SVCLASS_ID, "PnP Information" }, { GENERIC_NETWORKING_SVCLASS_ID,"Generic Networking" }, { GENERIC_FILETRANS_SVCLASS_ID, "Generic File Transfer" }, @@ -126,6 +128,8 @@ static struct tupla Profile[] = { { INTERCOM_PROFILE_ID, "Intercom" }, { FAX_PROFILE_ID, "Fax" }, { HEADSET_AGW_PROFILE_ID, "Headset Audio Gateway" }, + { WAP_PROFILE_ID, "WAP" }, + { WAP_CLIENT_PROFILE_ID, "WAP Client" }, { PANU_PROFILE_ID, "PAN user" }, { NAP_PROFILE_ID, "PAN access point" }, { GN_PROFILE_ID, "PAN group network" }, -- cgit From 603532d2b4141998d2c943c0b5f4077e27f6060f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 1 Dec 2004 14:48:16 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index fad7b418..d805a0ce 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:11:0 +libbluetooth_la_LDFLAGS = -version-info 1:12:0 INCLUDES = -I$(top_builddir)/include -- cgit From 6864c723272d4790a2fec4a1c23fa5e46ac15e5f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Dec 2004 11:29:58 +0000 Subject: Update the UUID constants and its translations --- src/sdp.c | 160 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 88 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index a830cf8b..7c3bd7d7 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -60,91 +60,105 @@ struct tupla { }; static struct tupla Protocol[] = { - { SDP_UUID, "SDP" }, - { RFCOMM_UUID, "RFCOMM" }, - { TCS_BIN_UUID, "TCS-BIN" }, - { L2CAP_UUID, "L2CAP" }, - { IP_UUID, "IP" }, - { UDP_UUID, "UDP" }, - { TCP_UUID, "TCP" }, - { TCS_AT_UUID, "TCS-AT" }, - { OBEX_UUID, "OBEX" }, - { FTP_UUID, "FTP" }, - { HTTP_UUID, "HTTP" }, - { WSP_UUID, "WSP" }, - { BNEP_UUID, "BNEP" }, - { HIDP_UUID, "HIDP" }, - { AVCTP_UUID, "AVCTP" }, - { AVDTP_UUID, "AVDTP" }, - { CMTP_UUID, "CMTP" }, + { SDP_UUID, "SDP" }, + { UDP_UUID, "UDP" }, + { RFCOMM_UUID, "RFCOMM" }, + { TCP_UUID, "TCP" }, + { TCS_BIN_UUID, "TCS-BIN" }, + { TCS_AT_UUID, "TCS-AT" }, + { OBEX_UUID, "OBEX" }, + { IP_UUID, "IP" }, + { FTP_UUID, "FTP" }, + { HTTP_UUID, "HTTP" }, + { WSP_UUID, "WSP" }, + { BNEP_UUID, "BNEP" }, + { UPNP_UUID, "UPNP" }, + { HIDP_UUID, "HIDP" }, + { HCRP_CTRL_UUID, "HCRP-Ctrl" }, + { HCRP_DATA_UUID, "HCRP-Data" }, + { HCRP_NOTE_UUID, "HCRP-Notify" }, + { AVCTP_UUID, "AVCTP" }, + { AVDTP_UUID, "AVDTP" }, + { CMTP_UUID, "CMTP" }, + { UDI_UUID, "UDI" }, + { L2CAP_UUID, "L2CAP" }, { 0 } }; static struct tupla ServiceClass[] = { - { SDP_SERVER_SVCLASS_ID, "SDP Server" }, - { BROWSE_GRP_DESC_SVCLASS_ID, "Browse Group Descriptor" }, - { PUBLIC_BROWSE_GROUP, "Public Browse Group" }, - { SERIAL_PORT_SVCLASS_ID, "Serial Port" }, - { LAN_ACCESS_SVCLASS_ID, "LAN Access Using PPP" }, - { DIALUP_NET_SVCLASS_ID, "Dialup Networking" }, - { IRMC_SYNC_SVCLASS_ID, "IrMCSync" }, - { OBEX_OBJPUSH_SVCLASS_ID, "OBEX Object Push" }, - { OBEX_FILETRANS_SVCLASS_ID, "OBEX File Transfer" }, - { IRMC_SYNC_CMD_SVCLASS_ID, "IrMCSync Command" }, - { HEADSET_SVCLASS_ID, "Headset" }, - { CORDLESS_TELEPHONY_SVCLASS_ID,"Cordless Telephony" }, - { AUDIO_SOURCE_SVCLASS_ID, "Audio Source" }, - { AUDIO_SINK_SVCLASS_ID, "Audio Sink" }, - { INTERCOM_SVCLASS_ID, "Intercom" }, - { FAX_SVCLASS_ID, "Fax" }, - { HEADSET_AGW_SVCLASS_ID, "Headset Audio Gateway" }, - { WAP_SVCLASS_ID, "WAP" }, - { WAP_CLIENT_SVCLASS_ID, "WAP Client" }, - { PNP_INFO_SVCLASS_ID, "PnP Information" }, - { GENERIC_NETWORKING_SVCLASS_ID,"Generic Networking" }, - { GENERIC_FILETRANS_SVCLASS_ID, "Generic File Transfer" }, - { GENERIC_AUDIO_SVCLASS_ID, "Generic Audio" }, - { GENERIC_TELEPHONY_SVCLASS_ID, "Generic Telephony" }, - { PANU_SVCLASS_ID, "PAN user" }, - { NAP_SVCLASS_ID, "Network access point" }, - { GN_SVCLASS_ID, "PAN group network" }, - { HID_SVCLASS_ID, "Human Interface Device" }, - { CIP_SVCLASS_ID, "Common ISDN Access" }, - { SAP_SVCLASS_ID, "SIM Access" }, + { SDP_SERVER_SVCLASS_ID, "SDP Server" }, + { BROWSE_GRP_DESC_SVCLASS_ID, "Browse Group Descriptor" }, + { PUBLIC_BROWSE_GROUP, "Public Browse Group" }, + { SERIAL_PORT_SVCLASS_ID, "Serial Port" }, + { LAN_ACCESS_SVCLASS_ID, "LAN Access Using PPP" }, + { DIALUP_NET_SVCLASS_ID, "Dialup Networking" }, + { IRMC_SYNC_SVCLASS_ID, "IrMC Sync" }, + { OBEX_OBJPUSH_SVCLASS_ID, "OBEX Object Push" }, + { OBEX_FILETRANS_SVCLASS_ID, "OBEX File Transfer" }, + { IRMC_SYNC_CMD_SVCLASS_ID, "IrMC Sync Command" }, + { HEADSET_SVCLASS_ID, "Headset" }, + { CORDLESS_TELEPHONY_SVCLASS_ID, "Cordless Telephony" }, + { AUDIO_SOURCE_SVCLASS_ID, "Audio Source" }, + { AUDIO_SINK_SVCLASS_ID, "Audio Sink" }, + { AV_REMOTE_TARGET_SVCLASS_ID, "AV Remote Target" }, + { ADVANCED_AUDIO_SVCLASS_ID, "Advanced Audio" }, + { AV_REMOTE_SVCLASS_ID, "AV Remote" }, + { VIDEO_CONF_SVCLASS_ID, "Video Conferencing" }, + { INTERCOM_SVCLASS_ID, "Intercom" }, + { FAX_SVCLASS_ID, "Fax" }, + { HEADSET_AGW_SVCLASS_ID, "Headset Audio Gateway" }, + { WAP_SVCLASS_ID, "WAP" }, + { WAP_CLIENT_SVCLASS_ID, "WAP Client" }, + { PANU_SVCLASS_ID, "PAN User" }, + { NAP_SVCLASS_ID, "Network Access Point" }, + { GN_SVCLASS_ID, "PAN Group Network" }, + { DIRECT_PRINTING_SVCLASS_ID, "Direct Printing" }, + { REFERENCE_PRINTING_SVCLASS_ID, "Reference Printing" }, + { IMAGING_SVCLASS_ID, "Imaging" }, + { IMAGING_RESPONDER_SVCLASS_ID, "Imaging Responder" }, + { IMAGING_ARCHIVE_SVCLASS_ID, "Imaging Automatic Archive" }, + { IMAGING_REFOBJS_SVCLASS_ID, "Imaging Referenced Objects" }, + { HANDSFREE_SVCLASS_ID, "Handsfree" }, + { HANDSFREE_AGW_SVCLASS_ID, "Handfree Audio Gateway" }, + { DIRECT_PRT_REFOBJS_SVCLASS_ID, "Direct Printing Ref. Objects" }, + { REFLECTED_UI_SVCLASS_ID, "Reflected UI" }, + { BASIC_PRINTING_SVCLASS_ID, "Basic Printing" }, + { PRINTING_STATUS_SVCLASS_ID, "Printing Status" }, + { HID_SVCLASS_ID, "Human Interface Device" }, + { HCR_SVCLASS_ID, "Hardcopy Cable Replacement" }, + { HCR_PRINT_SVCLASS_ID, "HCR Print" }, + { HCR_SCAN_SVCLASS_ID, "HCR Scan" }, + { CIP_SVCLASS_ID, "Common ISDN Access" }, + { VIDEO_CONF_GW_SVCLASS_ID, "Video Conferencing Gateway" }, + { UDI_MT_SVCLASS_ID, "UDI MT" }, + { UDI_TA_SVCLASS_ID, "UDI TA" }, + { AV_SVCLASS_ID, "Audio/Video" }, + { SAP_SVCLASS_ID, "SIM Access" }, + { PNP_INFO_SVCLASS_ID, "PnP Information" }, + { GENERIC_NETWORKING_SVCLASS_ID, "Generic Networking" }, + { GENERIC_FILETRANS_SVCLASS_ID, "Generic File Transfer" }, + { GENERIC_AUDIO_SVCLASS_ID, "Generic Audio" }, + { GENERIC_TELEPHONY_SVCLASS_ID, "Generic Telephony" }, + { UPNP_SVCLASS_ID, "UPnP" }, + { UPNP_IP_SVCLASS_ID, "UPnP IP" }, + { UPNP_PAN_SVCLASS_ID, "UPnP PAN" }, + { UPNP_LAP_SVCLASS_ID, "UPnP LAP" }, + { UPNP_L2CAP_SVCLASS_ID, "UPnP L2CAP" }, + { VIDEO_SOURCE_SVCLASS_ID, "Video Source" }, + { VIDEO_SINK_SVCLASS_ID, "Video Sink" }, { 0 } }; -static struct tupla Profile[] = { - { SERIAL_PORT_PROFILE_ID, "Serial Port" }, - { LAN_ACCESS_PROFILE_ID, "LAN Access Using PPP" }, - { DIALUP_NET_PROFILE_ID, "Dialup Networking" }, - { IRMC_SYNC_PROFILE_ID, "IrMCSync" }, - { OBEX_OBJPUSH_PROFILE_ID, "OBEX Object Push" }, - { OBEX_FILETRANS_PROFILE_ID, "OBEX File Transfer" }, - { IRMC_SYNC_CMD_PROFILE_ID, "IrMCSync Command" }, - { HEADSET_PROFILE_ID, "Headset" }, - { CORDLESS_TELEPHONY_PROFILE_ID, "Cordless Telephony" }, - { ADVANCED_AUDIO_PROFILE_ID, "Advanced Audio" }, - { INTERCOM_PROFILE_ID, "Intercom" }, - { FAX_PROFILE_ID, "Fax" }, - { HEADSET_AGW_PROFILE_ID, "Headset Audio Gateway" }, - { WAP_PROFILE_ID, "WAP" }, - { WAP_CLIENT_PROFILE_ID, "WAP Client" }, - { PANU_PROFILE_ID, "PAN user" }, - { NAP_PROFILE_ID, "PAN access point" }, - { GN_PROFILE_ID, "PAN group network" }, - { HID_PROFILE_ID, "Human Interface Device" }, - { CIP_PROFILE_ID, "Common ISDN Access" }, - { SAP_PROFILE_ID, "SIM Access" }, - { 0 } -}; +#define Profile ServiceClass static char *string_lookup(struct tupla *pt0, int index) { struct tupla *pt; + for (pt = pt0; pt->index; pt++) - if (pt->index == index) + if (pt->index == index) return pt->str; + return ""; } @@ -160,6 +174,7 @@ static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t snprintf(str, n, "NULL"); return -2; } + switch (uuid->type) { case SDP_UUID16: str2 = string_lookup(message, uuid->value.uuid16); @@ -175,6 +190,7 @@ static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); return -1; } + return 0; } -- cgit From 0e6eb45baedd15cc65beb454ec00cefb5fb7962d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 10 Dec 2004 09:05:49 +0000 Subject: Fix UUID-32 to string translation --- src/sdp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 7c3bd7d7..f138f1b3 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -181,10 +181,11 @@ static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t snprintf(str, n, str2); break; case SDP_UUID32: - snprintf(str, n, "Error: This is uuid32"); - return -3; + str2 = string_lookup(message, uuid->value.uuid32); + snprintf(str, n, str2); + break; case SDP_UUID128: - snprintf(str, n, "Error: This is uuid128"); + snprintf(str, n, "Error: This is UUID-128"); return -4; default: snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); -- cgit From 43e9e65bd31bb549babf77b33587243b1824b6c5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 25 Dec 2004 17:27:06 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index d805a0ce..508eaa98 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:12:0 +libbluetooth_la_LDFLAGS = -version-info 1:13:0 INCLUDES = -I$(top_builddir)/include -- cgit From 6c2fed4529b256285e495ccdb066de331db42ff4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 20:05:05 +0000 Subject: Remove deprecated functions --- src/hci.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 19ee3c4c..5d11309f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -55,7 +55,8 @@ #include typedef struct { - char *str; unsigned int val; + char *str; + unsigned int val; } hci_map; static char *hci_bit2str(hci_map *m, unsigned int val) @@ -255,11 +256,11 @@ int hci_strtoscoptype(char *str, unsigned int *val) /* Link policy mapping */ static hci_map link_policy_map[] = { - { "NONE", 0 }, - { "RSWITCH", HCI_LP_RSWITCH }, - { "HOLD", HCI_LP_HOLD }, - { "SNIFF", HCI_LP_SNIFF }, - { "PARK", HCI_LP_PARK }, + { "NONE", 0 }, + { "RSWITCH", HCI_LP_RSWITCH }, + { "HOLD", HCI_LP_HOLD }, + { "SNIFF", HCI_LP_SNIFF }, + { "PARK", HCI_LP_PARK }, { NULL } }; @@ -275,12 +276,14 @@ int hci_strtolp(char *str, unsigned int *val) /* Link mode mapping */ static hci_map link_mode_map[] = { - { "NONE", 0 }, - { "ACCEPT", HCI_LM_ACCEPT }, - { "MASTER", HCI_LM_MASTER }, - { "AUTH", HCI_LM_AUTH }, - { "ENCRYPT", HCI_LM_ENCRYPT}, - { "TRUSTED", HCI_LM_TRUSTED}, + { "NONE", 0 }, + { "ACCEPT", HCI_LM_ACCEPT }, + { "MASTER", HCI_LM_MASTER }, + { "AUTH", HCI_LM_AUTH }, + { "ENCRYPT", HCI_LM_ENCRYPT }, + { "TRUSTED", HCI_LM_TRUSTED }, + { "RELIABLE", HCI_LM_RELIABLE }, + { "SECURE", HCI_LM_SECURE }, { NULL } }; @@ -847,11 +850,6 @@ int hci_disconnect(int dd, uint16_t handle, uint8_t reason, int to) return 0; } -int hci_local_name(int dd, int len, char *name, int to) -{ - return hci_read_local_name(dd, len, name, to); -} - int hci_read_local_name(int dd, int len, char *name, int to) { read_local_name_rp rp; @@ -893,11 +891,6 @@ int hci_write_local_name(int dd, const char *name, int to) return 0; } -int hci_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) -{ - return hci_read_remote_name(dd, bdaddr, len, name, to); -} - int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) { evt_remote_name_req_complete rn; -- cgit From 32c8a21b7da2397da204015f4bf45983226cbed9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 20:16:40 +0000 Subject: Add function for reading the RSSI and the link quality --- src/hci.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 5d11309f..63a79d06 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1460,6 +1460,56 @@ int hci_set_afh_classification(int dd, uint8_t *map, int to) return 0; } +int hci_read_link_quality(int dd, uint16_t handle, uint8_t *link_quality, int to) +{ + read_link_quality_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_LINK_QUALITY; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_LINK_QUALITY_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *link_quality = rp.link_quality; + return 0; +} + +int hci_read_rssi(int dd, uint16_t handle, int8_t *rssi, int to) +{ + read_rssi_rp rp; + struct hci_request rq; + + 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, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *rssi = rp.rssi; + return 0; +} + int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int to) { read_afh_map_rp rp; -- cgit From 3d400b430ca82b915570be699d98b10648c593ac Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:37:58 +0000 Subject: Add link supervision timeout functions --- src/hci.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 63a79d06..10f4fcb6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1432,6 +1432,60 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } +int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout, int to) +{ + read_link_supervision_timeout_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + 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, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *timeout = rp.link_sup_to; + return 0; +} + +int hci_write_link_supervision_timeout(int dd, uint16_t handle, uint16_t timeout, int to) +{ + write_link_supervision_timeout_cp cp; + write_link_supervision_timeout_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.link_sup_to = timeout; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; + rq.cparam = &cp; + rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_set_afh_classification(int dd, uint8_t *map, int to) { set_afh_classification_cp cp; -- cgit From 864124c296636015f90e26512143cf2c297ed6d2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:46:41 +0000 Subject: The link supervision timeout is host control --- src/hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 10f4fcb6..ca53105e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1438,7 +1438,7 @@ int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout struct hci_request rq; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_READ_LINK_SUPERVISION_TIMEOUT; rq.cparam = &handle; rq.clen = 2; @@ -1468,7 +1468,7 @@ int hci_write_link_supervision_timeout(int dd, uint16_t handle, uint16_t timeout cp.link_sup_to = timeout; memset(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; + rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_LINK_SUPERVISION_TIMEOUT; rq.cparam = &cp; rq.clen = WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE; -- cgit From 84cc44acd712f84ff544b7e1b96d1410c732dc8c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Jan 2005 22:57:36 +0000 Subject: Add function for reading the transmit power level --- src/hci.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index ca53105e..8e0b7938 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1432,6 +1432,36 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } +int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, uint8_t *level, int to) +{ + read_transmit_power_level_cp cp; + read_transmit_power_level_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.type = type; + + 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, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *level = rp.level; + return 0; +} + int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout, int to) { read_link_supervision_timeout_rp rp; -- cgit From 00bb0adf5a9c8dee2ed3b25ec0f3c1588f2c91ca Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 14 Jan 2005 00:04:29 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 508eaa98..bec2f2dc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:13:0 +libbluetooth_la_LDFLAGS = -version-info 1:14:0 INCLUDES = -I$(top_builddir)/include -- cgit From badafc6e227a175022370017008f0d839ec90b25 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Jan 2005 08:10:42 +0000 Subject: Add functions hci_{local|remote}_name() --- src/hci.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 8e0b7938..87f4874b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1619,3 +1619,13 @@ int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int t memcpy(map, rp.map, 10); return 0; } + +int hci_local_name(int dd, int len, char *name, int to) +{ + return hci_read_local_name(dd, len, name, to); +} + +int hci_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) +{ + return hci_read_remote_name(dd, bdaddr, len, name, to); +} -- cgit From aae7cfb9807fd7452e6662fc9f6c3ebe0e64dbf5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Jan 2005 14:33:58 +0000 Subject: Replace sdp_{get|put}_unaligned with bt_{get|put}_unaligned --- src/sdp.c | 180 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 90 insertions(+), 90 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index f138f1b3..6230edfe 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -304,7 +304,7 @@ sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) { sdp_data_t *seq; int len = 0; - sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); if (!d) return NULL; @@ -317,36 +317,36 @@ sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) case SDP_DATA_NIL: break; case SDP_UINT8: - d->val.uint8 = *(uint8_t *)value; + d->val.uint8 = *(uint8_t *) value; d->unitSize += sizeof(uint8_t); break; case SDP_INT8: case SDP_BOOL: - d->val.int8 = *(int8_t *)value; + d->val.int8 = *(int8_t *) value; d->unitSize += sizeof(int8_t); break; case SDP_UINT16: - d->val.uint16 = sdp_get_unaligned((uint16_t *)value); + d->val.uint16 = bt_get_unaligned((uint16_t *) value); d->unitSize += sizeof(uint16_t); break; case SDP_INT16: - d->val.int16 = sdp_get_unaligned((int16_t *)value); + d->val.int16 = bt_get_unaligned((int16_t *) value); d->unitSize += sizeof(int16_t); break; case SDP_UINT32: - d->val.uint32 = sdp_get_unaligned((uint32_t *)value); + d->val.uint32 = bt_get_unaligned((uint32_t *) value); d->unitSize += sizeof(uint32_t); break; case SDP_INT32: - d->val.int32 = sdp_get_unaligned((int32_t *)value); + d->val.int32 = bt_get_unaligned((int32_t *) value); d->unitSize += sizeof(int32_t); break; case SDP_INT64: - d->val.int64 = sdp_get_unaligned((int64_t *)value); + d->val.int64 = bt_get_unaligned((int64_t *) value); d->unitSize += sizeof(int64_t); break; case SDP_UINT64: - d->val.uint64 = sdp_get_unaligned((uint64_t *)value); + d->val.uint64 = bt_get_unaligned((uint64_t *) value); d->unitSize += sizeof(uint64_t); break; case SDP_UINT128: @@ -358,11 +358,11 @@ sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) d->unitSize += sizeof(uint128_t); break; case SDP_UUID16: - sdp_uuid16_create(&d->val.uuid, sdp_get_unaligned((uint16_t *)value)); + sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value)); d->unitSize += sizeof(uint16_t); break; case SDP_UUID32: - sdp_uuid32_create(&d->val.uuid, sdp_get_unaligned((uint32_t *)value)); + sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value)); d->unitSize += sizeof(uint32_t); break; case SDP_UUID128: @@ -379,7 +379,7 @@ sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) len = strlen(value); d->unitSize += len; if (len <= USHRT_MAX) { - d->val.str = (char *)malloc(len + 1); + d->val.str = (char *) malloc(len + 1); if (!d->val.str) goto out_error; @@ -490,26 +490,26 @@ void sdp_attr_remove(sdp_record_t *rec, uint16_t attr) void sdp_set_seq_len(char *ptr, int length) { - uint8_t dtd = *(uint8_t *)ptr++; + uint8_t dtd = *(uint8_t *) ptr++; switch (dtd) { case SDP_SEQ8: case SDP_ALT8: case SDP_TEXT_STR8: case SDP_URL_STR8: - *(uint8_t *)ptr = (uint8_t)length; + *(uint8_t *)ptr = (uint8_t) length; break; case SDP_SEQ16: case SDP_ALT16: case SDP_TEXT_STR16: case SDP_URL_STR16: - sdp_put_unaligned(htons(length), (uint16_t *)ptr); + bt_put_unaligned(htons(length), (uint16_t *) ptr); break; case SDP_SEQ32: case SDP_ALT32: case SDP_TEXT_STR32: case SDP_URL_STR32: - sdp_put_unaligned(htonl(length), (uint32_t *)ptr); + bt_put_unaligned(htonl(length), (uint32_t *) ptr); break; } } @@ -551,7 +551,7 @@ void sdp_set_attrid(sdp_buf_t *buf, uint16_t attr) // data type for attr *p++ = SDP_UINT16; buf->data_size = sizeof(uint8_t); - sdp_put_unaligned(htons(attr), (uint16_t *)p); + bt_put_unaligned(htons(attr), (uint16_t *) p); p += sizeof(uint16_t); buf->data_size += sizeof(uint16_t); } @@ -755,11 +755,11 @@ void sdp_data_free(sdp_data_t *d) static sdp_data_t *extract_int(const void *p, int *len) { - sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); SDPDBG("Extracting integer\n"); memset(d, 0, sizeof(sdp_data_t)); - d->dtd = *(uint8_t *)p; + d->dtd = *(uint8_t *) p; p += sizeof(uint8_t); *len += sizeof(uint8_t); @@ -770,27 +770,27 @@ static sdp_data_t *extract_int(const void *p, int *len) case SDP_INT8: case SDP_UINT8: *len += sizeof(uint8_t); - d->val.uint8 = *(uint8_t *)p; + d->val.uint8 = *(uint8_t *) p; break; case SDP_INT16: case SDP_UINT16: *len += sizeof(uint16_t); - d->val.uint16 = ntohs(sdp_get_unaligned((uint16_t *)p)); + d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p)); break; case SDP_INT32: case SDP_UINT32: *len += sizeof(uint32_t); - d->val.uint32 = ntohl(sdp_get_unaligned((uint32_t *)p)); + d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p)); break; case SDP_INT64: case SDP_UINT64: *len += sizeof(uint64_t); - d->val.uint64 = ntoh64(sdp_get_unaligned((uint64_t *)p)); + d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p)); break; case SDP_INT128: case SDP_UINT128: *len += sizeof(uint128_t); - ntoh128((uint128_t *)p, &d->val.uint128); + ntoh128((uint128_t *) p, &d->val.uint128); break; default: free(d); @@ -801,7 +801,7 @@ static sdp_data_t *extract_int(const void *p, int *len) static sdp_data_t *extract_uuid(const void *p, int *len, sdp_record_t *rec) { - sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); SDPDBG("Extracting UUID"); memset(d, 0, sizeof(sdp_data_t)); @@ -809,7 +809,7 @@ static sdp_data_t *extract_uuid(const void *p, int *len, sdp_record_t *rec) free(d); return NULL; } - d->dtd = *(uint8_t *)p; + d->dtd = *(uint8_t *) p; sdp_pattern_add_uuid(rec, &d->val.uuid); return d; } @@ -821,23 +821,23 @@ static sdp_data_t *extract_str(const void *p, int *len) { char *s; int n; - sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); memset(d, 0, sizeof(sdp_data_t)); - d->dtd = *(uint8_t *)p; + d->dtd = *(uint8_t *) p; p += sizeof(uint8_t); *len += sizeof(uint8_t); switch (d->dtd) { case SDP_TEXT_STR8: case SDP_URL_STR8: - n = *(uint8_t *)p; + n = *(uint8_t *) p; p += sizeof(uint8_t); *len += sizeof(uint8_t) + n; break; case SDP_TEXT_STR16: case SDP_URL_STR16: - n = ntohs(sdp_get_unaligned((uint16_t *)p)); + n = ntohs(bt_get_unaligned((uint16_t *) p)); p += sizeof(uint16_t); *len += sizeof(uint16_t) + n; break; @@ -984,13 +984,13 @@ sdp_record_t *sdp_extract_pdu(const char *buf, int *scanned) sdp_data_t *data = NULL; SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, extracted); - dtd = *(uint8_t *)p; - attr = ntohs(sdp_get_unaligned((uint16_t *)(p+n))); + dtd = *(uint8_t *) p; + attr = ntohs(bt_get_unaligned((uint16_t *) (p + n))); n += sizeof(uint16_t); SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr); - data = sdp_extract_attr(p+n, &attrlen, rec); + data = sdp_extract_attr(p + n, &attrlen, rec); SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen); @@ -1109,7 +1109,7 @@ sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId) */ int sdp_extract_seqtype(const char *buf, uint8_t *dtdp, int *size) { - uint8_t dtd = *(uint8_t *)buf; + uint8_t dtd = *(uint8_t *) buf; int scanned = sizeof(uint8_t); buf += sizeof(uint8_t); @@ -1117,17 +1117,17 @@ int sdp_extract_seqtype(const char *buf, uint8_t *dtdp, int *size) switch (dtd) { case SDP_SEQ8: case SDP_ALT8: - *size = *(uint8_t *)buf; + *size = *(uint8_t *) buf; scanned += sizeof(uint8_t); break; case SDP_SEQ16: case SDP_ALT16: - *size = ntohs(sdp_get_unaligned((uint16_t *)buf)); + *size = ntohs(bt_get_unaligned((uint16_t *) buf)); scanned += sizeof(uint16_t); break; case SDP_SEQ32: case SDP_ALT32: - *size = ntohl(sdp_get_unaligned((uint32_t *)buf)); + *size = ntohl(bt_get_unaligned((uint32_t *) buf)); scanned += sizeof(uint32_t); break; default: @@ -2136,7 +2136,7 @@ int sdp_uuid_to_proto(uuid_t *uuid) int sdp_uuid_extract(const char *p, uuid_t *uuid, int *scanned) { - uint8_t type = *(const uint8_t *)p; + uint8_t type = *(const uint8_t *) p; if (!SDP_IS_UUID(type)) { SDPERR("Unknown data type : %d expecting a svc UUID\n", type); @@ -2145,11 +2145,11 @@ int sdp_uuid_extract(const char *p, uuid_t *uuid, int *scanned) p += sizeof(uint8_t); *scanned += sizeof(uint8_t); if (type == SDP_UUID16) { - sdp_uuid16_create(uuid, ntohs(sdp_get_unaligned((uint16_t *)p))); + sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p))); *scanned += sizeof(uint16_t); p += sizeof(uint16_t); } else if (type == SDP_UUID32) { - sdp_uuid32_create(uuid, ntohl(sdp_get_unaligned((uint32_t *)p))); + sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p))); *scanned += sizeof(uint32_t); p += sizeof(uint32_t); } else { @@ -2169,7 +2169,7 @@ int sdp_uuid_extract(const char *p, uuid_t *uuid, int *scanned) void sdp_append_to_buf(sdp_buf_t *dst, char *data, int len) { char *p = dst->data; - uint8_t dtd = *(uint8_t *)p; + uint8_t dtd = *(uint8_t *) p; SDPDBG("Append src size: %d\n", len); SDPDBG("Append dst size: %d\n", dst->data_size); @@ -2203,22 +2203,22 @@ void sdp_append_to_buf(sdp_buf_t *dst, char *data, int len) short offset = sizeof(uint8_t) + sizeof(uint8_t); memmove(dst->data + offset + 1, dst->data + offset, dst->data_size - offset); p = dst->data; - *(uint8_t *)p = SDP_SEQ16; + *(uint8_t *) p = SDP_SEQ16; p += sizeof(uint8_t); dst->data_size += 1; } p = dst->data; - dtd = *(uint8_t *)p; + dtd = *(uint8_t *) p; p += sizeof(uint8_t); switch (dtd) { case SDP_SEQ8: - *(uint8_t *)p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t); + *(uint8_t *) p = dst->data_size - sizeof(uint8_t) - sizeof(uint8_t); break; case SDP_SEQ16: - sdp_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *)p); + bt_put_unaligned(htons(dst->data_size - sizeof(uint8_t) - sizeof(uint16_t)), (uint16_t *) p); break; case SDP_SEQ32: - sdp_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *)p); + bt_put_unaligned(htonl(dst->data_size - sizeof(uint8_t) - sizeof(uint32_t)), (uint32_t *) p); break; } } @@ -2260,8 +2260,8 @@ int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags errno = EREMOTE; return -1; } - req = (char *)malloc(SDP_REQ_BUFFER_SIZE); - rsp = (char *)malloc(SDP_RSP_BUFFER_SIZE); + req = (char *) malloc(SDP_REQ_BUFFER_SIZE); + rsp = (char *) malloc(SDP_RSP_BUFFER_SIZE); if (req == NULL || rsp == NULL) { status = -1; errno = ENOMEM; @@ -2286,10 +2286,10 @@ int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize); if (status < 0) goto end; - rsphdr = (sdp_pdu_hdr_t *)rsp; + rsphdr = (sdp_pdu_hdr_t *) rsp; p = rsp + sizeof(sdp_pdu_hdr_t); if (rsphdr->pdu_id == SDP_SVC_REGISTER_RSP) { - uint32_t handle = ntohl(sdp_get_unaligned((uint32_t *)p)); + uint32_t handle = ntohl(bt_get_unaligned((uint32_t *) p)); sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); rec->handle = handle; sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); @@ -2325,28 +2325,28 @@ int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) errno = EREMOTE; return -1; } - reqbuf = (char *)malloc(SDP_REQ_BUFFER_SIZE); - rspbuf = (char *)malloc(SDP_RSP_BUFFER_SIZE); + reqbuf = (char *) malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = (char *) malloc(SDP_RSP_BUFFER_SIZE); if (!reqbuf || !rspbuf) { errno = ENOMEM; status = -1; goto end; } - reqhdr = (sdp_pdu_hdr_t *)reqbuf; + reqhdr = (sdp_pdu_hdr_t *) reqbuf; reqhdr->pdu_id = SDP_SVC_REMOVE_REQ; reqhdr->tid = htons(sdp_gen_tid(session)); p = reqbuf + sizeof(sdp_pdu_hdr_t); reqsize = sizeof(sdp_pdu_hdr_t); - sdp_put_unaligned(htonl(handle), (uint32_t *)p); + bt_put_unaligned(htonl(handle), (uint32_t *) p); reqsize += sizeof(uint32_t); reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); if (status == 0) { - rsphdr = (sdp_pdu_hdr_t *)rspbuf; + rsphdr = (sdp_pdu_hdr_t *) rspbuf; p = rspbuf + sizeof(sdp_pdu_hdr_t); - status = sdp_get_unaligned((uint16_t *)p); + status = bt_get_unaligned((uint16_t *) p); if (status == 0 && rsphdr->pdu_id == SDP_SVC_REMOVE_RSP) { SDPDBG("Removing local copy\n"); sdp_record_free(rec); @@ -2384,21 +2384,21 @@ int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) errno = EREMOTE; return -1; } - reqbuf = (char *)malloc(SDP_REQ_BUFFER_SIZE); - rspbuf = (char *)malloc(SDP_RSP_BUFFER_SIZE); + reqbuf = (char *) malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = (char *) malloc(SDP_RSP_BUFFER_SIZE); if (!reqbuf || !rspbuf) { errno = ENOMEM; status = -1; goto end; } - reqhdr = (sdp_pdu_hdr_t *)reqbuf; + reqhdr = (sdp_pdu_hdr_t *) reqbuf; reqhdr->pdu_id = SDP_SVC_UPDATE_REQ; reqhdr->tid = htons(sdp_gen_tid(session)); - p = (char *)(reqbuf + sizeof(sdp_pdu_hdr_t)); + p = (char *) (reqbuf + sizeof(sdp_pdu_hdr_t)); reqsize = sizeof(sdp_pdu_hdr_t); - sdp_put_unaligned(htonl(handle), (uint32_t *)p); + bt_put_unaligned(htonl(handle), (uint32_t *) p); reqsize += sizeof(uint32_t); p += sizeof(uint32_t); @@ -2416,9 +2416,9 @@ int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) SDPDBG("Send req status : %d\n", status); if (status == 0) { - rsphdr = (sdp_pdu_hdr_t *)rspbuf; + rsphdr = (sdp_pdu_hdr_t *) rspbuf; p = rspbuf + sizeof(sdp_pdu_hdr_t); - status = sdp_get_unaligned((uint16_t *)p); + status = bt_get_unaligned((uint16_t *) p); } end: if (reqbuf) @@ -2484,7 +2484,7 @@ static void extract_record_handle_seq(char *pdu, sdp_list_t **seq, int count, in for (n = 0; n < count; n++) { uint32_t *pSvcRec = (uint32_t *) malloc(sizeof(uint32_t)); - *pSvcRec = ntohl(sdp_get_unaligned((uint32_t *)pdata)); + *pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata)); pSeq = sdp_list_append(pSeq, pSvcRec); pdata += sizeof(uint32_t); *scanned += sizeof(uint32_t); @@ -2607,7 +2607,7 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, status = -1; goto end; } - reqhdr = (sdp_pdu_hdr_t *)reqbuf; + reqhdr = (sdp_pdu_hdr_t *) reqbuf; reqhdr->pdu_id = SDP_SVC_SEARCH_REQ; pdata = reqbuf + sizeof(sdp_pdu_hdr_t); reqsize = sizeof(sdp_pdu_hdr_t); @@ -2622,7 +2622,7 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, pdata += seqlen; // specify the maximum svc rec count that client expects - sdp_put_unaligned(htons(max_rec_num), (uint16_t *)pdata); + bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata); reqsize += sizeof(uint16_t); pdata += sizeof(uint16_t); @@ -2647,7 +2647,7 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, goto end; rsplen = 0; - rsphdr = (sdp_pdu_hdr_t *)rspbuf; + rsphdr = (sdp_pdu_hdr_t *) rspbuf; rsplen = ntohs(rsphdr->plen); if (rsphdr->pdu_id == SDP_ERROR_RSP) { @@ -2659,10 +2659,10 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, pdata = rspbuf + sizeof(sdp_pdu_hdr_t); // net service record match count - total_rec_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); pdata += sizeof(uint16_t); scanned += sizeof(uint16_t); - rec_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); pdata += sizeof(uint16_t); scanned += sizeof(uint16_t); @@ -2681,7 +2681,7 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, uint8_t cstate_len; pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned; - cstate_len = *(uint8_t *)pdata; + cstate_len = *(uint8_t *) pdata; if (cstate_len > 0) { cstate = (sdp_cstate_t *)pdata; SDPDBG("Cont state length: %d\n", cstate_len); @@ -2752,27 +2752,27 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, return 0; } - reqbuf = (char *)malloc(SDP_REQ_BUFFER_SIZE); - rspbuf = (char *)malloc(SDP_RSP_BUFFER_SIZE); + reqbuf = (char *) malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = (char *) malloc(SDP_RSP_BUFFER_SIZE); if (!reqbuf || !rspbuf) { errno = ENOMEM; status = -1; goto end; } - memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t)); - reqhdr = (sdp_pdu_hdr_t *)reqbuf; + memset((char *) &rsp_concat_buf, 0, sizeof(sdp_buf_t)); + reqhdr = (sdp_pdu_hdr_t *) reqbuf; reqhdr->pdu_id = SDP_SVC_ATTR_REQ; pdata = reqbuf + sizeof(sdp_pdu_hdr_t); reqsize = sizeof(sdp_pdu_hdr_t); // add the service record handle - sdp_put_unaligned(htonl(handle), (uint32_t *)pdata); + bt_put_unaligned(htonl(handle), (uint32_t *) pdata); reqsize += sizeof(uint32_t); pdata += sizeof(uint32_t); // specify the response limit - sdp_put_unaligned(htons(65535), (uint16_t *)pdata); + bt_put_unaligned(htons(65535), (uint16_t *) pdata); reqsize += sizeof(uint16_t); pdata += sizeof(uint16_t); @@ -2804,19 +2804,19 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, if (status < 0) goto end; rsp_count = 0; - rsphdr = (sdp_pdu_hdr_t *)rspbuf; + rsphdr = (sdp_pdu_hdr_t *) rspbuf; if (rsphdr->pdu_id == SDP_ERROR_RSP) { SDPDBG("PDU ID : 0x%x\n", rsphdr->pdu_id); status = -1; goto end; } pdata = rspbuf + sizeof(sdp_pdu_hdr_t); - rsp_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); attr_list_len += rsp_count; pdata += sizeof(uint16_t); // if continuation state set need to re-issue request before parsing - cstate_len = *(uint8_t *)(pdata + rsp_count); + cstate_len = *(uint8_t *) (pdata + rsp_count); SDPDBG("Response id : %d\n", rsphdr->pdu_id); SDPDBG("Attrlist byte count : %d\n", rsp_count); @@ -2829,10 +2829,10 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { char *targetPtr = NULL; - cstate = cstate_len > 0? (sdp_cstate_t *)(pdata + rsp_count): 0; + cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; // build concatenated response buffer - rsp_concat_buf.data = (char *)realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); + rsp_concat_buf.data = (char *) realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; memcpy(targetPtr, pdata, rsp_count); @@ -2920,8 +2920,8 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search errno = EINVAL; return -1; } - reqbuf = (char *)malloc(SDP_REQ_BUFFER_SIZE); - rspbuf = (char *)malloc(SDP_RSP_BUFFER_SIZE); + reqbuf = (char *) malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = (char *) malloc(SDP_RSP_BUFFER_SIZE); if (!reqbuf || !rspbuf) { errno = ENOMEM; status = -1; @@ -2929,7 +2929,7 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search } memset((char *)&rsp_concat_buf, 0, sizeof(sdp_buf_t)); - reqhdr = (sdp_pdu_hdr_t *)reqbuf; + reqhdr = (sdp_pdu_hdr_t *) reqbuf; reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ; // generate PDU @@ -2945,7 +2945,7 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search reqsize += seqlen; pdata += seqlen; - sdp_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *)pdata); + bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata); reqsize += sizeof(uint16_t); pdata += sizeof(uint16_t); @@ -2953,7 +2953,7 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search // get attr seq PDU form seqlen = gen_attridseq_pdu(pdata, attrids, - reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16: SDP_UINT32); + reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32); if (seqlen == -1) { status = EINVAL; goto end; @@ -2975,7 +2975,7 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search // set the request header's param length reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); - rsphdr = (sdp_pdu_hdr_t *)rspbuf; + rsphdr = (sdp_pdu_hdr_t *) rspbuf; status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); if (status < 0) { SDPDBG("Status : 0x%x\n", rsphdr->pdu_id); @@ -2988,10 +2988,10 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search } pdata = rspbuf + sizeof(sdp_pdu_hdr_t); - rsp_count = ntohs(sdp_get_unaligned((uint16_t *)pdata)); + rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); attr_list_len += rsp_count; pdata += sizeof(uint16_t); // pdata points to attribute list - cstate_len = *(uint8_t *)(pdata + rsp_count); + cstate_len = *(uint8_t *) (pdata + rsp_count); SDPDBG("Attrlist byte count : %d\n", attr_list_len); SDPDBG("Response byte count : %d\n", rsp_count); @@ -3003,7 +3003,7 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { char *targetPtr = NULL; - cstate = cstate_len > 0? (sdp_cstate_t *)(pdata + rsp_count): 0; + cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; // build concatenated response buffer rsp_concat_buf.data = (char *)realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); -- cgit From 654f832d98530b05dc7ffaefff5950a32de76b3c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 23 Jan 2005 22:49:48 +0000 Subject: Remove sdp_internal.h --- src/sdp.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 6230edfe..6f8ce14b 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -47,12 +48,55 @@ #include #include #include -#include + +#include + +#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 + +#if __BYTE_ORDER == __BIG_ENDIAN +#define ntoh64(x) (x) +static inline void ntoh128(uint128_t *src, uint128_t *dst) +{ + int i; + for (i = 0; i < 16; i++) + dst->data[i] = src->data[i]; +} +#else +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; +} +static inline void ntoh128(uint128_t *src, uint128_t *dst) +{ + int i; + for (i = 0; i < 16; i++) + dst->data[15 - i] = src->data[i]; +} +#endif + +#define hton64(x) ntoh64(x) +#define hton128(x, y) ntoh128(x, y) #define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB" static uint128_t *bluetooth_base_uuid = NULL; +#define SDP_BASIC_ATTR_PDUFORM_SIZE 32 +#define SDP_SEQ_PDUFORM_SIZE 128 +#define SDP_UUID_SEQ_SIZE 256 +#define SDP_MAX_ATTR_LEN 65535 + /* Message structure. */ struct tupla { int index; -- cgit From 1e2dec5679c175fc52d2e19ebe06b9e1a7b05461 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Jan 2005 21:36:28 +0000 Subject: Add hci_read_clock() function --- src/hci.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 87f4874b..387560aa 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1620,6 +1620,37 @@ int hci_read_afh_map(int dd, uint16_t handle, uint8_t *mode, uint8_t *map, int t return 0; } +int hci_read_clock(int dd, uint16_t handle, uint8_t which, uint32_t *clock, uint16_t *accuracy, int to) +{ + read_clock_cp cp; + read_clock_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.which_clock = which; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_STATUS_PARAM; + rq.ocf = OCF_READ_CLOCK; + rq.cparam = &cp; + rq.clen = READ_CLOCK_CP_SIZE; + rq.rparam = &rp; + rq.rlen = READ_CLOCK_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *clock = rp.clock; + *accuracy = rp.accuracy; + return 0; +} + int hci_local_name(int dd, int len, char *name, int to) { return hci_read_local_name(dd, len, name, to); -- cgit From 816b0a911d833aeb2b8af041b55c7b7c66e43588 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jan 2005 23:14:46 +0000 Subject: Update the copyright year --- src/bluetooth.c | 2 +- src/hci.c | 2 +- src/sdp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 20a1aee6..110d65cd 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.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/src/hci.c b/src/hci.c index 387560aa..a68f0122 100644 --- a/src/hci.c +++ b/src/hci.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/src/sdp.c b/src/sdp.c index 6f8ce14b..c6494304 100644 --- a/src/sdp.c +++ b/src/sdp.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 * * -- cgit From e6589c0f2a6d1dd3060a86a27d859c8fb08bf278 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Jan 2005 03:24:48 +0000 Subject: Add functions for reading the BD_ADDR and the features --- src/hci.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index a68f0122..822c7db4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1042,6 +1042,52 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) return 0; } +int hci_read_local_features(int dd, uint8_t *features, int to) +{ + read_local_features_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_FEATURES; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_FEATURES_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(features, rp.features, 8); + return 0; +} + +int hci_read_bd_addr(int dd, bdaddr_t *bdaddr, int to) +{ + read_bd_addr_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_BD_ADDR; + rq.rparam = &rp; + rq.rlen = READ_BD_ADDR_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + bacpy(bdaddr, &rp.bdaddr); + return 0; +} + int hci_read_class_of_dev(int dd, uint8_t *cls, int to) { read_class_of_dev_rp rp; -- cgit From 601655969dc1dc85696f8aa94cf68a6433228be7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Jan 2005 23:30:04 +0000 Subject: Skip devices in raw mode --- src/hci.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 822c7db4..088574f1 100644 --- a/src/hci.c +++ b/src/hci.c @@ -453,51 +453,58 @@ int hci_for_each_dev(int flag, int (*func)(int s, int dev_id, long arg), long ar struct hci_dev_list_req *dl; struct hci_dev_req *dr; int dev_id = -1; - int s, i; + int i, sk; - s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (s < 0) + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) return -1; dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); if (!dl) { - close(s); + close(sk); return -1; } dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(s, HCIGETDEVLIST, (void *)dl)) + if (ioctl(sk, HCIGETDEVLIST, (void *) dl)) goto done; - for (i=0; i < dl->dev_num; i++, dr++) { + for (i = 0; i < dl->dev_num; i++, dr++) { if (hci_test_bit(flag, &dr->dev_opt)) - if (!func || func(s, dr->dev_id, arg)) { + if (!func || func(sk, dr->dev_id, arg)) { dev_id = dr->dev_id; break; } } done: - close(s); + close(sk); free(dl); return dev_id; } -static int __other_bdaddr(int s, int dev_id, long arg) +static int __other_bdaddr(int sk, int dev_id, long arg) { - struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(s, HCIGETDEVINFO, (void *) &di)) + struct hci_dev_info di = { dev_id: dev_id }; + + if (ioctl(sk, HCIGETDEVINFO, (void *) &di)) return 0; + + if (hci_test_bit(HCI_RAW, &di.flags)) + return 0; + return bacmp((bdaddr_t *) arg, &di.bdaddr); } -static int __same_bdaddr(int s, int dev_id, long arg) +static int __same_bdaddr(int sk, int dev_id, long arg) { - struct hci_dev_info di = {dev_id: dev_id}; - if (ioctl(s, HCIGETDEVINFO, (void *) &di)) + struct hci_dev_info di = { dev_id: dev_id }; + + if (ioctl(sk, HCIGETDEVINFO, (void *) &di)) return 0; + return !bacmp((bdaddr_t *) arg, &di.bdaddr); } -- cgit From 25efdcf40470f471d7d4412f3c5d11e918b8452e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Jan 2005 23:04:28 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index bec2f2dc..2724291a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:14:0 +libbluetooth_la_LDFLAGS = -version-info 1:15:0 INCLUDES = -I$(top_builddir)/include -- cgit From c608311e7472325514f0578a20d59efc86792e39 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Feb 2005 04:17:16 +0000 Subject: Add function for getting the remote name with a clock offset --- src/hci.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 088574f1..37715613 100644 --- a/src/hci.c +++ b/src/hci.c @@ -898,7 +898,7 @@ int hci_write_local_name(int dd, const char *name, int to) return 0; } -int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) +int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint16_t clkoffset, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; @@ -907,6 +907,7 @@ int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, in memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, bdaddr); cp.pscan_rep_mode = 0x02; + cp.clock_offset = clkoffset; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; @@ -930,6 +931,11 @@ int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, in return 0; } +int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) +{ + return hci_read_remote_name_with_clock_offset(dd, bdaddr, 0x0000, len, name, to); +} + int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) { evt_read_remote_features_complete rp; -- cgit From ce742d95634d8a666a0f4df610c8eac4419d7716 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 02:36:27 +0000 Subject: Fix IAC support --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 37715613..82bdbffc 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1215,7 +1215,7 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_WRITE_CURRENT_IAC_LAP; rq.cparam = &cp; - rq.clen = WRITE_CURRENT_IAC_LAP_CP_SIZE; + rq.clen = num_iac * 3 + 1; return hci_send_req(dd, &rq, to); } -- cgit From db01d7596aa2ba2e40df5d3c7ef9b7cd0489ecad Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 02:37:49 +0000 Subject: The transmit power level is a signed integer --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 82bdbffc..83f09d9f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1491,7 +1491,7 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } -int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, uint8_t *level, int to) +int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to) { read_transmit_power_level_cp cp; read_transmit_power_level_rp rp; -- cgit From 1ec0481800a50aa14afe0513f69b4c7c04d5962a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Feb 2005 11:42:03 +0000 Subject: Support pscan_rep_mode for remote name request --- src/hci.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 83f09d9f..a0c0775e 100644 --- a/src/hci.c +++ b/src/hci.c @@ -886,7 +886,9 @@ int hci_write_local_name(int dd, const char *name, int to) change_local_name_cp cp; struct hci_request rq; + memset(&cp, 0, sizeof(cp)); strncpy(cp.name, name, sizeof(cp.name)); + memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; rq.ocf = OCF_CHANGE_LOCAL_NAME; @@ -895,10 +897,11 @@ int hci_write_local_name(int dd, const char *name, int to) if (hci_send_req(dd, &rq, to) < 0) return -1; + return 0; } -int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint16_t clkoffset, int len, char *name, int to) +int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint8_t pscan_rep_mode, uint16_t clkoffset, int len, char *name, int to) { evt_remote_name_req_complete rn; remote_name_req_cp cp; @@ -906,7 +909,7 @@ int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint1 memset(&cp, 0, sizeof(cp)); bacpy(&cp.bdaddr, bdaddr); - cp.pscan_rep_mode = 0x02; + cp.pscan_rep_mode = pscan_rep_mode; cp.clock_offset = clkoffset; memset(&rq, 0, sizeof(rq)); @@ -933,7 +936,27 @@ int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint1 int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to) { - return hci_read_remote_name_with_clock_offset(dd, bdaddr, 0x0000, len, name, to); + return hci_read_remote_name_with_clock_offset(dd, bdaddr, 0x02, 0x0000, len, name, to); +} + +int hci_read_remote_name_cancel(int dd, const bdaddr_t *bdaddr, int to) +{ + remote_name_req_cancel_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_REMOTE_NAME_REQ_CANCEL; + rq.cparam = &cp; + rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + return 0; } int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) -- cgit From 28b4f0aea5b15ed7c0acd17ab79705a38ffe7c2f Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Mon, 28 Feb 2005 12:19:25 +0000 Subject: fix incorrect doc comment --- src/sdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index c6494304..82bd996d 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2629,7 +2629,7 @@ static int copy_cstate(char *pdata, const sdp_cstate_t *cstate) * sdp_list_t **rsp_list * This variable is set on a successful return if there are * non-zero service handles. It is a singly linked list of - * service records (sdp_record_t *) + * service record handles (uint16_t) */ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num, sdp_list_t **rsp) -- cgit From 8b11908eac4e0b4e14534ec2d44ae62806fdfd2f Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Wed, 2 Mar 2005 10:23:16 +0000 Subject: fix comments --- src/sdp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 82bd996d..d2b40380 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2286,8 +2286,7 @@ void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) * It is incorrect to call this method on a record that * has been already registered with the server. * - * Returns a non-null value (a pointer) to a service - * record if successful, else -1 setting errno + * Returns zero on success, otherwise -1 (and sets errno). */ int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags) { -- cgit From 8bd7ef87e49b68c3090448f337454a1704f5e048 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 9 Mar 2005 17:04:37 +0000 Subject: Add some extra debug information --- src/sdp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index d2b40380..1e474db4 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include @@ -1008,7 +1010,9 @@ static void attr_print_func(void *value, void *userData) void sdp_print_service_attr(sdp_list_t *svcAttrList) { + SDPDBG("Printing service attr list %p\n", svcAttrList); sdp_list_foreach(svcAttrList, attr_print_func, NULL); + SDPDBG("Printed service attr list %p\n", svcAttrList); } #endif -- cgit From 9280b803576dc54bfc7f51c8e5154d1f29692991 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Mar 2005 14:37:59 +0000 Subject: Add ba*printf() functions --- src/bluetooth.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 110d65cd..484b263b 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -33,9 +33,10 @@ #endif #include +#include +#include #include #include -#include #include #include @@ -105,6 +106,54 @@ int str2ba(const char *str, bdaddr_t *ba) return 0; } +int baprintf(const char *format, ...) +{ + va_list ap; + int len; + + va_start(ap, format); + len = vprintf(format, ap); + va_end(ap); + + return len; +} + +int bafprintf(FILE *stream, const char *format, ...) +{ + va_list ap; + int len; + + va_start(ap, format); + len = vfprintf(stream, format, ap); + va_end(ap); + + return len; +} + +int basprintf(char *str, const char *format, ...) +{ + va_list ap; + int len; + + va_start(ap, format); + len = vsnprintf(str, (~0U) >> 1, format, ap); + va_end(ap); + + return len; +} + +int basnprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + int len; + + va_start(ap, format); + len = vsnprintf(str, size, format, ap); + va_end(ap); + + return len; +} + /* Bluetooth error codes to Unix errno mapping */ int bt_error(uint16_t code) { -- cgit From 4c2d1cbe438713b5d6c350ee0983e1d312c69823 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 27 Mar 2005 14:43:44 +0000 Subject: Add ba2oui() function --- src/bluetooth.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 484b263b..0f4c49e6 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -106,6 +106,14 @@ int str2ba(const char *str, bdaddr_t *ba) return 0; } +int ba2oui(const bdaddr_t *ba, char *str) +{ + uint8_t b[6]; + + baswap((bdaddr_t *) b, ba); + return sprintf(str, "%2.2X-%2.2X-%2.2X", b[0], b[1], b[2]); +} + int baprintf(const char *format, ...) { va_list ap; -- cgit From 607eee46b4e197ef0b3e73359b89daa0a8705516 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 13:09:06 +0000 Subject: Fix buffer allocation for features to string conversion --- src/hci.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index a0c0775e..ddcd680b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -414,9 +414,20 @@ static hci_map lmp_features_map[8][9] = { char *lmp_featurestostr(uint8_t *features, char *pref, int width) { - char *off, *ptr, *str = malloc(400); - int i; + char *off, *ptr, *str; + int i, size = 0; + for (i = 0; i < 8; i++) { + hci_map *m = lmp_features_map[i]; + + while (m->str) { + if ((unsigned int) m->val & (unsigned int) features[i]) + size += strlen(m->str) + (pref ? strlen(pref) : 0) + 1; + m++; + } + } + + str = malloc(size); if (!str) return NULL; @@ -427,10 +438,9 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) off = ptr; - for (i = 0; i < 8; i++) { - hci_map *m; + for (i = 0; i < 8; i++) { + hci_map *m = lmp_features_map[i]; - m = lmp_features_map[i]; while (m->str) { if ((unsigned int) m->val & (unsigned int) features[i]) { if (strlen(off) + strlen(m->str) > width - 1) { -- cgit From be2d979b6a592484862e78bed355d079f7eeb1e6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 23:14:52 +0000 Subject: Add funtions for reading local supported commands and extended features --- src/hci.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index ddcd680b..6e1067c4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1088,6 +1088,29 @@ int hci_read_local_version(int dd, struct hci_version *ver, int to) return 0; } +int hci_read_local_commands(int dd, uint8_t *commands, int to) +{ + read_local_commands_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_COMMANDS; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_COMMANDS_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(commands, rp.commands, 64); + return 0; +} + int hci_read_local_features(int dd, uint8_t *features, int to) { read_local_features_rp rp; @@ -1111,6 +1134,35 @@ int hci_read_local_features(int dd, uint8_t *features, int to) return 0; } +int hci_read_local_ext_features(int dd, uint8_t page, uint8_t *max_page, uint8_t *features, int to) +{ + read_local_ext_features_cp cp; + read_local_ext_features_rp rp; + struct hci_request rq; + + cp.page_num = page; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_INFO_PARAM; + rq.ocf = OCF_READ_LOCAL_EXT_FEATURES; + rq.cparam = &cp; + rq.clen = READ_LOCAL_EXT_FEATURES_CP_SIZE; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_EXT_FEATURES_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *max_page = rp.max_page_num; + memcpy(features, rp.features, 8); + return 0; +} + int hci_read_bd_addr(int dd, bdaddr_t *bdaddr, int to) { read_bd_addr_rp rp; -- cgit From 0887d119a0b61e38cbd3d30e207c09eb5a5ff463 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 17 Apr 2005 23:31:54 +0000 Subject: Add function for remote extended features --- src/hci.c | 54 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 6e1067c4..e04e55a8 100644 --- a/src/hci.c +++ b/src/hci.c @@ -969,6 +969,38 @@ int hci_read_remote_name_cancel(int dd, const bdaddr_t *bdaddr, int to) return 0; } +int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, int to) +{ + evt_read_remote_version_complete rp; + read_remote_version_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_CTL; + rq.ocf = OCF_READ_REMOTE_VERSION; + rq.event = EVT_READ_REMOTE_VERSION_COMPLETE; + rq.cparam = &cp; + rq.clen = READ_REMOTE_VERSION_CP_SIZE; + rq.rparam = &rp; + rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + ver->manufacturer = btohs(rp.manufacturer); + ver->lmp_ver = rp.lmp_ver; + ver->lmp_subver = btohs(rp.lmp_subver); + return 0; +} + int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) { evt_read_remote_features_complete rp; @@ -999,23 +1031,24 @@ int hci_read_remote_features(int dd, uint16_t handle, uint8_t *features, int to) return 0; } -int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, int to) +int hci_read_remote_ext_features(int dd, uint16_t handle, uint8_t page, uint8_t *max_page, uint8_t *features, int to) { - evt_read_remote_version_complete rp; - read_remote_version_cp cp; + evt_read_remote_ext_features_complete rp; + read_remote_ext_features_cp cp; struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = handle; + cp.handle = handle; + cp.page_num = page; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_READ_REMOTE_VERSION; - rq.event = EVT_READ_REMOTE_VERSION_COMPLETE; + rq.ocf = OCF_READ_REMOTE_EXT_FEATURES; + rq.event = EVT_READ_REMOTE_EXT_FEATURES_COMPLETE; rq.cparam = &cp; - rq.clen = READ_REMOTE_VERSION_CP_SIZE; + rq.clen = READ_REMOTE_EXT_FEATURES_CP_SIZE; rq.rparam = &rp; - rq.rlen = EVT_READ_REMOTE_VERSION_COMPLETE_SIZE; + rq.rlen = EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE; if (hci_send_req(dd, &rq, to) < 0) return -1; @@ -1025,9 +1058,8 @@ int hci_read_remote_version(int dd, uint16_t handle, struct hci_version *ver, in return -1; } - ver->manufacturer = btohs(rp.manufacturer); - ver->lmp_ver = rp.lmp_ver; - ver->lmp_subver = btohs(rp.lmp_subver); + *max_page = rp.max_page_num; + memcpy(features, rp.features, 8); return 0; } -- cgit From f1684dcb1badc1dfba7ad4133b8d6cac3e77c759 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 22:00:32 +0000 Subject: Support inquiry with unlimited number of responses --- src/hci.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index e04e55a8..6e7fa987 100644 --- a/src/hci.c +++ b/src/hci.c @@ -577,11 +577,14 @@ int hci_devba(int dev_id, bdaddr_t *bdaddr) int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info **ii, long flags) { struct hci_inquiry_req *ir; + uint8_t num_rsp = nrsp; void *buf; int s, err; - if (nrsp <= 0) - nrsp = 200; /* enough ? */ + if (nrsp <= 0) { + num_rsp = 0; + nrsp = 255; + } if (dev_id < 0 && (dev_id = hci_get_route(NULL)) < 0) { errno = ENODEV; @@ -600,7 +603,7 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info ir = buf; ir->dev_id = dev_id; - ir->num_rsp = nrsp; + ir->num_rsp = num_rsp; ir->length = len; ir->flags = flags; -- cgit From 137bc70b64b7b1d8280a6580532007e27e2c7e3f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 18 Apr 2005 22:55:19 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 2724291a..2be03d47 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:15:0 +libbluetooth_la_LDFLAGS = -version-info 1:16:0 INCLUDES = -I$(top_builddir)/include -- cgit From 48954bd49fdd7189bb725038801f3ca0ff2f4d12 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 1 May 2005 14:52:53 +0000 Subject: Add functions for stored link keys --- src/hci.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 6e7fa987..60898e9b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1340,6 +1340,61 @@ int hci_write_current_iac_lap(int dd, uint8_t num_iac, uint8_t *lap, int to) return hci_send_req(dd, &rq, to); } +int hci_read_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to) +{ + read_stored_link_key_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + cp.read_all = all; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_STORED_LINK_KEY; + rq.cparam = &cp; + rq.clen = READ_STORED_LINK_KEY_CP_SIZE; + + return hci_send_req(dd, &rq, to); +} + +int hci_write_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t *key, int to) +{ + unsigned char cp[WRITE_STORED_LINK_KEY_CP_SIZE + 6 + 16]; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp[0] = 1; + bacpy((bdaddr_t *) (cp + 1), bdaddr); + memcpy(cp + 7, key, 16); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_STORED_LINK_KEY; + rq.cparam = &cp; + rq.clen = WRITE_STORED_LINK_KEY_CP_SIZE + 6 + 16; + + return hci_send_req(dd, &rq, to); +} + +int hci_delete_stored_link_key(int dd, bdaddr_t *bdaddr, uint8_t all, int to) +{ + delete_stored_link_key_cp cp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + bacpy(&cp.bdaddr, bdaddr); + cp.delete_all = all; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_DELETE_STORED_LINK_KEY; + rq.cparam = &cp; + rq.clen = DELETE_STORED_LINK_KEY_CP_SIZE; + + return hci_send_req(dd, &rq, to); +} + int hci_authenticate_link(int dd, uint16_t handle, int to) { auth_requested_cp cp; -- cgit From 0a2a889c91f9b671b7c31bcb6e4e53daf306fb7e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 May 2005 17:18:18 +0000 Subject: Add SDP_WAIT_ON_CLOSE flag for sdp_connect() --- src/sdp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 1e474db4..93a518cb 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3167,13 +3167,17 @@ sdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t fl sa.l2_psm = 0; if (bacmp(src, BDADDR_ANY) != 0) { sa.l2_bdaddr = *src; - if (0 > bind(session->sock, (struct sockaddr *)&sa, sizeof(sa))) + if (bind(session->sock, (struct sockaddr *) &sa, sizeof(sa)) < 0) goto fail; } + if (flags & SDP_WAIT_ON_CLOSE) { + struct linger l = { .l_onoff = 1, .l_linger = 1 }; + setsockopt(session->sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)); + } sa.l2_psm = htobs(SDP_PSM); sa.l2_bdaddr = *dst; do - if (connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)) == 0) + if (connect(session->sock, (struct sockaddr *) &sa, sizeof(sa)) == 0) return session; while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY)); } -- cgit From 4e2579e42570a214353809903f6c8bc59db7d5ef Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 9 May 2005 12:23:53 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 2be03d47..c52358f3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:16:0 +libbluetooth_la_LDFLAGS = -version-info 1:17:0 INCLUDES = -I$(top_builddir)/include -- cgit From e8c8131bc6c67b3592a5b5ec1882f2d8abf00608 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 19 May 2005 12:20:54 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 0f4c49e6..c54d63e3 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -364,6 +364,8 @@ char *bt_compidtostr(int compid) return "Research In Motion"; case 61: return "IPextreme, Inc."; + case 62: + return "Systems and Chips, Inc"; case 65535: return "internal use"; default: -- cgit From f38a7523b3e2ec2109cd5c5f65803da5a354da03 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Jun 2005 13:53:08 +0000 Subject: Add support for reading and writing the inquiry scan type --- src/hci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 60898e9b..b52b53fa 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1564,6 +1564,57 @@ int hci_exit_park_mode(int dd, uint16_t handle, int to) return 0; } +int hci_read_inquiry_scan_type(int dd, uint8_t *type, int to) +{ + read_inquiry_scan_type_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_INQUIRY_SCAN_TYPE; + rq.rparam = &rp; + rq.rlen = READ_INQUIRY_SCAN_TYPE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *type = rp.type; + return 0; +} + +int hci_write_inquiry_scan_type(int dd, uint8_t type, int to) +{ + write_inquiry_scan_type_cp cp; + write_inquiry_scan_type_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.type = type; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQUIRY_SCAN_TYPE; + rq.cparam = &cp; + rq.clen = WRITE_INQUIRY_SCAN_TYPE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_INQUIRY_SCAN_TYPE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_inquiry_mode(int dd, uint8_t *mode, int to) { read_inquiry_mode_rp rp; -- cgit From 631f20f4f87398b68b658acc3c374c6b36c1b7eb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 21 Jun 2005 16:40:29 +0000 Subject: Fix some errno usages --- src/hci.c | 109 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index b52b53fa..db6e6da1 100644 --- a/src/hci.c +++ b/src/hci.c @@ -33,18 +33,14 @@ #endif #include -#include -#include -#include -#include -#include -#include #include -#include #include +#include +#include +#include +#include #include -#include #include #include #include @@ -458,28 +454,26 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) /* HCI functions that do not require open device */ -int hci_for_each_dev(int flag, int (*func)(int s, int dev_id, long arg), long arg) +int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long arg) { struct hci_dev_list_req *dl; struct hci_dev_req *dr; int dev_id = -1; - int i, sk; + int i, sk, err; sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) return -1; dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); - if (!dl) { - close(sk); - return -1; - } + if (!dl) + goto done; dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; if (ioctl(sk, HCIGETDEVLIST, (void *) dl)) - goto done; + goto free; for (i = 0; i < dl->dev_num; i++, dr++) { if (hci_test_bit(flag, &dr->dev_opt)) @@ -489,17 +483,25 @@ int hci_for_each_dev(int flag, int (*func)(int s, int dev_id, long arg), long ar } } + if (dev_id < 0) + errno = ENODEV; + +free: + free(dl); + done: + err = errno; close(sk); - free(dl); + errno = err; + return dev_id; } -static int __other_bdaddr(int sk, int dev_id, long arg) +static int __other_bdaddr(int dd, int dev_id, long arg) { struct hci_dev_info di = { dev_id: dev_id }; - if (ioctl(sk, HCIGETDEVINFO, (void *) &di)) + if (ioctl(dd, HCIGETDEVINFO, (void *) &di)) return 0; if (hci_test_bit(HCI_RAW, &di.flags)) @@ -508,11 +510,11 @@ static int __other_bdaddr(int sk, int dev_id, long arg) return bacmp((bdaddr_t *) arg, &di.bdaddr); } -static int __same_bdaddr(int sk, int dev_id, long arg) +static int __same_bdaddr(int dd, int dev_id, long arg) { struct hci_dev_info di = { dev_id: dev_id }; - if (ioctl(sk, HCIGETDEVINFO, (void *) &di)) + if (ioctl(dd, HCIGETDEVINFO, (void *) &di)) return 0; return !bacmp((bdaddr_t *) arg, &di.bdaddr); @@ -540,22 +542,26 @@ int hci_devid(const char *str) str2ba(str, &ba); id = hci_for_each_dev(HCI_UP, __same_bdaddr, (long) &ba); } + return id; } int hci_devinfo(int dev_id, struct hci_dev_info *di) { - int s, err; + int dd, err, ret; - s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (s < 0) - return s; + dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (dd < 0) + return dd; di->dev_id = dev_id; - err = ioctl(s, HCIGETDEVINFO, (void *) di); - close(s); + ret = ioctl(dd, HCIGETDEVINFO, (void *) di); + + err = errno; + close(dd); + errno = err; - return err; + return ret; } int hci_devba(int dev_id, bdaddr_t *bdaddr) @@ -571,6 +577,7 @@ int hci_devba(int dev_id, bdaddr_t *bdaddr) } bacpy(bdaddr, &di.bdaddr); + return 0; } @@ -579,7 +586,7 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info struct hci_inquiry_req *ir; uint8_t num_rsp = nrsp; void *buf; - int s, err; + int dd, size, err, ret = -1; if (nrsp <= 0) { num_rsp = 0; @@ -591,15 +598,13 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info return -1; } - s = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); - if (s < 0) - return -1; + dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (dd < 0) + return dd; buf = malloc(sizeof(*ir) + (sizeof(inquiry_info) * (nrsp))); - if (!buf) { - close(s); - return -1; - } + if (!buf) + goto done; ir = buf; ir->dev_id = dev_id; @@ -615,23 +620,30 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info ir->lap[2] = 0x9e; } - err = ioctl(s, HCIINQUIRY, (unsigned long) buf); - close(s); + ret = ioctl(dd, HCIINQUIRY, (unsigned long) buf); + if (ret < 0) + goto free; - if (!err) { - int size = sizeof(inquiry_info) * ir->num_rsp; + size = sizeof(inquiry_info) * ir->num_rsp; - if (!*ii) - *ii = (void *) malloc(size); + if (!*ii) + *ii = malloc(size); - if (*ii) { - memcpy((void *) *ii, buf + sizeof(*ir), size); - err = ir->num_rsp; - } else - err = -1; - } + if (*ii) { + memcpy((void *) *ii, buf + sizeof(*ir), size); + ret = ir->num_rsp; + } else + ret = -1; + +free: free(buf); - return err; + +done: + err = errno; + close(dd); + errno = err; + + return ret; } /* Open HCI device. @@ -658,6 +670,7 @@ failed: err = errno; close(dd); errno = err; + return -1; } -- cgit From b9b9f3700eefd8a32af2b68fb08c008b1fad650f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Jul 2005 14:50:03 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index c52358f3..ee4510ca 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:17:0 +libbluetooth_la_LDFLAGS = -version-info 1:18:0 INCLUDES = -I$(top_builddir)/include -- cgit From e27896801ac0514289f57def3a8b5c1491d316c6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jul 2005 19:54:42 +0000 Subject: Fix some GCC 4.0 warnings --- src/hci.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index db6e6da1..59f2afa7 100644 --- a/src/hci.c +++ b/src/hci.c @@ -717,8 +717,9 @@ int hci_send_req(int dd, struct hci_request *r, int to) unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr; uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); struct hci_filter nf, of; + socklen_t len; hci_event_hdr *hdr; - int err, len, try; + int err, try; len = sizeof(of); if (getsockopt(dd, SOL_HCI, HCI_FILTER, &of, &len) < 0) @@ -903,7 +904,7 @@ int hci_read_local_name(int dd, int len, char *name, int to) } rp.name[247] = '\0'; - strncpy(name, rp.name, len); + strncpy(name, (char *) rp.name, len); return 0; } @@ -913,7 +914,7 @@ int hci_write_local_name(int dd, const char *name, int to) struct hci_request rq; memset(&cp, 0, sizeof(cp)); - strncpy(cp.name, name, sizeof(cp.name)); + strncpy((char *) cp.name, name, sizeof(cp.name)); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; @@ -956,7 +957,7 @@ int hci_read_remote_name_with_clock_offset(int dd, const bdaddr_t *bdaddr, uint8 } rn.name[247] = '\0'; - strncpy(name, rn.name, len); + strncpy(name, (char *) rn.name, len); return 0; } -- cgit From cfa3a02e2593bd72ce4a83f521e1e89a5874ea7d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 6 Jul 2005 00:12:25 +0000 Subject: Fix more GCC 4.0 warnings --- src/sdp.c | 123 ++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 60 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 93a518cb..84d0a016 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -534,7 +534,7 @@ void sdp_attr_remove(sdp_record_t *rec, uint16_t attr) rec->attrlist = sdp_list_remove(rec->attrlist, d); } -void sdp_set_seq_len(char *ptr, int length) +void sdp_set_seq_len(uint8_t *ptr, uint32_t length) { uint8_t dtd = *(uint8_t *) ptr++; @@ -614,14 +614,14 @@ static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata) int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) { - int pdu_size = 0, data_size = 0; + uint32_t pdu_size = 0, data_size = 0; unsigned char *src = NULL, is_seq = 0, is_alt = 0; uint8_t dtd = d->dtd; uint16_t u16; uint32_t u32; uint64_t u64; uint128_t u128; - char *seqp = buf->data + buf->data_size; + uint8_t *seqp = buf->data + buf->data_size; pdu_size = sdp_set_data_type(buf, dtd); switch (dtd) { @@ -735,7 +735,7 @@ static void sdp_attr_pdu(void *value, void *udata) int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf) { - buf->data = (char *)malloc(SDP_PDU_CHUNK_SIZE); + buf->data = malloc(SDP_PDU_CHUNK_SIZE); if (buf->data) { buf->buf_size = SDP_PDU_CHUNK_SIZE; buf->data_size = 0; @@ -845,7 +845,7 @@ static sdp_data_t *extract_int(const void *p, int *len) return d; } -static sdp_data_t *extract_uuid(const void *p, int *len, sdp_record_t *rec) +static sdp_data_t *extract_uuid(const uint8_t *p, int *len, sdp_record_t *rec) { sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); @@ -942,7 +942,7 @@ static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec) return d; } -sdp_data_t *sdp_extract_attr(const char *p, int *size, sdp_record_t *rec) +sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec) { sdp_data_t *elem; int n = 0; @@ -1016,13 +1016,13 @@ void sdp_print_service_attr(sdp_list_t *svcAttrList) } #endif -sdp_record_t *sdp_extract_pdu(const char *buf, int *scanned) +sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned) { int extracted = 0, seqlen = 0; uint8_t dtd; uint16_t attr; sdp_record_t *rec = sdp_record_alloc(); - const char *p = buf; + const uint8_t *p = buf; *scanned = sdp_extract_seqtype(buf, &dtd, &seqlen); p += *scanned; @@ -1155,7 +1155,7 @@ sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId) * Extract the sequence type and its length, and return offset into buf * or 0 on failure. */ -int sdp_extract_seqtype(const char *buf, uint8_t *dtdp, int *size) +int sdp_extract_seqtype(const uint8_t *buf, uint8_t *dtdp, int *size) { uint8_t dtd = *(uint8_t *) buf; int scanned = sizeof(uint8_t); @@ -1185,9 +1185,9 @@ int sdp_extract_seqtype(const char *buf, uint8_t *dtdp, int *size) return scanned; } -int sdp_send_req(sdp_session_t *session, char *buf, int size) +int sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size) { - int sent = 0; + uint32_t sent = 0; while (sent < size) { int n = send(session->sock, buf + sent, size - sent, 0); @@ -1198,7 +1198,7 @@ int sdp_send_req(sdp_session_t *session, char *buf, int size) return 0; } -int sdp_read_rsp(sdp_session_t *session, char *buf, int size) +int sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size) { fd_set readFds; struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 }; @@ -1216,7 +1216,7 @@ int sdp_read_rsp(sdp_session_t *session, char *buf, int size) /* * generic send request, wait for response method. */ -int sdp_send_req_w4_rsp(sdp_session_t *session, char *reqbuf, char *rspbuf, int reqsize, int *rspsize) +int sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf, uint8_t *rspbuf, uint32_t reqsize, uint32_t *rspsize) { int n; sdp_pdu_hdr_t *reqhdr = (sdp_pdu_hdr_t *)reqbuf; @@ -1952,7 +1952,7 @@ uint128_t *sdp_create_base_uuid(void) char *dataPtr; char temp[10]; int toBeCopied; - char *data; + uint8_t *data; if (bluetooth_base_uuid == NULL) { strcpy(baseStr, BASE_UUID); @@ -2182,7 +2182,7 @@ int sdp_uuid_to_proto(uuid_t *uuid) return 0; } -int sdp_uuid_extract(const char *p, uuid_t *uuid, int *scanned) +int sdp_uuid_extract(const uint8_t *p, uuid_t *uuid, int *scanned) { uint8_t type = *(const uint8_t *) p; @@ -2214,9 +2214,9 @@ int sdp_uuid_extract(const char *p, uuid_t *uuid, int *scanned) * Should the PDU length exceed 2^8, then sequence type is * set accordingly and the data is memmove()'d. */ -void sdp_append_to_buf(sdp_buf_t *dst, char *data, int len) +void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len) { - char *p = dst->data; + uint8_t *p = dst->data; uint8_t dtd = *(uint8_t *) p; SDPDBG("Append src size: %d\n", len); @@ -2224,7 +2224,7 @@ void sdp_append_to_buf(sdp_buf_t *dst, char *data, int len) SDPDBG("Dst buffer size: %d\n", dst->buf_size); if (dst->data_size + len > dst->buf_size) { int need = SDP_PDU_CHUNK_SIZE * ((len / SDP_PDU_CHUNK_SIZE) + 1); - dst->data = (char *)realloc(dst->data, dst->buf_size + need); + dst->data = realloc(dst->data, dst->buf_size + need); SDPDBG("Realloc'ing : %d\n", need); @@ -2273,7 +2273,7 @@ void sdp_append_to_buf(sdp_buf_t *dst, char *data, int len) void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) { - char buf[SDP_SEQ_PDUFORM_SIZE]; + uint8_t buf[SDP_SEQ_PDUFORM_SIZE]; sdp_buf_t append; append.data = buf; @@ -2294,10 +2294,9 @@ void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) */ int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags) { - char *p; int status = 0; - char *req, *rsp; - int reqsize, rspsize; + uint8_t *req, *rsp, *p; + uint32_t reqsize, rspsize; sdp_pdu_hdr_t *reqhdr, *rsphdr; sdp_buf_t pdu; @@ -2307,8 +2306,8 @@ int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags errno = EREMOTE; return -1; } - req = (char *) malloc(SDP_REQ_BUFFER_SIZE); - rsp = (char *) malloc(SDP_RSP_BUFFER_SIZE); + req = malloc(SDP_REQ_BUFFER_SIZE); + rsp = malloc(SDP_RSP_BUFFER_SIZE); if (req == NULL || rsp == NULL) { status = -1; errno = ENOMEM; @@ -2354,10 +2353,9 @@ end: */ int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) { - char *p; int status = 0; - char *reqbuf, *rspbuf; - int reqsize = 0, rspsize = 0; + uint8_t *reqbuf, *rspbuf, *p; + uint32_t reqsize = 0, rspsize = 0; sdp_pdu_hdr_t *reqhdr, *rsphdr; uint32_t handle = 0; @@ -2372,8 +2370,8 @@ int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) errno = EREMOTE; return -1; } - reqbuf = (char *) malloc(SDP_REQ_BUFFER_SIZE); - rspbuf = (char *) malloc(SDP_RSP_BUFFER_SIZE); + reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = malloc(SDP_RSP_BUFFER_SIZE); if (!reqbuf || !rspbuf) { errno = ENOMEM; status = -1; @@ -2412,10 +2410,9 @@ end: */ int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) { - char *p; int status = 0; - char *reqbuf, *rspbuf; - int reqsize, rspsize; + uint8_t *reqbuf, *rspbuf, *p; + uint32_t reqsize, rspsize; sdp_pdu_hdr_t *reqhdr, *rsphdr; uint32_t handle; sdp_buf_t pdu; @@ -2431,8 +2428,8 @@ int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) errno = EREMOTE; return -1; } - reqbuf = (char *) malloc(SDP_REQ_BUFFER_SIZE); - rspbuf = (char *) malloc(SDP_RSP_BUFFER_SIZE); + reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = malloc(SDP_RSP_BUFFER_SIZE); if (!reqbuf || !rspbuf) { errno = ENOMEM; status = -1; @@ -2442,7 +2439,7 @@ int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) reqhdr->pdu_id = SDP_SVC_UPDATE_REQ; reqhdr->tid = htons(sdp_gen_tid(session)); - p = (char *) (reqbuf + sizeof(sdp_pdu_hdr_t)); + p = reqbuf + sizeof(sdp_pdu_hdr_t); reqsize = sizeof(sdp_pdu_hdr_t); bt_put_unaligned(htonl(handle), (uint32_t *) p); @@ -2523,10 +2520,10 @@ void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq) * handles are not in "data element sequence" form, but just like * an array of service handles */ -static void extract_record_handle_seq(char *pdu, sdp_list_t **seq, int count, int *scanned) +static void extract_record_handle_seq(uint8_t *pdu, sdp_list_t **seq, int count, int *scanned) { sdp_list_t *pSeq = *seq; - char *pdata = pdu; + uint8_t *pdata = pdu; int n; for (n = 0; n < count; n++) { @@ -2542,7 +2539,7 @@ static void extract_record_handle_seq(char *pdu, sdp_list_t **seq, int count, in * Generate the attribute sequence pdu form * from sdp_list_t elements. Return length of attr seq */ -static int gen_dataseq_pdu(char *dst, const sdp_list_t *seq, uint8_t dtd) +static int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd) { sdp_data_t *dataseq; void **types, **values; @@ -2553,7 +2550,7 @@ static int gen_dataseq_pdu(char *dst, const sdp_list_t *seq, uint8_t dtd) SDPDBG(""); memset(&buf, 0, sizeof(sdp_buf_t)); - buf.data = (char *)malloc(SDP_UUID_SEQ_SIZE); + buf.data = malloc(SDP_UUID_SEQ_SIZE); buf.buf_size = SDP_UUID_SEQ_SIZE; SDPDBG("Seq length : %d\n", seqlen); @@ -2583,18 +2580,18 @@ static int gen_dataseq_pdu(char *dst, const sdp_list_t *seq, uint8_t dtd) return seqlen; } -static int gen_searchseq_pdu(char *dst, const sdp_list_t *seq) +static int gen_searchseq_pdu(uint8_t *dst, const sdp_list_t *seq) { - uuid_t *uuid = (uuid_t *)seq->data; + uuid_t *uuid = (uuid_t *) seq->data; return gen_dataseq_pdu(dst, seq, uuid->type); } -static int gen_attridseq_pdu(char *dst, const sdp_list_t *seq, uint8_t dataType) +static int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataType) { return gen_dataseq_pdu(dst, seq, dataType); } -static int copy_cstate(char *pdata, const sdp_cstate_t *cstate) +static int copy_cstate(uint8_t *pdata, const sdp_cstate_t *cstate) { if (cstate) { *pdata++ = cstate->length; @@ -2638,12 +2635,12 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num, sdp_list_t **rsp) { int status = 0; - int reqsize = 0, _reqsize; - int rspsize = 0, rsplen; + uint32_t reqsize = 0, _reqsize; + uint32_t rspsize = 0, rsplen; int seqlen = 0; int scanned, total_rec_count, rec_count; - char *pdata, *_pdata; - char *reqbuf, *rspbuf; + uint8_t *pdata, *_pdata; + uint8_t *reqbuf, *rspbuf; sdp_pdu_hdr_t *reqhdr, *rsphdr; sdp_cstate_t *cstate = NULL; @@ -2782,12 +2779,12 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrids) { int status = 0; - int reqsize = 0, _reqsize; - int rspsize = 0, rsp_count; + uint32_t reqsize = 0, _reqsize; + uint32_t rspsize = 0, rsp_count; int attr_list_len = 0; int seqlen = 0; - char *pdata, *_pdata; - char *reqbuf, *rspbuf; + uint8_t *pdata, *_pdata; + uint8_t *reqbuf, *rspbuf; sdp_pdu_hdr_t *reqhdr, *rsphdr; sdp_cstate_t *cstate = NULL; uint8_t cstate_len = 0; @@ -2799,8 +2796,8 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, return 0; } - reqbuf = (char *) malloc(SDP_REQ_BUFFER_SIZE); - rspbuf = (char *) malloc(SDP_RSP_BUFFER_SIZE); + reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = malloc(SDP_RSP_BUFFER_SIZE); if (!reqbuf || !rspbuf) { errno = ENOMEM; status = -1; @@ -2874,12 +2871,12 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, * and the last one (which has cstate_len == 0) */ if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { - char *targetPtr = NULL; + uint8_t *targetPtr = NULL; cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; // build concatenated response buffer - rsp_concat_buf.data = (char *) realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); + rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; memcpy(targetPtr, pdata, rsp_count); @@ -2951,12 +2948,12 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrids, sdp_list_t **rsp) { int status = 0; - int reqsize = 0, _reqsize; - int rspsize = 0; + uint32_t reqsize = 0, _reqsize; + uint32_t rspsize = 0; int seqlen = 0, attr_list_len = 0; int rsp_count = 0, cstate_len = 0; - char *pdata, *_pdata; - char *reqbuf, *rspbuf; + uint8_t *pdata, *_pdata; + uint8_t *reqbuf, *rspbuf; sdp_pdu_hdr_t *reqhdr, *rsphdr; uint8_t dataType; sdp_list_t *rec_list = NULL; @@ -2967,8 +2964,8 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search errno = EINVAL; return -1; } - reqbuf = (char *) malloc(SDP_REQ_BUFFER_SIZE); - rspbuf = (char *) malloc(SDP_RSP_BUFFER_SIZE); + reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + rspbuf = malloc(SDP_RSP_BUFFER_SIZE); if (!reqbuf || !rspbuf) { errno = ENOMEM; status = -1; @@ -3048,12 +3045,12 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search * responses and the last one which will have cstate_len == 0 */ if (cstate_len > 0 || rsp_concat_buf.data_size != 0) { - char *targetPtr = NULL; + uint8_t *targetPtr = NULL; cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; // build concatenated response buffer - rsp_concat_buf.data = (char *)realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); + rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; memcpy(targetPtr, pdata, rsp_count); -- cgit From b809fb039119546a8b5b4fbb4bcbfbad6666cf24 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 9 Jul 2005 17:09:10 +0000 Subject: Fix the routing for dealing with raw devices --- src/hci.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 59f2afa7..0aca162f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -522,10 +522,8 @@ static int __same_bdaddr(int dd, int dev_id, long arg) int hci_get_route(bdaddr_t *bdaddr) { - if (bdaddr) - return hci_for_each_dev(HCI_UP, __other_bdaddr, (long) bdaddr); - else - return hci_for_each_dev(HCI_UP, NULL, 0); + return hci_for_each_dev(HCI_UP, __other_bdaddr, + (long) (bdaddr ? bdaddr : BDADDR_ANY)); } int hci_devid(const char *str) @@ -593,9 +591,12 @@ int hci_inquiry(int dev_id, int len, int nrsp, const uint8_t *lap, inquiry_info nrsp = 255; } - if (dev_id < 0 && (dev_id = hci_get_route(NULL)) < 0) { - errno = ENODEV; - return -1; + if (dev_id < 0) { + dev_id = hci_get_route(NULL); + if (dev_id < 0) { + errno = ENODEV; + return -1; + } } dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); -- cgit From a1454c0f12421da1849ca347f8a30d084778d679 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 3 Aug 2005 07:18:31 +0000 Subject: Create per device SDP server functions --- src/sdp.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 84d0a016..4c1117e1 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2292,7 +2292,7 @@ void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) * * Returns zero on success, otherwise -1 (and sets errno). */ -int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags) +int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags) { int status = 0; uint8_t *req, *rsp, *p; @@ -2348,10 +2348,15 @@ end: return status; } +int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags) +{ + return sdp_device_record_register(session, BDADDR_ANY, rec, flags); +} + /* * unregister a service record */ -int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) +int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec) { int status = 0; uint8_t *reqbuf, *rspbuf, *p; @@ -2405,10 +2410,15 @@ end: return status; } +int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) +{ + return sdp_device_record_unregister(session, BDADDR_ANY, rec); +} + /* * modify an existing service record */ -int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) +int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec) { int status = 0; uint8_t *reqbuf, *rspbuf, *p; @@ -2472,6 +2482,11 @@ end: return status; } +int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) +{ + return sdp_device_record_update(session, BDADDR_ANY, rec); +} + sdp_record_t *sdp_record_alloc() { sdp_record_t *rec = (sdp_record_t *)malloc(sizeof(sdp_record_t)); -- cgit From fb1557c4111ca9993e4927af6f65bdbf9c2fa8ec Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 3 Aug 2005 07:41:21 +0000 Subject: Add device specific record register --- src/sdp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 4c1117e1..22fcd362 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2318,8 +2318,13 @@ int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_rec reqhdr->tid = htons(sdp_gen_tid(session)); reqsize = sizeof(sdp_pdu_hdr_t) + 1; p = req + sizeof(sdp_pdu_hdr_t); - *p++ = flags; - if (0 > sdp_gen_record_pdu(rec, &pdu)) { + if (bacmp(device, BDADDR_ANY)) { + *p++ = flags | SDP_DEVICE_RECORD; + bacpy((bdaddr_t *) p, device); + p += sizeof(bdaddr_t); + } else + *p++ = flags; + if (sdp_gen_record_pdu(rec, &pdu) < 0) { status = -1; errno = ENOMEM; goto end; -- cgit From 6db62cfa3a8de69270cc5e5689b633f43c02e041 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 3 Aug 2005 07:45:45 +0000 Subject: Fix request size calculation for device specific register --- src/sdp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 22fcd362..d920a753 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2322,6 +2322,7 @@ int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_rec *p++ = flags | SDP_DEVICE_RECORD; bacpy((bdaddr_t *) p, device); p += sizeof(bdaddr_t); + reqsize += sizeof(bdaddr_t); } else *p++ = flags; if (sdp_gen_record_pdu(rec, &pdu) < 0) { -- cgit From e602dbfade3e4ef56ef04a81489ba0374133a313 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 04:26:53 +0000 Subject: Cleanup --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 0aca162f..2447ae9b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -472,7 +472,7 @@ int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long a dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(sk, HCIGETDEVLIST, (void *) dl)) + if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) goto free; for (i = 0; i < dl->dev_num; i++, dr++) { -- cgit From a73893381f0b7be98b8eb99d31ff834c7658d27c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 07:11:32 +0000 Subject: Introduce bt_malloc() and bt_free() functions --- src/bluetooth.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index c54d63e3..1c01e2d9 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -162,6 +163,16 @@ int basnprintf(char *str, size_t size, const char *format, ...) return len; } +void *bt_malloc(size_t size) +{ + return malloc(size); +} + +void bt_free(void *ptr) +{ + free(ptr); +} + /* Bluetooth error codes to Unix errno mapping */ int bt_error(uint16_t code) { -- cgit From 9409e3e8e152290e253889df6922c56ef606b62b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Aug 2005 07:33:57 +0000 Subject: Update lmp_featurestostr() function --- src/hci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 2447ae9b..c42d81c4 100644 --- a/src/hci.c +++ b/src/hci.c @@ -411,13 +411,13 @@ static hci_map lmp_features_map[8][9] = { char *lmp_featurestostr(uint8_t *features, char *pref, int width) { char *off, *ptr, *str; - int i, size = 0; + int i, size = 10; for (i = 0; i < 8; i++) { hci_map *m = lmp_features_map[i]; while (m->str) { - if ((unsigned int) m->val & (unsigned int) features[i]) + if (m->val & features[i]) size += strlen(m->str) + (pref ? strlen(pref) : 0) + 1; m++; } @@ -427,7 +427,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) if (!str) return NULL; - ptr = str; *ptr = 0; + ptr = str; *ptr = '\0'; if (pref) ptr += sprintf(ptr, "%s", pref); @@ -438,7 +438,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) hci_map *m = lmp_features_map[i]; while (m->str) { - if ((unsigned int) m->val & (unsigned int) features[i]) { + if (m->val & features[i]) { if (strlen(off) + strlen(m->str) > width - 1) { ptr += sprintf(ptr, "\n%s", pref ? pref : ""); off = ptr; -- cgit From e739d2ea50020d8bf8a470a0972ea80db6c3d563 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 6 Aug 2005 08:09:03 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index ee4510ca..9855edc6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:18:0 +libbluetooth_la_LDFLAGS = -version-info 1:19:0 INCLUDES = -I$(top_builddir)/include -- cgit From 2fa38208982e7c7bb55ae97acd13dbf82dd24e88 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 6 Aug 2005 17:43:48 +0000 Subject: Add UUID for video distribution --- src/sdp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index d920a753..c48d4ba7 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -192,6 +192,7 @@ static struct tupla ServiceClass[] = { { UPNP_L2CAP_SVCLASS_ID, "UPnP L2CAP" }, { VIDEO_SOURCE_SVCLASS_ID, "Video Source" }, { VIDEO_SINK_SVCLASS_ID, "Video Sink" }, + { VIDEO_DISTRIBUTION_SVCLASS_ID, "Video Distribution" }, { 0 } }; -- cgit From 8ce8108e712e40e1b9530c96f7ff6cbb32b5cb8b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Aug 2005 11:19:57 +0000 Subject: Add UUIDs for phonebook access profile --- src/sdp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index c48d4ba7..0198f9ec 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -180,6 +180,8 @@ static struct tupla ServiceClass[] = { { UDI_TA_SVCLASS_ID, "UDI TA" }, { AV_SVCLASS_ID, "Audio/Video" }, { SAP_SVCLASS_ID, "SIM Access" }, + { PBAP_PCE_SVCLASS_ID, "Phonebook Access - PCE" }, + { PBAP_PSE_SVCLASS_ID, "Phonebook Access - PSE" }, { PNP_INFO_SVCLASS_ID, "PnP Information" }, { GENERIC_NETWORKING_SVCLASS_ID, "Generic Networking" }, { GENERIC_FILETRANS_SVCLASS_ID, "Generic File Transfer" }, -- cgit From f544b5e43cc3c64d43e73a3fbfc5fd045b6de00c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Aug 2005 00:54:48 +0000 Subject: Add functions for the extended inquiry response --- src/hci.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index c42d81c4..f92aa4f2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1732,6 +1732,60 @@ int hci_write_afh_mode(int dd, uint8_t mode, int to) return 0; } +int hci_read_ext_inquiry_response(int dd, uint8_t *fec, uint8_t *data, int to) +{ + read_ext_inquiry_response_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_EXT_INQUIRY_RESPONSE; + rq.rparam = &rp; + rq.rlen = READ_EXT_INQUIRY_RESPONSE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *fec = rp.fec; + memcpy(data, rp.data, 240); + + return 0; +} + +int hci_write_ext_inquiry_response(int dd, uint8_t fec, uint8_t *data, int to) +{ + write_ext_inquiry_response_cp cp; + write_ext_inquiry_response_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.fec = fec; + memcpy(cp.data, data, 240); + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_EXT_INQUIRY_RESPONSE; + rq.cparam = &cp; + rq.clen = WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to) { read_transmit_power_level_cp cp; -- cgit From 652785638e4bf41e1a60827005d1253a0af7b3e8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 26 Aug 2005 22:26:49 +0000 Subject: Use bt_malloc() for address translation functions --- src/bluetooth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 1c01e2d9..9ba19c50 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -54,7 +54,7 @@ void baswap(bdaddr_t *dst, const bdaddr_t *src) char *batostr(const bdaddr_t *ba) { - char *str = malloc(18); + char *str = bt_malloc(18); if (!str) return NULL; @@ -69,7 +69,7 @@ bdaddr_t *strtoba(const char *str) const char *ptr = str; int i; - uint8_t *ba = malloc(sizeof(bdaddr_t)); + uint8_t *ba = bt_malloc(sizeof(bdaddr_t)); if (!ba) return NULL; -- cgit From f50545eae585ba4b3eac5d8764827342ae214843 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 27 Aug 2005 10:53:49 +0000 Subject: Add extended inquiry features bit --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index f92aa4f2..dd3d0d74 100644 --- a/src/hci.c +++ b/src/hci.c @@ -400,6 +400,7 @@ static hci_map lmp_features_map[8][9] = { { NULL } }, { /* Byte 6 */ + { "", LMP_EXT_INQ }, /* Bit 0 */ { NULL } }, { /* Byte 7 */ -- cgit From 0945829c8c01d162cdabfe96ba8d6f432769947a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 27 Aug 2005 13:18:21 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 9855edc6..3e5af5b2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:19:0 +libbluetooth_la_LDFLAGS = -version-info 1:20:0 INCLUDES = -I$(top_builddir)/include -- cgit From 7e5d794489e6dacb2e37553495af61c98cb78fbc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 4 Sep 2005 22:01:16 +0000 Subject: Add two new company identifiers --- src/bluetooth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 9ba19c50..36f186c5 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -377,6 +377,10 @@ char *bt_compidtostr(int compid) return "IPextreme, Inc."; case 62: return "Systems and Chips, Inc"; + case 63: + return "Bluetooth SIG, Inc"; + case 64: + return "Seiko Epson Corporation"; case 65535: return "internal use"; default: -- cgit From b48bccaf6c89da2af3a20617f4a496be4a633c5b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 7 Sep 2005 16:14:55 +0000 Subject: Add support for identification of supported commands --- src/hci.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 193 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index dd3d0d74..a9c482a2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -98,7 +98,7 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) static char *hci_uint2str(hci_map *m, unsigned int val) { - char *str = malloc(50); + char *str = bt_malloc(50); char *ptr = str; if (!str) @@ -309,6 +309,195 @@ int hci_strtolm(char *str, unsigned int *val) return hci_str2bit(link_mode_map, str, val); } +/* Command mapping */ +static hci_map commands_map[] = { + { "Inquiry", 0 }, + { "Inquiry Cancel", 1 }, + { "Periodic Inquiry Mode", 2 }, + { "Exit Periodic Inquiry Mode", 3 }, + { "Create Connection", 4 }, + { "Disconnect", 5 }, + { "Add SCO Connection", 6 }, + { "Cancel Create Connection", 7 }, + { "Accept Connection Request", 8 }, + { "Reject Connection Request", 9 }, + { "Link Key Request Reply", 10 }, + { "Link Key Request Negative Reply", 11 }, + { "PIN Code Request Reply", 12 }, + { "PIN Code Request Negative Reply", 13 }, + { "Change Connection Packet Type", 14 }, + { "Authentication Requested", 15 }, + { "Set Connection Encryption", 16 }, + { "Change Connection Link Key", 17 }, + { "Master Link Key", 18 }, + { "Remote Name Request", 19 }, + { "Cancel Remote Name Request", 20 }, + { "Read Remote Supported Features", 21 }, + { "Read Remote Extended Features", 22 }, + { "Read Remote Version Information", 23 }, + { "Read Clock Offset", 24 }, + { "Read LMP Handle", 25 }, + { "Reserved", 26 }, + { "Reserved", 27 }, + { "Reserved", 28 }, + { "Reserved", 29 }, + { "Reserved", 30 }, + { "Reserved", 31 }, + { "Reserved", 32 }, + { "Hold Mode", 33 }, + { "Sniff Mode", 34 }, + { "Exit Sniff Mode", 35 }, + { "Park State", 36 }, + { "Exit Park State", 37 }, + { "QoS Setup", 38 }, + { "Role Discovery", 39 }, + { "Switch Role", 40 }, + { "Read Link Policy Settings", 41 }, + { "Write Link Policy Settings", 42 }, + { "Read Default Link Policy Settings", 43 }, + { "Write Default Link Policy Settings", 44 }, + { "Flow Specification", 45 }, + { "Set Event Mask", 46 }, + { "Reset", 47 }, + { "Set Event Filter", 48 }, + { "Flush", 49 }, + { "Read PIN Type", 50 }, + { "Write PIN Type", 51 }, + { "Create New Unit Key", 52 }, + { "Read Stored Link Key", 53 }, + { "Write Stored Link Key", 54 }, + { "Delete Stored Link Key", 55 }, + { "Write Local Name", 56 }, + { "Read Local Name", 57 }, + { "Read Connection Accept Timeout", 58 }, + { "Write Connection Accept Timeout", 59 }, + { "Read Page Timeout", 60 }, + { "Write Page Timeout", 61 }, + { "Read Scan Enable", 62 }, + { "Write Scan Enable", 63 }, + { "Read Page Scan Activity", 64 }, + { "Write Page Scan Activity", 65 }, + { "Read Inquiry Scan Activity", 66 }, + { "Write Inquiry Scan Activity", 67 }, + { "Read Authentication Enable", 68 }, + { "Write Authentication Enable", 69 }, + { "Read Encryption Mode", 70 }, + { "Write Encryption Mode", 71 }, + { "Read Class Of Device", 72 }, + { "Write Class Of Device", 73 }, + { "Read Voice Setting", 74 }, + { "Write Voice Setting", 75 }, + { "Read Automatic Flush Timeout", 76 }, + { "Write Automatic Flush Timeout", 77 }, + { "Read Num Broadcast Retransmissions", 78 }, + { "Write Num Broadcast Retransmissions", 79 }, + { "Read Hold Mode Activity", 80 }, + { "Write Hold Mode Activity", 81 }, + { "Read Transmit Power Level", 82 }, + { "Read Synchronous Flow Control Enable", 83 }, + { "Write Synchronous Flow Control Enable", 84 }, + { "Set Host Controller To Host Flow Control", 85 }, + { "Host Buffer Size", 86 }, + { "Host Number Of Completed Packets", 87 }, + { "Read Link Supervision Timeout", 88 }, + { "Write Link Supervision Timeout", 89 }, + { "Read Number of Supported IAC", 90 }, + { "Read Current IAC LAP", 91 }, + { "Write Current IAC LAP", 92 }, + { "Reserved", 93 }, + { "Reserved", 94 }, + { "Read Page Scan Mode", 95 }, + { "Write Page Scan Mode", 96 }, + { "Set AFH Channel Classification", 97 }, + { "reserved", 98 }, + { "reserved", 99 }, + { "Read Inquiry Scan Type", 100 }, + { "Write Inquiry Scan Type", 101 }, + { "Read Inquiry Mode", 102 }, + { "Write Inquiry Mode", 103 }, + { "Read Page Scan Type", 104 }, + { "Write Page Scan Type", 105 }, + { "Read AFH Channel Assessment Mode", 106 }, + { "Write AFH Channel Assessment Mode", 107 }, + { "Reserved", 108 }, + { "Reserved", 109 }, + { "Reserved", 110 }, + { "Reserved", 111 }, + { "Reserved", 112 }, + { "Reserved", 113 }, + { "Reserved", 114 }, + { "Read Loacal Version Information", 115 }, + { "Reserved", 116 }, + { "Read Local Supported Features", 117 }, + { "Read Local Extended Features", 118 }, + { "Read Buffer Sizer", 119 }, + { "Read Country Code", 120 }, + { "Read BD ADDR", 121 }, + { "Read Failed Contact Counter", 122 }, + { "Reset Failed Contact Counter", 123 }, + { "Get Link Quality", 124 }, + { "Read RSSI", 125 }, + { "Read AFH Channel Map", 126 }, + { "Read BD Clock", 127 }, + { "Read Loopback Mode", 128 }, + { "Write Loopback Mode", 129 }, + { "Enable Device Under Test Mode", 130 }, + { "Setup Synchronous Connection", 131 }, + { "Accept Synchronous Connection", 132 }, + { "Reject Synchronous Connection", 133 }, + { "Reserved", 134 }, + { "Reserved", 135 }, + { "Read Extended Inquiry Response", 136 }, + { "Write Extended Inquiry Response", 137 }, + { NULL } +}; + +char *hci_cmdtostr(unsigned int cmd) +{ + return hci_uint2str(commands_map, cmd); +} + +char *hci_commandstostr(uint8_t *commands, char *pref, int width) +{ + hci_map *m; + char *off, *ptr, *str; + int size = 10; + + m = commands_map; + + while (m->str) { + if (hci_test_bit(m->val, commands)) + size += strlen(m->str) + (pref ? strlen(pref) : 0) + 3; + m++; + } + + str = bt_malloc(size); + if (!str) + return NULL; + + ptr = str; *ptr = '\0'; + + if (pref) + ptr += sprintf(ptr, "%s", pref); + + off = ptr; + + m = commands_map; + + while (m->str) { + if (hci_test_bit(m->val, commands)) { + if (strlen(off) + strlen(m->str) > width - 3) { + ptr += sprintf(ptr, "\n%s", pref ? pref : ""); + off = ptr; + } + ptr += sprintf(ptr, "'%s' ", m->str); + } + m++; + } + + return str; +} + /* Version mapping */ static hci_map ver_map[] = { { "1.0b", 0x00 }, @@ -320,8 +509,7 @@ static hci_map ver_map[] = { char *hci_vertostr(unsigned int ver) { - char *str = hci_uint2str(ver_map, ver); - return *str ? str : "n/a"; + return hci_uint2str(ver_map, ver); } int hci_strtover(char *str, unsigned int *ver) @@ -331,8 +519,7 @@ int hci_strtover(char *str, unsigned int *ver) char *lmp_vertostr(unsigned int ver) { - char *str = hci_uint2str(ver_map, ver); - return *str ? str : "n/a"; + return hci_uint2str(ver_map, ver); } int lmp_strtover(char *str, unsigned int *ver) @@ -424,7 +611,7 @@ char *lmp_featurestostr(uint8_t *features, char *pref, int width) } } - str = malloc(size); + str = bt_malloc(size); if (!str) return NULL; -- cgit From 4537f4ccc98218a2f716294ad957981118a20d8b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Sep 2005 10:50:07 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 3e5af5b2..8da234ae 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:20:0 +libbluetooth_la_LDFLAGS = -version-info 1:21:0 INCLUDES = -I$(top_builddir)/include -- cgit From 12862715c961bf6dabce2ed4e58da58e5dfe8c6b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 22 Sep 2005 23:10:48 +0000 Subject: Fix errno overwrite problems --- src/hci.c | 13 ++++++++----- src/sdp.c | 3 +++ 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index a9c482a2..05974432 100644 --- a/src/hci.c +++ b/src/hci.c @@ -647,21 +647,25 @@ int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long a struct hci_dev_list_req *dl; struct hci_dev_req *dr; int dev_id = -1; - int i, sk, err; + int i, sk, err = 0; sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) return -1; dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); - if (!dl) + if (!dl) { + err = errno; goto done; + } dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; - if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) + if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) { + err = errno; goto free; + } for (i = 0; i < dl->dev_num; i++, dr++) { if (hci_test_bit(flag, &dr->dev_opt)) @@ -672,13 +676,12 @@ int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long a } if (dev_id < 0) - errno = ENODEV; + err = ENODEV; free: free(dl); done: - err = errno; close(sk); errno = err; diff --git a/src/sdp.c b/src/sdp.c index 0198f9ec..56c74d49 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3160,6 +3160,7 @@ static inline int sdp_is_local(const bdaddr_t *device) sdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t flags) { + int err; sdp_session_t *session = malloc(sizeof(sdp_session_t)); if (!session) return session; @@ -3204,8 +3205,10 @@ sdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t fl } } fail: + err = errno; if (session->sock >= 0) close(session->sock); free(session); + errno = err; return 0; } -- cgit From 0f5a5a9580084a3c4e0644ef5cd75689aeb5ff40 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 30 Sep 2005 14:43:37 +0000 Subject: Fix profile descriptor problem with Samsung phones --- src/sdp.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 56c74d49..e0df7582 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -1529,12 +1529,24 @@ int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq) return -1; } for (seq = sdpdata->val.dataseq; seq && seq->val.dataseq; seq = seq->next) { - sdp_data_t *uuid = seq->val.dataseq; - sdp_data_t *pVnum = seq->val.dataseq->next; - if (uuid && pVnum) { + uuid_t *uuid = NULL; + uint16_t version = 0x100; + + if (SDP_IS_UUID(seq->dtd)) { + uuid = &seq->val.uuid; + } else { + sdp_data_t *puuid = seq->val.dataseq; + sdp_data_t *pVnum = seq->val.dataseq->next; + if (puuid && pVnum) { + uuid = &puuid->val.uuid; + version = pVnum->val.uint16; + } + } + + if (uuid != NULL) { profDesc = (sdp_profile_desc_t *)malloc(sizeof(sdp_profile_desc_t)); - profDesc->uuid = uuid->val.uuid; - profDesc->version = pVnum->val.uint16; + profDesc->uuid = *uuid; + profDesc->version = version; #ifdef SDP_DEBUG sdp_uuid_print(&profDesc->uuid); SDPDBG("Vnum : 0x%04x\n", profDesc->version); -- cgit From b60f09936298f7115d5387398d5eeb0156b08892 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 20 Oct 2005 08:55:11 +0000 Subject: Make EVT_CMD_STATUS as rp->event work --- src/hci.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 05974432..c4bb3cd3 100644 --- a/src/hci.c +++ b/src/hci.c @@ -976,7 +976,13 @@ int hci_send_req(int dd, struct hci_request *r, int to) errno = EIO; goto failed; } - break; + + if (r->event != EVT_CMD_STATUS) + break; + + r->rlen = MIN(len, r->rlen); + memcpy(r->rparam, ptr, r->rlen); + goto done; case EVT_CMD_COMPLETE: cc = (void *) ptr; -- cgit From 4fb6514cdebdeb4317ee3a5ef59abcdaf3697d2b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Oct 2005 14:27:14 +0000 Subject: Add deprecated command names from the Bluetooth 1.2 specification --- src/hci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index c4bb3cd3..c1aa9b28 100644 --- a/src/hci.c +++ b/src/hci.c @@ -404,8 +404,8 @@ static hci_map commands_map[] = { { "Read Number of Supported IAC", 90 }, { "Read Current IAC LAP", 91 }, { "Write Current IAC LAP", 92 }, - { "Reserved", 93 }, - { "Reserved", 94 }, + { "Read Page Scan Period Mode", 93 }, + { "Write Page Scan Period Mode", 94 }, { "Read Page Scan Mode", 95 }, { "Write Page Scan Mode", 96 }, { "Set AFH Channel Classification", 97 }, @@ -426,8 +426,8 @@ static hci_map commands_map[] = { { "Reserved", 112 }, { "Reserved", 113 }, { "Reserved", 114 }, - { "Read Loacal Version Information", 115 }, - { "Reserved", 116 }, + { "Read Local Version Information", 115 }, + { "Read Local Supported Commands", 116 }, { "Read Local Supported Features", 117 }, { "Read Local Extended Features", 118 }, { "Read Buffer Sizer", 119 }, -- cgit From 555ac3f21cb5f6099755d43c3c1e89a1a554b435 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Oct 2005 15:51:12 +0000 Subject: Fix typo --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index c1aa9b28..b286d46f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -430,7 +430,7 @@ static hci_map commands_map[] = { { "Read Local Supported Commands", 116 }, { "Read Local Supported Features", 117 }, { "Read Local Extended Features", 118 }, - { "Read Buffer Sizer", 119 }, + { "Read Buffer Size", 119 }, { "Read Country Code", 120 }, { "Read BD ADDR", 121 }, { "Read Failed Contact Counter", 122 }, -- cgit From 1364c63b9eea39b40ab07e0045ef26e76d1ade1a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Oct 2005 17:32:35 +0000 Subject: Decode reserved LMP feature bits --- src/hci.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index b286d46f..80813ad6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -556,10 +556,14 @@ static hci_map lmp_features_map[8][9] = { { "", LMP_PSCHEME }, /* Bit 1 */ { "", LMP_PCONTROL }, /* Bit 2 */ { "", LMP_TRSP_SCO }, /* Bit 3 */ + { "",LMP_BCAST_ENC }, /* Bit 7 */ { NULL } }, { /* Byte 3 */ + { "", 0x01 }, /* Bit 0 */ { "", LMP_EDR_ACL_2M }, /* Bit 1 */ { "", LMP_EDR_ACL_3M }, /* Bit 2 */ { "", LMP_ENH_ISCAN }, /* Bit 3 */ @@ -572,13 +576,18 @@ static hci_map lmp_features_map[8][9] = { { /* Byte 4 */ { "", LMP_EV4 }, /* Bit 0 */ { "", LMP_EV5 }, /* Bit 1 */ + { "", 0x04 }, /* Bit 2 */ { "", LMP_AFH_CAP_SLV }, /* Bit 3 */ { "", LMP_AFH_CLS_SLV }, /* Bit 4 */ + { "", 0x20 }, /* Bit 5 */ + { "", 0x40 }, /* Bit 6 */ { "<3-slot EDR ACL>", LMP_EDR_3SLOT }, /* Bit 7 */ { NULL } }, { /* Byte 5 */ { "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */ + { "", 0x02 }, /* Bit 1 */ + { "", 0x04 }, /* Bit 2 */ { "", LMP_AFH_CAP_MST }, /* Bit 3 */ { "",LMP_AFH_CLS_MST }, /* Bit 4 */ { "", LMP_EDR_ESCO_2M }, /* Bit 5 */ -- cgit From c0d524486a50e8366c12c5ebea1a4441e9db46aa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 29 Oct 2005 19:25:42 +0000 Subject: Big cleanup of CVS relics --- src/Makefile.am | 3 --- src/bluetooth.c | 25 ++++++++++--------------- src/hci.c | 25 ++++++++++--------------- src/sdp.c | 25 ++++++++++--------------- 4 files changed, 30 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 8da234ae..09544baf 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,3 @@ -# -# $Id$ -# lib_LTLIBRARIES = libbluetooth.la diff --git a/src/bluetooth.c b/src/bluetooth.c index 36f186c5..5b468285 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.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/src/hci.c b/src/hci.c index 80813ad6..eeb171a1 100644 --- a/src/hci.c +++ b/src/hci.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/src/sdp.c b/src/sdp.c index e0df7582..57da1df9 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -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 -- cgit From e36da2e02f410298e5ecc0238c439e659b861c2a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Oct 2005 16:27:56 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 09544baf..dcb2cb91 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:21:0 +libbluetooth_la_LDFLAGS = -version-info 1:22:0 INCLUDES = -I$(top_builddir)/include -- cgit From a097798c889cef47144b3cce2118c5d9e914864c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 2 Nov 2005 13:19:55 +0000 Subject: Remove decoding of flow control feature bits --- src/hci.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index eeb171a1..d21ef274 100644 --- a/src/hci.c +++ b/src/hci.c @@ -551,9 +551,6 @@ static hci_map lmp_features_map[8][9] = { { "", LMP_PSCHEME }, /* Bit 1 */ { "", LMP_PCONTROL }, /* Bit 2 */ { "", LMP_TRSP_SCO }, /* Bit 3 */ - { "",LMP_BCAST_ENC }, /* Bit 7 */ { NULL } }, -- cgit From 7575a227c3ad282247c288fa8def69d9dcd7603f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 21 Nov 2005 10:26:56 +0000 Subject: Add constants for sniff subrating --- src/hci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index d21ef274..a70fba9b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -444,6 +444,9 @@ static hci_map commands_map[] = { { "Reserved", 135 }, { "Read Extended Inquiry Response", 136 }, { "Write Extended Inquiry Response", 137 }, + { "Unknown", 138 }, + { "Unknown", 139 }, + { "Sniff Subrate", 140 }, { NULL } }; @@ -578,7 +581,7 @@ static hci_map lmp_features_map[8][9] = { }, { /* Byte 5 */ { "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */ - { "", 0x02 }, /* Bit 1 */ + { "", LMP_SNIFF_SUBR }, /* Bit 1 */ { "", 0x04 }, /* Bit 2 */ { "", LMP_AFH_CAP_MST }, /* Bit 3 */ { "",LMP_AFH_CLS_MST }, /* Bit 4 */ -- cgit From 8db4e616c0107df21e3cacd981d073a64414de77 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Nov 2005 04:19:49 +0000 Subject: Fix service discovery deadlocks with Samsung D600 phones --- src/sdp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 57da1df9..67a20008 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3115,6 +3115,10 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search status = -1; goto end; } + if (!recsize) { + sdp_record_free(rec); + break; + } scanned += recsize; pdata += recsize; -- cgit From 641d636fb24fb0dea567388a4f0d0f135d4ea48c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Dec 2005 09:12:44 +0000 Subject: Add support for allocation of binary text elements --- src/sdp.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 89 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 67a20008..9f3f79e1 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -344,10 +344,9 @@ void sdp_uuid_print(const uuid_t *uuid) } #endif -sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) +sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, uint32_t length) { sdp_data_t *seq; - int len = 0; sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); if (!d) @@ -414,21 +413,25 @@ sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) d->unitSize += sizeof(uint128_t); break; case SDP_URL_STR8: - case SDP_TEXT_STR8: case SDP_URL_STR16: + case SDP_TEXT_STR8: case SDP_TEXT_STR16: - if (!value) - goto out_error; + if (!value) { + free(d); + return NULL; + } + + d->unitSize += length; + if (length <= USHRT_MAX) { + d->val.str = malloc(length); + if (!d->val.str) { + free(d); + return NULL; + } - len = strlen(value); - d->unitSize += len; - if (len <= USHRT_MAX) { - d->val.str = (char *) malloc(len + 1); - if (!d->val.str) - goto out_error; + memcpy(d->val.str, value, length); - strcpy(d->val.str, value); - if (len <= UCHAR_MAX) { + if (length <= UCHAR_MAX) { d->unitSize += sizeof(uint8_t); if (dtd != SDP_URL_STR8 && dtd != SDP_TEXT_STR8) { if (dtd == SDP_URL_STR16) @@ -445,7 +448,8 @@ sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) } } else { SDPERR("Strings of size > USHRT_MAX not supported\n"); - goto out_error; + free(d); + d = NULL; } break; case SDP_URL_STR32: @@ -470,13 +474,33 @@ sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) d->unitSize += seq->unitSize; break; default: - goto out_error; + free(d); + d = NULL; } + return d; +} -out_error: - free(d); - return NULL; +sdp_data_t *sdp_data_alloc(uint8_t dtd, const void *value) +{ + uint32_t length; + + switch (dtd) { + case SDP_URL_STR8: + case SDP_URL_STR16: + case SDP_TEXT_STR8: + case SDP_TEXT_STR16: + if (!value) + return NULL; + + length = strlen((char *) value); + break; + default: + length = 0; + break; + } + + return sdp_data_alloc_with_length(dtd, value, length); } sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d) @@ -491,6 +515,34 @@ sdp_data_t *sdp_seq_append(sdp_data_t *seq, sdp_data_t *d) return seq; } +sdp_data_t *sdp_seq_alloc_with_length(void **dtds, void **values, int *length, int len) +{ + sdp_data_t *curr = NULL, *seq = NULL; + int i; + + for (i = 0; i < len; i++) { + sdp_data_t *data; + int8_t dtd = *(uint8_t *) dtds[i]; + + if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32) + data = (sdp_data_t *) values[i]; + else + data = sdp_data_alloc_with_length(dtd, values[i], length[i]); + + if (!data) + return NULL; + + if (curr) + curr->next = data; + else + seq = data; + + curr = data; + } + + return sdp_data_alloc_with_length(SDP_SEQ8, seq, length[i]); +} + sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len) { sdp_data_t *curr = NULL, *seq = NULL; @@ -498,19 +550,24 @@ sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len) for (i = 0; i < len; i++) { sdp_data_t *data; - uint8_t dtd = *(uint8_t *)dtds[i]; + uint8_t dtd = *(uint8_t *) dtds[i]; + if (dtd >= SDP_SEQ8 && dtd <= SDP_ALT32) - data = (sdp_data_t *)values[i]; + data = (sdp_data_t *) values[i]; else data = sdp_data_alloc(dtd, values[i]); + if (!data) return NULL; + if (curr) curr->next = data; else seq = data; + curr = data; } + return sdp_data_alloc(SDP_SEQ8, seq); } @@ -565,6 +622,7 @@ int sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd) *p++ = dtd; buf->data_size += sizeof(uint8_t); + switch (dtd) { case SDP_SEQ8: case SDP_TEXT_STR8: @@ -585,6 +643,7 @@ int sdp_set_data_type(sdp_buf_t *buf, uint8_t dtd) buf->data_size += sizeof(uint32_t); break; } + return buf->data_size - orig; } @@ -607,6 +666,7 @@ static int get_data_size(sdp_buf_t *buf, sdp_data_t *sdpdata) for (d = sdpdata->val.dataseq; d; d = d->next) n += sdp_gen_pdu(buf, d); + return n; } @@ -622,6 +682,7 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) uint8_t *seqp = buf->data + buf->data_size; pdu_size = sdp_set_data_type(buf, dtd); + switch (dtd) { case SDP_DATA_NIL: break; @@ -675,9 +736,13 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) data_size = sizeof(uint128_t); break; case SDP_TEXT_STR8: - case SDP_URL_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: + src = (unsigned char *)d->val.str; + data_size = d->unitSize - sizeof(uint8_t); + sdp_set_seq_len(seqp, data_size); + break; + case SDP_URL_STR8: case SDP_URL_STR16: case SDP_URL_STR32: src = (unsigned char *)d->val.str; @@ -715,6 +780,7 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) default: break; } + if (!is_seq && !is_alt) { if (src && buf) { memcpy(buf->data + buf->data_size, src, data_size); @@ -722,7 +788,9 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) } else if (dtd != SDP_DATA_NIL) SDPDBG("Gen PDU : Cant copy from NULL source or dest\n"); } + pdu_size += data_size; + return pdu_size; } -- cgit From 73fa16fccbb85592973068a25949d4c331f7f475 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Dec 2005 09:39:16 +0000 Subject: Add FD_ZERO() before usage of FD_SET() --- src/sdp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 9f3f79e1..90bc447e 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -1269,9 +1269,10 @@ int sdp_read_rsp(sdp_session_t *session, uint8_t *buf, uint32_t size) fd_set readFds; struct timeval timeout = { SDP_RESPONSE_TIMEOUT, 0 }; + FD_ZERO(&readFds); FD_SET(session->sock, &readFds); SDPDBG("Waiting for response\n"); - if (0 == select(session->sock + 1, &readFds, NULL, NULL, &timeout)) { + if (select(session->sock + 1, &readFds, NULL, NULL, &timeout) == 0) { SDPERR("Client timed out\n"); errno = ETIMEDOUT; return -1; -- cgit From 72c29d4475b8b5f06eb0e518797e014837101cb5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 10 Dec 2005 13:55:34 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index dcb2cb91..c6df14f6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:22:0 +libbluetooth_la_LDFLAGS = -version-info 1:23:0 INCLUDES = -I$(top_builddir)/include -- cgit From aa8d087a052ab9c54dde1b0ddaf3a47494ef899a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 14 Dec 2005 10:11:26 +0000 Subject: Add support for additional access protocols --- src/sdp.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 90bc447e..28c08679 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -1812,13 +1812,31 @@ static sdp_data_t *access_proto_to_dataseq(sdp_record_t *rec, sdp_list_t *proto) int sdp_set_access_protos(sdp_record_t *rec, const sdp_list_t *ap) { const sdp_list_t *p; - sdp_data_t *protos = 0; + sdp_data_t *protos = NULL; for (p = ap; p; p = p->next) { - sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *)p->data); + sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data); protos = sdp_seq_append(protos, seq); } + sdp_attr_add(rec, SDP_ATTR_PROTO_DESC_LIST, protos); + + return 0; +} + +int sdp_set_add_access_protos(sdp_record_t *rec, const sdp_list_t *ap) +{ + const sdp_list_t *p; + sdp_data_t *protos = NULL; + + for (p = ap; p; p = p->next) { + sdp_data_t *seq = access_proto_to_dataseq(rec, (sdp_list_t *) p->data); + protos = sdp_seq_append(protos, seq); + } + + sdp_attr_add(rec, SDP_ATTR_ADD_PROTO_DESC_LIST, + protos ? sdp_data_alloc(SDP_SEQ8, protos) : NULL); + return 0; } -- cgit From 5ccf1c4a96dfde5dc04c136644448483b648c186 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 24 Dec 2005 16:46:53 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index c6df14f6..8bfc37d8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:23:0 +libbluetooth_la_LDFLAGS = -version-info 1:24:0 INCLUDES = -I$(top_builddir)/include -- cgit From a1b96c15eb685081c9329531906d18fce8405af7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 09:56:12 +0000 Subject: Include sys/uio.h for writev() function --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index a70fba9b..8dd3e1c6 100644 --- a/src/hci.c +++ b/src/hci.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include -- cgit From 197a2aee34d9a1643cd474f8f167552ca6395d01 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jan 2006 12:56:09 +0000 Subject: Update copyright information --- src/bluetooth.c | 2 +- src/hci.c | 2 +- src/sdp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 5b468285..1482a56e 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.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/src/hci.c b/src/hci.c index 8dd3e1c6..6a33d3c4 100644 --- a/src/hci.c +++ b/src/hci.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/src/sdp.c b/src/sdp.c index 28c08679..da83c23e 100644 --- a/src/sdp.c +++ b/src/sdp.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 * * -- cgit From 42e0ce5b430ac5e36c0d21bdddcaf1fe83e025f5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 4 Jan 2006 00:04:30 +0000 Subject: Add definitions for Apple Agent --- src/sdp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index da83c23e..0421e699 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -190,6 +190,7 @@ static struct tupla ServiceClass[] = { { VIDEO_SOURCE_SVCLASS_ID, "Video Source" }, { VIDEO_SINK_SVCLASS_ID, "Video Sink" }, { VIDEO_DISTRIBUTION_SVCLASS_ID, "Video Distribution" }, + { APPLE_AGENT_SVCLASS_ID, "Apple Agent" }, { 0 } }; -- cgit From 49fe626b5c153e4bc6a174982a89e9b3b2e4baf2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 10:39:37 +0000 Subject: Add support for setting the record handle on service registration --- src/sdp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 0421e699..2510ccf3 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2411,6 +2411,11 @@ int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_rec errno = ENOMEM; goto end; } + if (rec->handle && rec->handle != 0xffffffff) { + uint32_t handle = rec->handle; + sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); + sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); + } reqhdr = (sdp_pdu_hdr_t *)req; reqhdr->pdu_id = SDP_SVC_REGISTER_REQ; reqhdr->tid = htons(sdp_gen_tid(session)); -- cgit From 12ee1dcf6933f6096f9763aee5dafeccf71ff2de Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 17 Jan 2006 23:10:01 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 8bfc37d8..61ef2fb1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:24:0 +libbluetooth_la_LDFLAGS = -version-info 1:25:0 INCLUDES = -I$(top_builddir)/include -- cgit From 1ba3b0978c73153513cfe016435e1e930038fbd4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Feb 2006 07:48:11 +0000 Subject: Add features bit for pause encryption --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 6a33d3c4..9e81653c 100644 --- a/src/hci.c +++ b/src/hci.c @@ -583,7 +583,7 @@ static hci_map lmp_features_map[8][9] = { { /* Byte 5 */ { "<5-slot EDR ACL>", LMP_EDR_5SLOT }, /* Bit 0 */ { "", LMP_SNIFF_SUBR }, /* Bit 1 */ - { "", 0x04 }, /* Bit 2 */ + { "", LMP_PAUSE_ENC }, /* Bit 2 */ { "", LMP_AFH_CAP_MST }, /* Bit 3 */ { "",LMP_AFH_CLS_MST }, /* Bit 4 */ { "", LMP_EDR_ESCO_2M }, /* Bit 5 */ -- cgit From 93048c3a1a3f8a86d8f5be1bd3409f77e9802d6e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 14 Mar 2006 18:25:35 +0000 Subject: Fix broken behavior with EVT_CMD_STATUS --- src/hci.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 9e81653c..d0c2394c 100644 --- a/src/hci.c +++ b/src/hci.c @@ -977,13 +977,13 @@ int hci_send_req(int dd, struct hci_request *r, int to) if (cs->opcode != opcode) continue; - if (cs->status) { - errno = EIO; - goto failed; - } - - if (r->event != EVT_CMD_STATUS) + if (r->event != EVT_CMD_STATUS) { + if (cs->status) { + errno = EIO; + goto failed; + } break; + } r->rlen = MIN(len, r->rlen); memcpy(r->rparam, ptr, r->rlen); -- cgit From fd920beb236c034c779de5ccf4a5d050897d40bc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 16 Apr 2006 19:32:38 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 1482a56e..75888730 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -376,6 +376,8 @@ char *bt_compidtostr(int compid) return "Bluetooth SIG, Inc"; case 64: return "Seiko Epson Corporation"; + case 65: + return "Integrated Silicon Solution Taiwain, Inc."; case 65535: return "internal use"; default: -- cgit From 07e291d7269885187586106e059f29abb336cb27 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Apr 2006 15:55:51 +0000 Subject: Add missing memset() for socket address --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index d0c2394c..35aa9059 100644 --- a/src/hci.c +++ b/src/hci.c @@ -856,6 +856,7 @@ int hci_open_dev(int dev_id) return dd; /* Bind socket to the HCI device */ + memset(&a, 0, sizeof(a)); a.hci_family = AF_BLUETOOTH; a.hci_dev = dev_id; if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0) -- cgit From 1b64c76ef66c10500f575240bd214c7b38b68a1f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 30 May 2006 10:51:54 +0000 Subject: Add two new company identifiers --- src/bluetooth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 75888730..9df142a0 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -378,6 +378,10 @@ char *bt_compidtostr(int compid) return "Seiko Epson Corporation"; case 65: return "Integrated Silicon Solution Taiwain, Inc."; + case 66: + return "CONWISE Technology Corporation Ltd"; + case 67: + return "PARROT SA"; case 65535: return "internal use"; default: -- cgit From 73f2fe893f6801358ea4fb88dc8d24050c7d0ca5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 30 May 2006 10:58:30 +0000 Subject: Add another Phonebook Access identifier --- src/sdp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 2510ccf3..58f7b269 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -177,6 +177,7 @@ static struct tupla ServiceClass[] = { { SAP_SVCLASS_ID, "SIM Access" }, { PBAP_PCE_SVCLASS_ID, "Phonebook Access - PCE" }, { PBAP_PSE_SVCLASS_ID, "Phonebook Access - PSE" }, + { PBAP_SVCLASS_ID, "Phonebook Access" }, { PNP_INFO_SVCLASS_ID, "PnP Information" }, { GENERIC_NETWORKING_SVCLASS_ID, "Generic Networking" }, { GENERIC_FILETRANS_SVCLASS_ID, "Generic File Transfer" }, -- cgit From 31530898cb8cba0952a1af0bfe8fd26806c7b075 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Jun 2006 15:41:44 +0000 Subject: Fix uninitialised value error --- src/hci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 35aa9059..d5d7124f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -762,6 +762,8 @@ int hci_devba(int dev_id, bdaddr_t *bdaddr) { struct hci_dev_info di; + memset(&di, 0, sizeof(di)); + if (hci_devinfo(dev_id, &di)) return -1; -- cgit From 1b9e5873f730b50987c494c7397b40ac614ba62d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Jun 2006 15:45:08 +0000 Subject: Fix sdp_gen_pdu data_size computation --- src/sdp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 58f7b269..abefca98 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -742,6 +742,10 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) case SDP_TEXT_STR32: src = (unsigned char *)d->val.str; data_size = d->unitSize - sizeof(uint8_t); + if (data_size - sizeof(uint8_t) <= UCHAR_MAX) + data_size -= sizeof(uint8_t); + else + data_size -= sizeof(uint16_t); sdp_set_seq_len(seqp, data_size); break; case SDP_URL_STR8: -- cgit From dcd9814735324f08d91a6a3d1eb7b2b31d2915a6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Jun 2006 15:57:21 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 61ef2fb1..5f6b7129 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 1:25:0 +libbluetooth_la_LDFLAGS = -version-info 2:0:0 INCLUDES = -I$(top_builddir)/include -- cgit From 5ed11d784fcfa59254246bd401d4d1142bb5b9cb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 16 Jun 2006 09:00:30 +0000 Subject: Add missing placeholders for feature bits --- src/hci.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index d5d7124f..977c60eb 100644 --- a/src/hci.c +++ b/src/hci.c @@ -593,9 +593,23 @@ static hci_map lmp_features_map[8][9] = { }, { /* Byte 6 */ { "", LMP_EXT_INQ }, /* Bit 0 */ + { "", 0x02 }, /* Bit 1 */ + { "", 0x04 }, /* Bit 2 */ + { "", 0x08 }, /* Bit 3 */ + { "", 0x10 }, /* Bit 4 */ + { "", 0x20 }, /* Bit 5 */ + { "", 0x40 }, /* Bit 6 */ + { "", 0x80 }, /* Bit 7 */ { NULL } }, { /* Byte 7 */ + { "", 0x01 }, /* Bit 1 */ + { "", 0x02 }, /* Bit 1 */ + { "", 0x04 }, /* Bit 2 */ + { "", 0x08 }, /* Bit 3 */ + { "", 0x10 }, /* Bit 4 */ + { "", 0x20 }, /* Bit 5 */ + { "", 0x40 }, /* Bit 6 */ { "",LMP_EXT_FEAT }, /* Bit 7 */ { NULL } }, -- cgit From bf73a154826860245f6af3f82c336c53e6286f20 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 17 Jun 2006 12:22:19 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 5f6b7129..707bfd98 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 2:0:0 +libbluetooth_la_LDFLAGS = -version-info 2:1:0 INCLUDES = -I$(top_builddir)/include -- cgit From 0ed4f8572e1b32b4dd57304db14351f0e0c59119 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 26 Jun 2006 12:44:31 +0000 Subject: Fix handling of strings --- src/sdp.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index abefca98..fd743b60 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -432,22 +432,6 @@ sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, uint32_t } memcpy(d->val.str, value, length); - - if (length <= UCHAR_MAX) { - d->unitSize += sizeof(uint8_t); - if (dtd != SDP_URL_STR8 && dtd != SDP_TEXT_STR8) { - if (dtd == SDP_URL_STR16) - dtd = SDP_URL_STR8; - else - dtd = SDP_TEXT_STR8; - } - } else { - d->unitSize += sizeof(uint16_t); - if (dtd == SDP_TEXT_STR8) - dtd = SDP_TEXT_STR16; - else - dtd = SDP_URL_STR16; - } } else { SDPERR("Strings of size > USHRT_MAX not supported\n"); free(d); @@ -742,10 +726,6 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) case SDP_TEXT_STR32: src = (unsigned char *)d->val.str; data_size = d->unitSize - sizeof(uint8_t); - if (data_size - sizeof(uint8_t) <= UCHAR_MAX) - data_size -= sizeof(uint8_t); - else - data_size -= sizeof(uint16_t); sdp_set_seq_len(seqp, data_size); break; case SDP_URL_STR8: @@ -973,7 +953,7 @@ static sdp_data_t *extract_str(const void *p, int *len) SDPDBG("Str : %s\n", s); d->val.str = s; - d->unitSize = n; + d->unitSize = n + sizeof(uint8_t); return d; } -- cgit From 39519245f25c517424d1f2ccbed07777c8e060fa Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 8 Jul 2006 11:45:21 +0000 Subject: Add adapter type for SDIO --- src/hci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 977c60eb..6fa61831 100644 --- a/src/hci.c +++ b/src/hci.c @@ -138,8 +138,8 @@ static int hci_str2uint(hci_map *map, char *str, unsigned int *val) char *hci_dtypetostr(int type) { switch (type) { - case HCI_VHCI: - return "VHCI"; + case HCI_VIRTUAL: + return "VIRTUAL"; case HCI_USB: return "USB"; case HCI_PCCARD: @@ -150,8 +150,10 @@ char *hci_dtypetostr(int type) return "RS232"; case HCI_PCI: return "PCI"; + case HCI_SDIO: + return "SDIO"; default: - return "UKNW"; + return "UNKNOWN"; } } -- cgit From 57834785d5445439c2abbc19903566f050bc98a2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jul 2006 01:23:04 +0000 Subject: Add features bit for link supervision timeout --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 6fa61831..48989aae 100644 --- a/src/hci.c +++ b/src/hci.c @@ -605,7 +605,7 @@ static hci_map lmp_features_map[8][9] = { { NULL } }, { /* Byte 7 */ - { "", 0x01 }, /* Bit 1 */ + { "", LMP_LSTO }, /* Bit 1 */ { "", 0x02 }, /* Bit 1 */ { "", 0x04 }, /* Bit 2 */ { "", 0x08 }, /* Bit 3 */ -- cgit From 05909adb9c4d36adb8d95c14ab5d4aa6514edbe5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 27 Jul 2006 02:16:43 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 707bfd98..8c4d613e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 2:1:0 +libbluetooth_la_LDFLAGS = -version-info 3:0:1 INCLUDES = -I$(top_builddir)/include -- cgit From 646fda930139720d7d9c45cc085ae4eb7018d8bb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 31 Jul 2006 09:56:18 +0000 Subject: Add link supervision timeout change event --- src/hci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 48989aae..7135501b 100644 --- a/src/hci.c +++ b/src/hci.c @@ -2058,7 +2058,7 @@ int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout return -1; } - *timeout = rp.link_sup_to; + *timeout = rp.timeout; return 0; } @@ -2069,8 +2069,8 @@ int hci_write_link_supervision_timeout(int dd, uint16_t handle, uint16_t timeout struct hci_request rq; memset(&cp, 0, sizeof(cp)); - cp.handle = handle; - cp.link_sup_to = timeout; + cp.handle = handle; + cp.timeout = timeout; memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; -- cgit From 8f6ea7c3d24dc21f120b6d29fc975936b4d4f3b7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 17 Aug 2006 21:59:25 +0000 Subject: Add additional private data field --- src/sdp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index fd743b60..edde4dbf 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3301,3 +3301,13 @@ fail: errno = err; return 0; } + +int sdp_get_socket(const sdp_session_t *session) +{ + return session->sock; +} + +uint16_t sdp_gen_tid(sdp_session_t *session) +{ + return session->tid++; +} -- cgit From 99b4c49f0afb4bb3bc92bded8ed8ab59e67a440a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 21 Aug 2006 10:32:10 +0000 Subject: Initialize hci_dev_info memory to zero before calling ioctl --- src/hci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 7135501b..caed69bf 100644 --- a/src/hci.c +++ b/src/hci.c @@ -764,6 +764,8 @@ int hci_devinfo(int dev_id, struct hci_dev_info *di) if (dd < 0) return dd; + memset(di, 0, sizeof(struct hci_dev_info)); + di->dev_id = dev_id; ret = ioctl(dd, HCIGETDEVINFO, (void *) di); -- cgit From 9b3d6f5cd180f037789e0b2af4656f55d6df2c0c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 21 Aug 2006 11:26:43 +0000 Subject: Initialize memory to zero in hci_for_each_dev --- src/hci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index caed69bf..dca4c096 100644 --- a/src/hci.c +++ b/src/hci.c @@ -680,6 +680,8 @@ int hci_for_each_dev(int flag, int (*func)(int dd, int dev_id, long arg), long a goto done; } + memset(dl, 0, HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); + dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; -- cgit From c1f630feca4f3fa9d172f27d00a68a2453d223b6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 Aug 2006 04:03:00 +0000 Subject: Update library version --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 8c4d613e..74aca994 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 3:0:1 +libbluetooth_la_LDFLAGS = -version-info 4:0:2 INCLUDES = -I$(top_builddir)/include -- cgit From 21f2a5244f0c6195e17ff71868328bc71d77f4d9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 23 Aug 2006 15:05:30 +0000 Subject: Fix malloc() versus bt_malloc() usage --- src/hci.c | 8 ++++---- src/sdp.c | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index dca4c096..f7235f74 100644 --- a/src/hci.c +++ b/src/hci.c @@ -94,7 +94,7 @@ static int hci_str2bit(hci_map *map, char *str, unsigned int *val) static char *hci_uint2str(hci_map *m, unsigned int val) { - char *str = bt_malloc(50); + char *str = malloc(50); char *ptr = str; if (!str) @@ -174,7 +174,7 @@ static hci_map dev_flags_map[] = { char *hci_dflagstostr(uint32_t flags) { - char *str = malloc(50); + char *str = bt_malloc(50); char *ptr = str; hci_map *m = dev_flags_map; @@ -283,7 +283,7 @@ static hci_map link_mode_map[] = { char *hci_lmtostr(unsigned int lm) { - char *s, *str = malloc(50); + char *s, *str = bt_malloc(50); if (!str) return NULL; @@ -293,7 +293,7 @@ char *hci_lmtostr(unsigned int lm) s = hci_bit2str(link_mode_map, lm); if (!s) { - free(str); + bt_free(str); return NULL; } diff --git a/src/sdp.c b/src/sdp.c index edde4dbf..86caa15c 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -349,7 +349,7 @@ void sdp_uuid_print(const uuid_t *uuid) sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value, uint32_t length) { sdp_data_t *seq; - sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); + sdp_data_t *d = malloc(sizeof(sdp_data_t)); if (!d) return NULL; @@ -853,7 +853,7 @@ void sdp_data_free(sdp_data_t *d) static sdp_data_t *extract_int(const void *p, int *len) { - sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); + sdp_data_t *d = malloc(sizeof(sdp_data_t)); SDPDBG("Extracting integer\n"); memset(d, 0, sizeof(sdp_data_t)); @@ -899,11 +899,11 @@ static sdp_data_t *extract_int(const void *p, int *len) static sdp_data_t *extract_uuid(const uint8_t *p, int *len, sdp_record_t *rec) { - sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); + sdp_data_t *d = malloc(sizeof(sdp_data_t)); SDPDBG("Extracting UUID"); memset(d, 0, sizeof(sdp_data_t)); - if (0 > sdp_uuid_extract(p, &d->val.uuid, len)) { + if (sdp_uuid_extract(p, &d->val.uuid, len) < 0) { free(d); return NULL; } @@ -919,7 +919,7 @@ static sdp_data_t *extract_str(const void *p, int *len) { char *s; int n; - sdp_data_t *d = (sdp_data_t *) malloc(sizeof(sdp_data_t)); + sdp_data_t *d = malloc(sizeof(sdp_data_t)); memset(d, 0, sizeof(sdp_data_t)); d->dtd = *(uint8_t *) p; @@ -961,7 +961,7 @@ static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec) { int seqlen, n = 0; sdp_data_t *curr, *prev; - sdp_data_t *d = (sdp_data_t *)malloc(sizeof(sdp_data_t)); + sdp_data_t *d = malloc(sizeof(sdp_data_t)); SDPDBG("Extracting SEQ"); memset(d, 0, sizeof(sdp_data_t)); @@ -1297,7 +1297,7 @@ int sdp_send_req_w4_rsp(sdp_session_t *session, uint8_t *reqbuf, uint8_t *rspbuf */ sdp_list_t *sdp_list_append(sdp_list_t *p, void *d) { - sdp_list_t *q, *n = (sdp_list_t *)malloc(sizeof(sdp_list_t)); + sdp_list_t *q, *n = malloc(sizeof(sdp_list_t)); if (!n) return 0; @@ -1335,7 +1335,7 @@ sdp_list_t *sdp_list_insert_sorted(sdp_list_t *list, void *d, sdp_comp_func_t f) { sdp_list_t *q, *p, *n; - n = (sdp_list_t *)malloc(sizeof(sdp_list_t)); + n = malloc(sizeof(sdp_list_t)); if (!n) return 0; n->data = d; @@ -1471,7 +1471,7 @@ int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **se if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) { sdp_data_t *d; for (d = sdpdata->val.dataseq; d; d = d->next) { - uuid_t *u = (uuid_t *)malloc(sizeof(uuid_t)); + uuid_t *u = malloc(sizeof(uuid_t)); memset((char *)u, 0, sizeof(uuid_t)); if (d->dtd >= SDP_UUID16 && d->dtd <= SDP_UUID128) { *u = d->val.uuid; @@ -1553,7 +1553,7 @@ int sdp_get_lang_attr(const sdp_record_t *rec, sdp_list_t **langSeq) sdp_data_t *pEncoding = pCode->next; sdp_data_t *pOffset = pEncoding->next; if (pCode && pEncoding && pOffset) { - lang = (sdp_lang_attr_t *)malloc(sizeof(sdp_lang_attr_t)); + lang = malloc(sizeof(sdp_lang_attr_t)); lang->code_ISO639 = pCode->val.uint16; lang->encoding = pEncoding->val.uint16; lang->base_offset = pOffset->val.uint16; @@ -1594,7 +1594,7 @@ int sdp_get_profile_descs(const sdp_record_t *rec, sdp_list_t **profDescSeq) } if (uuid != NULL) { - profDesc = (sdp_profile_desc_t *)malloc(sizeof(sdp_profile_desc_t)); + profDesc = malloc(sizeof(sdp_profile_desc_t)); profDesc->uuid = *uuid; profDesc->version = version; #ifdef SDP_DEBUG @@ -2039,7 +2039,7 @@ uint128_t *sdp_create_base_uuid(void) if (bluetooth_base_uuid == NULL) { strcpy(baseStr, BASE_UUID); - bluetooth_base_uuid = (uint128_t *)malloc(sizeof(uint128_t)); + bluetooth_base_uuid = malloc(sizeof(uint128_t)); data = bluetooth_base_uuid->data; memset(data, '\0', sizeof(uint128_t)); memset(temp, '\0', 10); @@ -2201,7 +2201,7 @@ void sdp_uuid32_to_uuid128(uuid_t *uuid128, uuid_t *uuid32) uuid_t *sdp_uuid_to_uuid128(uuid_t *uuid) { - uuid_t *uuid128 = (uuid_t *)malloc(sizeof(uuid_t)); + uuid_t *uuid128 = bt_malloc(sizeof(uuid_t)); memset(uuid128, 0, sizeof(uuid_t)); switch (uuid->type) { case SDP_UUID128: @@ -2583,7 +2583,7 @@ int sdp_record_update(sdp_session_t *session, const sdp_record_t *rec) sdp_record_t *sdp_record_alloc() { - sdp_record_t *rec = (sdp_record_t *)malloc(sizeof(sdp_record_t)); + sdp_record_t *rec = malloc(sizeof(sdp_record_t)); memset((void *)rec, 0, sizeof(sdp_record_t)); rec->handle = 0xffffffff; return rec; @@ -2610,7 +2610,7 @@ void sdp_pattern_add_uuid(sdp_record_t *rec, uuid_t *uuid) if (sdp_list_find(rec->pattern, uuid128, sdp_uuid128_cmp) == NULL) rec->pattern = sdp_list_insert_sorted(rec->pattern, uuid128, sdp_uuid128_cmp); else - free(uuid128); + bt_free(uuid128); SDPDBG("Elements in target pattern : %d\n", sdp_list_len(rec->pattern)); } @@ -2636,7 +2636,7 @@ static void extract_record_handle_seq(uint8_t *pdu, sdp_list_t **seq, int count, int n; for (n = 0; n < count; n++) { - uint32_t *pSvcRec = (uint32_t *) malloc(sizeof(uint32_t)); + uint32_t *pSvcRec = malloc(sizeof(uint32_t)); *pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata)); pSeq = sdp_list_append(pSeq, pSvcRec); pdata += sizeof(uint32_t); -- cgit From 3df8390f8e7be37d0adfac2192c425219941d844 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Aug 2006 14:51:05 +0000 Subject: Fix UUID128 string lookup handling --- src/sdp.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 86caa15c..b1ef47ea 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -208,6 +208,24 @@ static char *string_lookup(struct tupla *pt0, int index) return ""; } +static char *string_lookup_uuid(struct tupla *pt0, const uuid_t* uuid) +{ + uuid_t tmp_uuid; + + memcpy(&tmp_uuid, uuid, sizeof(tmp_uuid)); + + if (sdp_uuid128_to_uuid(&tmp_uuid)) { + switch (tmp_uuid.type) { + case SDP_UUID16: + return string_lookup(pt0, tmp_uuid.value.uuid16); + case SDP_UUID32: + return string_lookup(pt0, tmp_uuid.value.uuid32); + } + } + + return ""; +} + /* * Prints into a string the Protocol UUID * coping a maximum of n characters. @@ -231,8 +249,9 @@ static int uuid2str(struct tupla *message, const uuid_t *uuid, char *str, size_t snprintf(str, n, str2); break; case SDP_UUID128: - snprintf(str, n, "Error: This is UUID-128"); - return -4; + str2 = string_lookup_uuid(message, uuid); + snprintf(str, n, str2); + break; default: snprintf(str, n, "Type of UUID (%x) unknown.", uuid->type); return -1; -- cgit From 2b3d5cfe013c2abf259b86e8dc73bda3d36429c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 Aug 2006 22:56:35 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 74aca994..7fc9da99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 4:0:2 +libbluetooth_la_LDFLAGS = -version-info 4:1:2 INCLUDES = -I$(top_builddir)/include -- cgit From 8be090b298a02108146d3bf48271f8408ac31917 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 25 Aug 2006 19:12:38 +0000 Subject: Added sdp_create for async searches --- src/sdp.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index b1ef47ea..f535ad48 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3032,6 +3032,59 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, return rec; } +/* + * SDP transaction structure for asynchronous search + */ +struct sdp_transaction { + sdp_callback_t *cb; + void *udata; + sdp_cstate_t *cstate; + uint8_t *reqbuf; + sdp_buf_t rsp_concat_buf; + uint32_t reqsize; + int cstate_len; + int attr_list_len; +}; + +/* + * Creates a new sdp session for asynchronous search + * INPUT: + * int sk + * non-blocking L2CAP socket + * + * RETURN: + * sdp_session_t * + * NULL - On memory allocation failure + */ +sdp_session_t *sdp_create(int sk, uint32_t flags) +{ + + struct sdp_transaction *t; + sdp_session_t *session = malloc(sizeof(sdp_session_t)); + if (!session) { + errno = ENOMEM; + return NULL; + } + + memset(session, 0, sizeof(*session)); + + session->flags = flags; + session->sock = sk; + + t = malloc(sizeof(struct sdp_transaction)); + if (!t) { + errno = ENOMEM; + free(session); + return NULL; + } + + memset(t, 0, sizeof(*t)); + + session->priv = t; + + return session; +} + /* * This is a service search request combined with the service * attribute request. First a service class match is done and @@ -3256,7 +3309,25 @@ int sdp_general_inquiry(inquiry_info *ii, int num_dev, int duration, uint8_t *fo int sdp_close(sdp_session_t *session) { - int ret = close(session->sock); + struct sdp_transaction *t; + int ret; + + if (!session) + return -1; + + ret = close(session->sock); + + t = session->priv; + + if (t) { + if (t->reqbuf) + free(t->reqbuf); + + if (t->rsp_concat_buf.data) + free(t->rsp_concat_buf.data); + + free(t); + } free(session); return ret; } -- cgit From dd610a12694a42aeb67417c95d87384f2eef8e70 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 25 Aug 2006 22:22:01 +0000 Subject: Add sdp_set_notify function --- src/sdp.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index f535ad48..5bbc8ec8 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3085,6 +3085,34 @@ sdp_session_t *sdp_create(int sk, uint32_t flags) return session; } +/* + * Set the callback function to called when the transaction finishes + * + * INPUT: + * sdp_session_t *session + * Current sdp session to be handled + * sdp_callback_t *cb + * callback to be called when the transaction finishes + * void *udata + * user data passed to callback + * RETURN: + * 0 - Success + * -1 - Failure + */ +int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) +{ + struct sdp_transaction *t; + + if (!session || !session->priv) + return -1; + + t = session->priv; + t->cb = func; + t->udata = udata; + + return 0; +} + /* * This is a service search request combined with the service * attribute request. First a service class match is done and -- cgit From f9264e21a9e0c97e6a4d970c0b31cf01fc18781d Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 28 Aug 2006 19:49:18 +0000 Subject: Added sdp_process and sdp_service_search_async functions --- src/sdp.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 5bbc8ec8..601985d6 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3113,6 +3113,220 @@ int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) return 0; } +/* + * Set the callback function to called when the transaction finishes and send the + * service search attribute request PDU. + * + * INPUT: + * sdp_session_t *session + * Current sdp session to be handled + * sdp_list_t *search + * UUID pattern to search + * RETURN: + * 0 - if the request has been sent properly + * -1 - On any failure + */ +int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search) +{ + struct sdp_transaction *t; + sdp_pdu_hdr_t *reqhdr; + sdp_list_t *attrids; + uint8_t *pdata; + int seqlen = 0; + uint32_t range = 0x0000ffff; + + if (!session || !session->priv) { + errno = EINVAL; + return -1; + } + + t = session->priv; + t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + if (!t->reqbuf) { + errno = ENOMEM; + goto end; + } + + memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); + memset((char *)&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); + + reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; + reqhdr->tid = htons(sdp_gen_tid(session)); + reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ; + + // generate PDU + pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); + t->reqsize = sizeof(sdp_pdu_hdr_t); + + // add service class IDs for search + seqlen = gen_searchseq_pdu(pdata, search); + + SDPDBG("Data seq added : %d\n", seqlen); + + // now set the length and increment the pointer + t->reqsize += seqlen; + pdata += seqlen; + + bt_put_unaligned(htons(SDP_MAX_ATTR_LEN), (uint16_t *) pdata); + t->reqsize += sizeof(uint16_t); + pdata += sizeof(uint16_t); + + SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN); + + // get attr seq PDU form + attrids = sdp_list_append(0, &range); + seqlen = gen_attridseq_pdu(pdata, attrids, SDP_UINT32); + sdp_list_free(attrids, 0); + + if (seqlen == -1) { + errno = EINVAL; + goto end; + } + + pdata += seqlen; + SDPDBG("Attr list length : %d\n", seqlen); + t->reqsize += seqlen; + + // set the request header's param length + t->cstate_len = copy_cstate(pdata, t->cstate); + + reqhdr->plen = htons((t->reqsize + t->cstate_len) - sizeof(sdp_pdu_hdr_t)); + + if (sdp_send_req(session, t->reqbuf, t->reqsize + t->cstate_len) < 0) { + SDPERR("Error sendind data:%s", strerror(errno)); + goto end; + } + + session->priv = t; + + return 0; +end: + + if (t) { + if (t->reqbuf) + free(t->reqbuf); + free(t); + } + + return -1; +} + +/* + * Receive the incomming SDP PDU. This function must be called when there is data + * available to be read. On continuation state, the original request (with a new + * transaction ID) and the continuation state data will be appended in the initial PDU. + * If an error happens or the transaction finishes the callback function will be called. + * + * INPUT: + * sdp_session_t *session + * Current sdp session to be handled + * RETURN: + * 0 - if the transaction is on continuation state + * -1 - On any failure or the transaction finished + */ +int sdp_process(sdp_session_t *session) +{ + struct sdp_transaction *t = NULL; + sdp_pdu_hdr_t *reqhdr = NULL; + sdp_pdu_hdr_t *rsphdr = NULL; + uint8_t *pdata = NULL, *rspbuf = NULL; + int n, err = 0, rsp_count = 0, status = -1; + + if (!session || !session->priv) { + err= EINVAL; + goto end; + } + + rspbuf = malloc(SDP_RSP_BUFFER_SIZE); + if (!rspbuf) { + err = ENOMEM; + goto end; + } + + t = session->priv; + reqhdr = (sdp_pdu_hdr_t *)t->reqbuf; + rsphdr = (sdp_pdu_hdr_t *)rspbuf; + + n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE); + if (n < 0) { + err = errno; + goto end; + } + + if (n == 0 || reqhdr->tid != rsphdr->tid || rsphdr->pdu_id == SDP_ERROR_RSP) { + err = EPROTO; + goto end; + } + + pdata = rspbuf + sizeof(sdp_pdu_hdr_t); + rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); + t->attr_list_len += rsp_count; + pdata += sizeof(uint16_t); // pdata points to attribute list + + t->cstate_len = *(uint8_t *) (pdata + rsp_count); + + SDPDBG("Attrlist byte count : %d\n", t->attr_list_len); + SDPDBG("Response byte count : %d\n", rsp_count); + SDPDBG("Cstate length : %d\n", t->cstate_len); + /* + * This is a split response, need to concatenate intermediate + * responses and the last one which will have cstate_len == 0 + */ + if (t->cstate_len > 0 || t->rsp_concat_buf.data_size != 0) { + uint8_t *targetPtr = NULL; + + t->cstate = t->cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; + + // build concatenated response buffer + t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count); + targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size; + t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count; + memcpy(targetPtr, pdata, rsp_count); + t->rsp_concat_buf.data_size += rsp_count; + } + + if (t->cstate) { + int reqsize; + reqhdr->tid = htons(sdp_gen_tid(session)); + + // add continuation state (can be null) + t->cstate_len = copy_cstate(t->reqbuf + t->reqsize, t->cstate); + + reqsize = t->reqsize + t->cstate_len; + + // set the request header's param length + reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); + + if (sdp_send_req(session, t->reqbuf, reqsize) < 0) { + err = errno; + goto end; + } + status = 0; + } else { + if (t->attr_list_len == 0) { + err = ENODATA; + goto end; + } + } + +end: + + /* error detected or transaction finished */ + if (err || !t->cstate) { + if (t->rsp_concat_buf.data_size != 0) + pdata = t->rsp_concat_buf.data; + + if (t->cb) + t->cb(rsphdr->pdu_id, err, pdata, + t->attr_list_len, t->udata); + } + + if (rspbuf) + free(rspbuf); + + return status; +} + /* * This is a service search request combined with the service * attribute request. First a service class match is done and -- cgit From 343f72ba28deaf9ddc68043567baad76e0325e5d Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 28 Aug 2006 21:26:50 +0000 Subject: Added SDP error response parsing --- src/sdp.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 601985d6..53c7196b 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3253,12 +3253,18 @@ int sdp_process(sdp_session_t *session) goto end; } - if (n == 0 || reqhdr->tid != rsphdr->tid || rsphdr->pdu_id == SDP_ERROR_RSP) { + if (n == 0 || reqhdr->tid != rsphdr->tid) err = EPROTO; goto end; } pdata = rspbuf + sizeof(sdp_pdu_hdr_t); + + if (rsphdr->pdu_id == SDP_ERROR_RSP) { + err = ntohs(bt_get_unaligned((uint16_t *) pdata)); + goto end; + } + rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); t->attr_list_len += rsp_count; pdata += sizeof(uint16_t); // pdata points to attribute list -- cgit From 3f7d61cbeff52ce209a75cec97ba29507ed764bc Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 28 Aug 2006 21:32:20 +0000 Subject: fixed syntax error --- src/sdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 53c7196b..63a9ba1c 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3253,7 +3253,7 @@ int sdp_process(sdp_session_t *session) goto end; } - if (n == 0 || reqhdr->tid != rsphdr->tid) + if (n == 0 || reqhdr->tid != rsphdr->tid) { err = EPROTO; goto end; } -- cgit From c8e5a1464ff8edb068e7361a257ef4ae34674cf8 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 29 Aug 2006 16:29:00 +0000 Subject: changed error handling in sdp_process function --- src/sdp.c | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 63a9ba1c..bc69551a 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3230,38 +3230,34 @@ int sdp_process(sdp_session_t *session) sdp_pdu_hdr_t *reqhdr = NULL; sdp_pdu_hdr_t *rsphdr = NULL; uint8_t *pdata = NULL, *rspbuf = NULL; - int n, err = 0, rsp_count = 0, status = -1; + int rsp_count = 0, err = -1; + uint16_t status = 0; if (!session || !session->priv) { - err= EINVAL; - goto end; + SDPERR("Invalid session"); + return -1; } rspbuf = malloc(SDP_RSP_BUFFER_SIZE); - if (!rspbuf) { - err = ENOMEM; - goto end; - } + if (!rspbuf) + return -1; + + memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE); t = session->priv; reqhdr = (sdp_pdu_hdr_t *)t->reqbuf; rsphdr = (sdp_pdu_hdr_t *)rspbuf; - n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE); - if (n < 0) { - err = errno; + if (sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE) <= 0) goto end; - } - if (n == 0 || reqhdr->tid != rsphdr->tid) { - err = EPROTO; + if (reqhdr->tid != rsphdr->tid) goto end; - } pdata = rspbuf + sizeof(sdp_pdu_hdr_t); if (rsphdr->pdu_id == SDP_ERROR_RSP) { - err = ntohs(bt_get_unaligned((uint16_t *) pdata)); + status = ntohs(bt_get_unaligned((uint16_t *) pdata)); goto end; } @@ -3304,33 +3300,26 @@ int sdp_process(sdp_session_t *session) reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); if (sdp_send_req(session, t->reqbuf, reqsize) < 0) { - err = errno; - goto end; - } - status = 0; - } else { - if (t->attr_list_len == 0) { - err = ENODATA; + SDPERR("Error sendind data:%s", strerror(errno)); goto end; } + err = 0; } end: - - /* error detected or transaction finished */ - if (err || !t->cstate) { + if (err) { if (t->rsp_concat_buf.data_size != 0) pdata = t->rsp_concat_buf.data; if (t->cb) - t->cb(rsphdr->pdu_id, err, pdata, + t->cb(rsphdr->pdu_id, status, pdata, t->attr_list_len, t->udata); } if (rspbuf) free(rspbuf); - return status; + return err; } /* -- cgit From 453a0cedb6c909047553ffc7145bcef26a3ae94c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 29 Aug 2006 21:39:07 +0000 Subject: Correct prototypes for async functions --- src/sdp.c | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index bc69551a..1d6d65fe 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3113,6 +3113,18 @@ int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) return 0; } +int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search_list, uint16_t max_rec_num) +{ + /* FIXME: implement! */ + return 0; +} + +int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) +{ + /* FIXME: implement! */ + return 0; +} + /* * Set the callback function to called when the transaction finishes and send the * service search attribute request PDU. @@ -3120,20 +3132,39 @@ int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) * INPUT: * sdp_session_t *session * Current sdp session to be handled - * sdp_list_t *search - * UUID pattern to search + * + * sdp_list_t *search + * Singly linked list containing elements of the search + * pattern. Each entry in the list is a UUID(DataTypeSDP_UUID16) + * of the service to be searched + * + * AttributeSpecification attrSpec + * Attribute identifiers are 16 bit unsigned integers specified + * in one of 2 ways described below : + * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers + * They are the actual attribute identifiers in ascending order + * + * SDP_ATTR_REQ_RANGE - 32bit identifier range + * The high-order 16bits is the start of range + * the low-order 16bits are the end of range + * 0x0000 to 0xFFFF gets all attributes + * + * sdp_list_t *attrids + * Singly linked list containing attribute identifiers desired. + * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) + * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) + * + * RETURN: * 0 - if the request has been sent properly * -1 - On any failure */ -int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search) +int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search_list, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) { struct sdp_transaction *t; sdp_pdu_hdr_t *reqhdr; - sdp_list_t *attrids; uint8_t *pdata; int seqlen = 0; - uint32_t range = 0x0000ffff; if (!session || !session->priv) { errno = EINVAL; @@ -3159,7 +3190,7 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search) t->reqsize = sizeof(sdp_pdu_hdr_t); // add service class IDs for search - seqlen = gen_searchseq_pdu(pdata, search); + seqlen = gen_searchseq_pdu(pdata, search_list); SDPDBG("Data seq added : %d\n", seqlen); @@ -3174,10 +3205,8 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search) SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN); // get attr seq PDU form - attrids = sdp_list_append(0, &range); - seqlen = gen_attridseq_pdu(pdata, attrids, SDP_UINT32); - sdp_list_free(attrids, 0); - + seqlen = gen_attridseq_pdu(pdata, attrid_list, + reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32); if (seqlen == -1) { errno = EINVAL; goto end; -- cgit From a76dc65489dd8959547a97a391e405b2025bbd79 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 29 Aug 2006 22:03:13 +0000 Subject: Make sdp_connect() async aware --- src/sdp.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 1d6d65fe..d694fd24 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3059,8 +3059,10 @@ struct sdp_transaction { sdp_session_t *sdp_create(int sk, uint32_t flags) { + sdp_session_t *session; struct sdp_transaction *t; - sdp_session_t *session = malloc(sizeof(sdp_session_t)); + + session = malloc(sizeof(sdp_session_t)); if (!session) { errno = ENOMEM; return NULL; @@ -3605,12 +3607,30 @@ static inline int sdp_is_local(const bdaddr_t *device) sdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t flags) { + sdp_session_t *session; + struct sdp_transaction *t; int err; - sdp_session_t *session = malloc(sizeof(sdp_session_t)); + + session = malloc(sizeof(sdp_session_t)); if (!session) return session; + memset(session, 0, sizeof(*session)); + session->flags = flags; + session->sock = -1; + + t = malloc(sizeof(struct sdp_transaction)); + if (!t) { + errno = ENOMEM; + free(session); + return NULL; + } + + memset(t, 0, sizeof(*t)); + + session->priv = t; + if (sdp_is_local(dst)) { struct sockaddr_un sa; @@ -3649,10 +3669,13 @@ sdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t fl while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY)); } } + fail: err = errno; if (session->sock >= 0) close(session->sock); + if (session->priv) + free(session->priv); free(session); errno = err; return 0; -- cgit From adff4cad15e4e13bb9847a0ff62b355caddf89e3 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 30 Aug 2006 12:52:34 +0000 Subject: added/updated async functions comments --- src/sdp.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index d694fd24..27a895f4 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3088,7 +3088,9 @@ sdp_session_t *sdp_create(int sk, uint32_t flags) } /* - * Set the callback function to called when the transaction finishes + * Sets the callback function/user data used to notify the application + * that the asynchronous transaction finished. This function must be + * called before request an asynchronous search. * * INPUT: * sdp_session_t *session @@ -3098,7 +3100,7 @@ sdp_session_t *sdp_create(int sk, uint32_t flags) * void *udata * user data passed to callback * RETURN: - * 0 - Success + * 0 - Success * -1 - Failure */ int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) @@ -3115,12 +3117,75 @@ int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) return 0; } +/* + * This function starts an asynchronous service search request. + * The incomming and outgoing data are stored in the transaction structure + * buffers. When there is incomming data the sdp_process function must be + * called to get the data and handle the continuation state. + * + * INPUT : + * sdp_session_t *session + * Current sdp session to be handled + * + * sdp_list_t *search_list + * Singly linked list containing elements of the search + * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16) + * of the service to be searched + * + * uint16_t max_rec_num + * A 16 bit integer which tells the service, the maximum + * entries that the client can handle in the response. The + * server is obliged not to return > max_rec_num entries + * + * OUTPUT : + * + * int return value + * 0 - if the request has been sent properly + * -1 - On any failure and sets errno + */ + int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search_list, uint16_t max_rec_num) { /* FIXME: implement! */ return 0; } +/* + * This function starts an asynchronous service attribute request. + * The incomming and outgoing data are stored in the transaction structure + * buffers. When there is incomming data the sdp_process function must be + * called to get the data and handle the continuation state. + * + * INPUT : + * sdp_session_t *session + * Current sdp session to be handled + * + * uint32_t handle + * The handle of the service for which the attribute(s) are + * requested + * + * sdp_attrreq_type_t reqtype + * Attribute identifiers are 16 bit unsigned integers specified + * in one of 2 ways described below : + * SDP_ATTR_REQ_INDIVIDUAL - 16bit individual identifiers + * They are the actual attribute identifiers in ascending order + * + * SDP_ATTR_REQ_RANGE - 32bit identifier range + * The high-order 16bits is the start of range + * the low-order 16bits are the end of range + * 0x0000 to 0xFFFF gets all attributes + * + * sdp_list_t *attrid_list + * Singly linked list containing attribute identifiers desired. + * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) + * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) + * + * OUTPUT : + * int return value + * 0 - if the request has been sent properly + * -1 - On any failure and sets errno + */ + int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) { /* FIXME: implement! */ @@ -3128,8 +3193,11 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ } /* - * Set the callback function to called when the transaction finishes and send the - * service search attribute request PDU. + * This function starts an asynchronous service search attributes. + * It is a service search request combined with attribute request. The incomming + * and outgoing data are stored in the transaction structure buffers. When there + * is incomming data the sdp_process function must be called to get the data + * and handle the continuation state. * * INPUT: * sdp_session_t *session @@ -3151,14 +3219,14 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ * the low-order 16bits are the end of range * 0x0000 to 0xFFFF gets all attributes * - * sdp_list_t *attrids + * sdp_list_t *attrid_list * Singly linked list containing attribute identifiers desired. * Every element is either a uint16_t(attrSpec = SDP_ATTR_REQ_INDIVIDUAL) * or a uint32_t(attrSpec=SDP_ATTR_REQ_RANGE) * * RETURN: - * 0 - if the request has been sent properly + * 0 - if the request has been sent properly * -1 - On any failure */ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search_list, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) -- cgit From ef1fe5feaa0dde16562723bcb36343c7bc4c31be Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 30 Aug 2006 21:34:20 +0000 Subject: added sdp_service_attr_async function --- src/sdp.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 27a895f4..014fc4c8 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3188,8 +3188,77 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search_li int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) { - /* FIXME: implement! */ + struct sdp_transaction *t; + sdp_pdu_hdr_t *reqhdr; + uint8_t *pdata; + int seqlen = 0; + + if (!session || !session->priv) { + errno = EINVAL; + return -1; + } + + t = session->priv; + t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + if (!t->reqbuf) { + errno = ENOMEM; + goto end; + } + + memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); + memset((char *)&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); + + reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; + reqhdr->tid = htons(sdp_gen_tid(session)); + reqhdr->pdu_id = SDP_SVC_ATTR_REQ; + + // generate PDU + pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); + t->reqsize = sizeof(sdp_pdu_hdr_t); + + // add the service record handle + bt_put_unaligned(htonl(handle), (uint32_t *) pdata); + t->reqsize += sizeof(uint32_t); + pdata += sizeof(uint32_t); + + // specify the response limit + bt_put_unaligned(htons(65535), (uint16_t *) pdata); + t->reqsize += sizeof(uint16_t); + pdata += sizeof(uint16_t); + + // get attr seq PDU form + seqlen = gen_attridseq_pdu(pdata, attrid_list, + reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32); + if (seqlen == -1) { + errno = EINVAL; + goto end; + } + + // now set the length and increment the pointer + t->reqsize += seqlen; + pdata += seqlen; + SDPDBG("Attr list length : %d\n", seqlen); + + // set the request header's param length + t->cstate_len = copy_cstate(pdata, t->cstate); + + reqhdr->plen = htons((t->reqsize + t->cstate_len) - sizeof(sdp_pdu_hdr_t)); + + if (sdp_send_req(session, t->reqbuf, t->reqsize + t->cstate_len) < 0) { + SDPERR("Error sendind data:%s", strerror(errno)); + goto end; + } + return 0; +end: + + if (t) { + if (t->reqbuf) + free(t->reqbuf); + free(t); + } + + return -1; } /* @@ -3296,8 +3365,6 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear goto end; } - session->priv = t; - return 0; end: -- cgit From e9527af7533e35a59580cda37ff58152cb356103 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 30 Aug 2006 22:02:14 +0000 Subject: added sdp_service_search_async function --- src/sdp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 014fc4c8..c10737a5 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3146,8 +3146,67 @@ int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search_list, uint16_t max_rec_num) { - /* FIXME: implement! */ + struct sdp_transaction *t; + sdp_pdu_hdr_t *reqhdr; + uint8_t *pdata; + int seqlen = 0; + + if (!session || !session->priv) { + errno = EINVAL; + return -1; + } + + t = session->priv; + t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + if (!t->reqbuf) { + errno = ENOMEM; + goto end; + } + + memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); + memset((char *)&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); + + reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; + reqhdr->tid = htons(sdp_gen_tid(session)); + reqhdr->pdu_id = SDP_SVC_SEARCH_REQ; + + // generate PDU + pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); + t->reqsize = sizeof(sdp_pdu_hdr_t); + + // add service class IDs for search + seqlen = gen_searchseq_pdu(pdata, search_list); + + SDPDBG("Data seq added : %d\n", seqlen); + + // now set the length and increment the pointer + t->reqsize += seqlen; + pdata += seqlen; + + bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata); + t->reqsize += sizeof(uint16_t); + pdata += sizeof(uint16_t); + + // set the request header's param length + t->cstate_len = copy_cstate(pdata, t->cstate); + + reqhdr->plen = htons((t->reqsize + t->cstate_len) - sizeof(sdp_pdu_hdr_t)); + + if (sdp_send_req(session, t->reqbuf, t->reqsize + t->cstate_len) < 0) { + SDPERR("Error sendind data:%s", strerror(errno)); + goto end; + } + return 0; +end: + + if (t) { + if (t->reqbuf) + free(t->reqbuf); + free(t); + } + + return -1; } /* -- cgit From 41064d605ba2f88f967c8388c9b20b92a7868a87 Mon Sep 17 00:00:00 2001 From: Ulisses Furquim Date: Wed, 30 Aug 2006 22:44:49 +0000 Subject: fix prototypes for sdp sync/async functions --- src/sdp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index c10737a5..362dcfb1 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2735,7 +2735,7 @@ static int copy_cstate(uint8_t *pdata, const sdp_cstate_t *cstate) * * INPUT : * - * sdp_list_t *search_list + * sdp_list_t *search * Singly linked list containing elements of the search * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16) * of the service to be searched @@ -3127,7 +3127,7 @@ int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) * sdp_session_t *session * Current sdp session to be handled * - * sdp_list_t *search_list + * sdp_list_t *search * Singly linked list containing elements of the search * pattern. Each entry in the list is a UUID (DataTypeSDP_UUID16) * of the service to be searched @@ -3144,7 +3144,7 @@ int sdp_set_notify(sdp_session_t *session, sdp_callback_t *func, void *udata) * -1 - On any failure and sets errno */ -int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search_list, uint16_t max_rec_num) +int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, uint16_t max_rec_num) { struct sdp_transaction *t; sdp_pdu_hdr_t *reqhdr; @@ -3175,7 +3175,7 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search_li t->reqsize = sizeof(sdp_pdu_hdr_t); // add service class IDs for search - seqlen = gen_searchseq_pdu(pdata, search_list); + seqlen = gen_searchseq_pdu(pdata, search); SDPDBG("Data seq added : %d\n", seqlen); @@ -3357,7 +3357,7 @@ end: * 0 - if the request has been sent properly * -1 - On any failure */ -int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search_list, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) +int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *search, sdp_attrreq_type_t reqtype, const sdp_list_t *attrid_list) { struct sdp_transaction *t; sdp_pdu_hdr_t *reqhdr; @@ -3388,7 +3388,7 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear t->reqsize = sizeof(sdp_pdu_hdr_t); // add service class IDs for search - seqlen = gen_searchseq_pdu(pdata, search_list); + seqlen = gen_searchseq_pdu(pdata, search); SDPDBG("Data seq added : %d\n", seqlen); -- cgit From 58eb769e7620e03c8b0bf2d2bcf38c06ab58065f Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 31 Aug 2006 21:22:06 +0000 Subject: fixed sdp_process to handle cstate --- src/sdp.c | 78 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 362dcfb1..11896cb0 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3043,7 +3043,7 @@ struct sdp_transaction { sdp_buf_t rsp_concat_buf; uint32_t reqsize; int cstate_len; - int attr_list_len; + int size; }; /* @@ -3454,7 +3454,8 @@ int sdp_process(sdp_session_t *session) struct sdp_transaction *t = NULL; sdp_pdu_hdr_t *reqhdr = NULL; sdp_pdu_hdr_t *rsphdr = NULL; - uint8_t *pdata = NULL, *rspbuf = NULL; + sdp_cstate_t *pcstate = NULL; + uint8_t *pdata = NULL, *rspbuf = NULL, *targetPtr = NULL; int rsp_count = 0, err = -1; uint16_t status = 0; @@ -3486,40 +3487,69 @@ int sdp_process(sdp_session_t *session) goto end; } - rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); - t->attr_list_len += rsp_count; - pdata += sizeof(uint16_t); // pdata points to attribute list + switch (rsphdr->pdu_id) { + uint8_t *ssr_pdata; + uint16_t tsrc, csrc; + case SDP_SVC_SEARCH_RSP: + /* + * TSRC: Total Service Record Count + * CSRC: Current Service Record Count + */ + ssr_pdata = pdata; + ssr_pdata += sizeof(tsrc); + tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); + csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); + + if (t->size == 0) { + /* first fragment */ + rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4; + SDPDBG("Total svc count: %d\n", tsrc); + SDPDBG("Current svc count: %d\n", csrc); + } else { + pdata += 2 * sizeof(uint16_t); /* Ignore TSRC and CSRC */ + rsp_count = csrc * 4; + } + t->size += rsp_count; + break; + case SDP_SVC_ATTR_RSP: + case SDP_SVC_SEARCH_ATTR_RSP: + rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); + SDPDBG("Attrlist byte count : %d\n", rsp_count); - t->cstate_len = *(uint8_t *) (pdata + rsp_count); + pdata += sizeof(uint16_t); // points to attribute list + t->size += rsp_count; + break; + default: + /* FIXME: how handle this situation? */ + SDPDBG("Illegal PDU ID!"); + goto end; + } - SDPDBG("Attrlist byte count : %d\n", t->attr_list_len); - SDPDBG("Response byte count : %d\n", rsp_count); - SDPDBG("Cstate length : %d\n", t->cstate_len); + pcstate = (sdp_cstate_t *) (pdata + rsp_count); + + SDPDBG("Cstate length : %d\n", pcstate->length); /* * This is a split response, need to concatenate intermediate * responses and the last one which will have cstate_len == 0 */ - if (t->cstate_len > 0 || t->rsp_concat_buf.data_size != 0) { - uint8_t *targetPtr = NULL; - t->cstate = t->cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; - // build concatenated response buffer - t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count); - targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size; - t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count; - memcpy(targetPtr, pdata, rsp_count); - t->rsp_concat_buf.data_size += rsp_count; - } + // build concatenated response buffer + t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count); + targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size; + t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count; + memcpy(targetPtr, pdata, rsp_count); + t->rsp_concat_buf.data_size += rsp_count; + + if (pcstate->length > 0) { + int reqsize, cstate_len; - if (t->cstate) { - int reqsize; reqhdr->tid = htons(sdp_gen_tid(session)); // add continuation state (can be null) - t->cstate_len = copy_cstate(t->reqbuf + t->reqsize, t->cstate); + cstate_len = copy_cstate(t->reqbuf + t->reqsize, pcstate); - reqsize = t->reqsize + t->cstate_len; + reqsize = t->reqsize + cstate_len; // set the request header's param length reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); @@ -3538,7 +3568,7 @@ end: if (t->cb) t->cb(rsphdr->pdu_id, status, pdata, - t->attr_list_len, t->udata); + t->size, t->udata); } if (rspbuf) -- cgit From e4c8ef4fa293cb27510c898e84ce25f948122286 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Sep 2006 09:26:32 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 9df142a0..645a4d63 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -382,6 +382,8 @@ char *bt_compidtostr(int compid) return "CONWISE Technology Corporation Ltd"; case 67: return "PARROT SA"; + case 68: + return "Socket Communications"; case 65535: return "internal use"; default: -- cgit From c01b6039f44d9e78acc26cd8482b5e0c7b23fe14 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 3 Sep 2006 19:51:41 +0000 Subject: Remove cstate and cstate_len from transaction structure --- src/sdp.c | 53 +++++++++++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 11896cb0..1ce5e81b 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3036,14 +3036,11 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, * SDP transaction structure for asynchronous search */ struct sdp_transaction { - sdp_callback_t *cb; - void *udata; - sdp_cstate_t *cstate; - uint8_t *reqbuf; + sdp_callback_t *cb; /* called when the transaction finishes */ + void *udata; /* client user data */ + uint8_t *reqbuf; /* pointer to request PDU */ sdp_buf_t rsp_concat_buf; - uint32_t reqsize; - int cstate_len; - int size; + uint32_t reqsize; /* without cstate */ }; /* @@ -3149,7 +3146,7 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, u struct sdp_transaction *t; sdp_pdu_hdr_t *reqhdr; uint8_t *pdata; - int seqlen = 0; + int cstate_len, seqlen = 0; if (!session || !session->priv) { errno = EINVAL; @@ -3187,12 +3184,12 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, u t->reqsize += sizeof(uint16_t); pdata += sizeof(uint16_t); + // set the request header's param length - t->cstate_len = copy_cstate(pdata, t->cstate); - - reqhdr->plen = htons((t->reqsize + t->cstate_len) - sizeof(sdp_pdu_hdr_t)); + cstate_len = copy_cstate(pdata, NULL); + reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); - if (sdp_send_req(session, t->reqbuf, t->reqsize + t->cstate_len) < 0) { + if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { SDPERR("Error sendind data:%s", strerror(errno)); goto end; } @@ -3250,7 +3247,7 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ struct sdp_transaction *t; sdp_pdu_hdr_t *reqhdr; uint8_t *pdata; - int seqlen = 0; + int cstate_len, seqlen = 0; if (!session || !session->priv) { errno = EINVAL; @@ -3299,11 +3296,10 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ SDPDBG("Attr list length : %d\n", seqlen); // set the request header's param length - t->cstate_len = copy_cstate(pdata, t->cstate); - - reqhdr->plen = htons((t->reqsize + t->cstate_len) - sizeof(sdp_pdu_hdr_t)); + cstate_len = copy_cstate(pdata, NULL); + reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); - if (sdp_send_req(session, t->reqbuf, t->reqsize + t->cstate_len) < 0) { + if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { SDPERR("Error sendind data:%s", strerror(errno)); goto end; } @@ -3362,7 +3358,7 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear struct sdp_transaction *t; sdp_pdu_hdr_t *reqhdr; uint8_t *pdata; - int seqlen = 0; + int cstate_len, seqlen = 0; if (!session || !session->priv) { errno = EINVAL; @@ -3415,11 +3411,10 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear t->reqsize += seqlen; // set the request header's param length - t->cstate_len = copy_cstate(pdata, t->cstate); - - reqhdr->plen = htons((t->reqsize + t->cstate_len) - sizeof(sdp_pdu_hdr_t)); + cstate_len = copy_cstate(pdata, NULL); + reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); - if (sdp_send_req(session, t->reqbuf, t->reqsize + t->cstate_len) < 0) { + if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { SDPERR("Error sendind data:%s", strerror(errno)); goto end; } @@ -3457,6 +3452,7 @@ int sdp_process(sdp_session_t *session) sdp_cstate_t *pcstate = NULL; uint8_t *pdata = NULL, *rspbuf = NULL, *targetPtr = NULL; int rsp_count = 0, err = -1; + size_t size = 0; uint16_t status = 0; if (!session || !session->priv) { @@ -3484,6 +3480,7 @@ int sdp_process(sdp_session_t *session) if (rsphdr->pdu_id == SDP_ERROR_RSP) { status = ntohs(bt_get_unaligned((uint16_t *) pdata)); + size = rsphdr->plen; goto end; } @@ -3500,7 +3497,7 @@ int sdp_process(sdp_session_t *session) tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); - if (t->size == 0) { + if (t->rsp_concat_buf.data_size == 0) { /* first fragment */ rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4; SDPDBG("Total svc count: %d\n", tsrc); @@ -3509,7 +3506,6 @@ int sdp_process(sdp_session_t *session) pdata += 2 * sizeof(uint16_t); /* Ignore TSRC and CSRC */ rsp_count = csrc * 4; } - t->size += rsp_count; break; case SDP_SVC_ATTR_RSP: case SDP_SVC_SEARCH_ATTR_RSP: @@ -3517,7 +3513,6 @@ int sdp_process(sdp_session_t *session) SDPDBG("Attrlist byte count : %d\n", rsp_count); pdata += sizeof(uint16_t); // points to attribute list - t->size += rsp_count; break; default: /* FIXME: how handle this situation? */ @@ -3533,7 +3528,6 @@ int sdp_process(sdp_session_t *session) * responses and the last one which will have cstate_len == 0 */ - // build concatenated response buffer t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count); targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size; @@ -3556,6 +3550,7 @@ int sdp_process(sdp_session_t *session) if (sdp_send_req(session, t->reqbuf, reqsize) < 0) { SDPERR("Error sendind data:%s", strerror(errno)); + /* FIXME: how handle this error ? */ goto end; } err = 0; @@ -3563,12 +3558,14 @@ int sdp_process(sdp_session_t *session) end: if (err) { - if (t->rsp_concat_buf.data_size != 0) + if (t->rsp_concat_buf.data_size != 0) { pdata = t->rsp_concat_buf.data; + size = t->rsp_concat_buf.data_size; + } if (t->cb) t->cb(rsphdr->pdu_id, status, pdata, - t->size, t->udata); + size, t->udata); } if (rspbuf) -- cgit From 1be1f79648ba7aafde6349cfe51f9c929e20d018 Mon Sep 17 00:00:00 2001 From: Ulisses Furquim Date: Mon, 4 Sep 2006 17:13:33 +0000 Subject: Make sdp_connect() fully async aware --- src/sdp.c | 158 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 100 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 1ce5e81b..2a054094 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -3041,21 +3042,33 @@ struct sdp_transaction { uint8_t *reqbuf; /* pointer to request PDU */ sdp_buf_t rsp_concat_buf; uint32_t reqsize; /* without cstate */ + uint8_t connected; }; +inline int sdp_is_connected(sdp_session_t *session) +{ + struct sdp_transaction *t = session->priv; + return t->connected; +} + +static inline void sdp_set_connected(sdp_session_t *session) +{ + struct sdp_transaction *t = session->priv; + t->connected = 1; +} + /* * Creates a new sdp session for asynchronous search * INPUT: * int sk - * non-blocking L2CAP socket - * + * non-blocking L2CAP socket + * * RETURN: * sdp_session_t * * NULL - On memory allocation failure */ sdp_session_t *sdp_create(int sk, uint32_t flags) { - sdp_session_t *session; struct sdp_transaction *t; @@ -3064,7 +3077,6 @@ sdp_session_t *sdp_create(int sk, uint32_t flags) errno = ENOMEM; return NULL; } - memset(session, 0, sizeof(*session)); session->flags = flags; @@ -3076,7 +3088,6 @@ sdp_session_t *sdp_create(int sk, uint32_t flags) free(session); return NULL; } - memset(t, 0, sizeof(*t)); session->priv = t; @@ -3826,71 +3837,101 @@ static inline int sdp_is_local(const bdaddr_t *device) return memcmp(device, BDADDR_LOCAL, sizeof(bdaddr_t)) == 0; } -sdp_session_t *sdp_connect(const bdaddr_t *src, const bdaddr_t *dst, uint32_t flags) +static int sdp_connect_local(sdp_session_t *session) { - sdp_session_t *session; - struct sdp_transaction *t; - int err; + struct sockaddr_un sa; + int ret; - session = malloc(sizeof(sdp_session_t)); - if (!session) - return session; + session->sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (session->sock < 0) + return -1; + session->local = 1; - memset(session, 0, sizeof(*session)); + sa.sun_family = AF_UNIX; + strcpy(sa.sun_path, SDP_UNIX_PATH); - session->flags = flags; - session->sock = -1; + ret = connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)); + if (!ret) + sdp_set_connected(session); - t = malloc(sizeof(struct sdp_transaction)); - if (!t) { - errno = ENOMEM; - free(session); - return NULL; + return ret; +} + +static int sdp_connect_l2cap(const bdaddr_t *src, + const bdaddr_t *dst, sdp_session_t *session) +{ + uint32_t flags = session->flags; + struct sockaddr_l2 sa; + int sk; + + session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (session->sock < 0) + return -1; + session->local = 0; + + sk = session->sock; + + if (flags & SDP_NON_BLOCKING) { + long arg = fcntl(sk, F_GETFL, 0); + fcntl(sk, F_SETFL, arg | O_NONBLOCK); } - memset(t, 0, sizeof(*t)); + sa.l2_family = AF_BLUETOOTH; + sa.l2_psm = 0; - session->priv = t; + if (bacmp(src, BDADDR_ANY)) { + sa.l2_bdaddr = *src; + if (bind(sk, (struct sockaddr *) &sa, sizeof(sa)) < 0) + return -1; + } - if (sdp_is_local(dst)) { - struct sockaddr_un sa; - - // create local unix connection - session->sock = socket(PF_UNIX, SOCK_STREAM, 0); - session->local = 1; - if (session->sock >= 0) { - sa.sun_family = AF_UNIX; - strcpy(sa.sun_path, SDP_UNIX_PATH); - if (connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)) == 0) - return session; + if (flags & SDP_WAIT_ON_CLOSE) { + struct linger l = { .l_onoff = 1, .l_linger = 1 }; + setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)); + } + + sa.l2_psm = htobs(SDP_PSM); + sa.l2_bdaddr = *dst; + + do { + int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa)); + if (!ret) { + sdp_set_connected(session); + return 0; } + if (ret < 0 && (flags & SDP_NON_BLOCKING) && + (errno == EAGAIN || errno == EINPROGRESS)) + return 0; + } while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY)); + + return -1; +} + +sdp_session_t *sdp_connect(const bdaddr_t *src, + const bdaddr_t *dst, uint32_t flags) +{ + sdp_session_t *session; + int err; + + if ((flags & SDP_RETRY_IF_BUSY) && (flags & SDP_NON_BLOCKING)) { + errno = EINVAL; + return NULL; + } + + session = sdp_create(-1, flags); + if (!session) + return NULL; + + if (sdp_is_local(dst)) { + if (sdp_connect_local(session) < 0) + goto fail; } else { - struct sockaddr_l2 sa; - - // create L2CAP connection - session->sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - session->local = 0; - if (session->sock >= 0) { - sa.l2_family = AF_BLUETOOTH; - sa.l2_psm = 0; - if (bacmp(src, BDADDR_ANY) != 0) { - sa.l2_bdaddr = *src; - if (bind(session->sock, (struct sockaddr *) &sa, sizeof(sa)) < 0) - goto fail; - } - if (flags & SDP_WAIT_ON_CLOSE) { - struct linger l = { .l_onoff = 1, .l_linger = 1 }; - setsockopt(session->sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l)); - } - sa.l2_psm = htobs(SDP_PSM); - sa.l2_bdaddr = *dst; - do - if (connect(session->sock, (struct sockaddr *) &sa, sizeof(sa)) == 0) - return session; - while (errno == EBUSY && (flags & SDP_RETRY_IF_BUSY)); - } + if (sdp_connect_l2cap(src, dst, session) < 0) + goto fail; } + return session; + fail: err = errno; if (session->sock >= 0) @@ -3899,7 +3940,8 @@ fail: free(session->priv); free(session); errno = err; - return 0; + + return NULL; } int sdp_get_socket(const sdp_session_t *session) -- cgit From aa7577018bb1faac4b67b52dc8b003663cdd03ad Mon Sep 17 00:00:00 2001 From: Ulisses Furquim Date: Mon, 4 Sep 2006 21:10:23 +0000 Subject: Remove connected flag from SDP transaction structure --- src/sdp.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 2a054094..26f01eac 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3042,21 +3042,8 @@ struct sdp_transaction { uint8_t *reqbuf; /* pointer to request PDU */ sdp_buf_t rsp_concat_buf; uint32_t reqsize; /* without cstate */ - uint8_t connected; }; -inline int sdp_is_connected(sdp_session_t *session) -{ - struct sdp_transaction *t = session->priv; - return t->connected; -} - -static inline void sdp_set_connected(sdp_session_t *session) -{ - struct sdp_transaction *t = session->priv; - t->connected = 1; -} - /* * Creates a new sdp session for asynchronous search * INPUT: @@ -3840,7 +3827,6 @@ static inline int sdp_is_local(const bdaddr_t *device) static int sdp_connect_local(sdp_session_t *session) { struct sockaddr_un sa; - int ret; session->sock = socket(PF_UNIX, SOCK_STREAM, 0); if (session->sock < 0) @@ -3850,11 +3836,7 @@ static int sdp_connect_local(sdp_session_t *session) sa.sun_family = AF_UNIX; strcpy(sa.sun_path, SDP_UNIX_PATH); - ret = connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)); - if (!ret) - sdp_set_connected(session); - - return ret; + return connect(session->sock, (struct sockaddr *)&sa, sizeof(sa)); } static int sdp_connect_l2cap(const bdaddr_t *src, @@ -3895,10 +3877,8 @@ static int sdp_connect_l2cap(const bdaddr_t *src, do { int ret = connect(sk, (struct sockaddr *) &sa, sizeof(sa)); - if (!ret) { - sdp_set_connected(session); + if (!ret) return 0; - } if (ret < 0 && (flags & SDP_NON_BLOCKING) && (errno == EAGAIN || errno == EINPROGRESS)) return 0; -- cgit From 113a53acaec2519108f0cab944687b7abc537e74 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Sep 2006 09:41:50 +0000 Subject: Remove sdp_cstate_t from the header file --- src/sdp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 26f01eac..f961c7d3 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2720,6 +2720,11 @@ static int gen_attridseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dataTy return gen_dataseq_pdu(dst, seq, dataType); } +typedef struct { + uint8_t length; + unsigned char data[16]; +} __attribute__ ((packed)) sdp_cstate_t; + static int copy_cstate(uint8_t *pdata, const sdp_cstate_t *cstate) { if (cstate) { -- cgit From 6d83e9274971235c05b40349dbbaf3f826853ff5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Sep 2006 09:52:42 +0000 Subject: Print only unitSize length of the strings --- src/sdp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index f961c7d3..c59a6157 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -1149,13 +1149,13 @@ void sdp_record_print(const sdp_record_t *rec) { sdp_data_t *d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); if (d) - printf("Service Name: %s\n", d->val.str); + printf("Service Name: %.*s\n", d->unitSize, d->val.str); d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); if (d) - printf("Service Description: %s\n", d->val.str); + printf("Service Description: %.*s\n", d->unitSize, d->val.str); d = sdp_data_get(rec, SDP_ATTR_PROVNAME_PRIMARY); if (d) - printf("Service Provider: %s\n", d->val.str); + printf("Service Provider: %.*s\n", d->unitSize, d->val.str); } #ifdef SDP_DEBUG -- cgit From 997f54c70b25706839544018ad15a718911eb45f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Sep 2006 10:17:46 +0000 Subject: Cleanup of some memory usage --- src/sdp.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index c59a6157..ccbc1657 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -90,9 +90,6 @@ static inline void ntoh128(uint128_t *src, uint128_t *dst) static uint128_t *bluetooth_base_uuid = NULL; -#define SDP_BASIC_ATTR_PDUFORM_SIZE 32 -#define SDP_SEQ_PDUFORM_SIZE 128 -#define SDP_UUID_SEQ_SIZE 256 #define SDP_MAX_ATTR_LEN 65535 /* Message structure. */ @@ -808,14 +805,15 @@ static void sdp_attr_pdu(void *value, void *udata) int sdp_gen_record_pdu(const sdp_record_t *rec, sdp_buf_t *buf) { buf->data = malloc(SDP_PDU_CHUNK_SIZE); - if (buf->data) { - buf->buf_size = SDP_PDU_CHUNK_SIZE; - buf->data_size = 0; - memset(buf->data, 0, buf->buf_size); - sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf); - return 0; - } - return -1; + if (!buf->data) + return -ENOMEM; + + buf->buf_size = SDP_PDU_CHUNK_SIZE; + buf->data_size = 0; + memset(buf->data, 0, buf->buf_size); + sdp_list_foreach(rec->attrlist, sdp_attr_pdu, buf); + + return 0; } void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d) @@ -2376,12 +2374,14 @@ void sdp_append_to_buf(sdp_buf_t *dst, uint8_t *data, uint32_t len) void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) { - uint8_t buf[SDP_SEQ_PDUFORM_SIZE]; + uint8_t buf[256]; sdp_buf_t append; + memset(&append, 0, sizeof(sdp_buf_t)); append.data = buf; append.buf_size = sizeof(buf); append.data_size = 0; + sdp_set_attrid(&append, d->attrId); sdp_gen_pdu(&append, d); sdp_append_to_buf(pdu, append.data, append.data_size); @@ -2679,8 +2679,11 @@ static int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd) SDPDBG(""); memset(&buf, 0, sizeof(sdp_buf_t)); - buf.data = malloc(SDP_UUID_SEQ_SIZE); - buf.buf_size = SDP_UUID_SEQ_SIZE; + buf.data = malloc(256); + buf.buf_size = 256; + + if (!buf.data) + return -ENOMEM; SDPDBG("Seq length : %d\n", seqlen); -- cgit From 0f49354526ab98dc4e78c112343dcdc03efb26f6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 6 Sep 2006 12:30:10 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 7fc9da99..c4497674 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 4:1:2 +libbluetooth_la_LDFLAGS = -version-info 5:0:3 INCLUDES = -I$(top_builddir)/include -- cgit From 5ec20cab698055029198b10afb4db20bee06ce72 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 11 Sep 2006 20:55:05 +0000 Subject: fixed error handling in sdp_process( ) --- src/sdp.c | 89 +++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index ccbc1657..e311f014 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3050,6 +3050,7 @@ struct sdp_transaction { uint8_t *reqbuf; /* pointer to request PDU */ sdp_buf_t rsp_concat_buf; uint32_t reqsize; /* without cstate */ + int err; /* ZERO if success or the errno if failed */ }; /* @@ -3437,6 +3438,35 @@ end: return -1; } +/* + * Function used to get the error reason after sdp_callback_t function has been called + * and the status is 0xffff. It indicates that an error NOT related to SDP_ErrorResponse + * happened. Get errno directly is not safe because multiple transactions can be triggered. + * This function must be used with asynchronous sdp functions only. + * + * INPUT: + * sdp_session_t *session + * Current sdp session to be handled + * RETURN: + * 0 = No error in the current transaction + * -1 - if the session is invalid + * positive value - the errno value + * + */ +int sdp_get_error(sdp_session_t *session) +{ + struct sdp_transaction *t; + + if (!session || !session->priv) { + SDPERR("Invalid session"); + return -1; + } + + t = session->priv; + + return t->err; +} + /* * Receive the incomming SDP PDU. This function must be called when there is data * available to be read. On continuation state, the original request (with a new @@ -3452,14 +3482,14 @@ end: */ int sdp_process(sdp_session_t *session) { - struct sdp_transaction *t = NULL; - sdp_pdu_hdr_t *reqhdr = NULL; - sdp_pdu_hdr_t *rsphdr = NULL; - sdp_cstate_t *pcstate = NULL; - uint8_t *pdata = NULL, *rspbuf = NULL, *targetPtr = NULL; - int rsp_count = 0, err = -1; + struct sdp_transaction *t; + sdp_pdu_hdr_t *reqhdr, *rsphdr; + sdp_cstate_t *pcstate; + uint8_t *pdata, *rspbuf, *targetPtr; + int rsp_count, err = -1; size_t size = 0; - uint16_t status = 0; + uint16_t status = 0xffff; + uint8_t pdu_id = 0x00; if (!session || !session->priv) { SDPERR("Invalid session"); @@ -3467,8 +3497,11 @@ int sdp_process(sdp_session_t *session) } rspbuf = malloc(SDP_RSP_BUFFER_SIZE); - if (!rspbuf) + if (!rspbuf) { + SDPERR("Response buffer alloc failure:%s (%d)", + strerror(errno), errno); return -1; + } memset(rspbuf, 0, SDP_RSP_BUFFER_SIZE); @@ -3476,20 +3509,21 @@ int sdp_process(sdp_session_t *session) reqhdr = (sdp_pdu_hdr_t *)t->reqbuf; rsphdr = (sdp_pdu_hdr_t *)rspbuf; - if (sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE) <= 0) - goto end; + pdata = rspbuf + sizeof(sdp_pdu_hdr_t); - if (reqhdr->tid != rsphdr->tid) + if (sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE) <= 0) { + SDPERR("Read response:%s (%d)", strerror(errno), errno); + t->err = errno; goto end; + } - pdata = rspbuf + sizeof(sdp_pdu_hdr_t); - - if (rsphdr->pdu_id == SDP_ERROR_RSP) { - status = ntohs(bt_get_unaligned((uint16_t *) pdata)); - size = rsphdr->plen; + if (reqhdr->tid != rsphdr->tid) { + t->err = EPROTO; + SDPERR("Wrong transaction ID."); goto end; } + pdu_id = rsphdr->pdu_id; switch (rsphdr->pdu_id) { uint8_t *ssr_pdata; uint16_t tsrc, csrc; @@ -3512,6 +3546,7 @@ int sdp_process(sdp_session_t *session) pdata += 2 * sizeof(uint16_t); /* Ignore TSRC and CSRC */ rsp_count = csrc * 4; } + status = 0x0000; break; case SDP_SVC_ATTR_RSP: case SDP_SVC_SEARCH_ATTR_RSP: @@ -3519,10 +3554,15 @@ int sdp_process(sdp_session_t *session) SDPDBG("Attrlist byte count : %d\n", rsp_count); pdata += sizeof(uint16_t); // points to attribute list + status = 0x0000; break; + case SDP_ERROR_RSP: + status = ntohs(bt_get_unaligned((uint16_t *) pdata)); + size = rsphdr->plen; + goto end; default: - /* FIXME: how handle this situation? */ - SDPDBG("Illegal PDU ID!"); + t->err = EPROTO; + SDPERR("Illegal PDU ID: 0x%x", rsphdr->pdu_id); goto end; } @@ -3531,7 +3571,7 @@ int sdp_process(sdp_session_t *session) SDPDBG("Cstate length : %d\n", pcstate->length); /* * This is a split response, need to concatenate intermediate - * responses and the last one which will have cstate_len == 0 + * responses and the last one which will have cstate length == 0 */ // build concatenated response buffer @@ -3546,7 +3586,7 @@ int sdp_process(sdp_session_t *session) reqhdr->tid = htons(sdp_gen_tid(session)); - // add continuation state (can be null) + // add continuation state cstate_len = copy_cstate(t->reqbuf + t->reqsize, pcstate); reqsize = t->reqsize + cstate_len; @@ -3555,8 +3595,9 @@ int sdp_process(sdp_session_t *session) reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); if (sdp_send_req(session, t->reqbuf, reqsize) < 0) { - SDPERR("Error sendind data:%s", strerror(errno)); - /* FIXME: how handle this error ? */ + SDPERR("Error sendind data:%s(%d)", strerror(errno), errno); + status = 0xffff; + t->err = errno; goto end; } err = 0; @@ -3568,10 +3609,8 @@ end: pdata = t->rsp_concat_buf.data; size = t->rsp_concat_buf.data_size; } - if (t->cb) - t->cb(rsphdr->pdu_id, status, pdata, - size, t->udata); + t->cb(pdu_id, status, pdata, size, t->udata); } if (rspbuf) -- cgit From f207a4f0f6d5d38a3e357f62d4976bedaed2cf4f Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 13 Sep 2006 18:21:48 +0000 Subject: fixed search transaction reqbuf double free --- src/sdp.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index e311f014..d82a23d7 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3204,10 +3204,9 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, u return 0; end: - if (t) { - if (t->reqbuf) - free(t->reqbuf); - free(t); + if (t->reqbuf) { + free(t->reqbuf); + t->reqbuf = NULL; } return -1; @@ -3314,10 +3313,9 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ return 0; end: - if (t) { - if (t->reqbuf) - free(t->reqbuf); - free(t); + if (t->reqbuf) { + free(t->reqbuf); + t->reqbuf = NULL; } return -1; @@ -3429,10 +3427,9 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear return 0; end: - if (t) { - if (t->reqbuf) - free(t->reqbuf); - free(t); + if (t->reqbuf) { + free(t->reqbuf); + t->reqbuf = NULL; } return -1; -- cgit From 12f41aa6ff9529a80a182754d0855dccb11978ac Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 13 Sep 2006 21:33:19 +0000 Subject: Use transaction err instead of errno for *_async funcs --- src/sdp.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index d82a23d7..3e56f490 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3155,15 +3155,13 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, u uint8_t *pdata; int cstate_len, seqlen = 0; - if (!session || !session->priv) { - errno = EINVAL; + if (!session || !session->priv) return -1; - } t = session->priv; t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); if (!t->reqbuf) { - errno = ENOMEM; + t->err = ENOMEM; goto end; } @@ -3191,13 +3189,13 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, u t->reqsize += sizeof(uint16_t); pdata += sizeof(uint16_t); - // set the request header's param length cstate_len = copy_cstate(pdata, NULL); reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { SDPERR("Error sendind data:%s", strerror(errno)); + t->err = errno; goto end; } @@ -3255,15 +3253,13 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ uint8_t *pdata; int cstate_len, seqlen = 0; - if (!session || !session->priv) { - errno = EINVAL; + if (!session || !session->priv) return -1; - } t = session->priv; t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); if (!t->reqbuf) { - errno = ENOMEM; + t->err = ENOMEM; goto end; } @@ -3292,7 +3288,7 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ seqlen = gen_attridseq_pdu(pdata, attrid_list, reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32); if (seqlen == -1) { - errno = EINVAL; + t->err = EINVAL; goto end; } @@ -3307,6 +3303,7 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { SDPERR("Error sendind data:%s", strerror(errno)); + t->err = errno; goto end; } @@ -3365,15 +3362,13 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear uint8_t *pdata; int cstate_len, seqlen = 0; - if (!session || !session->priv) { - errno = EINVAL; + if (!session || !session->priv) return -1; - } t = session->priv; t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); if (!t->reqbuf) { - errno = ENOMEM; + t->err = ENOMEM; goto end; } @@ -3407,7 +3402,7 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear seqlen = gen_attridseq_pdu(pdata, attrid_list, reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32); if (seqlen == -1) { - errno = EINVAL; + t->err = EINVAL; goto end; } @@ -3421,6 +3416,7 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { SDPERR("Error sendind data:%s", strerror(errno)); + t->err = errno; goto end; } @@ -3437,8 +3433,9 @@ end: /* * Function used to get the error reason after sdp_callback_t function has been called - * and the status is 0xffff. It indicates that an error NOT related to SDP_ErrorResponse - * happened. Get errno directly is not safe because multiple transactions can be triggered. + * and the status is 0xffff or if sdp_service_{search, attr, search_attr}_async returns -1. + * It indicates that an error NOT related to SDP_ErrorResponse happened. Get errno directly + * is not safe because multiple transactions can be triggered. * This function must be used with asynchronous sdp functions only. * * INPUT: -- cgit From 18a82a6fce76be0883a431380495510010515fff Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 13 Sep 2006 21:45:21 +0000 Subject: avoid multiple allocs/leak in *_async calls --- src/sdp.c | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 3e56f490..a9187865 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3159,14 +3159,20 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, u return -1; t = session->priv; - t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + + /* check if the buffer is already allocated */ + if (t->rsp_concat_buf.data) + free(t->rsp_concat_buf.data); + memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); + if (!t->reqbuf) { - t->err = ENOMEM; - goto end; + t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + if (!t->reqbuf) { + t->err = ENOMEM; + goto end; + } } - memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); - memset((char *)&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; reqhdr->tid = htons(sdp_gen_tid(session)); @@ -3257,14 +3263,20 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ return -1; t = session->priv; - t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + + /* check if the buffer is already allocated */ + if (t->rsp_concat_buf.data) + free(t->rsp_concat_buf.data); + memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); + if (!t->reqbuf) { - t->err = ENOMEM; - goto end; + t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + if (!t->reqbuf) { + t->err = ENOMEM; + goto end; + } } - memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); - memset((char *)&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; reqhdr->tid = htons(sdp_gen_tid(session)); @@ -3366,14 +3378,20 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear return -1; t = session->priv; - t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + + /* check if the buffer is already allocated */ + if (t->rsp_concat_buf.data) + free(t->rsp_concat_buf.data); + memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); + if (!t->reqbuf) { - t->err = ENOMEM; - goto end; + t->reqbuf = malloc(SDP_REQ_BUFFER_SIZE); + if (!t->reqbuf) { + t->err = ENOMEM; + goto end; + } } - memset(t->reqbuf, 0, SDP_REQ_BUFFER_SIZE); - memset((char *)&t->rsp_concat_buf, 0, sizeof(sdp_buf_t)); reqhdr = (sdp_pdu_hdr_t *) t->reqbuf; reqhdr->tid = htons(sdp_gen_tid(session)); -- cgit From b214431051ac907f47cc8e798216869c5a5e1d5a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 24 Sep 2006 19:25:32 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index c4497674..bcf2543d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 5:0:3 +libbluetooth_la_LDFLAGS = -version-info 6:0:4 INCLUDES = -I$(top_builddir)/include -- cgit From 9203084c0b92805006c133f82fbc0cbd6b203904 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 28 Sep 2006 19:30:01 +0000 Subject: sdp_process:check if the PDU length match with the received data --- src/sdp.c | 55 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index a9187865..7e7698b2 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3500,6 +3500,7 @@ int sdp_process(sdp_session_t *session) uint8_t *pdata, *rspbuf, *targetPtr; int rsp_count, err = -1; size_t size = 0; + int n, plen; uint16_t status = 0xffff; uint8_t pdu_id = 0x00; @@ -3523,15 +3524,17 @@ int sdp_process(sdp_session_t *session) pdata = rspbuf + sizeof(sdp_pdu_hdr_t); - if (sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE) <= 0) { + n = sdp_read_rsp(session, rspbuf, SDP_RSP_BUFFER_SIZE); + if (n < 0) { SDPERR("Read response:%s (%d)", strerror(errno), errno); t->err = errno; goto end; } - if (reqhdr->tid != rsphdr->tid) { + if (n == 0 || reqhdr->tid != rsphdr->tid || + (n != (ntohs(rsphdr->plen) + sizeof(sdp_pdu_hdr_t)))) { t->err = EPROTO; - SDPERR("Wrong transaction ID."); + SDPERR("Protocol error."); goto end; } @@ -3541,19 +3544,30 @@ int sdp_process(sdp_session_t *session) uint16_t tsrc, csrc; case SDP_SVC_SEARCH_RSP: /* - * TSRC: Total Service Record Count - * CSRC: Current Service Record Count + * TSRC: Total Service Record Count (2 bytes) + * CSRC: Current Service Record Count (2 bytes) */ ssr_pdata = pdata; - ssr_pdata += sizeof(tsrc); tsrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); + ssr_pdata += sizeof(uint16_t); csrc = ntohs(bt_get_unaligned((uint16_t *) ssr_pdata)); + /* csrc should never be larger than tsrc */ + if (csrc > tsrc) { + t->err = EPROTO; + SDPERR("Protocol error: wrong current service record count value."); + goto end; + } + + SDPDBG("Total svc count: %d\n", tsrc); + SDPDBG("Current svc count: %d\n", csrc); + + /* parameter length without continuation state */ + plen = sizeof(tsrc) + sizeof(csrc) + csrc * 4; + if (t->rsp_concat_buf.data_size == 0) { /* first fragment */ rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4; - SDPDBG("Total svc count: %d\n", tsrc); - SDPDBG("Current svc count: %d\n", csrc); } else { pdata += 2 * sizeof(uint16_t); /* Ignore TSRC and CSRC */ rsp_count = csrc * 4; @@ -3564,13 +3578,22 @@ int sdp_process(sdp_session_t *session) case SDP_SVC_SEARCH_ATTR_RSP: rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); SDPDBG("Attrlist byte count : %d\n", rsp_count); + + /* + * Number of bytes in the AttributeLists parameter(without + * continuation state) + AttributeListsByteCount field size. + */ + plen = sizeof(uint16_t) + rsp_count; pdata += sizeof(uint16_t); // points to attribute list status = 0x0000; break; case SDP_ERROR_RSP: status = ntohs(bt_get_unaligned((uint16_t *) pdata)); - size = rsphdr->plen; + size = ntohs(rsphdr->plen); + + /* error code + error info */ + plen = size; goto end; default: t->err = EPROTO; @@ -3581,12 +3604,22 @@ int sdp_process(sdp_session_t *session) pcstate = (sdp_cstate_t *) (pdata + rsp_count); SDPDBG("Cstate length : %d\n", pcstate->length); + + /* + * Check out of bound. Continuation state must have at least + * 1 byte: ZERO to indicate that it is not a partial response. + */ + if ((n - sizeof(sdp_pdu_hdr_t)) != (plen + pcstate->length + 1)) { + t->err = EPROTO; + SDPERR("Protocol error: wrong PDU size."); + status = 0xffff; + goto end; + } + /* * This is a split response, need to concatenate intermediate * responses and the last one which will have cstate length == 0 */ - - // build concatenated response buffer t->rsp_concat_buf.data = realloc(t->rsp_concat_buf.data, t->rsp_concat_buf.data_size + rsp_count); targetPtr = t->rsp_concat_buf.data + t->rsp_concat_buf.data_size; t->rsp_concat_buf.buf_size = t->rsp_concat_buf.data_size + rsp_count; -- cgit From e3dbc939bd096c8604d1480e0994f73f65a39f16 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 28 Sep 2006 21:36:48 +0000 Subject: fixed csrc for partial responses --- src/sdp.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 7e7698b2..0eeb5a09 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3569,7 +3569,17 @@ int sdp_process(sdp_session_t *session) /* first fragment */ rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4; } else { - pdata += 2 * sizeof(uint16_t); /* Ignore TSRC and CSRC */ + /* point to the first csrc */ + uint16_t *pcsrc = (uint16_t *) (t->rsp_concat_buf.data + 2); + + /* FIXME: update the interface later. csrc doesn't need be passed to clients */ + + pdata += sizeof(uint16_t); /* point to csrc */ + + /* the first csrc contains the sum of partial csrc responses */ + *pcsrc += bt_get_unaligned((uint16_t *) pdata); + + pdata += sizeof(uint16_t); /* point to the first handle */ rsp_count = csrc * 4; } status = 0x0000; -- cgit From 3c8d737f3ebcd49548d364e8976f0ca1cdb4e5ae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 29 Sep 2006 21:11:37 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index bcf2543d..10abc721 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 6:0:4 +libbluetooth_la_LDFLAGS = -version-info 6:1:4 INCLUDES = -I$(top_builddir)/include -- cgit From 82817924a25fb0eaaeb9824372106870c45c9db9 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 7 Nov 2006 18:30:16 +0000 Subject: Add functions for registering binary records --- src/sdp.c | 103 ++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 0eeb5a09..d83dea76 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2395,13 +2395,12 @@ void sdp_append_to_pdu(sdp_buf_t *pdu, sdp_data_t *d) * * Returns zero on success, otherwise -1 (and sets errno). */ -int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags) +int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, uint8_t *data, uint32_t size, uint8_t flags, uint32_t *handle) { - int status = 0; uint8_t *req, *rsp, *p; uint32_t reqsize, rspsize; sdp_pdu_hdr_t *reqhdr, *rsphdr; - sdp_buf_t pdu; + int status; SDPDBG(""); @@ -2416,16 +2415,13 @@ int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_rec errno = ENOMEM; goto end; } - if (rec->handle && rec->handle != 0xffffffff) { - uint32_t handle = rec->handle; - sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); - sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); - } + reqhdr = (sdp_pdu_hdr_t *)req; reqhdr->pdu_id = SDP_SVC_REGISTER_REQ; reqhdr->tid = htons(sdp_gen_tid(session)); reqsize = sizeof(sdp_pdu_hdr_t) + 1; p = req + sizeof(sdp_pdu_hdr_t); + if (bacmp(device, BDADDR_ANY)) { *p++ = flags | SDP_DEVICE_RECORD; bacpy((bdaddr_t *) p, device); @@ -2433,35 +2429,66 @@ int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_rec reqsize += sizeof(bdaddr_t); } else *p++ = flags; - if (sdp_gen_record_pdu(rec, &pdu) < 0) { - status = -1; - errno = ENOMEM; - goto end; - } - memcpy(p, pdu.data, pdu.data_size); - free(pdu.data); - reqsize += pdu.data_size; + + memcpy(p, data, size); + reqsize += size; reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); status = sdp_send_req_w4_rsp(session, req, rsp, reqsize, &rspsize); if (status < 0) goto end; + rsphdr = (sdp_pdu_hdr_t *) rsp; p = rsp + sizeof(sdp_pdu_hdr_t); + if (rsphdr->pdu_id == SDP_SVC_REGISTER_RSP) { - uint32_t handle = ntohl(bt_get_unaligned((uint32_t *) p)); - sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); - rec->handle = handle; - sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); + if (handle) + *handle = ntohl(bt_get_unaligned((uint32_t *) p)); } + end: if (req) free(req); + if (rsp) free(rsp); + return status; } +int sdp_device_record_register(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec, uint8_t flags) +{ + sdp_buf_t pdu; + uint32_t handle; + int err; + + SDPDBG(""); + + if (rec->handle && rec->handle != 0xffffffff) { + uint32_t handle = rec->handle; + sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); + sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); + } + + if (sdp_gen_record_pdu(rec, &pdu) < 0) { + errno = ENOMEM; + return -1; + } + + err = sdp_device_record_register_binary(session, device, + pdu.data, pdu.data_size, flags, &handle); + + free(pdu.data); + + if (err == 0) { + sdp_data_t *data = sdp_data_alloc(SDP_UINT32, &handle); + rec->handle = handle; + sdp_attr_replace(rec, SDP_ATTR_RECORD_HANDLE, data); + } + + return err; +} + int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags) { return sdp_device_record_register(session, BDADDR_ANY, rec, flags); @@ -2470,25 +2497,25 @@ int sdp_record_register(sdp_session_t *session, sdp_record_t *rec, uint8_t flags /* * unregister a service record */ -int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec) +int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle) { - int status = 0; uint8_t *reqbuf, *rspbuf, *p; uint32_t reqsize = 0, rspsize = 0; sdp_pdu_hdr_t *reqhdr, *rsphdr; - uint32_t handle = 0; + int status; SDPDBG(""); - handle = rec->handle; if (handle == SDP_SERVER_RECORD_HANDLE) { errno = EINVAL; return -1; } + if (!session->local) { errno = EREMOTE; return -1; } + reqbuf = malloc(SDP_REQ_BUFFER_SIZE); rspbuf = malloc(SDP_RSP_BUFFER_SIZE); if (!reqbuf || !rspbuf) { @@ -2511,19 +2538,31 @@ int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_r rsphdr = (sdp_pdu_hdr_t *) rspbuf; p = rspbuf + sizeof(sdp_pdu_hdr_t); status = bt_get_unaligned((uint16_t *) p); - if (status == 0 && rsphdr->pdu_id == SDP_SVC_REMOVE_RSP) { - SDPDBG("Removing local copy\n"); - sdp_record_free(rec); - } + if (status != 0 || rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) + status = -1; } + end: if (reqbuf) free(reqbuf); + if (rspbuf) free(rspbuf); + return status; } +int sdp_device_record_unregister(sdp_session_t *session, bdaddr_t *device, sdp_record_t *rec) +{ + int err; + + err = sdp_device_record_unregister_binary(session, device, rec->handle); + if (err == 0) + sdp_record_free(rec); + + return err; +} + int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) { return sdp_device_record_unregister(session, BDADDR_ANY, rec); @@ -2532,16 +2571,22 @@ int sdp_record_unregister(sdp_session_t *session, sdp_record_t *rec) /* * modify an existing service record */ +int sdp_device_record_update_binary(sdp_session_t *session, bdaddr_t *device, uint32_t handle, uint8_t *data, uint32_t size) +{ + return -1; +} + int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp_record_t *rec) { - int status = 0; uint8_t *reqbuf, *rspbuf, *p; uint32_t reqsize, rspsize; sdp_pdu_hdr_t *reqhdr, *rsphdr; uint32_t handle; sdp_buf_t pdu; + int status; SDPDBG(""); + handle = rec->handle; if (handle == SDP_SERVER_RECORD_HANDLE) { -- cgit From a7c82c586998da5b64e680a9027a6f5aeba915f5 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 9 Nov 2006 21:25:30 +0000 Subject: handling invalid sdp record sintax for registration/unregistration/update --- src/sdp.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index d83dea76..d55f3159 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2441,7 +2441,14 @@ int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, rsphdr = (sdp_pdu_hdr_t *) rsp; p = rsp + sizeof(sdp_pdu_hdr_t); - if (rsphdr->pdu_id == SDP_SVC_REGISTER_RSP) { + if (rsphdr->pdu_id == SDP_ERROR_RSP) { + /* Invalid service record */ + errno = EINVAL; + status = -1; + } else if (rsphdr->pdu_id != SDP_SVC_REGISTER_RSP) { + errno = EPROTO; + status = -1; + } else { if (handle) *handle = ntohl(bt_get_unaligned((uint32_t *) p)); } @@ -2534,14 +2541,21 @@ int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); - if (status == 0) { - rsphdr = (sdp_pdu_hdr_t *) rspbuf; - p = rspbuf + sizeof(sdp_pdu_hdr_t); - status = bt_get_unaligned((uint16_t *) p); - if (status != 0 || rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) - status = -1; - } + if (status < 0) + goto end; + + rsphdr = (sdp_pdu_hdr_t *) rspbuf; + p = rspbuf + sizeof(sdp_pdu_hdr_t); + status = bt_get_unaligned((uint16_t *) p); + if (rsphdr->pdu_id == SDP_ERROR_RSP) { + /* For this case the status always is invalid record handle */ + errno = EINVAL; + status = -1; + } else if (rsphdr->pdu_id != SDP_SVC_REMOVE_RSP) { + errno = EPROTO; + status = -1; + } end: if (reqbuf) free(reqbuf); @@ -2625,13 +2639,22 @@ int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); + if (status < 0) + goto end; SDPDBG("Send req status : %d\n", status); - if (status == 0) { - rsphdr = (sdp_pdu_hdr_t *) rspbuf; - p = rspbuf + sizeof(sdp_pdu_hdr_t); - status = bt_get_unaligned((uint16_t *) p); + rsphdr = (sdp_pdu_hdr_t *) rspbuf; + p = rspbuf + sizeof(sdp_pdu_hdr_t); + status = bt_get_unaligned((uint16_t *) p); + + if (rsphdr->pdu_id == SDP_ERROR_RSP) { + /* The status can be invalid sintax or invalid record handle */ + errno = EINVAL; + status = -1; + } else if (rsphdr->pdu_id != SDP_SVC_UPDATE_RSP) { + errno = EPROTO; + status = -1; } end: if (reqbuf) -- cgit From 85a6b6ed56f25eb8f766b2efbbf0c86aa9848c3a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 25 Dec 2006 13:45:52 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 10abc721..79bcaaa5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 6:1:4 +libbluetooth_la_LDFLAGS = -version-info 7:0:5 INCLUDES = -I$(top_builddir)/include -- cgit From 25effaf3a661c4de960ebae7125ba56a990ad628 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 13 Jan 2007 17:50:06 +0000 Subject: Update copyright information --- src/bluetooth.c | 2 +- src/hci.c | 2 +- src/sdp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 645a4d63..33e033ad 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/src/hci.c b/src/hci.c index f7235f74..7d30c552 100644 --- a/src/hci.c +++ b/src/hci.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/src/sdp.c b/src/sdp.c index d55f3159..4270ac83 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2006 Marcel Holtmann + * Copyright (C) 2002-2007 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * -- cgit From 397609f69cbc21cfd87b27246f4f5ed9dada646d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 13 Feb 2007 14:44:47 +0000 Subject: Add version code for Bluetooth 2.1 --- src/hci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 7d30c552..a064980f 100644 --- a/src/hci.c +++ b/src/hci.c @@ -505,6 +505,7 @@ static hci_map ver_map[] = { { "1.1", 0x01 }, { "1.2", 0x02 }, { "2.0", 0x03 }, + { "2.1", 0x04 }, { NULL } }; -- cgit From c5621bfbf9071ed359d904bdd91308f6599dc5e5 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 26 Apr 2007 19:47:36 +0000 Subject: Fixed memory leak --- src/sdp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 4270ac83..af2cf162 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2629,13 +2629,14 @@ int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp reqsize += sizeof(uint32_t); p += sizeof(uint32_t); - if (0 > sdp_gen_record_pdu(rec, &pdu)) { + if (sdp_gen_record_pdu(rec, &pdu) < 0) { errno = ENOMEM; status = -1; goto end; } memcpy(p, pdu.data, pdu.data_size); reqsize += pdu.data_size; + free(pdu.data); reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); -- cgit From 0910c7010b29b9716d69459ecbd5ab29c6a34fa4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 May 2007 07:22:22 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 79bcaaa5..4ecf123e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 7:0:5 +libbluetooth_la_LDFLAGS = -version-info 8:0:6 INCLUDES = -I$(top_builddir)/include -- cgit From cb08fcdb50544c554e1275ede85605e4542b5b1b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 May 2007 08:13:54 +0000 Subject: Fix URL data size handling --- src/sdp.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index af2cf162..0414d013 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -695,61 +695,57 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) break; case SDP_UINT16: u16 = htons(d->val.uint16); - src = (unsigned char *)&u16; + src = (unsigned char *) &u16; data_size = sizeof(uint16_t); break; case SDP_UINT32: u32 = htonl(d->val.uint32); - src = (unsigned char *)&u32; + src = (unsigned char *) &u32; data_size = sizeof(uint32_t); break; case SDP_UINT64: u64 = hton64(d->val.uint64); - src = (unsigned char *)&u64; + src = (unsigned char *) &u64; data_size = sizeof(uint64_t); break; case SDP_UINT128: hton128(&d->val.uint128, &u128); - src = (unsigned char *)&u128; + src = (unsigned char *) &u128; data_size = sizeof(uint128_t); break; case SDP_INT8: case SDP_BOOL: - src = (unsigned char *)&d->val.int8; + src = (unsigned char *) &d->val.int8; data_size = sizeof(int8_t); break; case SDP_INT16: u16 = htons(d->val.int16); - src = (unsigned char *)&u16; + src = (unsigned char *) &u16; data_size = sizeof(int16_t); break; case SDP_INT32: u32 = htonl(d->val.int32); - src = (unsigned char *)&u32; + src = (unsigned char *) &u32; data_size = sizeof(int32_t); break; case SDP_INT64: u64 = hton64(d->val.int64); - src = (unsigned char *)&u64; + src = (unsigned char *) &u64; data_size = sizeof(int64_t); break; case SDP_INT128: hton128(&d->val.int128, &u128); - src = (unsigned char *)&u128; + src = (unsigned char *) &u128; data_size = sizeof(uint128_t); break; case SDP_TEXT_STR8: case SDP_TEXT_STR16: case SDP_TEXT_STR32: - src = (unsigned char *)d->val.str; - data_size = d->unitSize - sizeof(uint8_t); - sdp_set_seq_len(seqp, data_size); - break; case SDP_URL_STR8: case SDP_URL_STR16: case SDP_URL_STR32: - src = (unsigned char *)d->val.str; - data_size = strlen(d->val.str); + src = (unsigned char *) d->val.str; + data_size = d->unitSize - sizeof(uint8_t); sdp_set_seq_len(seqp, data_size); break; case SDP_SEQ8: @@ -768,16 +764,16 @@ int sdp_gen_pdu(sdp_buf_t *buf, sdp_data_t *d) break; case SDP_UUID16: u16 = htons(d->val.uuid.value.uuid16); - src = (unsigned char *)&u16; + src = (unsigned char *) &u16; data_size = sizeof(uint16_t); break; case SDP_UUID32: u32 = htonl(d->val.uuid.value.uuid32); - src = (unsigned char *)&u32; + src = (unsigned char *) &u32; data_size = sizeof(uint32_t); break; case SDP_UUID128: - src = (unsigned char *)&d->val.uuid.value.uuid128; + src = (unsigned char *) &d->val.uuid.value.uuid128; data_size = sizeof(uint128_t); break; default: -- cgit From 8be6e8b5936c34b4f826af0b91bb1df565a083f1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 24 May 2007 14:21:44 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 4ecf123e..0602d4e9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 8:0:6 +libbluetooth_la_LDFLAGS = -version-info 8:1:6 INCLUDES = -I$(top_builddir)/include -- cgit From 07c0013ff14eb0b16570d33fc50a9130d008609c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 11 Jun 2007 18:48:59 +0000 Subject: Add new company identifiers --- src/bluetooth.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 33e033ad..e2ba87ca 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -384,6 +384,16 @@ char *bt_compidtostr(int compid) return "PARROT SA"; case 68: return "Socket Communications"; + case 69: + return "Atheros Communications, Inc."; + case 70: + return "MediaTek, Inc."; + case 71: + return "Bluegiga"; /* (tentative) */ + case 72: + return "Marvell Technology Group Ltd."; + case 73: + return "3DSP Corporation"; case 65535: return "internal use"; default: -- cgit From 9d9a7646b189cc2471b925cc448862e14c10c0c4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 15 Jun 2007 11:00:46 +0000 Subject: Check record struct pointer before adding an UUID --- src/sdp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 0414d013..920bc880 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -922,7 +922,8 @@ static sdp_data_t *extract_uuid(const uint8_t *p, int *len, sdp_record_t *rec) return NULL; } d->dtd = *(uint8_t *) p; - sdp_pattern_add_uuid(rec, &d->val.uuid); + if (rec) + sdp_pattern_add_uuid(rec, &d->val.uuid); return d; } -- cgit From 34c5828e678e244a28b7c3ba7078a08583273aa3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 16 Jun 2007 11:46:22 +0000 Subject: Add definitions for inquiry power level and erroneous data --- src/hci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index a064980f..4e95a420 100644 --- a/src/hci.c +++ b/src/hci.c @@ -600,14 +600,14 @@ static hci_map lmp_features_map[8][9] = { { "", 0x04 }, /* Bit 2 */ { "", 0x08 }, /* Bit 3 */ { "", 0x10 }, /* Bit 4 */ - { "", 0x20 }, /* Bit 5 */ - { "", 0x40 }, /* Bit 6 */ + { "", LMP_ERR_DAT_REP }, /* Bit 5 */ + { "", LMP_NFLUSH_PKTS }, /* Bit 6 */ { "", 0x80 }, /* Bit 7 */ { NULL } }, { /* Byte 7 */ { "", LMP_LSTO }, /* Bit 1 */ - { "", 0x02 }, /* Bit 1 */ + { "", LMP_INQ_TX_PWR }, /* Bit 1 */ { "", 0x04 }, /* Bit 2 */ { "", 0x08 }, /* Bit 3 */ { "", 0x10 }, /* Bit 4 */ -- cgit From 54d90a07ab77d86aeac4eed963071a07247eff18 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 20 Jun 2007 15:34:46 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index e2ba87ca..f0f800a5 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -394,6 +394,8 @@ char *bt_compidtostr(int compid) return "Marvell Technology Group Ltd."; case 73: return "3DSP Corporation"; + case 74: + return "Accel Semiconductor Ltd."; case 65535: return "internal use"; default: -- cgit From 3536636a5b1664499ee0ededd305b9bdc9ddeaa4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 21 Jun 2007 21:18:00 +0000 Subject: Add common bachk() function --- src/bluetooth.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index f0f800a5..676e468e 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -110,6 +111,40 @@ int ba2oui(const bdaddr_t *ba, char *str) return sprintf(str, "%2.2X-%2.2X-%2.2X", b[0], b[1], b[2]); } +int bachk(const char *str) +{ + char tmp[18], *ptr = tmp; + + if (!str) + return -1; + + if (strlen(str) != 17) + return -1; + + memcpy(tmp, str, 18); + + while (*ptr) { + *ptr = toupper(*ptr); + if (*ptr < '0'|| (*ptr > '9' && *ptr < 'A') || *ptr > 'F') + return -1; + ptr++; + + *ptr = toupper(*ptr); + if (*ptr < '0'|| (*ptr > '9' && *ptr < 'A') || *ptr > 'F') + return -1; + ptr++; + + *ptr = toupper(*ptr); + if (*ptr == 0) + break; + if (*ptr != ':') + return -1; + ptr++; + } + + return 0; +} + int baprintf(const char *format, ...) { va_list ap; -- cgit From a9ad7c6fef3c62fa773a586d10402a343a4ee91b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 22 Jun 2007 19:09:54 +0000 Subject: Add HCI command text descriptions --- src/hci.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 4e95a420..47359195 100644 --- a/src/hci.c +++ b/src/hci.c @@ -447,9 +447,35 @@ static hci_map commands_map[] = { { "Reserved", 135 }, { "Read Extended Inquiry Response", 136 }, { "Write Extended Inquiry Response", 137 }, - { "Unknown", 138 }, - { "Unknown", 139 }, - { "Sniff Subrate", 140 }, + { "Refresh Encryption Key", 138 }, + { "Reserved", 139 }, + { "Sniff Subrating", 140 }, + { "Unknown", 141 }, + { "Unknown", 142 }, + { "Unknown", 143 }, + { "Read Inquiry Transmit Power Level", 144 }, + { "Write Inquiry Transmit Power Level", 145 }, + { "Read Default Erroneous Data Reporting", 146 }, + { "Write Default Erroneous Data Reporting", 147 }, + { "Reserved", 148 }, + { "Reserved", 149 }, + { "Reserved", 150 }, + { "Unknown", 151 }, + { "Unknown", 152 }, + { "Unknown", 153 }, + { "Unknown", 154 }, + { "Unknown", 155 }, + { "Unknown", 156 }, + { "Enhanced Flush", 157 }, + { "Unknown", 158 }, + { "Reserved", 159 }, + { "Reserved", 160 }, + { "Unknown", 161 }, + { "Unknown", 162 }, + { "Reserved", 163 }, + { "Reserved", 164 }, + { "Reserved", 165 }, + { "Reserved", 166 }, { NULL } }; -- cgit From 362b9690036f8324e2d0a40bed4adc6d0986caad Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 23 Jun 2007 23:37:00 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 0602d4e9..0b662369 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 8:1:6 +libbluetooth_la_LDFLAGS = -version-info 9:0:7 INCLUDES = -I$(top_builddir)/include -- cgit From 08b3ddeeff510f9ac61c860a74d13575a47420b7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jul 2007 08:25:50 +0000 Subject: Update HCI command table --- src/hci.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 47359195..04da6de5 100644 --- a/src/hci.c +++ b/src/hci.c @@ -317,6 +317,7 @@ static hci_map commands_map[] = { { "Disconnect", 5 }, { "Add SCO Connection", 6 }, { "Cancel Create Connection", 7 }, + { "Accept Connection Request", 8 }, { "Reject Connection Request", 9 }, { "Link Key Request Reply", 10 }, @@ -325,6 +326,7 @@ static hci_map commands_map[] = { { "PIN Code Request Negative Reply", 13 }, { "Change Connection Packet Type", 14 }, { "Authentication Requested", 15 }, + { "Set Connection Encryption", 16 }, { "Change Connection Link Key", 17 }, { "Master Link Key", 18 }, @@ -333,6 +335,7 @@ static hci_map commands_map[] = { { "Read Remote Supported Features", 21 }, { "Read Remote Extended Features", 22 }, { "Read Remote Version Information", 23 }, + { "Read Clock Offset", 24 }, { "Read LMP Handle", 25 }, { "Reserved", 26 }, @@ -341,6 +344,7 @@ static hci_map commands_map[] = { { "Reserved", 29 }, { "Reserved", 30 }, { "Reserved", 31 }, + { "Reserved", 32 }, { "Hold Mode", 33 }, { "Sniff Mode", 34 }, @@ -349,6 +353,7 @@ static hci_map commands_map[] = { { "Exit Park State", 37 }, { "QoS Setup", 38 }, { "Role Discovery", 39 }, + { "Switch Role", 40 }, { "Read Link Policy Settings", 41 }, { "Write Link Policy Settings", 42 }, @@ -357,6 +362,7 @@ static hci_map commands_map[] = { { "Flow Specification", 45 }, { "Set Event Mask", 46 }, { "Reset", 47 }, + { "Set Event Filter", 48 }, { "Flush", 49 }, { "Read PIN Type", 50 }, @@ -365,6 +371,7 @@ static hci_map commands_map[] = { { "Read Stored Link Key", 53 }, { "Write Stored Link Key", 54 }, { "Delete Stored Link Key", 55 }, + { "Write Local Name", 56 }, { "Read Local Name", 57 }, { "Read Connection Accept Timeout", 58 }, @@ -373,6 +380,7 @@ static hci_map commands_map[] = { { "Write Page Timeout", 61 }, { "Read Scan Enable", 62 }, { "Write Scan Enable", 63 }, + { "Read Page Scan Activity", 64 }, { "Write Page Scan Activity", 65 }, { "Read Inquiry Scan Activity", 66 }, @@ -381,6 +389,7 @@ static hci_map commands_map[] = { { "Write Authentication Enable", 69 }, { "Read Encryption Mode", 70 }, { "Write Encryption Mode", 71 }, + { "Read Class Of Device", 72 }, { "Write Class Of Device", 73 }, { "Read Voice Setting", 74 }, @@ -389,6 +398,7 @@ static hci_map commands_map[] = { { "Write Automatic Flush Timeout", 77 }, { "Read Num Broadcast Retransmissions", 78 }, { "Write Num Broadcast Retransmissions", 79 }, + { "Read Hold Mode Activity", 80 }, { "Write Hold Mode Activity", 81 }, { "Read Transmit Power Level", 82 }, @@ -397,6 +407,7 @@ static hci_map commands_map[] = { { "Set Host Controller To Host Flow Control", 85 }, { "Host Buffer Size", 86 }, { "Host Number Of Completed Packets", 87 }, + { "Read Link Supervision Timeout", 88 }, { "Write Link Supervision Timeout", 89 }, { "Read Number of Supported IAC", 90 }, @@ -405,14 +416,16 @@ static hci_map commands_map[] = { { "Read Page Scan Period Mode", 93 }, { "Write Page Scan Period Mode", 94 }, { "Read Page Scan Mode", 95 }, + { "Write Page Scan Mode", 96 }, { "Set AFH Channel Classification", 97 }, - { "reserved", 98 }, - { "reserved", 99 }, + { "Reserved", 98 }, + { "Reserved", 99 }, { "Read Inquiry Scan Type", 100 }, { "Write Inquiry Scan Type", 101 }, { "Read Inquiry Mode", 102 }, { "Write Inquiry Mode", 103 }, + { "Read Page Scan Type", 104 }, { "Write Page Scan Type", 105 }, { "Read AFH Channel Assessment Mode", 106 }, @@ -421,6 +434,7 @@ static hci_map commands_map[] = { { "Reserved", 109 }, { "Reserved", 110 }, { "Reserved", 111 }, + { "Reserved", 112 }, { "Reserved", 113 }, { "Reserved", 114 }, @@ -429,6 +443,7 @@ static hci_map commands_map[] = { { "Read Local Supported Features", 117 }, { "Read Local Extended Features", 118 }, { "Read Buffer Size", 119 }, + { "Read Country Code", 120 }, { "Read BD ADDR", 121 }, { "Read Failed Contact Counter", 122 }, @@ -437,6 +452,7 @@ static hci_map commands_map[] = { { "Read RSSI", 125 }, { "Read AFH Channel Map", 126 }, { "Read BD Clock", 127 }, + { "Read Loopback Mode", 128 }, { "Write Loopback Mode", 129 }, { "Enable Device Under Test Mode", 130 }, @@ -445,6 +461,7 @@ static hci_map commands_map[] = { { "Reject Synchronous Connection", 133 }, { "Reserved", 134 }, { "Reserved", 135 }, + { "Read Extended Inquiry Response", 136 }, { "Write Extended Inquiry Response", 137 }, { "Refresh Encryption Key", 138 }, @@ -453,6 +470,7 @@ static hci_map commands_map[] = { { "Unknown", 141 }, { "Unknown", 142 }, { "Unknown", 143 }, + { "Read Inquiry Transmit Power Level", 144 }, { "Write Inquiry Transmit Power Level", 145 }, { "Read Default Erroneous Data Reporting", 146 }, @@ -461,21 +479,25 @@ static hci_map commands_map[] = { { "Reserved", 149 }, { "Reserved", 150 }, { "Unknown", 151 }, + { "Unknown", 152 }, { "Unknown", 153 }, { "Unknown", 154 }, { "Unknown", 155 }, { "Unknown", 156 }, - { "Enhanced Flush", 157 }, - { "Unknown", 158 }, - { "Reserved", 159 }, + { "Unknown", 157 }, + { "Enhanced Flush", 158 }, + { "Unknown", 159 }, + { "Reserved", 160 }, - { "Unknown", 161 }, + { "Reserved", 161 }, { "Unknown", 162 }, - { "Reserved", 163 }, + { "Unknown", 163 }, { "Reserved", 164 }, { "Reserved", 165 }, { "Reserved", 166 }, + { "Reserved", 167 }, + { NULL } }; -- cgit From 7092f984dafd1b9e67873f73ffe9334289ff1a17 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 26 Jul 2007 08:30:21 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 0b662369..9392082d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 9:0:7 +libbluetooth_la_LDFLAGS = -version-info 9:1:7 INCLUDES = -I$(top_builddir)/include -- cgit From a3cc218cd5f213922cd529ebfb5da5ba1b1f1aca Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 1 Aug 2007 07:29:23 +0000 Subject: Add definitions and functions for Simple Pairing --- src/hci.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 91 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 04da6de5..d3e81d2c 100644 --- a/src/hci.c +++ b/src/hci.c @@ -467,9 +467,9 @@ static hci_map commands_map[] = { { "Refresh Encryption Key", 138 }, { "Reserved", 139 }, { "Sniff Subrating", 140 }, - { "Unknown", 141 }, - { "Unknown", 142 }, - { "Unknown", 143 }, + { "Read Simple Pairing Mode", 141 }, + { "Write Simple Pairing Mode", 142 }, + { "Read Local OOB Data", 143 }, { "Read Inquiry Transmit Power Level", 144 }, { "Write Inquiry Transmit Power Level", 145 }, @@ -478,21 +478,21 @@ static hci_map commands_map[] = { { "Reserved", 148 }, { "Reserved", 149 }, { "Reserved", 150 }, - { "Unknown", 151 }, - - { "Unknown", 152 }, - { "Unknown", 153 }, - { "Unknown", 154 }, - { "Unknown", 155 }, - { "Unknown", 156 }, - { "Unknown", 157 }, + { "IO Capability Request Reply", 151 }, + + { "User Confirmation Request Reply", 152 }, + { "User Confirmation Request Negative Reply", 153 }, + { "User Passkey Request Reply", 154 }, + { "User Passkey Request Negative Reply", 155 }, + { "Remote OOB Data Request Reply", 156 }, + { "Write Simple Pairing Debug Mode", 157 }, { "Enhanced Flush", 158 }, - { "Unknown", 159 }, + { "Remote OOB Data Request Negative Reply", 159 }, { "Reserved", 160 }, { "Reserved", 161 }, - { "Unknown", 162 }, - { "Unknown", 163 }, + { "Send Keypress Notification", 162 }, + { "IO Capabilities Response Negative Reply", 163 }, { "Reserved", 164 }, { "Reserved", 165 }, { "Reserved", 166 }, @@ -646,8 +646,8 @@ static hci_map lmp_features_map[8][9] = { { "", LMP_EXT_INQ }, /* Bit 0 */ { "", 0x02 }, /* Bit 1 */ { "", 0x04 }, /* Bit 2 */ - { "", 0x08 }, /* Bit 3 */ - { "", 0x10 }, /* Bit 4 */ + { "", LMP_SIMPLE_PAIR }, /* Bit 3 */ + { "", LMP_ENCAPS_PDU }, /* Bit 4 */ { "", LMP_ERR_DAT_REP }, /* Bit 5 */ { "", LMP_NFLUSH_PKTS }, /* Bit 6 */ { "", 0x80 }, /* Bit 7 */ @@ -2060,6 +2060,81 @@ int hci_write_ext_inquiry_response(int dd, uint8_t fec, uint8_t *data, int to) return 0; } +int hci_read_simple_pairing_mode(int dd, uint8_t *mode, int to) +{ + read_simple_pairing_mode_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_SIMPLE_PAIRING_MODE; + rq.rparam = &rp; + rq.rlen = READ_SIMPLE_PAIRING_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *mode = rp.mode; + return 0; +} + +int hci_write_simple_pairing_mode(int dd, uint8_t mode, int to) +{ + write_simple_pairing_mode_cp cp; + write_simple_pairing_mode_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.mode = mode; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_SIMPLE_PAIRING_MODE; + rq.cparam = &cp; + rq.clen = WRITE_SIMPLE_PAIRING_MODE_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_SIMPLE_PAIRING_MODE_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + +int hci_read_local_oob_data(int dd, uint8_t *hash, uint8_t *randomizer, int to) +{ + read_local_oob_data_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_LOCAL_OOB_DATA; + rq.rparam = &rp; + rq.rlen = READ_LOCAL_OOB_DATA_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + memcpy(hash, rp.hash, 16); + memcpy(randomizer, rp.randomizer, 16); + return 0; +} + int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to) { read_transmit_power_level_cp cp; -- cgit From 3ad6c870f3759d3e98a1a3e0f2e71dc3b26e0994 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 8 Aug 2007 16:30:46 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 9392082d..6d3e627f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 9:1:7 +libbluetooth_la_LDFLAGS = -version-info 10:0:8 INCLUDES = -I$(top_builddir)/include -- cgit From 4c6bbf0a08426efd008c1b9e439c693a826ee708 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 22 Aug 2007 00:31:24 +0000 Subject: Extract main service class for later use --- src/sdp.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 920bc880..c39ad64d 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -574,22 +574,48 @@ sdp_data_t *sdp_seq_alloc(void **dtds, void **values, int len) return sdp_data_alloc(SDP_SEQ8, seq); } +static void extract_svclass_uuid(sdp_data_t *data, uuid_t *uuid) +{ + sdp_data_t *d; + + if (!data || data->dtd < SDP_SEQ8 || data->dtd > SDP_SEQ32) + return; + + d = data->val.dataseq; + if (!d) + return; + + if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) + return; + + *uuid = d->val.uuid; +} + int sdp_attr_add(sdp_record_t *rec, uint16_t attr, sdp_data_t *d) { sdp_data_t *p = sdp_data_get(rec, attr); if (p) return -1; + d->attrId = attr; rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func); + + if (attr == SDP_ATTR_SVCLASS_ID_LIST) + extract_svclass_uuid(d, &rec->svclass); + return 0; } void sdp_attr_remove(sdp_record_t *rec, uint16_t attr) { sdp_data_t *d = sdp_data_get(rec, attr); + if (d) rec->attrlist = sdp_list_remove(rec->attrlist, d); + + if (attr == SDP_ATTR_SVCLASS_ID_LIST) + memset(&rec->svclass, 0, sizeof(rec->svclass)); } void sdp_set_seq_len(uint8_t *ptr, uint32_t length) @@ -820,8 +846,12 @@ void sdp_attr_replace(sdp_record_t *rec, uint16_t attr, sdp_data_t *d) rec->attrlist = sdp_list_remove(rec->attrlist, p); sdp_data_free(p); } + d->attrId = attr; - rec->attrlist = sdp_list_insert_sorted(rec->attrlist, (void *)d, sdp_attrid_comp_func); + rec->attrlist = sdp_list_insert_sorted(rec->attrlist, d, sdp_attrid_comp_func); + + if (attr == SDP_ATTR_SVCLASS_ID_LIST) + extract_svclass_uuid(d, &rec->svclass); } int sdp_attrid_comp_func(const void *key1, const void *key2) @@ -1114,8 +1144,13 @@ sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned) SDPDBG("Terminating extraction of attributes"); break; } + if (attr == SDP_ATTR_RECORD_HANDLE) rec->handle = data->val.uint32; + + if (attr == SDP_ATTR_SVCLASS_ID_LIST) + extract_svclass_uuid(data, &rec->svclass); + extracted += n; p += n; sdp_attr_replace(rec, attr, data); @@ -1215,7 +1250,7 @@ sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId) if (p) return (sdp_data_t *)p->data; } - return 0; + return NULL; } /* -- cgit From 54146f1c528394e399b2d4375d7468f9f9a6644b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 23 Aug 2007 11:21:26 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 6d3e627f..f0027ccd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 10:0:8 +libbluetooth_la_LDFLAGS = -version-info 10:1:8 INCLUDES = -I$(top_builddir)/include -- cgit From 175d6403eb52b7f6c2f081624159405d28521749 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 27 Aug 2007 11:29:08 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 676e468e..5cbff47f 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -431,6 +431,8 @@ char *bt_compidtostr(int compid) return "3DSP Corporation"; case 74: return "Accel Semiconductor Ltd."; + case 75: + return "Continental Automotive Systems"; case 65535: return "internal use"; default: -- cgit From 1160385cf5604689c14d73397d11a0ca1edfcbe7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 28 Aug 2007 17:53:49 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index f0027ccd..7975212b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 10:1:8 +libbluetooth_la_LDFLAGS = -version-info 10:2:8 INCLUDES = -I$(top_builddir)/include -- cgit From c04e0056db8c4a8dc02b87fb647e300b26ccb207 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 29 Aug 2007 14:32:55 +0000 Subject: Fix supported commands bit calculation --- src/hci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index d3e81d2c..54e57cf3 100644 --- a/src/hci.c +++ b/src/hci.c @@ -515,7 +515,7 @@ char *hci_commandstostr(uint8_t *commands, char *pref, int width) m = commands_map; while (m->str) { - if (hci_test_bit(m->val, commands)) + if (commands[m->val / 8] & (1 << (m->val % 8))) size += strlen(m->str) + (pref ? strlen(pref) : 0) + 3; m++; } @@ -534,7 +534,7 @@ char *hci_commandstostr(uint8_t *commands, char *pref, int width) m = commands_map; while (m->str) { - if (hci_test_bit(m->val, commands)) { + if (commands[m->val / 8] & (1 << (m->val % 8))) { if (strlen(off) + strlen(m->str) > width - 3) { ptr += sprintf(ptr, "\n%s", pref ? pref : ""); off = ptr; -- cgit From bf3139919cb3732931100b0aa6de18ad16c451d1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 30 Aug 2007 14:24:30 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 7975212b..8b805f22 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 10:2:8 +libbluetooth_la_LDFLAGS = -version-info 10:3:8 INCLUDES = -I$(top_builddir)/include -- cgit From 3f8700636d21bb868c2dbb8d2403e550a7750ceb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 31 Aug 2007 18:43:40 +0000 Subject: Don't allocate memory for the Bluetooth base UUID --- src/sdp.c | 149 ++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 78 insertions(+), 71 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index c39ad64d..fcf5c897 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -88,7 +88,10 @@ static inline void ntoh128(uint128_t *src, uint128_t *dst) #define BASE_UUID "00000000-0000-1000-8000-00805F9B34FB" -static uint128_t *bluetooth_base_uuid = NULL; +static uint128_t bluetooth_base_uuid = { + .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0x80, 0x5F, 0xF9, 0xB3, 0xFB } +}; #define SDP_MAX_ATTR_LEN 65535 @@ -2078,6 +2081,7 @@ void sdp_set_url_attr(sdp_record_t *rec, const char *client, const char *doc, co */ uint128_t *sdp_create_base_uuid(void) { + uint128_t *base_uuid; char baseStr[128]; int delim = '-'; unsigned long dataLongValue; @@ -2087,69 +2091,75 @@ uint128_t *sdp_create_base_uuid(void) int toBeCopied; uint8_t *data; - if (bluetooth_base_uuid == NULL) { - strcpy(baseStr, BASE_UUID); - bluetooth_base_uuid = malloc(sizeof(uint128_t)); - data = bluetooth_base_uuid->data; - memset(data, '\0', sizeof(uint128_t)); - memset(temp, '\0', 10); - dataPtr = baseStr; - delimPtr = NULL; - delimPtr = strchr(dataPtr, delim); - toBeCopied = delimPtr - dataPtr; - if (toBeCopied != 8) { - SDPDBG("To be copied(1) : %d\n", toBeCopied); - return NULL; - } - strncpy(temp, dataPtr, toBeCopied); - dataLongValue = htonl(strtoul(temp, NULL, 16)); - memcpy(&data[0], &dataLongValue, 4); + strcpy(baseStr, BASE_UUID); + base_uuid = malloc(sizeof(uint128_t)); + if (!base_uuid) + return NULL; - /* - * Get the next 4 bytes (note that there is a "-" - * between them now) - */ - memset(temp, '\0', 10); - dataPtr = delimPtr + 1; - delimPtr = strchr(dataPtr, delim); - toBeCopied = delimPtr - dataPtr; - if (toBeCopied != 4) { - SDPDBG("To be copied(2) : %d\n", toBeCopied); - return NULL; - } - strncpy(temp, dataPtr, toBeCopied); - dataPtr = delimPtr + 1; - delimPtr = strchr(dataPtr, delim); - toBeCopied = delimPtr - dataPtr; - if (toBeCopied != 4) { - SDPDBG("To be copied(3) : %d\n", toBeCopied); - return NULL; - } - strncat(temp, dataPtr, toBeCopied); - dataLongValue = htonl(strtoul(temp, NULL, 16)); - memcpy(&data[4], &dataLongValue, 4); + data = base_uuid->data; + memset(data, '\0', sizeof(uint128_t)); + memset(temp, '\0', 10); + dataPtr = baseStr; + delimPtr = NULL; + delimPtr = strchr(dataPtr, delim); + toBeCopied = delimPtr - dataPtr; + if (toBeCopied != 8) { + SDPDBG("To be copied(1) : %d\n", toBeCopied); + free(base_uuid); + return NULL; + } + strncpy(temp, dataPtr, toBeCopied); + dataLongValue = htonl(strtoul(temp, NULL, 16)); + memcpy(&data[0], &dataLongValue, 4); - /* - * Get the last 4 bytes (note that there are 6 bytes - * after the last separator, which is truncated (2+4) - */ - memset(temp, '\0', 10); - dataPtr = delimPtr + 1; - dataPtr = delimPtr + 1; - delimPtr = strchr(dataPtr, delim); - toBeCopied = delimPtr - dataPtr; - if (toBeCopied != 4) { - SDPDBG("To be copied(4) : %d\n", toBeCopied); - return NULL; - } - strncpy(temp, dataPtr, toBeCopied); - strncat(temp, (delimPtr + 1), 4); - dataLongValue = htonl(strtoul(temp, NULL, 16)); - memcpy(&data[8], &dataLongValue, 4); - dataLongValue = htonl(strtoul(delimPtr + 5, NULL, 16)); - memcpy(&data[12], &dataLongValue, 4); + /* + * Get the next 4 bytes (note that there is a "-" + * between them now) + */ + memset(temp, '\0', 10); + dataPtr = delimPtr + 1; + delimPtr = strchr(dataPtr, delim); + toBeCopied = delimPtr - dataPtr; + if (toBeCopied != 4) { + SDPDBG("To be copied(2) : %d\n", toBeCopied); + free(base_uuid); + return NULL; + } + strncpy(temp, dataPtr, toBeCopied); + dataPtr = delimPtr + 1; + delimPtr = strchr(dataPtr, delim); + toBeCopied = delimPtr - dataPtr; + if (toBeCopied != 4) { + SDPDBG("To be copied(3) : %d\n", toBeCopied); + free(base_uuid); + return NULL; + } + strncat(temp, dataPtr, toBeCopied); + dataLongValue = htonl(strtoul(temp, NULL, 16)); + memcpy(&data[4], &dataLongValue, 4); + + /* + * Get the last 4 bytes (note that there are 6 bytes + * after the last separator, which is truncated (2+4) + */ + memset(temp, '\0', 10); + dataPtr = delimPtr + 1; + dataPtr = delimPtr + 1; + delimPtr = strchr(dataPtr, delim); + toBeCopied = delimPtr - dataPtr; + if (toBeCopied != 4) { + SDPDBG("To be copied(4) : %d\n", toBeCopied); + free(base_uuid); + return NULL; } - return bluetooth_base_uuid; + strncpy(temp, dataPtr, toBeCopied); + strncat(temp, (delimPtr + 1), 4); + dataLongValue = htonl(strtoul(temp, NULL, 16)); + memcpy(&data[8], &dataLongValue, 4); + dataLongValue = htonl(strtoul(delimPtr + 5, NULL, 16)); + memcpy(&data[12], &dataLongValue, 4); + + return base_uuid; } uuid_t *sdp_uuid16_create(uuid_t *u, uint16_t val) @@ -2212,12 +2222,11 @@ void sdp_uuid16_to_uuid128(uuid_t *uuid128, uuid_t *uuid16) unsigned short data1; // allocate a 128bit UUID and init to the Bluetooth base UUID - uint128_t *pBTBase128Bit = sdp_create_base_uuid(); - uuid128->value.uuid128 = *pBTBase128Bit; + uuid128->value.uuid128 = bluetooth_base_uuid; uuid128->type = SDP_UUID128; // extract bytes 2 and 3 of 128bit BT base UUID - memcpy(&data1, &pBTBase128Bit->data[2], 2); + memcpy(&data1, &bluetooth_base_uuid.data[2], 2); // add the given UUID (16 bits) data1 += htons(uuid16->value.uuid16); @@ -2235,12 +2244,11 @@ void sdp_uuid32_to_uuid128(uuid_t *uuid128, uuid_t *uuid32) unsigned int data0; // allocate a 128bit UUID and init to the Bluetooth base UUID - uint128_t *pBTBase128Bit = sdp_create_base_uuid(); - uuid128->value.uuid128 = *pBTBase128Bit; + uuid128->value.uuid128 = bluetooth_base_uuid; uuid128->type = SDP_UUID128; // extract first 4 bytes - memcpy(&data0, &pBTBase128Bit->data[0], 4); + memcpy(&data0, &bluetooth_base_uuid.data[0], 4); // add the given UUID (32bits) data0 += htonl(uuid32->value.uuid32); @@ -2273,11 +2281,10 @@ uuid_t *sdp_uuid_to_uuid128(uuid_t *uuid) */ int sdp_uuid128_to_uuid(uuid_t *uuid) { - extern uint128_t *sdp_create_base_uuid(); - int i; - uint128_t *b = sdp_create_base_uuid(); + uint128_t *b = &bluetooth_base_uuid; uint128_t *u = &uuid->value.uuid128; uint32_t data; + int i; if (uuid->type != SDP_UUID128) return 1; @@ -2290,7 +2297,7 @@ int sdp_uuid128_to_uuid(uuid_t *uuid) data = htonl(data); if (data <= 0xffff) { uuid->type = SDP_UUID16; - uuid->value.uuid16 = (uint16_t)data; + uuid->value.uuid16 = (uint16_t) data; } else { uuid->type = SDP_UUID32; uuid->value.uuid32 = data; -- cgit From c30706178221e3df5dfe82eb5c91f39fe118eb78 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 31 Aug 2007 20:08:52 +0000 Subject: Fix Bluetooth base UUID typo --- src/sdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index fcf5c897..cf1a9895 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -90,7 +90,7 @@ static inline void ntoh128(uint128_t *src, uint128_t *dst) static uint128_t bluetooth_base_uuid = { .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0x80, 0x5F, 0xF9, 0xB3, 0xFB } + 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB } }; #define SDP_MAX_ATTR_LEN 65535 -- cgit From 819661edc6f2144e85690c5a957f338ee668d89d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 2 Sep 2007 18:34:50 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 8b805f22..c7591d6d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 10:3:8 +libbluetooth_la_LDFLAGS = -version-info 10:4:8 INCLUDES = -I$(top_builddir)/include -- cgit From 0d5bcfd73f1d52e3c2b49b28062f9972f40ad42f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 16 Sep 2007 10:56:39 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index c7591d6d..0c758ee1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 10:4:8 +libbluetooth_la_LDFLAGS = -version-info 10:5:8 INCLUDES = -I$(top_builddir)/include -- cgit From f4afe8ea387410929ee303a510fd7cdfd1cc7552 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Oct 2007 11:23:35 +0000 Subject: Add support for inquiry transmit power level --- src/hci.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 54e57cf3..8351c475 100644 --- a/src/hci.c +++ b/src/hci.c @@ -2135,6 +2135,57 @@ int hci_read_local_oob_data(int dd, uint8_t *hash, uint8_t *randomizer, int to) return 0; } +int hci_read_inquiry_transmit_power_level(int dd, int8_t *level, int to) +{ + read_inquiry_transmit_power_level_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_READ_INQUIRY_TRANSMIT_POWER_LEVEL; + rq.rparam = &rp; + rq.rlen = READ_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *level = rp.level; + return 0; +} + +int hci_write_inquiry_transmit_power_level(int dd, int8_t level, int to) +{ + write_inquiry_transmit_power_level_cp cp; + write_inquiry_transmit_power_level_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.level = level; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_HOST_CTL; + rq.ocf = OCF_WRITE_INQUIRY_TRANSMIT_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_INQUIRY_TRANSMIT_POWER_LEVEL_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t *level, int to) { read_transmit_power_level_cp cp; -- cgit From a0303b05f6eeb967dfa60600e10c32282f6ab33f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 5 Oct 2007 11:26:17 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 0c758ee1..27d7dec5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 10:5:8 +libbluetooth_la_LDFLAGS = -version-info 11:0:9 INCLUDES = -I$(top_builddir)/include -- cgit From f35f7aa9aacf6cba18949d927f279475c7ca1571 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 24 Oct 2007 22:22:34 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 27d7dec5..5f021b39 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 11:0:9 +libbluetooth_la_LDFLAGS = -version-info 11:1:9 INCLUDES = -I$(top_builddir)/include -- cgit From d1a192c601d9e0e0f4f0da13fadccb50904c5004 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Oct 2007 23:03:55 +0000 Subject: Fix remote name request event handling --- src/hci.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 8351c475..dbfc8ba5 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1009,7 +1009,9 @@ int hci_send_req(int dd, struct hci_request *r, int to) try = 10; while (try--) { evt_cmd_complete *cc; - evt_cmd_status *cs; + evt_cmd_status *cs; + evt_remote_name_req_complete *rn; + remote_name_req_cp *cp; if (to) { struct pollfd p; @@ -1074,6 +1076,20 @@ int hci_send_req(int dd, struct hci_request *r, int to) memcpy(r->rparam, ptr, r->rlen); goto done; + case EVT_REMOTE_NAME_REQ_COMPLETE: + if (hdr->evt != r->event) + break; + + rn = r->rparam; + cp = r->cparam; + + if (bacmp(&rn->bdaddr, &cp->bdaddr)) + continue; + + r->rlen = MIN(len, r->rlen); + memcpy(r->rparam, ptr, r->rlen); + goto done; + default: if (hdr->evt != r->event) break; -- cgit From ea66d4c5353160087ff0cb4c6a1014c5fdd1cffc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 25 Oct 2007 23:05:25 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 5f021b39..87429799 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 11:1:9 +libbluetooth_la_LDFLAGS = -version-info 11:2:9 INCLUDES = -I$(top_builddir)/include -- cgit From 6c33a52af7bb9bd45c2526265e0ec91ac3f994c0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Nov 2007 12:41:14 +0000 Subject: Fix remote name request handling bug --- src/hci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index dbfc8ba5..875ac9c2 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1080,7 +1080,7 @@ int hci_send_req(int dd, struct hci_request *r, int to) if (hdr->evt != r->event) break; - rn = r->rparam; + rn = (void *) ptr; cp = r->cparam; if (bacmp(&rn->bdaddr, &cp->bdaddr)) -- cgit From a1ade55a6ffb38b0a3c10fa3e1f88a265d28cab6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 8 Dec 2007 21:49:10 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 87429799..2613af59 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 11:2:9 +libbluetooth_la_LDFLAGS = -version-info 11:3:9 INCLUDES = -I$(top_builddir)/include -- cgit From 1622daf2f8fa0abeb0a11be14558ed30a17fc044 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Dec 2007 20:35:41 +0000 Subject: Add definitions for MDP --- src/sdp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index cf1a9895..16dd7774 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -192,6 +192,9 @@ static struct tupla ServiceClass[] = { { VIDEO_SOURCE_SVCLASS_ID, "Video Source" }, { VIDEO_SINK_SVCLASS_ID, "Video Sink" }, { VIDEO_DISTRIBUTION_SVCLASS_ID, "Video Distribution" }, + { MDP_SVCLASS_ID, "MDP" }, + { MDP_SOURCE_SVCLASS_ID, "MDP Source" }, + { MDP_SINK_SVCLASS_ID, "MDP Sink" }, { APPLE_AGENT_SVCLASS_ID, "Apple Agent" }, { 0 } }; -- cgit From cd0c03f1c182b633855b256540a42d83cbed4538 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 25 Dec 2007 20:40:04 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 2613af59..0c91924d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 11:3:9 +libbluetooth_la_LDFLAGS = -version-info 11:4:9 INCLUDES = -I$(top_builddir)/include -- cgit From 7208028266fc19d380ac77c97c46b6f2fdc80e1d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:11:09 +0000 Subject: Update copyright information --- src/bluetooth.c | 2 +- src/hci.c | 2 +- src/sdp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 5cbff47f..afbd4928 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/src/hci.c b/src/hci.c index 875ac9c2..dd8a6ace 100644 --- a/src/hci.c +++ b/src/hci.c @@ -4,7 +4,7 @@ * * Copyright (C) 2000-2001 Qualcomm Incorporated * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/src/sdp.c b/src/sdp.c index 16dd7774..40d694de 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -4,7 +4,7 @@ * * Copyright (C) 2001-2002 Nokia Corporation * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2002-2007 Marcel Holtmann + * Copyright (C) 2002-2008 Marcel Holtmann * Copyright (C) 2002-2003 Stephen Crane * * -- cgit From b393cdff611943a05ec598048b5c4be8130151dd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 13:17:16 +0000 Subject: Fix compilation problem with USHRT_MAX and UCHAR_MAX --- src/sdp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 40d694de..3b1a5d93 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -30,9 +30,10 @@ #include #include -#include #include +#include #include +#include #include #include #include -- cgit From 20b6d88f9505c38b03a998db38be742eedf0e0df Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 23 Feb 2008 00:22:19 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index afbd4928..c8ad0b11 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -433,6 +433,8 @@ char *bt_compidtostr(int compid) return "Accel Semiconductor Ltd."; case 75: return "Continental Automotive Systems"; + case 76: + return "Apple, Inc."; case 65535: return "internal use"; default: -- cgit From f767416e71484be2463caa6482dc978e165cabae Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 5 Mar 2008 19:30:32 +0000 Subject: Add support for MCAP UUIDs --- src/sdp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 3b1a5d93..44ba17e4 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -124,6 +124,8 @@ static struct tupla Protocol[] = { { AVDTP_UUID, "AVDTP" }, { CMTP_UUID, "CMTP" }, { UDI_UUID, "UDI" }, + { MCAP_CTRL_UUID, "MCAP-Ctrl" }, + { MCAP_DATA_UUID, "MCAP-Data" }, { L2CAP_UUID, "L2CAP" }, { 0 } }; -- cgit From 03bac653ed513d6efaaa36eb349b5ca9a23dce19 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 5 Mar 2008 19:36:50 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 0c91924d..0115a7c5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 11:4:9 +libbluetooth_la_LDFLAGS = -version-info 11:5:9 INCLUDES = -I$(top_builddir)/include -- cgit From 1f9ec47e02cc789ab45c85e855c4f9e377df7e3c Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 10 Mar 2008 21:57:46 +0000 Subject: sdp_get_uuidseq_attr: fixed memory leak --- src/sdp.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 44ba17e4..28e24c0a 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -1530,13 +1530,14 @@ int sdp_get_uuidseq_attr(const sdp_record_t *rec, uint16_t attr, sdp_list_t **se if (sdpdata && sdpdata->dtd >= SDP_SEQ8 && sdpdata->dtd <= SDP_SEQ32) { sdp_data_t *d; for (d = sdpdata->val.dataseq; d; d = d->next) { - uuid_t *u = malloc(sizeof(uuid_t)); - memset((char *)u, 0, sizeof(uuid_t)); - if (d->dtd >= SDP_UUID16 && d->dtd <= SDP_UUID128) { - *u = d->val.uuid; - *seqp = sdp_list_append(*seqp, u); - } else + uuid_t *u; + if (d->dtd < SDP_UUID16 || d->dtd > SDP_UUID128) goto fail; + + u = malloc(sizeof(uuid_t)); + memset(u, 0, sizeof(uuid_t)); + *u = d->val.uuid; + *seqp = sdp_list_append(*seqp, u); } return 0; } -- cgit From 60ece348f344fc1e5d4ac7113e916155c1e350a2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 21 Mar 2008 23:34:11 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 0115a7c5..7d19490f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 11:5:9 +libbluetooth_la_LDFLAGS = -version-info 11:6:9 INCLUDES = -I$(top_builddir)/include -- cgit From f4f6e80b7ba37ed1f4e6505995a24f9185e6fb19 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 3 Apr 2008 01:11:50 +0000 Subject: Add another company identifier --- src/bluetooth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index c8ad0b11..d183d97e 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -435,6 +435,8 @@ char *bt_compidtostr(int compid) return "Continental Automotive Systems"; case 76: return "Apple, Inc."; + case 77: + return "Staccato Communications, Inc."; case 65535: return "internal use"; default: -- cgit From bb45b882917f26aaa26b2b903b70d622b39cce84 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 11 Jun 2008 13:12:21 +0000 Subject: It is better to include string.h instead of malloc.h --- src/bluetooth.c | 1 - src/hci.c | 1 - src/sdp.c | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index d183d97e..463e0e05 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/src/hci.c b/src/hci.c index dd8a6ace..280a654a 100644 --- a/src/hci.c +++ b/src/hci.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/src/sdp.c b/src/sdp.c index 28e24c0a..3ec877a1 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include -- cgit From a39a1b4c3e075e80d05caad61646a352693f5455 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 12 Jun 2008 21:40:14 +0000 Subject: Add functions for reading and writing the link policy settings --- src/hci.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index 280a654a..e2c355c0 100644 --- a/src/hci.c +++ b/src/hci.c @@ -2231,6 +2231,60 @@ int hci_read_transmit_power_level(int dd, uint16_t handle, uint8_t type, int8_t return 0; } +int hci_read_link_policy(int dd, uint16_t handle, uint16_t *policy, int to) +{ + read_link_policy_rp rp; + struct hci_request rq; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_READ_LINK_POLICY; + rq.cparam = &handle; + rq.clen = 2; + rq.rparam = &rp; + rq.rlen = READ_LINK_POLICY_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + *policy = rp.policy; + return 0; +} + +int hci_write_link_policy(int dd, uint16_t handle, uint16_t policy, int to) +{ + write_link_policy_cp cp; + write_link_policy_rp rp; + struct hci_request rq; + + memset(&cp, 0, sizeof(cp)); + cp.handle = handle; + cp.policy = policy; + + memset(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LINK_POLICY; + rq.ocf = OCF_WRITE_LINK_POLICY; + rq.cparam = &cp; + rq.clen = WRITE_LINK_POLICY_CP_SIZE; + rq.rparam = &rp; + rq.rlen = WRITE_LINK_POLICY_RP_SIZE; + + if (hci_send_req(dd, &rq, to) < 0) + return -1; + + if (rp.status) { + errno = EIO; + return -1; + } + + return 0; +} + int hci_read_link_supervision_timeout(int dd, uint16_t handle, uint16_t *timeout, int to) { read_link_supervision_timeout_rp rp; -- cgit From 5e4c3e1a8fdab9ac8a45ef0e80cd045421c73621 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 18 Jun 2008 16:09:54 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 7d19490f..a03816e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 11:6:9 +libbluetooth_la_LDFLAGS = -version-info 12:0:10 INCLUDES = -I$(top_builddir)/include -- cgit From a3648e0df0ff53fef74e5437ff089aef96209db2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 20 Jun 2008 03:30:53 +0000 Subject: Add more safe version of three low-level extraction functions --- src/sdp.c | 299 +++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 220 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 3ec877a1..977f6660 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -904,15 +904,76 @@ void sdp_data_free(sdp_data_t *d) free(d); } -static sdp_data_t *extract_int(const void *p, int *len) +int sdp_uuid_extract_safe(const uint8_t *p, int bufsize, uuid_t *uuid, int *scanned) { - sdp_data_t *d = malloc(sizeof(sdp_data_t)); + uint8_t type; + + if (bufsize < sizeof(uint8_t)) { + SDPERR("Unexpected end of packet"); + return -1; + } + + type = *(const uint8_t *) p; + + if (!SDP_IS_UUID(type)) { + SDPERR("Unknown data type : %d expecting a svc UUID\n", type); + return -1; + } + p += sizeof(uint8_t); + *scanned += sizeof(uint8_t); + bufsize -= sizeof(uint8_t); + if (type == SDP_UUID16) { + if (bufsize < sizeof(uint16_t)) { + SDPERR("Not enough room for 16-bit UUID"); + return -1; + } + sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p))); + *scanned += sizeof(uint16_t); + p += sizeof(uint16_t); + } else if (type == SDP_UUID32) { + if (bufsize < sizeof(uint32_t)) { + SDPERR("Not enough room for 32-bit UUID"); + return -1; + } + sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p))); + *scanned += sizeof(uint32_t); + p += sizeof(uint32_t); + } else { + if (bufsize < sizeof(uint128_t)) { + SDPERR("Not enough room for 128-bit UUID"); + return -1; + } + sdp_uuid128_create(uuid, p); + *scanned += sizeof(uint128_t); + p += sizeof(uint128_t); + } + return 0; +} + +int sdp_uuid_extract(const uint8_t *p, uuid_t *uuid, int *scanned) +{ + /* Assume p points to a buffer of size at least SDP_MAX_ATTR_LEN, + because we don't have any better information */ + return sdp_uuid_extract_safe(p, SDP_MAX_ATTR_LEN, uuid, scanned); +} + +static sdp_data_t *extract_int(const void *p, int bufsize, int *len) +{ + sdp_data_t *d; + + if (bufsize < sizeof(uint8_t)) { + SDPERR("Unexpected end of packet"); + return NULL; + } + + d = malloc(sizeof(sdp_data_t)); SDPDBG("Extracting integer\n"); memset(d, 0, sizeof(sdp_data_t)); d->dtd = *(uint8_t *) p; p += sizeof(uint8_t); *len += sizeof(uint8_t); + bufsize -= sizeof(uint8_t); switch (d->dtd) { case SDP_DATA_NIL: @@ -920,26 +981,51 @@ static sdp_data_t *extract_int(const void *p, int *len) case SDP_BOOL: case SDP_INT8: case SDP_UINT8: + if (bufsize < sizeof(uint8_t)) { + SDPERR("Unexpected end of packet"); + free(d); + return NULL; + } *len += sizeof(uint8_t); d->val.uint8 = *(uint8_t *) p; break; case SDP_INT16: case SDP_UINT16: + if (bufsize < sizeof(uint16_t)) { + SDPERR("Unexpected end of packet"); + free(d); + return NULL; + } *len += sizeof(uint16_t); d->val.uint16 = ntohs(bt_get_unaligned((uint16_t *) p)); break; case SDP_INT32: case SDP_UINT32: + if (bufsize < sizeof(uint32_t)) { + SDPERR("Unexpected end of packet"); + free(d); + return NULL; + } *len += sizeof(uint32_t); d->val.uint32 = ntohl(bt_get_unaligned((uint32_t *) p)); break; case SDP_INT64: case SDP_UINT64: + if (bufsize < sizeof(uint64_t)) { + SDPERR("Unexpected end of packet"); + free(d); + return NULL; + } *len += sizeof(uint64_t); d->val.uint64 = ntoh64(bt_get_unaligned((uint64_t *) p)); break; case SDP_INT128: case SDP_UINT128: + if (bufsize < sizeof(uint128_t)) { + SDPERR("Unexpected end of packet"); + free(d); + return NULL; + } *len += sizeof(uint128_t); ntoh128((uint128_t *) p, &d->val.uint128); break; @@ -950,13 +1036,13 @@ static sdp_data_t *extract_int(const void *p, int *len) return d; } -static sdp_data_t *extract_uuid(const uint8_t *p, int *len, sdp_record_t *rec) +static sdp_data_t *extract_uuid(const uint8_t *p, int bufsize, int *len, sdp_record_t *rec) { sdp_data_t *d = malloc(sizeof(sdp_data_t)); SDPDBG("Extracting UUID"); memset(d, 0, sizeof(sdp_data_t)); - if (sdp_uuid_extract(p, &d->val.uuid, len) < 0) { + if (sdp_uuid_extract_safe(p, bufsize, &d->val.uuid, len) < 0) { free(d); return NULL; } @@ -969,29 +1055,49 @@ static sdp_data_t *extract_uuid(const uint8_t *p, int *len, sdp_record_t *rec) /* * Extract strings from the PDU (could be service description and similar info) */ -static sdp_data_t *extract_str(const void *p, int *len) +static sdp_data_t *extract_str(const void *p, int bufsize, int *len) { char *s; int n; - sdp_data_t *d = malloc(sizeof(sdp_data_t)); + sdp_data_t *d; + + if (bufsize < sizeof(uint8_t)) { + SDPERR("Unexpected end of packet"); + return NULL; + } + + d = malloc(sizeof(sdp_data_t)); memset(d, 0, sizeof(sdp_data_t)); d->dtd = *(uint8_t *) p; p += sizeof(uint8_t); *len += sizeof(uint8_t); + bufsize -= sizeof(uint8_t); switch (d->dtd) { case SDP_TEXT_STR8: case SDP_URL_STR8: + if (bufsize < sizeof(uint8_t)) { + SDPERR("Unexpected end of packet"); + free(d); + return NULL; + } n = *(uint8_t *) p; p += sizeof(uint8_t); - *len += sizeof(uint8_t) + n; + *len += sizeof(uint8_t); + bufsize -= sizeof(uint8_t); break; case SDP_TEXT_STR16: case SDP_URL_STR16: + if (bufsize < sizeof(uint16_t)) { + SDPERR("Unexpected end of packet"); + free(d); + return NULL; + } n = ntohs(bt_get_unaligned((uint16_t *) p)); p += sizeof(uint16_t); *len += sizeof(uint16_t) + n; + bufsize -= sizeof(uint16_t); break; default: SDPERR("Sizeof text string > UINT16_MAX\n"); @@ -999,10 +1105,23 @@ static sdp_data_t *extract_str(const void *p, int *len) return 0; } + if (bufsize < n) { + SDPERR("String too long to fit in packet"); + free(d); + return NULL; + } + s = malloc(n + 1); + if (!s) { + SDPERR("Not enough memory for incoming string"); + free(d); + return NULL; + } memset(s, 0, n + 1); memcpy(s, p, n); + *len += n; + SDPDBG("Len : %d\n", n); SDPDBG("Str : %s\n", s); @@ -1011,7 +1130,67 @@ static sdp_data_t *extract_str(const void *p, int *len) return d; } -static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec) +/* + * Extract the sequence type and its length, and return offset into buf + * or 0 on failure. + */ +int sdp_extract_seqtype_safe(const uint8_t *buf, int bufsize, uint8_t *dtdp, int *size) +{ + uint8_t dtd; + int scanned = sizeof(uint8_t); + + if (bufsize < sizeof(uint8_t)) { + SDPERR("Unexpected end of packet"); + return 0; + } + + dtd = *(uint8_t *) buf; + buf += sizeof(uint8_t); + bufsize -= sizeof(uint8_t); + *dtdp = dtd; + switch (dtd) { + case SDP_SEQ8: + case SDP_ALT8: + if (bufsize < sizeof(uint8_t)) { + SDPERR("Unexpected end of packet"); + return 0; + } + *size = *(uint8_t *) buf; + scanned += sizeof(uint8_t); + break; + case SDP_SEQ16: + case SDP_ALT16: + if (bufsize < sizeof(uint16_t)) { + SDPERR("Unexpected end of packet"); + return 0; + } + *size = ntohs(bt_get_unaligned((uint16_t *) buf)); + scanned += sizeof(uint16_t); + break; + case SDP_SEQ32: + case SDP_ALT32: + if (bufsize < sizeof(uint32_t)) { + SDPERR("Unexpected end of packet"); + return 0; + } + *size = ntohl(bt_get_unaligned((uint32_t *) buf)); + scanned += sizeof(uint32_t); + break; + default: + SDPERR("Unknown sequence type, aborting\n"); + return 0; + } + return scanned; +} + +int sdp_extract_seqtype(const uint8_t *buf, uint8_t *dtdp, int *size) +{ + /* Assume buf points to a buffer of size at least SDP_MAX_ATTR_LEN, + because we don't have any better information */ + return sdp_extract_seqtype_safe(buf, SDP_MAX_ATTR_LEN, dtdp, size); +} + +static sdp_data_t *extract_seq(const void *p, int bufsize, int *len, sdp_record_t *rec) { int seqlen, n = 0; sdp_data_t *curr, *prev; @@ -1019,17 +1198,24 @@ static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec) SDPDBG("Extracting SEQ"); memset(d, 0, sizeof(sdp_data_t)); - *len = sdp_extract_seqtype(p, &d->dtd, &seqlen); + *len = sdp_extract_seqtype_safe(p, bufsize, &d->dtd, &seqlen); SDPDBG("Sequence Type : 0x%x length : 0x%x\n", d->dtd, seqlen); if (*len == 0) return d; + if (*len > bufsize) { + SDPERR("Packet not big enough to hold sequence."); + free(d); + return NULL; + } + p += *len; + bufsize -= *len; curr = prev = NULL; while (n < seqlen) { int attrlen = 0; - curr = sdp_extract_attr(p, &attrlen, rec); + curr = sdp_extract_attr_safe(p, bufsize, &attrlen, rec); if (curr == NULL) break; @@ -1040,6 +1226,7 @@ static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec) prev = curr; p += attrlen; n += attrlen; + bufsize -= attrlen; SDPDBG("Extracted: %d SequenceLength: %d", n, seqlen); } @@ -1048,11 +1235,18 @@ static sdp_data_t *extract_seq(const void *p, int *len, sdp_record_t *rec) return d; } -sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec) +sdp_data_t *sdp_extract_attr_safe(const uint8_t *p, int bufsize, int *size, sdp_record_t *rec) { sdp_data_t *elem; int n = 0; - uint8_t dtd = *(const uint8_t *)p; + uint8_t dtd; + + if (bufsize < sizeof(uint8_t)) { + SDPERR("Unexpected end of packet"); + return NULL; + } + + dtd = *(const uint8_t *)p; SDPDBG("extract_attr: dtd=0x%x", dtd); switch (dtd) { @@ -1068,12 +1262,12 @@ sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec) case SDP_INT32: case SDP_INT64: case SDP_INT128: - elem = extract_int(p, &n); + elem = extract_int(p, bufsize, &n); break; case SDP_UUID16: case SDP_UUID32: case SDP_UUID128: - elem = extract_uuid(p, &n, rec); + elem = extract_uuid(p, bufsize, &n, rec); break; case SDP_TEXT_STR8: case SDP_TEXT_STR16: @@ -1081,7 +1275,7 @@ sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec) case SDP_URL_STR8: case SDP_URL_STR16: case SDP_URL_STR32: - elem = extract_str(p, &n); + elem = extract_str(p, bufsize, &n); break; case SDP_SEQ8: case SDP_SEQ16: @@ -1089,7 +1283,7 @@ sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec) case SDP_ALT8: case SDP_ALT16: case SDP_ALT32: - elem = extract_seq(p, &n, rec); + elem = extract_seq(p, bufsize, &n, rec); break; default: SDPERR("Unknown data descriptor : 0x%x terminating\n", dtd); @@ -1099,6 +1293,13 @@ sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec) return elem; } +sdp_data_t *sdp_extract_attr(const uint8_t *p, int *size, sdp_record_t *rec) +{ + /* Assume p points to a buffer of size at least SDP_MAX_ATTR_LEN, + because we don't have any better information */ + return sdp_extract_attr_safe(p, SDP_MAX_ATTR_LEN, size, rec); +} + #ifdef SDP_DEBUG static void attr_print_func(void *value, void *userData) { @@ -1262,40 +1463,6 @@ sdp_data_t *sdp_data_get(const sdp_record_t *rec, uint16_t attrId) return NULL; } -/* - * Extract the sequence type and its length, and return offset into buf - * or 0 on failure. - */ -int sdp_extract_seqtype(const uint8_t *buf, uint8_t *dtdp, int *size) -{ - uint8_t dtd = *(uint8_t *) buf; - int scanned = sizeof(uint8_t); - - buf += sizeof(uint8_t); - *dtdp = dtd; - switch (dtd) { - case SDP_SEQ8: - case SDP_ALT8: - *size = *(uint8_t *) buf; - scanned += sizeof(uint8_t); - break; - case SDP_SEQ16: - case SDP_ALT16: - *size = ntohs(bt_get_unaligned((uint16_t *) buf)); - scanned += sizeof(uint16_t); - break; - case SDP_SEQ32: - case SDP_ALT32: - *size = ntohl(bt_get_unaligned((uint32_t *) buf)); - scanned += sizeof(uint32_t); - break; - default: - SDPERR("Unknown sequence type, aborting\n"); - return 0; - } - return scanned; -} - int sdp_send_req(sdp_session_t *session, uint8_t *buf, uint32_t size) { uint32_t sent = 0; @@ -2329,32 +2496,6 @@ int sdp_uuid_to_proto(uuid_t *uuid) return 0; } -int sdp_uuid_extract(const uint8_t *p, uuid_t *uuid, int *scanned) -{ - uint8_t type = *(const uint8_t *) p; - - if (!SDP_IS_UUID(type)) { - SDPERR("Unknown data type : %d expecting a svc UUID\n", type); - return -1; - } - p += sizeof(uint8_t); - *scanned += sizeof(uint8_t); - if (type == SDP_UUID16) { - sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p))); - *scanned += sizeof(uint16_t); - p += sizeof(uint16_t); - } else if (type == SDP_UUID32) { - sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p))); - *scanned += sizeof(uint32_t); - p += sizeof(uint32_t); - } else { - sdp_uuid128_create(uuid, p); - *scanned += sizeof(uint128_t); - p += sizeof(uint128_t); - } - return 0; -} - /* * This function appends data to the PDU buffer "dst" from source "src". * The data length is also computed and set. @@ -2792,7 +2933,7 @@ static int gen_dataseq_pdu(uint8_t *dst, const sdp_list_t *seq, uint8_t dtd) // Fill up the value and the dtd arrays SDPDBG(""); - + memset(&buf, 0, sizeof(sdp_buf_t)); buf.data = malloc(256); buf.buf_size = 256; @@ -2986,7 +3127,7 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, } } while (cstate); - end: +end: if (reqbuf) free(reqbuf); if (rspbuf) @@ -3146,7 +3287,7 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, status = -1; } - end: +end: if (reqbuf) free(reqbuf); if (rsp_concat_buf.data) -- cgit From 0e1789b3f1897512eb30d63c8e9803f1461446c1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 22 Jun 2008 21:59:42 +0000 Subject: Add safe version of sdp_extract_pdu function --- src/sdp.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 977f6660..b9b0e4f6 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -1323,7 +1323,7 @@ void sdp_print_service_attr(sdp_list_t *svcAttrList) } #endif -sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned) +sdp_record_t *sdp_extract_pdu_safe(const uint8_t *buf, int bufsize, int *scanned) { int extracted = 0, seqlen = 0; uint8_t dtd; @@ -1331,21 +1331,30 @@ sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned) sdp_record_t *rec = sdp_record_alloc(); const uint8_t *p = buf; - *scanned = sdp_extract_seqtype(buf, &dtd, &seqlen); + *scanned = sdp_extract_seqtype_safe(buf, bufsize, &dtd, &seqlen); p += *scanned; + bufsize -= *scanned; rec->attrlist = NULL; - while (extracted < seqlen) { + + while (extracted < seqlen && bufsize > 0) { int n = sizeof(uint8_t), attrlen = 0; sdp_data_t *data = NULL; - SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", seqlen, extracted); + SDPDBG("Extract PDU, sequenceLength: %d localExtractedLength: %d", + seqlen, extracted); + + if (bufsize < n + sizeof(uint16_t)) { + SDPERR("Unexpected end of packet"); + break; + } + dtd = *(uint8_t *) p; attr = ntohs(bt_get_unaligned((uint16_t *) (p + n))); n += sizeof(uint16_t); SDPDBG("DTD of attrId : %d Attr id : 0x%x \n", dtd, attr); - data = sdp_extract_attr(p + n, &attrlen, rec); + data = sdp_extract_attr_safe(p + n, bufsize - n, &attrlen, rec); SDPDBG("Attr id : 0x%x attrValueLength : %d\n", attr, attrlen); @@ -1363,9 +1372,11 @@ sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned) extracted += n; p += n; + bufsize -= n; sdp_attr_replace(rec, attr, data); + SDPDBG("Extract PDU, seqLength: %d localExtractedLength: %d", - seqlen, extracted); + seqlen, extracted); } #ifdef SDP_DEBUG SDPDBG("Successful extracting of Svc Rec attributes\n"); @@ -1375,6 +1386,13 @@ sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned) return rec; } +sdp_record_t *sdp_extract_pdu(const uint8_t *buf, int *scanned) +{ + /* Assume buf points to a buffer of size at least SDP_MAX_ATTR_LEN, + because we don't have any better information */ + return sdp_extract_pdu_safe(buf, SDP_MAX_ATTR_LEN, scanned); +} + #ifdef SDP_DEBUG static void print_dataseq(sdp_data_t *p) { -- cgit From 0a8f7c9206e17ab118966bf7da8a053ef34dce84 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 Jun 2008 02:49:12 +0000 Subject: Add safety check for continuation state function --- src/sdp.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index b9b0e4f6..59686388 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -3002,12 +3002,17 @@ typedef struct { unsigned char data[16]; } __attribute__ ((packed)) sdp_cstate_t; -static int copy_cstate(uint8_t *pdata, const sdp_cstate_t *cstate) +static int copy_cstate(uint8_t *pdata, int pdata_len, const sdp_cstate_t *cstate) { if (cstate) { - *pdata++ = cstate->length; - memcpy(pdata, cstate->data, cstate->length); - return cstate->length + 1; + uint8_t len = cstate->length; + if (len >= pdata_len) { + SDPERR("Continuation state size exceeds internal buffer"); + len = pdata_len - 1; + } + *pdata++ = len; + memcpy(pdata, cstate->data, len); + return len + 1; } *pdata = 0; return 1; @@ -3087,7 +3092,8 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, do { // Add continuation state or NULL (first time) - reqsize = _reqsize + copy_cstate(_pdata, cstate); + reqsize = _reqsize + copy_cstate(_pdata, + SDP_REQ_BUFFER_SIZE - _reqsize, cstate); // Set the request header's param length reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); @@ -3249,7 +3255,8 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, do { // add NULL continuation state - reqsize = _reqsize + copy_cstate(_pdata, cstate); + reqsize = _reqsize + copy_cstate(_pdata, + SDP_REQ_BUFFER_SIZE - _reqsize, cstate); // set the request header's param length reqhdr->tid = htons(sdp_gen_tid(session)); @@ -3470,7 +3477,7 @@ int sdp_service_search_async(sdp_session_t *session, const sdp_list_t *search, u pdata += sizeof(uint16_t); // set the request header's param length - cstate_len = copy_cstate(pdata, NULL); + cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL); reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { @@ -3584,7 +3591,7 @@ int sdp_service_attr_async(sdp_session_t *session, uint32_t handle, sdp_attrreq_ SDPDBG("Attr list length : %d\n", seqlen); // set the request header's param length - cstate_len = copy_cstate(pdata, NULL); + cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL); reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { @@ -3703,7 +3710,7 @@ int sdp_service_search_attr_async(sdp_session_t *session, const sdp_list_t *sear t->reqsize += seqlen; // set the request header's param length - cstate_len = copy_cstate(pdata, NULL); + cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL); reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); if (sdp_send_req(session, t->reqbuf, t->reqsize + cstate_len) < 0) { @@ -3916,7 +3923,8 @@ int sdp_process(sdp_session_t *session) reqhdr->tid = htons(sdp_gen_tid(session)); // add continuation state - cstate_len = copy_cstate(t->reqbuf + t->reqsize, pcstate); + cstate_len = copy_cstate(t->reqbuf + t->reqsize, + SDP_REQ_BUFFER_SIZE - t->reqsize, pcstate); reqsize = t->reqsize + cstate_len; @@ -4059,7 +4067,8 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search reqhdr->tid = htons(sdp_gen_tid(session)); // add continuation state (can be null) - reqsize = _reqsize + copy_cstate(_pdata, cstate); + reqsize = _reqsize + copy_cstate(_pdata, + SDP_REQ_BUFFER_SIZE - _reqsize, cstate); // set the request header's param length reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); -- cgit From 121c632f01e3f49a69a9d637e0da4d25c2ee090d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 Jun 2008 06:18:33 +0000 Subject: Have the service routines use the new safe functions --- src/sdp.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 59686388..4217aedd 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2923,18 +2923,23 @@ void sdp_pattern_add_uuidseq(sdp_record_t *rec, sdp_list_t *seq) * handles are not in "data element sequence" form, but just like * an array of service handles */ -static void extract_record_handle_seq(uint8_t *pdu, sdp_list_t **seq, int count, int *scanned) +static void extract_record_handle_seq(uint8_t *pdu, int bufsize, sdp_list_t **seq, int count, int *scanned) { sdp_list_t *pSeq = *seq; uint8_t *pdata = pdu; int n; for (n = 0; n < count; n++) { + if (bufsize < sizeof(uint32_t)) { + SDPERR("Unexpected end of packet"); + break; + } uint32_t *pSvcRec = malloc(sizeof(uint32_t)); *pSvcRec = ntohl(bt_get_unaligned((uint32_t *) pdata)); pSeq = sdp_list_append(pSeq, pSvcRec); pdata += sizeof(uint32_t); *scanned += sizeof(uint32_t); + bufsize -= sizeof(uint32_t); } *seq = pSeq; } @@ -3054,7 +3059,7 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, uint32_t reqsize = 0, _reqsize; uint32_t rspsize = 0, rsplen; int seqlen = 0; - int scanned, total_rec_count, rec_count; + int scanned, total_rec_count, rec_count, pdata_len; uint8_t *pdata, *_pdata; uint8_t *reqbuf, *rspbuf; sdp_pdu_hdr_t *reqhdr, *rsphdr; @@ -3107,7 +3112,12 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, if (status < 0) goto end; - rsplen = 0; + if (rspsize < sizeof(sdp_pdu_hdr_t)) { + SDPERR("Unexpected end of packet"); + status = -1; + goto end; + } + rsphdr = (sdp_pdu_hdr_t *) rspbuf; rsplen = ntohs(rsphdr->plen); @@ -3118,14 +3128,23 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, } scanned = 0; pdata = rspbuf + sizeof(sdp_pdu_hdr_t); + pdata_len = rspsize - sizeof(sdp_pdu_hdr_t); + + if (pdata_len < sizeof(uint16_t) + sizeof(uint16_t)) { + SDPERR("Unexpected end of packet"); + status = -1; + goto end; + } // net service record match count total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); pdata += sizeof(uint16_t); scanned += sizeof(uint16_t); + pdata_len -= sizeof(uint16_t); rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); pdata += sizeof(uint16_t); scanned += sizeof(uint16_t); + pdata_len -= sizeof(uint16_t); SDPDBG("Total svc count: %d\n", total_rec_count); SDPDBG("Current svc count: %d\n", rec_count); @@ -3135,12 +3154,18 @@ int sdp_service_search_req(sdp_session_t *session, const sdp_list_t *search, status = -1; goto end; } - extract_record_handle_seq(pdata, rsp, rec_count, &scanned); + extract_record_handle_seq(pdata, pdata_len, rsp, rec_count, &scanned); SDPDBG("BytesScanned : %d\n", scanned); if (rsplen > scanned) { uint8_t cstate_len; + if (rspsize < sizeof(sdp_pdu_hdr_t) + scanned + sizeof(uint8_t)) { + SDPERR("Unexpected end of packet: continuation state data missing"); + status = -1; + goto end; + } + pdata = rspbuf + sizeof(sdp_pdu_hdr_t) + scanned; cstate_len = *(uint8_t *) pdata; if (cstate_len > 0) { @@ -3199,7 +3224,7 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, uint32_t reqsize = 0, _reqsize; uint32_t rspsize = 0, rsp_count; int attr_list_len = 0; - int seqlen = 0; + int seqlen = 0, pdata_len; uint8_t *pdata, *_pdata; uint8_t *reqbuf, *rspbuf; sdp_pdu_hdr_t *reqhdr, *rsphdr; @@ -3265,6 +3290,13 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); if (status < 0) goto end; + + if (rspsize < sizeof(sdp_pdu_hdr_t)) { + SDPERR("Unexpected end of packet"); + status = -1; + goto end; + } + rsp_count = 0; rsphdr = (sdp_pdu_hdr_t *) rspbuf; if (rsphdr->pdu_id == SDP_ERROR_RSP) { @@ -3273,11 +3305,25 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, goto end; } pdata = rspbuf + sizeof(sdp_pdu_hdr_t); + pdata_len = rspsize - sizeof(sdp_pdu_hdr_t); + + if (pdata_len < sizeof(uint16_t)) { + SDPERR("Unexpected end of packet"); + status = -1; + goto end; + } + rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); attr_list_len += rsp_count; pdata += sizeof(uint16_t); + pdata_len -= sizeof(uint16_t); // if continuation state set need to re-issue request before parsing + if (pdata_len < rsp_count + sizeof(uint8_t)) { + SDPERR("Unexpected end of packet: continuation state data missing"); + status = -1; + goto end; + } cstate_len = *(uint8_t *) (pdata + rsp_count); SDPDBG("Response id : %d\n", rsphdr->pdu_id); @@ -3304,9 +3350,11 @@ sdp_record_t *sdp_service_attr_req(sdp_session_t *session, uint32_t handle, if (attr_list_len > 0) { int scanned = 0; - if (rsp_concat_buf.data_size != 0) + if (rsp_concat_buf.data_size != 0) { pdata = rsp_concat_buf.data; - rec = sdp_extract_pdu(pdata, &scanned); + pdata_len = rsp_concat_buf.data_size; + } + rec = sdp_extract_pdu_safe(pdata, pdata_len, &scanned); if (!rec) status = -1; @@ -4003,7 +4051,7 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search uint32_t reqsize = 0, _reqsize; uint32_t rspsize = 0; int seqlen = 0, attr_list_len = 0; - int rsp_count = 0, cstate_len = 0; + int rsp_count = 0, cstate_len = 0, pdata_len; uint8_t *pdata, *_pdata; uint8_t *reqbuf, *rspbuf; sdp_pdu_hdr_t *reqhdr, *rsphdr; @@ -4074,6 +4122,12 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); rsphdr = (sdp_pdu_hdr_t *) rspbuf; status = sdp_send_req_w4_rsp(session, reqbuf, rspbuf, reqsize, &rspsize); + if (rspsize < sizeof(sdp_pdu_hdr_t)) { + SDPERR("Unexpected end of packet"); + status = -1; + goto end; + } + if (status < 0) { SDPDBG("Status : 0x%x\n", rsphdr->pdu_id); goto end; @@ -4085,9 +4139,25 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search } pdata = rspbuf + sizeof(sdp_pdu_hdr_t); + pdata_len = rspsize - sizeof(sdp_pdu_hdr_t); + + if (pdata_len < sizeof(uint16_t)) { + SDPERR("Unexpected end of packet"); + status = -1; + goto end; + } + rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); attr_list_len += rsp_count; pdata += sizeof(uint16_t); // pdata points to attribute list + pdata_len -= sizeof(uint16_t); + + if (pdata_len < rsp_count + sizeof(uint8_t)) { + SDPERR("Unexpected end of packet: continuation state data missing"); + status = -1; + goto end; + } + cstate_len = *(uint8_t *) (pdata + rsp_count); SDPDBG("Attrlist byte count : %d\n", attr_list_len); @@ -4114,24 +4184,27 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search if (attr_list_len > 0) { int scanned = 0; - if (rsp_concat_buf.data_size != 0) + if (rsp_concat_buf.data_size != 0) { pdata = rsp_concat_buf.data; + pdata_len = rsp_concat_buf.data_size; + } /* * Response is a sequence of sequence(s) for one or * more data element sequence(s) representing services * for which attributes are returned */ - scanned = sdp_extract_seqtype(pdata, &dataType, &seqlen); + scanned = sdp_extract_seqtype_safe(pdata, pdata_len, &dataType, &seqlen); SDPDBG("Bytes scanned : %d\n", scanned); SDPDBG("Seq length : %d\n", seqlen); if (scanned && seqlen) { pdata += scanned; + pdata_len -= scanned; do { int recsize = 0; - sdp_record_t *rec = sdp_extract_pdu(pdata, &recsize); + sdp_record_t *rec = sdp_extract_pdu_safe(pdata, pdata_len, &recsize); if (rec == NULL) { SDPERR("SVC REC is null\n"); status = -1; @@ -4143,13 +4216,14 @@ int sdp_service_search_attr_req(sdp_session_t *session, const sdp_list_t *search } scanned += recsize; pdata += recsize; + pdata_len -= recsize; SDPDBG("Loc seq length : %d\n", recsize); SDPDBG("Svc Rec Handle : 0x%x\n", rec->handle); SDPDBG("Bytes scanned : %d\n", scanned); SDPDBG("Attrlist byte count : %d\n", attr_list_len); rec_list = sdp_list_append(rec_list, rec); - } while (scanned < attr_list_len); + } while (scanned < attr_list_len && pdata_len > 0); SDPDBG("Successful scan of service attr lists\n"); *rsp = rec_list; -- cgit From ca0d3dc0bb5a573b44496847919cc02c9da2016f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 23 Jun 2008 07:29:13 +0000 Subject: More validation of incoming packet lengths --- src/sdp.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index 4217aedd..f8953c42 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -2643,6 +2643,13 @@ int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, if (status < 0) goto end; + if (rspsize < sizeof(sdp_pdu_hdr_t)) { + SDPERR("Unexpected end of packet"); + errno = EPROTO; + status = -1; + goto end; + } + rsphdr = (sdp_pdu_hdr_t *) rsp; p = rsp + sizeof(sdp_pdu_hdr_t); @@ -2654,6 +2661,12 @@ int sdp_device_record_register_binary(sdp_session_t *session, bdaddr_t *device, errno = EPROTO; status = -1; } else { + if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint32_t)) { + SDPERR("Unexpected end of packet"); + errno = EPROTO; + status = -1; + goto end; + } if (handle) *handle = ntohl(bt_get_unaligned((uint32_t *) p)); } @@ -2749,6 +2762,13 @@ int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device if (status < 0) goto end; + if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) { + SDPERR("Unexpected end of packet"); + errno = EPROTO; + status = -1; + goto end; + } + rsphdr = (sdp_pdu_hdr_t *) rspbuf; p = rspbuf + sizeof(sdp_pdu_hdr_t); status = bt_get_unaligned((uint16_t *) p); @@ -2848,6 +2868,13 @@ int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp if (status < 0) goto end; + if (rspsize < sizeof(sdp_pdu_hdr_t) + sizeof(uint16_t)) { + SDPERR("Unexpected end of packet"); + errno = EPROTO; + status = -1; + goto end; + } + SDPDBG("Send req status : %d\n", status); rsphdr = (sdp_pdu_hdr_t *) rspbuf; -- cgit From c7a088963f4c5f767fc08f7e123f4389b0182c53 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 24 Jun 2008 00:33:44 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index a03816e7..e458ff06 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 12:0:10 +libbluetooth_la_LDFLAGS = -version-info 13:0:11 INCLUDES = -I$(top_builddir)/include -- cgit From 522cd764e3d3666b773f016609026bf8287979f6 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Jul 2008 03:00:53 +0000 Subject: Add two additional company identifiers --- src/bluetooth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/bluetooth.c b/src/bluetooth.c index 463e0e05..f7a46bcf 100644 --- a/src/bluetooth.c +++ b/src/bluetooth.c @@ -436,6 +436,10 @@ char *bt_compidtostr(int compid) return "Apple, Inc."; case 77: return "Staccato Communications, Inc."; + case 78: + return "Avago Technologies"; + case 79: + return "APT Ltd."; case 65535: return "internal use"; default: -- cgit From cd8c7ab8f70bd0f0c1c69bd9454be0ad25809533 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 1 Jul 2008 03:04:06 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index e458ff06..975c603c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 13:0:11 +libbluetooth_la_LDFLAGS = -version-info 13:1:11 INCLUDES = -I$(top_builddir)/include -- cgit From 3a585b6fe13ff35b6c1ecf12295b2db75e9221c2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 01:42:26 +0000 Subject: Define MIN if not available --- src/hci.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/hci.c b/src/hci.c index e2c355c0..a72b0355 100644 --- a/src/hci.c +++ b/src/hci.c @@ -45,6 +45,10 @@ #include #include +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#endif + typedef struct { char *str; unsigned int val; -- cgit From bd32ca373cd507d9c9746bde40b0e7bb4034adbe Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 01:43:09 +0000 Subject: Fix spelling --- src/sdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index f8953c42..e365370c 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -164,7 +164,7 @@ static struct tupla ServiceClass[] = { { IMAGING_ARCHIVE_SVCLASS_ID, "Imaging Automatic Archive" }, { IMAGING_REFOBJS_SVCLASS_ID, "Imaging Referenced Objects" }, { HANDSFREE_SVCLASS_ID, "Handsfree" }, - { HANDSFREE_AGW_SVCLASS_ID, "Handfree Audio Gateway" }, + { HANDSFREE_AGW_SVCLASS_ID, "Handsfree Audio Gateway" }, { DIRECT_PRT_REFOBJS_SVCLASS_ID, "Direct Printing Ref. Objects" }, { REFLECTED_UI_SVCLASS_ID, "Reflected UI" }, { BASIC_PRINTING_SVCLASS_ID, "Basic Printing" }, -- cgit From 924fa35c97929ff95590a1f33cc2bd8cca7cf1f2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 Jul 2008 01:44:16 +0000 Subject: Change order of includes --- src/sdp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sdp.c b/src/sdp.c index e365370c..3149c0f1 100644 --- a/src/sdp.c +++ b/src/sdp.c @@ -36,10 +36,10 @@ #include #include #include -#include -#include #include #include +#include +#include #include #include -- cgit From 9b58ef755fe8dabbd82a9a9f88e172b7b9d9222a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 11 Jul 2008 10:11:38 +0000 Subject: Update changelog and bump version number --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 975c603c..065bbe60 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,7 +2,7 @@ lib_LTLIBRARIES = libbluetooth.la libbluetooth_la_SOURCES = bluetooth.c hci.c sdp.c -libbluetooth_la_LDFLAGS = -version-info 13:1:11 +libbluetooth_la_LDFLAGS = -version-info 13:2:11 INCLUDES = -I$(top_builddir)/include -- cgit