From: Claudio Takahasi <cktakahasi@gmail.com>
To: bluez-devel@lists.sourceforge.net
Subject: Re: [Bluez-devel] Re: bluetoothd specification - new patch
Date: Tue, 26 Jul 2005 13:31:41 -0300 [thread overview]
Message-ID: <e1effdeb05072609312aa92cc0@mail.gmail.com> (raw)
In-Reply-To: <e1effdeb05071809461382a01c@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 5427 bytes --]
Hi folks,
I am sending a new patch of bluetoothd.
Marcel, if possible, send me a feedback.
The ideia behind this daemon is provide a modular
D-Bus implementation for Bluez. Profiles(pan, dund, hcid) and
other services(sdp, hcitool, hciconfig) can be developed individualy.
It is possible enable/disable this profile at run-time.
There are a lot of pieces missing. This is just a skeleton of the
architecture. My ideia is export all current features of the bluez-utils
daemons and tools using a D-Bus interface.
Suggestions are welcome!
Regards,
Claudio.
On 7/18/05, Claudio Takahasi <cktakahasi@gmail.com> wrote:
> Hi Fred,
>
> Thanks for your comment.
> I will consider your suggestion. Currently, I am
> developing the main loop. This is the biggest
> challenge. The main loop function must be flexible
> in order to monitor a lot of file descriptors: D-Bus,
> periodic inquiry, incomming connections, ...
>
> My ideia is develop the bluetoothd flexible, making
> possible enable/disable D-Bus service for the
> profiles(daemons: pand, dund, hidd ) at run-time.
>
> If you have time, try analyze the architecture(skeleton)
> that I sent in the last patch and send me a feedback.
>
> Regards,
> Claudio.
>
>
> On 7/18/05, Frederic Danis <frederic.danis@palmsource.com> wrote:
> > Hello,
> >
> > I think that it could be interesting to add interfaces to bluetoothd to
> > manage paired devices like:
> > - get paired devices list
> > - remove paired device
> >
> > Regards
> >
> > Fred
> >
> > -----------------------------------------------
> > It is not by improving the oil lamp that one invents the electric bulb!
> > -----------------------------------------------
> > Danis Frederic PalmSource Europe
> > Software engineer
> > Mail : mailto:frederic.danis@palmsource.com
> > -----------------------------------------------
> >
> >
> >
> > Claudio Takahasi wrote:
> >
> > >Hi Marcel,
> > >
> > >I am sending a suggestion for bluetoothd implementation.
> > >
> > >Please send your feedback.
> > >
> > >Regarding the d-bus version checking, there is a different
> > >approach using pkg-config for check dbus version instead of
> > >verify if a function belongs to the dbus-1
> > >
> > >
> > >The next step is implement the main loop.
> > >
> > >Regards,
> > >Claudio.
> > >
> > >On 7/12/05, Claudio Takahasi <cktakahasi@gmail.com> wrote:
> > >
> > >
> > >>Hi Marcel,
> > >>
> > >>Periodic inquiry and adapter setup is extremely
> > >>necessary for me. Is it possible set a high priority
> > >>for these features?
> > >>
> > >>Regarding the interfaces and objects path of the
> > >>bluetoothd my suggestion is:
> > >>
> > >>
> > >>
> > >>>>>bluetoothd
> > >>>>>
> > >>>>>
> > >>DBus service : org.bluez.hci
> > >>DBus interface: org.bluez.hci
> > >>DBus object path: org/bluez/hci
> > >> - setup link properties
> > >> - setup inquiry mode
> > >> - kill bluetoothd
> > >> - show local adapters
> > >> - ???
> > >>
> > >>
> > >>>>>SDP
> > >>>>>
> > >>>>>
> > >>DBus service : org.bluez.sdp
> > >>DBus interface: org.bluez.sdp
> > >>DBus object path: org/bluez/sdp
> > >>methods:
> > >> - search
> > >> - register/unregister
> > >> - get local services
> > >> - ???
> > >>
> > >>
> > >>
> > >>>>>PAN
> > >>>>>
> > >>>>>
> > >>DBus service : org.bluez.pan
> > >>DBus interface: org.bluez.pan
> > >>DBus object path: org/bluez/pan
> > >> - connect/disconnect
> > >> - listen start/stop
> > >> - connections
> > >>
> > >>
> > >>Open issues:
> > >>- How/Where handle multiple bluetooth adapters?
> > >> solution1: the device id (hci0) can be part of object path
> > >> eg: org.bluez.hci0.pan org.bluez.hci0.sdp
> > >>
> > >> solution2: pass the device id as parameter or define a method
> > >> to set the active adapter.
> > >>
> > >>
> > >>I am not sure if it is better define a hierarchical objects or
> > >>register multiples objects. Dbus support two functions:
> > >>dbus_connection_register_object_path and
> > >>dbus_connection_register_fallback(for a given subsection of the
> > >>object hierarchy). But I think that it is not important now because
> > >>for both approachs the message handler functions are distinct.
> > >>I will investigate more which approach is the best.
> > >>
> > >>Defining an hierarchical approach make easier define policy/rules
> > >>in the dbus configuration files.
> > >>
> > >>Do you have a different design for it or suggestions?
> > >>There are a lot services that shall be inserted in the bluetoothd,
> > >>maybe should be better define multiple interfaces(adapter, link, ... )
> > >>for this daemon.
> > >>
> > >>
> > >>Regards,
> > >>Claudio.
> > >>
> > >>
> > >>
> > >
> >
> >
> > -------------------------------------------------------
> > SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
> > from IBM. Find simple to follow Roadmaps, straightforward articles,
> > informative Webcasts and more! Get everything you need to get up to
> > speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
> > _______________________________________________
> > Bluez-devel mailing list
> > Bluez-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/bluez-devel
> >
>
[-- Attachment #2: bluetoothd_patch_00.02 --]
[-- Type: application/octet-stream, Size: 85338 bytes --]
--- bluez-utils-2.18.orig/acinclude.m4 2005-07-03 18:19:51.000000000 -0300
+++ bluetoothd-0.0.6/acinclude.m4 2005-07-26 11:42:08.361214352 -0300
@@ -255,6 +255,34 @@
AC_SUBST(DBUS_LIBS)
])
+AC_DEFUN([AC_VER_DBUS], [
+ if test "${dbus_found}" = "yes"; then
+ if test -z "$PKG_CONFIG"; then
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+ fi
+ if test "$PKG_CONFIG" = "no" ; then
+ echo "*** The pkg-config script could not be found. It is"
+ echo "*** required for check D-BUS version. Make sure it is"
+ echo "*** in your path, or set the PKG_CONFIG environment"
+ echo "*** variable to the full path to pkg-config."
+ else
+
+ AC_MSG_CHECKING([dbus version])
+
+ DBUS_VERSION=`$PKG_CONFIG --modversion dbus-1`
+ DBUS_MAJOR_VER=`echo $DBUS_VERSION | cut -d. -f 1`
+ DBUS_MINOR_VER=`echo $DBUS_VERSION | cut -d. -f 2`
+ DBUS_MICRO_VER=`echo $DBUS_VERSION | cut -d. -f 3`
+
+ AC_MSG_RESULT($DBUS_VERSION)
+ AC_DEFINE_UNQUOTED(DBUS_MAJOR_VER, $DBUS_MAJOR_VER, [D-BUS major version.])
+ AC_DEFINE_UNQUOTED(DBUS_MINOR_VER, $DBUS_MINOR_VER, [D-BUS minor version.])
+ AC_DEFINE_UNQUOTED(DBUS_MICRO_VER, $DBUS_MICRO_VER, [D-BUS micro version.])
+
+ fi
+ fi
+])
+
AC_DEFUN([AC_ARG_BLUEZ], [
debug_enable=no
pie_enable=no
--- bluez-utils-2.18.orig/aclocal.m4 2005-07-03 20:15:36.000000000 -0300
+++ bluetoothd-0.0.6/aclocal.m4 2005-07-26 11:42:08.365213744 -0300
@@ -268,6 +268,34 @@
AC_SUBST(DBUS_LIBS)
])
+AC_DEFUN([AC_VER_DBUS], [
+ if test "${dbus_found}" = "yes"; then
+ if test -z "$PKG_CONFIG"; then
+ AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
+ fi
+ if test "$PKG_CONFIG" = "no" ; then
+ echo "*** The pkg-config script could not be found. It is"
+ echo "*** required for check D-BUS version. Make sure it is"
+ echo "*** in your path, or set the PKG_CONFIG environment"
+ echo "*** variable to the full path to pkg-config."
+ else
+
+ AC_MSG_CHECKING([dbus version])
+
+ DBUS_VERSION=`$PKG_CONFIG --modversion dbus-1`
+ DBUS_MAJOR_VER=`echo $DBUS_VERSION | cut -d. -f 1`
+ DBUS_MINOR_VER=`echo $DBUS_VERSION | cut -d. -f 2`
+ DBUS_MICRO_VER=`echo $DBUS_VERSION | cut -d. -f 3`
+
+ AC_MSG_RESULT($DBUS_VERSION)
+ AC_DEFINE_UNQUOTED(DBUS_MAJOR_VER, $DBUS_MAJOR_VER, [D-BUS major version.])
+ AC_DEFINE_UNQUOTED(DBUS_MINOR_VER, $DBUS_MINOR_VER, [D-BUS minor version.])
+ AC_DEFINE_UNQUOTED(DBUS_MICRO_VER, $DBUS_MICRO_VER, [D-BUS micro version.])
+
+ fi
+ fi
+])
+
AC_DEFUN([AC_ARG_BLUEZ], [
debug_enable=no
pie_enable=no
--- bluez-utils-2.18.orig/config.h.in 2005-07-03 20:15:38.000000000 -0300
+++ bluetoothd-0.0.6/config.h.in 2005-07-26 11:42:08.360214504 -0300
@@ -15,6 +15,15 @@
/* Define to 1 if you have the dbus_pending_call_steal_reply() function. */
#undef HAVE_DBUS_PENDING_CALL_STEAL_REPLY
+/* D-BUS major version. */
+#undef DBUS_MAJOR_VER
+
+/* D-BUS minor version. */
+#undef DBUS_MINOR_VER
+
+/* D-BUS micro version. */
+#undef DBUS_MICRO_VER
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
--- bluez-utils-2.18.orig/configure.in 2005-07-03 20:12:08.000000000 -0300
+++ bluetoothd-0.0.6/configure.in 2005-07-26 11:42:08.359214656 -0300
@@ -31,7 +31,8 @@
AC_PATH_ALSA
AC_PATH_USB
AC_PATH_DBUS
+AC_VER_DBUS
AC_ARG_BLUEZ
-AC_OUTPUT(Makefile common/Makefile tools/Makefile rfcomm/Makefile hcid/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile)
+AC_OUTPUT(Makefile common/Makefile daemon/Makefile tools/Makefile rfcomm/Makefile hcid/Makefile sdpd/Makefile dund/Makefile pand/Makefile hidd/Makefile cups/Makefile alsa/Makefile test/Makefile scripts/Makefile pcmcia/Makefile extra/Makefile)
--- bluez-utils-2.18.orig/Makefile.am 2005-05-09 15:33:24.000000000 -0300
+++ bluetoothd-0.0.6/Makefile.am 2005-07-26 11:42:08.364213896 -0300
@@ -2,7 +2,7 @@
# $Id: Makefile.am,v 1.19 2005/04/22 12:15:36 holtmann Exp $
#
-SUBDIRS = common tools rfcomm hcid sdpd dund pand hidd \
+SUBDIRS = common daemon tools rfcomm hcid sdpd dund pand hidd \
cups alsa test scripts pcmcia extra
MAINTAINERCLEANFILES = Makefile.in \
--- bluez-utils-2.18.orig/daemon/bluetoothd_dbus.c 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/bluetoothd_dbus.c 2005-07-26 11:42:08.063259648 -0300
@@ -0,0 +1,724 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "bluetoothd_internal.h"
+
+#define WATCH_MAX 7
+
+
+
+
+typedef struct {
+ const char *profile;
+ int8_t status; /* 1:active 0:disabled*/
+ register_function_t *reg_func;
+ unregister_function_t *unreg_func;
+ timer_handler_func_t timer_func;
+}__attribute__((packed))btd_fallback_entry_t;
+
+typedef struct fd_poll_struct fd_poll_t;
+struct fd_poll_struct{
+ int32_t fd;
+ uint32_t flags;
+ watch_handler_func_t func;
+ watch_handler_func_free_udata_t free_udata_func;
+ void *udata;
+ fd_poll_t *next;
+}__attribute__((packed));
+
+
+typedef struct
+{
+ int8_t run;
+ DBusConnection* sys_bus;
+ DBusConnection* sess_bus;
+ fd_poll_t *fd_poll;
+}__attribute__((packed)) bluetoothd_app_data_t;
+
+
+btd_fallback_entry_t btd_profiles [] = {
+ {HCICONFIG_DBUS_PATH, 1 , hciconfig_dbus_register, hciconfig_dbus_unregister, NULL},
+ {HCI_DBUS_PATH, 1 , hci_dbus_register, hci_dbus_unregister, NULL},
+ {PAN_DBUS_PATH, 1 , pan_dbus_register, pan_dbus_unregister, NULL},
+ {SDP_DBUS_PATH, 1 , sdp_dbus_register, sdp_dbus_unregister, NULL},
+ /* dund */
+ /* hid */
+ { NULL, 0, NULL , NULL }
+};
+
+ /*****************************************************************
+ *
+ * Section reserved to D-BUS prototypes
+ *
+ *****************************************************************/
+static DBusHandlerResult btd_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data);
+
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_exit_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_enable_profile_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_disable_profile_req(DBusMessage *msg, void *data);
+
+
+
+/*****************************************************************
+ *
+ * Section reserved to local variables
+ *
+ *****************************************************************/
+
+static bluetoothd_app_data_t app_data;
+
+static service_table_t btd_services[] = {
+{BLUETOOTHD_LIST_SERVICES_REQ, handle_list_services_req, BLUETOOTHD_LIST_SERVICES_REQ_SIGNATURE },
+{BLUETOOTHD_EXIT_REQ, handle_exit_req, BLUETOOTHD_EXIT_REQ_SIGNATURE},
+{BLUETOOTHD_ENABLE_PROFILE_REQ, handle_enable_profile_req, BLUETOOTHD_ENABLE_PROFILE_REQ_SIGNATURE },
+{BLUETOOTHD_DISABLE_PROFILE_REQ, handle_disable_profile_req, BLUETOOTHD_DISABLE_PROFILE_REQ_SIGNATURE },
+{NULL, NULL, NULL}
+};
+
+/**
+ * Virtual table that implements the handlers
+ * of the object path hierarchy
+ **/
+static DBusObjectPathVTable btd_vtable = {
+ NULL,
+ &btd_msg_func,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+/*****************************************************************
+ *
+ * Section reserved to D-Bus/Bluetoooth file descriptor handlers
+ *
+ *****************************************************************/
+
+/**
+ * dbus_fd_handler - D-Bus file descriptor handler
+ * @param fd D-Bus file descriptor
+ * @param cond socket condition
+ * @param udata watch
+ * @return TRUE
+ * Function called when there is data to be send
+ **/
+static uint8_t dbus_fd_handler(int32_t fd, uint32_t cond, void *udata)
+{
+ DBusWatch *watch = (DBusWatch *) udata;
+ uint32_t flags = 0;
+
+ if (cond & POLLIN)
+ flags |= DBUS_WATCH_READABLE;
+ if (cond & POLLOUT)
+ flags |= DBUS_WATCH_WRITABLE;
+ if (cond & POLLHUP)
+ flags |= DBUS_WATCH_HANGUP;
+ if (cond & POLLERR)
+ flags |= DBUS_WATCH_ERROR;
+
+
+ dbus_watch_handle(watch, flags);
+
+ dbus_connection_ref(app_data.sys_bus);
+
+ /* Dispatch messages */
+ while (dbus_connection_dispatch(app_data.sys_bus) == DBUS_DISPATCH_DATA_REMAINS);
+
+ dbus_connection_unref(app_data.sys_bus);
+
+ return TRUE;
+}
+
+/**
+ * bluetoothd_monitor_add - Add fd to the poll list
+ * @param fd D-Bus or Bluetooth file descriptor
+ * @param flags socket flags, see poll events
+ * @param func Bluetooth or D-Bus fd handler
+ * @param free_udata_func user data free function
+ * @param udata user data
+ * @return file descriptor added or (0) if failed
+ * Function used to add a new file descriptor to
+ * the poll list monitored in the main loop
+ **/
+int32_t bluetoothd_monitor_add (int32_t fd, uint32_t flags, watch_handler_func_t func,
+ watch_handler_func_free_udata_t free_udata_func, void *udata)
+{
+ fd_poll_t *fdesc = malloc(sizeof(fd_poll_t));
+
+ if(fdesc) {
+ fdesc->fd = fd;
+ fdesc->flags = flags;
+ fdesc->func = func;
+ fdesc->free_udata_func = free_udata_func;
+ fdesc->udata = udata;
+ fdesc->next = (app_data.fd_poll)->next;
+ (app_data.fd_poll)->next = fdesc;
+ return fdesc->fd;
+ } else {
+ return 0;
+ }
+
+
+}
+
+/**
+ * bluetoothd_monitor_remove - Remove fd from the poll list
+ * @param fd D-Bus or Bluetooth file descriptor
+ * @return TRUE
+ * Function used to remove a file descriptor from the
+ * poll list monitored in the main loop
+ **/
+uint8_t bluetoothd_monitor_remove(int32_t fd)
+{
+ fd_poll_t *pfd, *ptr;
+ uint8_t ret_val = -1;
+
+ for (ptr = (app_data.fd_poll), pfd = (app_data.fd_poll->next); pfd; pfd = pfd->next) {
+ if (pfd->fd == fd) {
+ ptr->next = pfd->next;
+ if(pfd->free_udata_func)
+ pfd->free_udata_func(pfd->udata);
+ free (pfd);
+ ret_val = 0;
+ break;
+ }
+ }
+ return ret_val;
+
+}
+
+/**
+ * fd_poll_free - Free a fd_poll list
+ * @param node fist element of the list
+ * @return TRUE
+ * Free recursively the poll list. This function
+ * must be called before the daemon exits.
+ **/
+static void fd_poll_free(fd_poll_t *node)
+{
+ if (node->next)
+ fd_poll_free(node->next);
+ if (node->free_udata_func)
+ node->free_udata_func(node->udata);
+ free(node);
+}
+
+/**
+ * add_dbus_watch - Add D-Bus watch function
+ * @param watch D-Bus watch
+ * @return TRUE
+ * This function is called internaly by
+ * dbus_connection_set_watch_functions. It is
+ * responsible for add the D-Bus file descriptor
+ * to poll list monitored in the main loop
+ **/
+uint32_t add_dbus_watch(DBusWatch *watch, void *data)
+{
+ uint32_t ret_val = 0;
+ uint32_t cond = POLLHUP | POLLERR;
+ int32_t *fd, flags;
+
+ if (!dbus_watch_get_enabled(watch))
+ return TRUE;
+
+ fd = (int32_t*)malloc(sizeof(int32_t));
+ if(!fd) {
+ syslog(LOG_ERR, "Can't allocate memory\n");
+ return TRUE;
+ }
+
+ (*fd) = dbus_watch_get_fd(watch);
+
+
+ flags = dbus_watch_get_flags(watch);
+ if (flags & DBUS_WATCH_READABLE)
+ cond |= POLLIN;
+ if (flags & DBUS_WATCH_WRITABLE)
+ cond |= POLLOUT;
+
+ bluetoothd_monitor_add(*fd, cond, dbus_fd_handler , NULL, watch);
+
+ dbus_watch_set_data(watch, fd ,(DBusFreeFunction)free);
+
+ return ret_val;
+}
+
+/**
+ * remove_dbus_watch - Remove D-Bus watch function
+ * @param watch D-Bus watch
+ * @return TRUE
+ * Function used to remove a watch from the connection
+ **/
+static void remove_dbus_watch(DBusWatch *watch, void *data)
+{
+ uint32_t *id = dbus_watch_get_data(watch);
+ if (!id) {
+ return; /* probably a not-enabled watch that was added */
+ }
+ bluetoothd_monitor_remove(*id);
+ dbus_watch_set_data(watch, NULL, NULL);
+}
+
+/**
+ * watch_dbus_toggled - Function called when D-Bus watch status changes
+ * @param watch D-Bus watch
+ * @param data user data
+ *
+ **/
+static void watch_dbus_toggled(DBusWatch *watch, void *data)
+{
+ if (dbus_watch_get_enabled(watch))
+ add_dbus_watch(watch, data);
+ else
+ remove_dbus_watch(watch, data);
+
+}
+
+/**
+ * poll_main_loop_new - Creates a main loop
+ * @return returns the main loop
+ * Creates a new application main loop.
+ **/
+static fd_poll_t * fd_poll_new()
+{
+ fd_poll_t * pfd_poll = NULL;
+
+ pfd_poll = (fd_poll_t *) malloc(sizeof(fd_poll_t));
+ if(!pfd_poll) {
+ syslog(LOG_ERR, "Can't allocate memory\n");
+ return NULL;
+ }
+
+ memset(pfd_poll, 0, sizeof(fd_poll_t));
+ return pfd_poll;
+}
+
+
+/**
+ * main_loop_run - The main loop of the daemon
+ * @param loop the main loop pointer
+ * Application main loop function responsible for
+ * monitor all file descriptors: D-Bus and incomming
+ * connections
+ **/
+static void main_loop_run()
+{
+ struct pollfd *fds;
+ btd_fallback_entry_t *ptr;
+ fd_poll_t *p, *w;
+ int nfds, res, i;
+ uint8_t keep;
+
+ fds = malloc(WATCH_MAX * sizeof(struct pollfd));
+
+ if (!fds) {
+ syslog(LOG_ERR, "Can't allocate memory\n");
+ return;
+ }
+
+ app_data.run = 1;
+
+ while (app_data.run) {
+
+ nfds = 0;
+ for (w = (app_data.fd_poll->next); w != NULL; w = w->next) {
+ fds[nfds].fd = w->fd;
+ fds[nfds].events = w->flags;
+ fds[nfds].revents = 0;
+ nfds++;
+ }
+
+ res = poll(fds, nfds, POLL_TIMEOUT);
+
+ if (res <= 0) {
+ ptr = btd_profiles;
+ for(;ptr->profile; ptr++) {
+ if(ptr->status && ptr->timer_func) {
+ ptr->timer_func(POLL_TIMEOUT);
+ }
+ }
+ continue;
+ }
+
+ p = app_data.fd_poll;
+ w = app_data.fd_poll->next;
+ i = 0;
+
+ while (w) {
+ if (fds[i].revents) {
+ keep = w->func(w->fd, fds[i].revents, w->udata);
+ if (!keep) {
+ syslog(LOG_INFO, "%s - line:%d - run:%d",__PRETTY_FUNCTION__, __LINE__, app_data.run );
+ p->next = w->next;
+ memset(w, 0, sizeof(*w));
+ w = p->next;
+ i++;
+ continue;
+ }
+ }
+ p = w;
+ w = w->next;
+ i++;
+ }
+
+ }
+
+ free(fds);
+}
+
+
+
+
+/*****************************************************************
+ *
+ * Section reserved to bluetoothd public functions
+ *
+ *****************************************************************/
+int8_t bluetoothd_disable_profile(const char *profile)
+{
+ int8_t ret = -1;
+ btd_fallback_entry_t *ptr = btd_profiles;
+ char service[128];
+
+ sprintf(service, "%s/%s",BLUETOOTHD_DBUS_PATH, profile);
+
+ for(;ptr->profile; ptr++) {
+ if(strcasecmp(ptr->profile, service) == 0 ) {
+ if(ptr->status && app_data.run) {
+ ptr->unreg_func(app_data.sys_bus);
+ }
+ ptr->status = 0;
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+int8_t bluetoothd_enable_profile(const char *profile)
+{
+ int8_t ret = -1;
+ btd_fallback_entry_t *ptr = btd_profiles;
+ char service[128];
+
+ sprintf(service, "%s/%s",BLUETOOTHD_DBUS_PATH, profile);
+
+
+ for(;ptr->profile; ptr++) {
+ if(strcasecmp(ptr->profile, service) == 0 ) {
+ if(!ptr->status && app_data.run) {
+ ptr->reg_func(app_data.sys_bus);
+ }
+ ptr->status = 1;
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+/*****************************************************************
+ *
+ * Section reserved to xxxxxxxxxxxxxxx
+ *
+ *****************************************************************/
+
+
+static DBusHandlerResult btd_signal_filter (DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ const char *iface;
+ const char *method;
+
+ if(!msg || !conn)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ if (dbus_message_get_type (msg) != DBUS_MESSAGE_TYPE_SIGNAL)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+ iface = dbus_message_get_interface(msg);
+ method = dbus_message_get_member(msg);
+
+ if(strcmp(iface, DBUS_INTERFACE_LOCAL) == 0) {
+ if(strcmp(method, "Disconnected") == 0){
+ syslog(LOG_INFO, "%s - line:%d - Disconnected",__PRETTY_FUNCTION__, __LINE__ );
+ app_data.run = 0;
+ ret = DBUS_HANDLER_RESULT_HANDLED;
+ }
+ } else if(strcmp(iface, DBUS_INTERFACE_DBUS) == 0) {
+ if(strcmp(method, "NameOwnerChanged") == 0) {
+ //TODO
+ syslog(LOG_INFO, "%s - line:%d - NameOwnerChanged",__PRETTY_FUNCTION__, __LINE__ );
+ ret = DBUS_HANDLER_RESULT_HANDLED;
+ }
+ if(strcmp(method, "NameAcquired") == 0) {
+ //TODO
+ syslog(LOG_INFO, "%s - line:%d - NameAcquired",__PRETTY_FUNCTION__, __LINE__ );
+ ret = DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
+ return ret;
+}
+
+
+
+int8_t bluetoothd_init()
+{
+ btd_fallback_entry_t *ptr = btd_profiles;
+
+ DBusError dbus_error;
+ int8_t ret = 0;
+
+
+ memset(&app_data, 0, sizeof(bluetoothd_app_data_t));
+
+ dbus_error_init(&dbus_error);
+ app_data.sys_bus = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error);
+
+ if (!app_data.sys_bus) {
+ syslog(LOG_ERR, "D-Bus Error: %s", dbus_error.message);
+ dbus_error_free(&dbus_error);
+ ret = -1;
+ goto cleanup;
+ }
+
+#if 0
+ Disable for now
+ dbus_error_init(&dbus_error);
+ app_data.sess_bus = dbus_bus_get(DBUS_BUS_SESSION, &dbus_error);
+
+ if (!app_data.sess_bus) {
+ syslog(LOG_ERR, "D-Bus Error: %s", dbus_error.message);
+ dbus_error_free(&dbus_error);
+ ret = -1;
+ goto cleanup;
+ }
+#endif
+ dbus_error_init (&dbus_error);
+
+ DBUS_BUS_REQUEST_NAME(app_data.sys_bus, BLUETOOTHD_DBUS_SERVICE,
+ DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT,
+ &dbus_error);
+
+ if (dbus_error_is_set (&dbus_error)) {
+ syslog(LOG_ERR,"D-Bus Error: %s\n", dbus_error.message);
+ dbus_error_free (&dbus_error);
+ ret = -1;
+ goto cleanup;
+
+ }
+
+ if(!dbus_connection_register_object_path(app_data.sys_bus, BLUETOOTHD_DBUS_PATH, &btd_vtable, NULL)) {
+ syslog(LOG_ERR,"DBUS failed to register %s object", BLUETOOTHD_DBUS_PATH);
+ ret = -1;
+ goto cleanup;
+ }
+ //Register fallback D-Bus objects
+ while(ptr->profile)
+ {
+ if(ptr->status)
+ ptr->reg_func(app_data.sys_bus);
+ ptr++;
+ }
+
+
+ if (!dbus_connection_add_filter (app_data.sys_bus, btd_signal_filter, NULL, NULL)) {
+ syslog(LOG_ERR,"DBUS failed to add filter");
+ ret = -1;
+ goto cleanup;
+ }
+
+ app_data.fd_poll = fd_poll_new();
+
+ dbus_connection_set_watch_functions(app_data.sys_bus,
+ add_dbus_watch,
+ remove_dbus_watch,
+ watch_dbus_toggled,
+ NULL,
+ NULL);
+
+
+
+ main_loop_run();
+ fd_poll_free(app_data.fd_poll);
+
+cleanup:
+ return ret;
+}
+
+int8_t bluetoothd_exit()
+{
+ int8_t ret = 0;
+ app_data.run = 0;
+ return ret;
+}
+
+/*****************************************************************
+ *
+ * Section reserved to D-Bus message handlers
+ *
+ *****************************************************************/
+
+int8_t bluetoothd_msg_send(DBusMessage *msg)
+{
+ int8_t ret = -1;
+ if(msg) {
+ if (!dbus_connection_send (app_data.sys_bus, msg, NULL)) { \
+ syslog(LOG_ERR, "%s line:%d Can't send message!", \
+ __PRETTY_FUNCTION__, __LINE__) ;
+ }
+ dbus_connection_flush(app_data.sys_bus);
+ dbus_message_unref (msg);
+ ret = 0;
+ }
+
+ return ret;
+}
+static DBusHandlerResult btd_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ service_table_t *ptr_handlers = btd_services;
+ DBusMessage *reply = NULL;
+ DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ uint16_t type;
+ const char *iface;
+ const char *method;
+
+ type = dbus_message_get_type(msg);
+ iface = dbus_message_get_interface(msg);
+ method = dbus_message_get_member (msg);
+
+ if((type == DBUS_MESSAGE_TYPE_METHOD_CALL) &&
+ (strcmp(iface, BLUETOOTHD_DBUS_IFACE_REQ) == 0) &&
+ (method != NULL)){
+ for (;ptr_handlers->name; ptr_handlers++) {
+ if (strcmp(method, ptr_handlers->name) == 0) {
+ if (strcmp(ptr_handlers->signature, dbus_message_get_signature(msg)) == 0)
+ {
+ reply = (ptr_handlers->handler_func)(msg, data);
+ if (reply) {
+ if (!dbus_connection_send (conn, reply, NULL)) { \
+ syslog(LOG_ERR, "%s line:%d Can't send reply message!", \
+ __PRETTY_FUNCTION__, __LINE__) ;
+ }
+ dbus_message_unref (reply);
+ }
+ ret = DBUS_HANDLER_RESULT_HANDLED;
+ } else {
+ //signature is not matching
+ }
+ break;
+ }
+ }
+ }
+ return ret;
+
+}
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+
+ reply = dbus_message_new_method_return(msg);
+
+ common_list_services(reply, btd_services);
+
+ return reply;
+}
+
+static DBusMessage* handle_exit_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *signal = NULL;
+
+ signal = dbus_message_new_signal
+ ((const char*)BLUETOOTHD_DBUS_PATH,
+ (const char*)BLUETOOTHD_DBUS_IFACE_SIGNAL,
+ (const char*)BLUETOOTHD_SIG_EXIT);
+
+ if (dbus_connection_send (app_data.sys_bus, signal, NULL)) {
+ dbus_message_unref (signal);
+ }
+ dbus_connection_flush(app_data.sys_bus);
+ app_data.run = 0;
+
+ return NULL;
+}
+
+static DBusMessage* handle_enable_profile_req(DBusMessage *msg, void *data)
+{
+ int8_t ret = 0;
+ DBusMessageIter iter;
+ DBusMessage *reply = NULL;
+ char *profile = NULL;
+ BTD_RESULT cnf = BTD_SUCCESS;
+
+ dbus_message_iter_init(msg, &iter);
+ DBUS_MSG_ITER_GET_STR(&iter, profile);
+
+ if(profile) {
+ ret = bluetoothd_enable_profile(profile);
+ if(ret) cnf = BTD_FAILED;
+ }else {
+ cnf = BTD_WRONG_PARAM;
+
+ }
+
+ reply = dbus_message_new_method_return(msg);
+ DBUS_MSG_APPEND_ITER_INIT(reply, &iter);
+ DBUS_MSG_ITER_APPEND_BYTE(&iter, cnf);
+ return reply;
+}
+
+static DBusMessage* handle_disable_profile_req(DBusMessage *msg, void *data)
+{
+ int8_t ret = 0;
+ DBusMessageIter iter;
+ DBusMessage *reply = NULL;
+ char *profile = NULL;
+ BTD_RESULT cnf = BTD_SUCCESS;
+
+
+
+ dbus_message_iter_init(msg, &iter);
+ DBUS_MSG_ITER_GET_STR(&iter, profile);
+
+ if(profile) {
+ ret = bluetoothd_disable_profile(profile);
+ if(ret) cnf = BTD_FAILED;
+ }else {
+ cnf = BTD_WRONG_PARAM;
+
+ }
+
+ reply = dbus_message_new_method_return(msg);
+ DBUS_MSG_APPEND_ITER_INIT(reply, &iter);
+ DBUS_MSG_ITER_APPEND_BYTE(&iter, cnf);
+
+ return reply;
+}
+
+
--- bluez-utils-2.18.orig/daemon/bluetoothd_dbus.h 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/bluetoothd_dbus.h 2005-07-26 11:42:08.065259344 -0300
@@ -0,0 +1,33 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __H_BLUETOOTHD_DBUS_H__
+#define __H_BLUETOOTHD_DBUS_H__
+
+#include "bluetoothd_internal.h"
+
+int8_t bluetoothd_init();
+int8_t bluetoothd_exit();
+int8_t bluetoothd_disable_profile(const char *profile);
+int8_t bluetoothd_enable_profile(const char *profile);
+
+#endif /* __H_BLUETOOTHD_DBUS_H__ */
--- bluez-utils-2.18.orig/daemon/bluetoothd_internal.h 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/bluetoothd_internal.h 2005-07-26 11:42:08.065259344 -0300
@@ -0,0 +1,170 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __H_BLUETOOTHD_INTERNAL_H__
+#define __H_BLUETOOTHD_INTERNAL_H__
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <dbus/dbus.h>
+#include <errno.h>
+#include <signal.h>
+
+#include <sys/syslog.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <sys/ioctl.h>
+
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <bluetooth/l2cap.h>
+#include <bluetooth/bnep.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include "dbus.h"
+
+#define POLL_TIMEOUT (10240) /* tick each 10.24s second */
+#define MAX_CACHE_TTL 368640 /* 6.144 seconds */
+#define INQUIRY_CACHE_SIZE 24
+#define MAX_TTL_INQUIRY 3
+#define INQUIRY_TIME (10240) /* tick each 10.24s second */
+
+
+#define CHECK_DBUS_VERSION(major, minor) \
+ (DBUS_MAJOR_VER > (major) || \
+ (DBUS_MAJOR_VER == (major) && DBUS_MINOR_VER >= (minor)))
+
+
+#if CHECK_DBUS_VERSION(0, 30)
+ /* For D-Bus version >= 0.30 */
+ #define DBUS_BUS_REQUEST_NAME(x,y,z,w) dbus_bus_request_name(x,y,z,w)
+ #define DBUS_MSG_APPEND_BYTE_ARRAY(a,b,c,d,e,f) dbus_message_append_args(a,b,c,&d,e,f)
+ #define DBUS_MSG_ITER_APPEND_BYTE(iter, val) \
+ dbus_message_iter_append_basic((iter), DBUS_TYPE_BYTE, &(val))
+ #define DBUS_MSG_ITER_APPEND_STR(iter, val) \
+ dbus_message_iter_append_basic((iter), DBUS_TYPE_STRING, &(val))
+ #define DBUS_MSG_ITER_APPEND_INT32(iter, val) \
+ dbus_message_iter_append_basic((iter), DBUS_TYPE_INT32, &(val))
+ #define DBUS_MSG_ITER_APPEND_UINT32(iter, val) \
+ dbus_message_iter_append_basic((iter), DBUS_TYPE_UINT32, &(val))
+ #define DBUS_MSG_ITER_GET_BYTE(iter, retvar) \
+ dbus_message_iter_get_basic((iter), &(retvar))
+ #define DBUS_MSG_ITER_GET_STR(iter, retvar) \
+ dbus_message_iter_get_basic((iter), &(retvar))
+ #define DBUS_MSG_ITER_GET_INT16(iter, retvar) \
+ dbus_message_iter_get_basic((iter), &(retvar))
+ #define DBUS_MSG_ITER_GET_UINT16(iter, retvar) \
+ dbus_message_iter_get_basic((iter), &(retvar))
+ #define DBUS_MSG_ITER_GET_INT32(iter, retvar) \
+ dbus_message_iter_get_basic((iter), &(retvar))
+ #define DBUS_MSG_ITER_GET_UINT32(iter, retvar) \
+ dbus_message_iter_get_basic((iter), &(retvar))
+ #define DBUS_MSG_APPEND_ITER_INIT(a, b) \
+ dbus_message_iter_init_append(a, b)
+#else /* < 0.30 */
+ /* For D-Bus version older than 0.30 */
+ #define DBUS_INTERFACE_LOCAL DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL
+ #define DBUS_INTERFACE_DBUS DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS
+ #define DBUS_BUS_REQUEST_NAME(x,y,z,w) dbus_bus_acquire_service(x,y,z,w)
+ #define DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT DBUS_SERVICE_FLAG_PROHIBIT_REPLACEMENT
+ #define DBUS_MSG_ITER_APPEND_BYTE(iter, val) \
+ dbus_message_iter_append_byte((iter), (val))
+ #define DBUS_MSG_APPEND_BYTE_ARRAY(a,b,c,d,e,f) dbus_message_append_args(a,b,c,d,e,f)
+ #define DBUS_MSG_ITER_APPEND_STR(iter, val) \
+ dbus_message_iter_append_string((iter), (val))
+ #define DBUS_MSG_ITER_APPEND_INT32(iter, val) \
+ dbus_message_iter_append_int32((iter), (val))
+ #define DBUS_MSG_ITER_APPEND_UINT32(iter, val) \
+ dbus_message_iter_append_uint32((iter), (val))
+ #define DBUS_MSG_ITER_GET_BYTE(iter, retvar) \
+ retvar = dbus_message_iter_get_byte((iter))
+ #define DBUS_MSG_ITER_GET_STR(iter, retvar) \
+ retvar = dbus_message_iter_get_string(iter)
+ #define DBUS_MSG_ITER_GET_INT16(iter, retvar) \
+ retvar = dbus_message_iter_get_int16((iter))
+ #define DBUS_MSG_ITER_GET_UINT16(iter, retvar) \
+ retvar = dbus_message_iter_get_uint16((iter))
+ #define DBUS_MSG_ITER_GET_INT32(iter, retvar) \
+ retvar = dbus_message_iter_get_int32((iter))
+ #define DBUS_MSG_ITER_GET_UINT32(iter, retvar) \
+ retvar = dbus_message_iter_get_uint32((iter))
+ #define DBUS_MSG_APPEND_ITER_INIT(a, b) \
+ dbus_message_append_iter_init(a, b)
+
+#endif
+
+
+typedef int8_t register_function_t(DBusConnection*);
+typedef int8_t unregister_function_t(DBusConnection*);
+typedef DBusMessage* (service_handler_func_t)(DBusMessage *, void *);
+typedef uint8_t (*watch_handler_func_t) (int32_t fd, uint32_t flags, void *udata);
+typedef void (*watch_handler_func_free_udata_t) (void *udata);
+typedef void (*timer_handler_func_t) (uint32_t period);
+
+
+typedef struct
+{
+ const char *name;
+ service_handler_func_t *handler_func;
+ const char *signature; /* TODO */
+}__attribute__((packed))service_table_t;
+
+/* File descriptors monitors */
+int32_t bluetoothd_monitor_add (int32_t fd, uint32_t flags, watch_handler_func_t func, \
+ watch_handler_func_free_udata_t free_udata_func, void *udata);
+uint8_t bluetoothd_monitor_remove(int32_t fd);
+int8_t bluetoothd_msg_send(DBusMessage *msg);
+
+/* Profiles register and unregister functions */
+int8_t hci_dbus_register(DBusConnection* conn);
+int8_t hci_dbus_unregister(DBusConnection* conn);
+
+int8_t hciconfig_dbus_register(DBusConnection* conn);
+int8_t hciconfig_dbus_unregister(DBusConnection* conn);
+
+int8_t pan_dbus_register(DBusConnection* conn);
+int8_t pan_dbus_unregister(DBusConnection* conn);
+
+int8_t sdp_dbus_register(DBusConnection* conn);
+int8_t sdp_dbus_unregister(DBusConnection* conn);
+
+
+/* Common functions */
+void common_list_services (DBusMessage *msg, service_table_t *ptr);
+
+int8_t set_ip(const char* interface, const char * address);
+int8_t enable_interface(const char *ifname);
+int8_t disable_interface(const char *ifname);
+
+
+#endif /* __H_BLUETOOTHD_INTERNAL_H__ */
--- bluez-utils-2.18.orig/daemon/btnet.c 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/btnet.c 2005-07-26 11:42:08.066259192 -0300
@@ -0,0 +1,152 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2005 Claudio Takahasi <claudio.takahasi@indt.org>
+ * Copyright (C) 2002-2004 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * 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: btnet.c,v 1.12 2005/05/22 13:00:00 holtmann Exp $
+ */
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <syslog.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <net/if_arp.h>
+
+
+
+static char *safe_strncpy(char *dst, const char *src, size_t size)
+{
+ dst[size-1] = '\0';
+ return strncpy(dst,src,size-1);
+}
+
+int8_t set_ip(const char* interface, const char * address)
+{
+
+ int sock=0;
+ struct sockaddr_in *sin = NULL;
+ struct ifreq ifr;
+
+
+ sock = socket( PF_INET, SOCK_DGRAM, 0 );
+
+ if( sock == -1 ) {
+ syslog(LOG_ERR, "Cannot obtain socket :%s(%d)", strerror(errno), errno);
+ return (-1);
+ }
+
+ memset( &ifr, 0, sizeof( struct ifreq ) );
+ sin = (struct sockaddr_in *)&(ifr.ifr_addr);
+ sin->sin_family=AF_INET;
+ sin->sin_addr.s_addr=inet_addr(address);
+ safe_strncpy( ifr.ifr_name,interface,IFNAMSIZ);
+
+ if( ioctl( sock, SIOCSIFADDR, &ifr ) != 0 ) {
+ syslog(LOG_ERR, "Cannot set IP address of interface '%s' to '%s':%s\n", interface, address,strerror(errno));
+ close(sock);
+ return (-1);
+ } else {
+ syslog(LOG_ERR,"IP address of '%s' set to '%s'\n",interface,address);
+ }
+ close(sock);
+ return(0);
+}
+
+
+
+int8_t enable_interface(const char *ifname)
+{
+ int sock;
+ const short int flag = IFF_UP | IFF_RUNNING;
+ struct ifreq ifr;
+
+ sock = socket( PF_INET, SOCK_DGRAM, 0 );
+
+ if( sock == -1 ) {
+ syslog(LOG_ERR, "Cannot obtain socket :%s(%d)", strerror(errno), errno);
+ return (-1);
+ }
+
+ safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
+ syslog(LOG_ERR,"%s: ERROR while getting interface flags: %s\n",
+ ifname, strerror(errno));
+ close(sock);
+ return (-1);
+ }
+
+ safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ ifr.ifr_flags |= flag;
+
+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
+ syslog(LOG_ERR, "%s: ERROR while setting SIOCSIFFLAGS:%s\n", ifname, strerror(errno));
+ close(sock);
+ return -1;
+ }
+ close(sock);
+ return (0);
+}
+
+int8_t disable_interface(const char *ifname)
+{
+ int sock;
+ const short int flag = (IFF_UP | IFF_RUNNING);
+ struct ifreq ifr;
+
+ sock = socket( PF_INET, SOCK_DGRAM, 0 );
+
+ if( sock == -1 ) {
+ syslog(LOG_ERR, "Cannot obtain socket :%s(%d)", strerror(errno), errno);
+ return (-1);
+ }
+
+ safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
+ syslog(LOG_ERR,"%s: ERROR while getting interface flags: %s\n",
+ ifname, strerror(errno));
+ close(sock);
+ return (-1);
+ }
+
+ safe_strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ ifr.ifr_flags &= !flag;
+
+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
+ syslog(LOG_ERR, "%s: ERROR while setting SIOCSIFFLAGS:%s\n", ifname, strerror(errno));
+ close(sock);
+ return -1;
+ }
+ close(sock);
+ return (0);
+}
--- bluez-utils-2.18.orig/daemon/common_dbus.c 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/common_dbus.c 2005-07-26 11:42:08.063259648 -0300
@@ -0,0 +1,47 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "bluetoothd_internal.h"
+
+
+void common_list_services (DBusMessage *msg, service_table_t *ptr) {
+ DBusMessageIter iter;
+ char prototype[256];
+ const char *pprot = prototype;
+
+ DBUS_MSG_APPEND_ITER_INIT(msg, &iter);
+ for (;ptr->name; ptr++) {
+ if(ptr->signature) {
+ sprintf(prototype, "%s(%s)", ptr->name, ptr->signature);
+ } else {
+ sprintf(prototype, "%s()", ptr->name);
+ }
+ DBUS_MSG_ITER_APPEND_STR(&iter, pprot);
+ }
+}
+
+
--- bluez-utils-2.18.orig/daemon/dbus.h 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/dbus.h 2005-07-26 11:42:08.061259952 -0300
@@ -0,0 +1,202 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef __H_BLUETOOTHD_H__
+#define __H_BLUETOOTHD_H__
+
+#include <unistd.h>
+#include <stdint.h>
+
+
+
+#define __END_SIG__ DBUS_TYPE_INVALID_AS_STRING
+#define FEATURE_DISABLED 0
+#define FEATURE_ENABLED 1
+
+
+/* bluetoothd D-Bus services */
+#define BLUETOOTHD_NAME "bluetoothd"
+#define BLUETOOTHD_DBUS_SERVICE "org.bluez."BLUETOOTHD_NAME
+#define BLUETOOTHD_DBUS_IFACE_REQ BLUETOOTHD_DBUS_SERVICE".request"
+#define BLUETOOTHD_DBUS_IFACE_SIGNAL BLUETOOTHD_DBUS_SERVICE".signal"
+#define BLUETOOTHD_DBUS_PATH "/org/bluez/bluetoothd"
+//Provided services
+#define BLUETOOTHD_GET_PAIRED_DEVICES_REQ "GetPairedDevicesReq"
+#define BLUETOOTHD_REMOVE_PAIRED_DEVICE_REQ "RemovePairedDeviceReq"
+#define BLUETOOTHD_LIST_SERVICES_REQ "ListServicesReq"
+#define BLUETOOTHD_ENABLE_PROFILE_REQ "EnableProfileReq"
+#define BLUETOOTHD_DISABLE_PROFILE_REQ "DisableProfileReq"
+#define BLUETOOTHD_EXIT_REQ "ExitReq"
+//Signatures
+#define BLUETOOTHD_ENABLE_PROFILE_REQ_SIGNATURE DBUS_TYPE_STRING_AS_STRING\
+ __END_SIG__
+#define BLUETOOTHD_DISABLE_PROFILE_REQ_SIGNATURE DBUS_TYPE_STRING_AS_STRING\
+ __END_SIG__
+#define BLUETOOTHD_EXIT_REQ_SIGNATURE __END_SIG__
+#define BLUETOOTHD_LIST_SERVICES_REQ_SIGNATURE __END_SIG__
+//Signals
+#define BLUETOOTHD_SIG_EXIT "ExitSig"
+
+
+/* HCI D-Bus services */
+#define HCI_DBUS_IFACE_REQ BLUETOOTHD_DBUS_SERVICE".hci.request"
+#define HCI_DBUS_IFACE_SIGNAL BLUETOOTHD_DBUS_SERVICE".hci.signal"
+#define HCI_DBUS_PATH BLUETOOTHD_DBUS_PATH"/hci"
+//Provided services
+#define HCI_LIST_SERVICES_REQ "ListServicesReq"
+#define HCI_PERIODIC_INQ_REQ "PeriodicInqReq"
+#define HCI_CANCEL_PERIODIC_INQ_REQ "CancelPeriodicInqReq"
+#define HCI_INQ_REQ "InquiryReq"
+#define HCI_SCAN_REQ "ScanReq"
+#define HCI_GET_DEVICES_REQ "GetDevReq"
+//Signatures
+#define HCI_LIST_SERVICES_REQ_SIGNATURE __END_SIG__
+#define HCI_PERIODIC_INQ_REQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\
+ DBUS_TYPE_BYTE_AS_STRING\
+ DBUS_TYPE_BYTE_AS_STRING\
+ DBUS_TYPE_UINT32_AS_STRING\
+ __END_SIG__
+#define HCI_CANCEL_PERIODIC_INQ_REQ_SIGNATURE __END_SIG__
+#define HCI_INQ_REQ_SIGNATURE __END_SIG__
+#define HCI_SCAN_REQ_SIGNATURE __END_SIG__
+#define HCI_GET_DEVICES_REQ_SIGNATURE __END_SIG__
+//Signals
+#define HCI_SIGNAL_NEW_DEVICE "NewDevSig"
+
+
+/* TODO complete missing features */
+
+/* HCI CONFIG D-Bus services */
+#define HCICONFIG_DBUS_IFACE_REQ BLUETOOTHD_DBUS_SERVICE".hciconfig.request"
+#define HCICONFIG_DBUS_IFACE_SIGNAL BLUETOOTHD_DBUS_SERVICE".hciconfig.signal"
+#define HCICONFIG_DBUS_PATH BLUETOOTHD_DBUS_PATH"/hciconfig"
+//Provided services
+#define HCICONFIG_LIST_SERVICES_REQ "ListServicesReq"
+#define HCICONFIG_UP_REQ "UpReq"
+#define HCICONFIG_DOWN_REQ "DownReq"
+#define HCICONFIG_RESET_REQ "ResetReq"
+#define HCICONFIG_ENABLE_PAGE_INQ_SCAN_REQ "PIScanReq"
+#define HCICONFIG_DISABLE_SCAN_REQ "NOScanReq"
+#define HCICONFIG_ENABLE_INQ_SCAN_REQ "IScanReq"
+#define HCICONFIG_ENABLE_PAGE_SCAN_REQ "PScanReq"
+/* TODO complete missing features */
+//Signatures
+#define HCICONFIG_LIST_SERVICES_REQ_SIGNATURE __END_SIG__
+//Signals
+/* pan D-Bus services */
+#define PAN_DBUS_IFACE_REQ BLUETOOTHD_DBUS_SERVICE".pan.request"
+#define PAN_DBUS_IFACE_SIGNAL BLUETOOTHD_DBUS_SERVICE".pan.signal"
+#define PAN_DBUS_PATH BLUETOOTHD_DBUS_PATH"/pan"
+//Provided services
+#define PAN_LIST_SERVICES_REQ "ListServicesReq" /* return the exported D-Bus services */
+#define PAN_CONN_REQ "ConnectReq"
+#define PAN_DISCONN_REQ "DisconnectReq"
+#define PAN_LISTEN_REQ "ListenReq"
+#define PAN_SHOW_REQ "ShowReq" /* Show active connections */
+#define PAN_IFCONFIG_REQ "IfconfigReq" /* Used for set IP, netmask, bcast */
+/* TODO complete missing features */
+//Signatures
+#define PAN_LIST_SERVICES_REQ_SIGNATURE __END_SIG__
+#define PAN_CONN_REQ_SIGNATURE DBUS_TYPE_UINT16_AS_STRING\
+ DBUS_TYPE_UINT16_AS_STRING\
+ DBUS_TYPE_BYTE_AS_STRING\
+ DBUS_TYPE_BYTE_AS_STRING\
+ DBUS_TYPE_STRING_AS_STRING\
+ __END_SIG__
+#define PAN_SHOW_CONN __END_SIG__
+
+
+//default value for PAN profile
+#define PAN_DFT_LOCAL_ROLE BNEP_SVC_PANU
+#define PAN_DFT_REMOTE_SERVICE BNEP_SVC_NAP
+#define PAN_DFT_UDHCP_STATUS FEATURE_DISABLED
+#define PAN_DFT_BRIDGE_STATUS FEATURE_DISABLED
+
+
+
+//Signals
+
+/* DUN D-Bus services */
+#define DUN_DBUS_IFACE_REQ DUN_DBUS_SERVICE".dun.request"
+#define DUN_DBUS_IFACE_SIGNAL DUN_DBUS_SERVICE".dun.signal"
+#define DUN_DBUS_PATH DUN_DBUS_OBJ_PATH"/dun"
+//Provided services
+#define DUN_LIST_SERVICES_REQ "ListServicesReq" /* return the exported D-Bus services */
+#define DUN_CONN_REQ "ConnectReq"
+#define DUN_DISCONN_REQ "DisconnectReq"
+#define DUN_LISTEN_REQ "ListenReq"
+#define DUN_SHOW_REQ "ShowReq" /* Show active connections */
+/* TODO complete missing features */
+//Signatures
+#define DUN_LIST_SERVICES_REQ_SIGNATURE __END_SIG__
+//Signals
+
+/* sdp D-Bus services */
+#define SDP_DBUS_IFACE_REQ BLUETOOTHD_DBUS_SERVICE".sdp.request"
+#define SDP_DBUS_IFACE_SIGNAL BLUETOOTHD_DBUS_SERVICE".sdp.signal"
+#define SDP_DBUS_PATH BLUETOOTHD_DBUS_PATH"/sdp"
+//Provided services
+#define SDP_LIST_SERVICES_REQ "ListServicesReq" /* return the exported D-Bus services */
+#define SDP_SEARCH_REQ "SearchReq"
+#define SDP_BROWSE_REQ "BrowseReq"
+/* TODO complete missing features */
+//Signatures
+#define SDP_LIST_SERVICES_REQ_SIGNATURE __END_SIG__
+#define SDP_SEARCH_REQ_SIGNATURE DBUS_TYPE_UINT32_AS_STRING\
+ __END_SIG__
+
+//Signals
+
+
+/* constants used to call periodic inquiry service */
+#define DFT_INQUIRY_LENGTH (4)
+#define DFT_MAX_INQUIRY_PERIOD (49)
+#define DFT_MIN_INQUIRY_PERIOD (27)
+#define DFT_DEVICE_CLASS (0x003e0100) /*All devices*/
+
+
+typedef struct {
+ uint8_t num_rsp;
+ uint8_t inq_len;
+ uint8_t max_period;
+ uint8_t min_period;
+ uint16_t dev_class;
+ uint32_t iac_type;
+}__attribute__((packed))btd_periodic_inq_req_t;
+
+typedef enum
+{
+ BTD_SUCCESS = 0,
+ BTD_FAILED,
+ BTD_WRONG_PARAM,
+ BTD_BUSY
+}__attribute__((packed)) BTD_RESULT;
+
+typedef struct
+{
+ BTD_RESULT result;
+ void *data;
+}btd_req_cnf_t;
+
+
+
+#endif /* __H_BLUETOOTHD_H__ */
--- bluez-utils-2.18.orig/daemon/hciconfig_dbus.c 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/hciconfig_dbus.c 2005-07-26 11:42:08.064259496 -0300
@@ -0,0 +1,155 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#include "bluetoothd_internal.h"
+
+
+
+
+
+ /*****************************************************************
+ *
+ * Section reserved to D-BUS prototypes
+ *
+ *****************************************************************/
+ static DBusHandlerResult hciconfig_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data);
+
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data);
+
+static service_table_t hciconfig_services[] = {
+{HCICONFIG_LIST_SERVICES_REQ, handle_list_services_req , HCICONFIG_LIST_SERVICES_REQ_SIGNATURE},
+{NULL, NULL, NULL}
+};
+
+
+/*****************************************************************
+ *
+ * Section reserved to local variables
+ *
+ *****************************************************************/
+
+
+static DBusConnection *bus_conn;
+/**
+ * Virtual table that implements the handlers
+ * of the object path hierarchy
+ **/
+static DBusObjectPathVTable hciconfig_vtable = {
+ NULL,
+ &hciconfig_msg_func,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+/*****************************************************************
+ *
+ * Section reserved to hciconfig public functions
+ *
+ *****************************************************************/
+
+int8_t hciconfig_dbus_register(DBusConnection* conn)
+{
+ int8_t ret = 0;
+
+ if(!dbus_connection_register_fallback (conn, HCICONFIG_DBUS_PATH, &hciconfig_vtable, NULL)) {
+ syslog(LOG_ERR,"DBUS failed to register %s object", PAN_DBUS_PATH);
+ }
+ // TODO add filter
+ return ret;
+}
+
+
+int8_t hciconfig_dbus_unregister(DBusConnection* conn)
+{
+ int8_t ret = 0;
+
+ if(!dbus_connection_unregister_object_path(conn, PAN_DBUS_PATH)) {
+ syslog(LOG_ERR,"DBUS failed to unregister %s object", PAN_DBUS_PATH);
+ }
+ // TODO remove filters
+
+ return ret;
+}
+
+/*****************************************************************
+ *
+ * Section reserved to D-Bus message handlers
+ *
+ *****************************************************************/
+
+static DBusHandlerResult hciconfig_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ service_table_t *ptr_handlers = hciconfig_services;
+ DBusMessage *reply = NULL;
+ DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ uint16_t type;
+ const char *iface;
+ const char *method;
+
+ syslog(LOG_INFO, "%s - line:%d",__PRETTY_FUNCTION__, __LINE__ );
+
+ type = dbus_message_get_type(msg);
+ iface = dbus_message_get_interface(msg);
+ method = dbus_message_get_member (msg);
+
+ if((type == DBUS_MESSAGE_TYPE_METHOD_CALL) &&
+ (strcmp(iface, HCICONFIG_DBUS_IFACE_REQ) == 0) &&
+ (method != NULL)){
+ for (;ptr_handlers->name; ptr_handlers++) {
+ if (strcmp(method, ptr_handlers->name) == 0) {
+ if (strcmp(ptr_handlers->signature,dbus_message_get_signature(msg)) == 0) {
+ reply = (ptr_handlers->handler_func)(msg, data);
+ if (reply) {
+ if (!dbus_connection_send (conn, reply, NULL)) {
+ syslog(LOG_ERR, "%s line:%d Can't send reply message!",
+ __PRETTY_FUNCTION__, __LINE__) ;
+ }
+ dbus_message_unref (reply);
+ }
+ ret = DBUS_HANDLER_RESULT_HANDLED;
+ break;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ syslog(LOG_INFO, "%s - line:%d",__PRETTY_FUNCTION__, __LINE__ );
+
+ reply = dbus_message_new_method_return(msg);
+
+ common_list_services(reply, hciconfig_services);
+
+ return reply;
+}
+
--- bluez-utils-2.18.orig/daemon/hci_dbus.c 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/hci_dbus.c 2005-07-26 11:42:08.061259952 -0300
@@ -0,0 +1,575 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#include "bluetoothd_internal.h"
+#include <signal.h>
+#include <sys/time.h>
+
+/* hci0 */
+#define DEV_NUMBER 0
+#define INQUIRY_LENGTH 4 /* 5.12s */
+#define MAX_PERIOD 49 /* 62.72s */
+#define MIN_PERIOD 27 /* 34.56s */
+
+
+#define INQUIRY_WITH_RSSI 0x01
+#define INTERLACED_SCAN 0x01
+
+
+
+
+/*****************************************************************
+ *
+ * Section reserved to local prototypes
+ *
+ *****************************************************************/
+static int32_t create_event_socket();
+static int8_t inquiry_parse_result(uint8_t *body, void *udata);
+static void inquiry_cache_cleanup();
+static void inquiry_cache_add(inquiry_info *dev);
+static void inquiry_cache_ttl_update();
+
+static uint8_t hci_fd_handler(int32_t fd, uint32_t flags, void *udata);
+
+static DBusHandlerResult hci_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data);
+
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_inq_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_scan_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data);
+
+
+
+/*****************************************************************
+ *
+ * Section reserved to local variables
+ *
+ *****************************************************************/
+
+static int8_t inq_in_progress = 0;
+static int8_t per_inq_in_progress = 0;
+static int32_t hci_sock = 0;
+static DBusConnection *bus_conn;
+
+
+
+/**
+ * Virtual table that implements the handlers
+ * of the object path hierarchy
+ **/
+static DBusObjectPathVTable hci_vtable = {
+ NULL,
+ &hci_msg_func,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static service_table_t hci_services[] = {
+{HCI_LIST_SERVICES_REQ, handle_list_services_req, HCI_LIST_SERVICES_REQ_SIGNATURE },
+{HCI_PERIODIC_INQ_REQ, handle_periodic_inq_req, HCI_PERIODIC_INQ_REQ_SIGNATURE},
+{HCI_CANCEL_PERIODIC_INQ_REQ, handle_cancel_periodic_inq_req, HCI_CANCEL_PERIODIC_INQ_REQ_SIGNATURE},
+//{HCI_GET_DEVICES_REQ, handle_get_devices_req, HCI_GET_DEVICES_REQ_SIGNATURE},
+
+//{HCI_INQ_REQ, handle_inq_req, HCI_INQ_REQ_SIGNATURE},
+//{HCI_SCAN_REQ, handle_scan_req, HCI_SCAN_REQ_SIGNATURE},
+{NULL, NULL, NULL}
+};
+
+
+
+/*****************************************************************
+ *
+ * Section reserved to bluetoothd public functions
+ *
+ *****************************************************************/
+
+int8_t hci_dbus_register(DBusConnection* conn)
+{
+ int8_t ret = 0;
+
+ bus_conn = conn;
+
+ if(!dbus_connection_register_fallback (conn, HCI_DBUS_PATH, &hci_vtable, NULL)) {
+ syslog(LOG_ERR,"DBUS failed to register %s object", HCI_DBUS_PATH);
+ }
+ // TODO add filter
+
+ return ret;
+}
+
+
+int8_t hci_dbus_unregister(DBusConnection* conn)
+{
+ int8_t ret = 0;
+
+ if(!dbus_connection_unregister_object_path(conn, HCI_DBUS_PATH)) {
+ syslog(LOG_ERR,"DBUS failed to unregister %s object", HCI_DBUS_PATH);
+ }
+ // TODO remove filters
+
+ return ret;
+}
+
+
+/*****************************************************************
+ *
+ * Section reserved to D-Bus message handlers
+ *
+ *****************************************************************/
+
+static DBusHandlerResult hci_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ service_table_t *ptr_handlers = hci_services;
+ DBusMessage *reply = NULL;
+ DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ uint16_t type;
+ const char *iface;
+ const char *method;
+
+ type = dbus_message_get_type(msg);
+ iface = dbus_message_get_interface(msg);
+ method = dbus_message_get_member (msg);
+
+ if((type == DBUS_MESSAGE_TYPE_METHOD_CALL) &&
+ (strcmp(iface, HCI_DBUS_IFACE_REQ) == 0) &&
+ (method != NULL)){
+ for (;ptr_handlers->name; ptr_handlers++) {
+ if (strcmp(method, ptr_handlers->name) == 0) {
+ if (strcmp(ptr_handlers->signature,dbus_message_get_signature(msg)) == 0) {
+ reply = (ptr_handlers->handler_func)(msg, data);
+ if (reply) {
+ if (!dbus_connection_send (conn, reply, NULL)) {
+ syslog(LOG_ERR, "%s line:%d Can't send reply message!",
+ __PRETTY_FUNCTION__, __LINE__) ;
+ }
+ dbus_message_unref (reply);
+ }
+ ret = DBUS_HANDLER_RESULT_HANDLED;
+ break;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+
+ reply = dbus_message_new_method_return(msg);
+
+ common_list_services(reply, hci_services);
+
+ return reply;
+}
+
+
+static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data)
+{
+
+ write_inquiry_mode_cp inq_mode;
+ periodic_inquiry_cp inq_param;
+ DBusMessageIter iter;
+ DBusMessage *reply = NULL;
+ int32_t flags = POLLIN | POLLERR | POLLHUP | POLLNVAL;
+ BTD_RESULT cnf = BTD_SUCCESS;
+ uint8_t length;
+ uint8_t max_period;
+ uint8_t min_period;
+ uint32_t devclass;
+ uint32_t *user_data;
+
+ if(per_inq_in_progress) {
+ syslog(LOG_ERR, "Device is busy.");
+ cnf = BTD_BUSY;
+ goto cleanup;
+ }
+
+ hci_sock = create_event_socket();
+ if(hci_sock < 0) {
+ syslog(LOG_ERR, "Can't create HCI sock.");
+ cnf = BTD_FAILED;
+ goto cleanup;
+ }
+
+ inq_mode.mode = INQUIRY_WITH_RSSI;
+
+ if(hci_send_cmd(hci_sock, OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE, \
+ WRITE_INQUIRY_MODE_CP_SIZE, &inq_mode) < 0) {
+ //TODO inquiry with rssi is not working
+ syslog(LOG_ERR, "Can't set inquiry mode:%s.", strerror(errno));
+ cnf = BTD_FAILED;
+ goto cleanup;
+ }
+
+ user_data = (uint32_t*)malloc(sizeof(uint32_t));
+
+ dbus_message_iter_init(msg, &iter);
+ DBUS_MSG_ITER_GET_BYTE(&iter, length);
+ dbus_message_iter_next(&iter);
+ DBUS_MSG_ITER_GET_BYTE(&iter, max_period);
+ dbus_message_iter_next(&iter);
+ DBUS_MSG_ITER_GET_BYTE(&iter, min_period);
+ dbus_message_iter_next(&iter);
+ DBUS_MSG_ITER_GET_UINT32(&iter, devclass);
+
+ user_data = (uint32_t*)malloc(sizeof(uint32_t));
+ *user_data = devclass;
+
+ inq_param.num_rsp = 100;
+ inq_param.length = length;
+
+ inq_param.max_period = max_period;
+ inq_param.min_period = min_period;
+
+ /* General/Unlimited Inquiry Access Code (GIAC) */
+ inq_param.lap[0] = 0x33;
+ inq_param.lap[1] = 0x8b;
+ inq_param.lap[2] = 0x9e;
+
+ if(hci_send_cmd(hci_sock, OGF_LINK_CTL, OCF_PERIODIC_INQUIRY, \
+ PERIODIC_INQUIRY_CP_SIZE, &inq_param) < 0){
+ syslog(LOG_ERR, "Can't send HCI commands:%s.", strerror(errno));
+ cnf = BTD_FAILED;
+ goto cleanup;
+ }
+ inq_in_progress = 1;
+ per_inq_in_progress = 1;
+ bluetoothd_monitor_add(hci_sock, flags, hci_fd_handler, NULL, user_data);
+ inquiry_cache_cleanup();
+cleanup:
+ reply = dbus_message_new_method_return(msg);
+ DBUS_MSG_APPEND_ITER_INIT(reply, &iter);
+ DBUS_MSG_ITER_APPEND_BYTE(&iter, cnf);
+
+ return reply;
+}
+static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data)
+{
+ DBusMessageIter iter;
+ DBusMessage *reply = NULL;
+ BTD_RESULT cnf = BTD_SUCCESS;
+
+ if (!per_inq_in_progress) {
+ syslog(LOG_ERR, "Inquiry is not running.");
+ cnf = BTD_FAILED;
+ goto cleanup;
+ }
+
+ if(hci_send_cmd(hci_sock, OGF_LINK_CTL, OCF_INQUIRY_CANCEL, 0 , NULL) < 0) {
+ syslog(LOG_ERR, "Send hci command failed.");
+ cnf = BTD_FAILED;
+ goto cleanup;
+ }
+ per_inq_in_progress = 0;
+ bluetoothd_monitor_remove(hci_sock);
+ close(hci_sock);
+cleanup:
+ reply = dbus_message_new_method_return(msg);
+ DBUS_MSG_APPEND_ITER_INIT(reply, &iter);
+ DBUS_MSG_ITER_APPEND_BYTE(&iter, cnf);
+
+ return reply;
+}
+
+static DBusMessage* handle_inq_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ syslog(LOG_INFO, "%s - line:%d - not implemented",__PRETTY_FUNCTION__, __LINE__ );
+
+ return reply;
+}
+static DBusMessage* handle_scan_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ syslog(LOG_INFO, "%s - line:%d - not implemented",__PRETTY_FUNCTION__, __LINE__ );
+
+ return reply;
+}
+static DBusMessage* handle_get_devices_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ syslog(LOG_INFO, "%s - line:%d - not implemented",__PRETTY_FUNCTION__, __LINE__ );
+
+ return reply;
+}
+
+/*****************************************************************
+ *
+ * Section reserved to local functions
+ *
+ *****************************************************************/
+static int32_t create_event_socket() {
+ struct hci_filter filter;
+ struct sockaddr_hci addr;
+ int32_t sock = -1;
+ int8_t i;
+ int8_t hci_events[] = { EVT_INQUIRY_RESULT, \
+ EVT_INQUIRY_RESULT_WITH_RSSI, \
+ EVT_INQUIRY_COMPLETE, \
+ EVT_CMD_STATUS, \
+ EVT_REMOTE_NAME_REQ_COMPLETE, \
+ 0 };
+
+ /* Create HCI socket */
+ sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+ if (sock < 0) {
+ syslog(LOG_ERR, "Can't create HCI socket(%s).", strerror(errno));
+ return sock;
+ }
+
+ /* Setup filter */
+ hci_filter_clear(&filter);
+ hci_filter_set_ptype(HCI_EVENT_PKT, &filter);
+ for (i = 0; hci_events[i] != 0; i++)
+ hci_filter_set_event(hci_events[i], &filter);
+ if (setsockopt(sock, SOL_HCI, HCI_FILTER, &filter, sizeof(filter)) < 0) {
+ syslog(LOG_ERR, "Can't set HCI filter: %s", strerror(errno));
+ }
+
+ /* Bind socket to the HCI device */
+ addr.hci_family = AF_BLUETOOTH;
+ addr.hci_dev = DEV_NUMBER;
+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ syslog(LOG_ERR, "Can't attach to device hci%d. %s(%d)",
+ DEV_NUMBER, strerror(errno), errno);
+ }
+
+ return sock;
+}
+/*****************************************************************
+ *
+ * Section reserved to signal functions
+ *
+ *****************************************************************/
+
+int8_t send_new_device_signal(inquiry_info *dev)
+{
+ DBusMessageIter iter;
+ DBusMessage *signal = NULL;
+ int8_t ret = -1;
+ uint32_t devclass = 0;
+ char bdaddr[18];
+ const char *pbdaddr = bdaddr;
+
+ syslog(LOG_INFO, "%s - line:%d",__PRETTY_FUNCTION__, __LINE__ );
+
+
+ signal = dbus_message_new_signal
+ ((const char*)HCI_DBUS_PATH,
+ (const char*)HCI_DBUS_IFACE_SIGNAL,
+ (const char*)HCI_SIGNAL_NEW_DEVICE);
+
+ devclass = ((dev->dev_class[2])<< 16) | ((dev->dev_class[1]) << 8) | dev->dev_class[0];
+ ba2str(&(dev->bdaddr), bdaddr);
+
+ DBUS_MSG_APPEND_ITER_INIT(signal, &iter);
+ DBUS_MSG_ITER_APPEND_STR(&iter, pbdaddr);
+ DBUS_MSG_ITER_APPEND_UINT32(&iter, devclass);
+ ret = bluetoothd_msg_send(signal);
+ return ret;
+}
+/*****************************************************************
+ *
+ * Section reserved to device cache
+ *
+ *****************************************************************/
+
+typedef struct {
+ uint8_t ttl; /* time to live counter */
+ uint8_t hits; /* counter used to notify new devices */
+ uint8_t status; /* 0-free, 1-allocated*/
+ inquiry_info dev;
+}__attribute__ ((packed))inq_device_info_t;
+
+static inq_device_info_t cache[INQUIRY_CACHE_SIZE];
+
+static void inquiry_cache_cleanup() {
+ memset(cache, 0, sizeof(inq_device_info_t) * INQUIRY_CACHE_SIZE);
+}
+
+static void inquiry_cache_add(inquiry_info *dev)
+{
+ int8_t i;
+ int8_t first_free = 0;
+ int8_t dev_found = -1;
+ inq_device_info_t *node;
+ char address[18];
+
+ syslog(LOG_INFO, "%s - line:%d",__PRETTY_FUNCTION__, __LINE__ );
+
+ ba2str(&(dev->bdaddr), address);
+
+ for( i = (INQUIRY_CACHE_SIZE-1); i >= 0; i-- ) {
+ node = &cache[i];
+ if(node->status == 0) {
+ if(!first_free)
+ first_free = i;
+ } else if(memcmp(&(node->dev.bdaddr), &(dev->bdaddr), 6) == 0) {
+ dev_found = i;
+ node->hits++;
+ node->ttl = MAX_TTL_INQUIRY;
+ syslog(LOG_INFO, "Updating %s ttl: %d", address, MAX_TTL_INQUIRY);
+ break;
+ }
+ }
+
+ if(dev_found == -1) {
+ /* Add a new element */
+ node = &cache[first_free];
+ node->ttl = MAX_TTL_INQUIRY;
+ node->status = 1;
+ memcpy(&(node->dev), dev, sizeof(inquiry_info));
+ syslog(LOG_INFO, "New Device: %s ttl: %d", address, MAX_TTL_INQUIRY);
+ send_new_device_signal(dev);
+ }
+}
+
+static void inquiry_cache_ttl_update() {
+ int8_t i;
+ char address[18];
+
+ syslog(LOG_INFO, "%s - line:%d",__PRETTY_FUNCTION__, __LINE__ );
+
+ for( i = (INQUIRY_CACHE_SIZE-1); i >= 0; i-- ) {
+ if(cache[i].status && cache[i].ttl) {
+ ba2str(&(cache[i].dev.bdaddr), address);
+ if(--(cache[i].ttl) == 0) {
+ //remove from cache
+ cache[i].status = 0;
+ syslog(LOG_INFO, "Removing %s ttl: 0", address);
+ } else {
+ syslog(LOG_INFO, "Updating %s ttl: %d ", address, cache[i].ttl);
+ }
+ }
+ }
+}
+
+
+static int8_t inquiry_parse_result(uint8_t *body, void *udata)
+{
+ int8_t ret = 0;
+ int8_t i;
+ //uint32_t *devclass =(uint32_t*)udata;
+ uint32_t devclass_filter;
+ uint8_t num_resp = body[0];
+ uint8_t *ptr = &(body[1]);
+ char bdaddr[18];
+
+ for (i = 0; i < (int)num_resp; i++) {
+ inquiry_info *info = (inquiry_info*)ptr;
+ devclass_filter = ((info->dev_class[2])<< 16) | ((info->dev_class[1]) << 8) | info->dev_class[0];
+ ba2str(&(info->bdaddr), bdaddr);
+ inquiry_cache_add(info);
+#if 0
+ device class filter
+ if(*devclass == 0) {
+ } else {
+ if(*devclass == devclass_filter) {
+ }
+ }
+#endif
+ ptr += INQUIRY_INFO_SIZE;
+ }
+
+ return ret;
+}
+
+
+/*****************************************************************
+ *
+ * Section reserved to local functions definition
+ *
+ *****************************************************************/
+static uint8_t hci_fd_handler(int32_t fd, uint32_t flags, void *udata) {
+ uint8_t *buffer = NULL;
+ hci_event_hdr *header = NULL;
+ uint8_t *body = NULL;
+
+ int16_t read_bytes;
+
+ if (flags != POLLIN){
+ syslog(LOG_ERR, "HCI sock error.");
+ goto cleanup;
+ }
+
+ buffer = (uint8_t*)malloc(HCI_MAX_FRAME_SIZE);
+
+ if(!buffer) {
+ syslog(LOG_ERR, "Memory allocation failure");
+ goto cleanup;
+ }
+ read_bytes = read(fd, buffer, HCI_MAX_FRAME_SIZE);
+
+ if(read_bytes < 0) {
+ syslog(LOG_ERR, "Read HCI sock error.");
+ goto cleanup;
+ }
+ if(buffer[0] == HCI_EVENT_PKT) {
+ header = (hci_event_hdr *)&buffer[1];
+ body = &buffer[HCI_EVENT_HDR_SIZE + 1];
+ switch(header->evt) {
+ case EVT_INQUIRY_RESULT:
+ inquiry_parse_result(body, udata);
+ break;
+ case EVT_INQUIRY_RESULT_WITH_RSSI:
+ //TODO Why rssi is not working???
+ break;
+ case EVT_INQUIRY_COMPLETE:
+ inq_in_progress = 0;
+ if(per_inq_in_progress) {
+ /*
+ * Update the tll for each record after
+ * each inquiry comlete event.
+ */
+ inquiry_cache_ttl_update();
+ }
+ free(udata);
+ break;
+ case EVT_REMOTE_NAME_REQ_COMPLETE:
+ break;
+ case EVT_CMD_STATUS:
+ break;
+ default:
+ syslog(LOG_ERR, "Received invalid packet type.");
+ }
+ }
+cleanup:
+ if(buffer) {
+ free (buffer);
+ }
+ return TRUE;
+}
+
+
+
+
+
--- bluez-utils-2.18.orig/daemon/main.c 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/main.c 2005-07-26 11:42:08.062259800 -0300
@@ -0,0 +1,138 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <getopt.h>
+
+#include <sys/socket.h>
+#include <sys/syslog.h>
+#include <sys/types.h>
+
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+
+#include <dbus/dbus.h>
+
+#include "bluetoothd_dbus.h"
+
+
+static struct option main_lopts[] = {
+{ "help", 0, 0, 'h' },
+{ "nodetach", 0, 0, 'n' },
+{ "disable", 1, 0, 'd' },
+{ 0, 0, 0, 0 }
+};
+
+static char main_sopts[] = "hnd:";
+
+static char main_help[] =
+ "Bluetooth D-Bus daemon version " VERSION " \n"
+ "Usage:\n"
+ "\tbluetoothd <options>\n"
+ "Options:\n"
+ "\t--nodetach -n Do not become a daemon\n"
+ "\t--disable -d <profile> Disable a profile\n"
+ "\n\nProfile:\n"
+ "\tPAN DUN HID ...\n";
+
+
+void sig_hup(int sig)
+{
+ return;
+}
+
+void sig_term(int sig)
+{
+ bluetoothd_exit();
+}
+
+int main(int argc, char *argv[])
+{
+ struct sigaction sa;
+ int8_t detach = 1;
+ int8_t opt;
+
+ while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) {
+ switch(opt) {
+ case 'n':
+ detach = 0;
+ break;
+ case 'd':
+ bluetoothd_disable_profile(optarg);
+ break;
+ case 'h':
+ default:
+ printf(main_help);
+ exit(0);
+ }
+ }
+
+ /* Initialize signals */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_flags = SA_NOCLDSTOP;
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGPIPE, &sa, NULL);
+
+ sa.sa_handler = sig_hup;
+ sigaction(SIGHUP, &sa, NULL);
+
+ sa.sa_handler = sig_term;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+
+ if (detach) {
+ if (fork()) exit(0);
+
+ /* Direct stdin,stdout,stderr to '/dev/null' */
+ {
+ int fd = open("/dev/null", O_RDWR);
+ dup2(fd, 0); dup2(fd, 1); dup2(fd, 2);
+ close(fd);
+ }
+
+ setsid();
+ chdir("/");
+ }
+
+ openlog("bluetoothd", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
+ syslog(LOG_INFO, "Bluetooth D-Bus daemon version %s", VERSION);
+
+ bluetoothd_init();
+
+
+ return 0;
+}
--- bluez-utils-2.18.orig/daemon/Makefile.am 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/Makefile.am 2005-07-26 11:42:08.064259496 -0300
@@ -0,0 +1,17 @@
+#
+# $Id: Makefile.am,v 1.2 2005/07/04 17:29:17 holtmann Exp $
+#
+
+if DBUS
+sbin_PROGRAMS = bluetoothd
+
+bluetoothd_SOURCES = main.c common_dbus.c bluetoothd_dbus.c hci_dbus.c hciconfig_dbus.c pan_dbus.c sdp_dbus.c btnet.c ../pand/bnep.c
+
+bluetoothd_LDADD = @DBUS_LIBS@ @BLUEZ_LIBS@ $(top_builddir)/common/libtextfile.a
+endif
+
+AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@
+
+INCLUDES = -I$(top_srcdir)/common
+
+MAINTAINERCLEANFILES = Makefile.in
--- bluez-utils-2.18.orig/daemon/pan_dbus.c 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/pan_dbus.c 2005-07-26 11:42:08.066259192 -0300
@@ -0,0 +1,369 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#include "bluetoothd_internal.h"
+#include "../pand/pand.h"
+
+#define IFACE_NAME_LENGTH (8)
+//TODO unify with pand.h
+#define PAND_CONFIG_DIR "/etc/bluetooth/pan"
+#define PAND_RUN_UDHCP_CMD "run-udhcp"
+
+
+/*****************************************************************
+ *
+ * Section reserved to local prototypes
+ *
+ *****************************************************************/
+
+
+static int8_t pan_connect(uint16_t role, uint16_t service, uint8_t udhcp, uint8_t bridge, const char* host, char **iface);
+
+static DBusHandlerResult pan_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data);
+
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_conn_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_disconn_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_show_req(DBusMessage *msg, void *data);
+
+/*****************************************************************
+ *
+ * Section reserved to local variables
+ *
+ *****************************************************************/
+
+/**
+ * Virtual table that implements the handlers
+ * of the object path hierarchy
+ **/
+static DBusObjectPathVTable pan_vtable = {
+ NULL,
+ &pan_msg_func,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+
+static service_table_t pan_services[] = {
+{PAN_LIST_SERVICES_REQ, handle_list_services_req, PAN_LIST_SERVICES_REQ_SIGNATURE},
+{PAN_CONN_REQ, handle_conn_req, PAN_CONN_REQ_SIGNATURE },
+{PAN_DISCONN_REQ, handle_disconn_req, PAN_CONN_REQ_SIGNATURE },
+{PAN_SHOW_REQ, handle_show_req, PAN_SHOW_CONN },
+{NULL, NULL, NULL}
+};
+
+static DBusConnection *bus_conn;
+static char netdev[8] = "bnep%d";
+
+
+/*****************************************************************
+ *
+ * Section reserved to bluetoothd public functions
+ *
+ *****************************************************************/
+int8_t pan_dbus_register(DBusConnection* conn)
+{
+ int8_t ret = 0;
+
+ bus_conn = conn;
+
+ if(!dbus_connection_register_fallback (conn, PAN_DBUS_PATH, &pan_vtable, NULL)) {
+ syslog(LOG_ERR,"DBUS failed to register %s object", PAN_DBUS_PATH);
+ }
+ // TODO add filter
+
+ if(bnep_init()) {
+ syslog(LOG_ERR,"Can't initialize bnep");
+ ret = -1;
+ goto cleanup;
+ }
+
+cleanup:
+ return ret;
+}
+
+
+int8_t pan_dbus_unregister(DBusConnection* conn)
+{
+ int8_t ret = 0;
+
+ if(!dbus_connection_unregister_object_path(conn, PAN_DBUS_PATH)) {
+ syslog(LOG_ERR,"DBUS failed to unregister %s object", PAN_DBUS_PATH);
+ }
+ // TODO remove filters
+
+ return ret;
+}
+
+
+/*****************************************************************
+ *
+ * Section reserved to D-Bus message handlers
+ *
+ *****************************************************************/
+static DBusHandlerResult pan_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ service_table_t *ptr_handlers = pan_services;
+ DBusMessage *reply = NULL;
+ DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ uint16_t type;
+ const char *iface;
+ const char *method;
+
+ type = dbus_message_get_type(msg);
+ iface = dbus_message_get_interface(msg);
+ method = dbus_message_get_member (msg);
+
+ if((type == DBUS_MESSAGE_TYPE_METHOD_CALL) &&
+ (strcmp(iface, PAN_DBUS_IFACE_REQ) == 0) &&
+ (method != NULL)){
+ for (;ptr_handlers->name; ptr_handlers++) {
+ if (strcmp(method, ptr_handlers->name) == 0) {
+ if (strcmp(ptr_handlers->signature,dbus_message_get_signature(msg)) == 0) {
+ reply = (ptr_handlers->handler_func)(msg, data);
+ if (reply) {
+ if (!dbus_connection_send (conn, reply, NULL)) {
+ syslog(LOG_ERR, "%s line:%d Can't send reply message!",
+ __PRETTY_FUNCTION__, __LINE__) ;
+ }
+ dbus_message_unref (reply);
+ }
+ ret = DBUS_HANDLER_RESULT_HANDLED;
+ break;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+
+ reply = dbus_message_new_method_return(msg);
+
+ common_list_services(reply, pan_services);
+
+ return reply;
+}
+
+
+
+static DBusMessage* handle_conn_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ DBusMessageIter iter;
+ BTD_RESULT cnf;
+ uint16_t role;
+ uint16_t service;
+ uint8_t udhcp;
+ uint8_t bridge;
+ char *host = NULL;
+
+ char *iface = NULL;
+
+ dbus_message_iter_init(msg, &iter);
+ DBUS_MSG_ITER_GET_UINT16(&iter, role);
+ dbus_message_iter_next(&iter);
+ DBUS_MSG_ITER_GET_UINT16(&iter, service);
+ dbus_message_iter_next(&iter);
+ DBUS_MSG_ITER_GET_BYTE(&iter, udhcp);
+ dbus_message_iter_next(&iter);
+ DBUS_MSG_ITER_GET_BYTE(&iter, bridge);
+ dbus_message_iter_next(&iter);
+ DBUS_MSG_ITER_GET_STR(&iter, host);
+
+ reply = dbus_message_new_method_return(msg);
+
+ if(pan_connect(role, service, udhcp, bridge, host, &iface) < 0)
+ {
+ cnf = BTD_FAILED;
+ DBUS_MSG_APPEND_ITER_INIT(reply, &iter);
+ DBUS_MSG_ITER_APPEND_BYTE(&iter, cnf);
+
+ } else {
+ cnf = BTD_SUCCESS;
+ DBUS_MSG_APPEND_ITER_INIT(reply, &iter);
+ DBUS_MSG_ITER_APPEND_BYTE(&iter, cnf);
+ DBUS_MSG_ITER_APPEND_STR(&iter, iface);
+
+ }
+
+ return reply;
+}
+static DBusMessage* handle_disconn_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+
+ return reply;
+}
+static DBusMessage* handle_show_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+
+ return reply;
+}
+
+
+
+
+
+
+
+
+
+
+/*****************************************************************
+ *
+ * Section reserved to local functions definition
+ *
+ *****************************************************************/
+
+static void run_udhcp(const char *dev)
+{
+ char *argv[4], prog[40];
+ struct sigaction sa;
+ int ret;
+
+ sprintf(prog, "%s/%s", PAND_CONFIG_DIR, PAND_RUN_UDHCP_CMD);
+
+ if (access(prog, R_OK | X_OK)) {
+ syslog(LOG_ERR, "%s : wrong path or permission\n", prog);
+ return;
+ }
+
+ if (fork()) {
+ return;
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGPIPE, &sa, NULL);
+
+ argv[0] = prog;
+ argv[1] = (char*)dev;
+ argv[2] = NULL;
+ ret = execv(prog, argv);
+ if(ret != 0) {
+ syslog(LOG_ERR, "%s error: %s(%d)\n", prog, strerror(errno), errno);
+ }
+ exit(1);
+}
+static int8_t pan_connect(uint16_t role, uint16_t service, uint8_t udhcp, uint8_t bridge, const char* host, char **iface)
+{
+
+ int8_t ret = 0;
+
+ struct l2cap_options l2o;
+ struct sockaddr_l2 l2a;
+ bdaddr_t src_addr = *BDADDR_ANY;
+ int sk = -1, olen;
+ int8_t ret_val = 0;
+
+ *iface = NULL;
+
+ sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
+ if (sk < 0) {
+ syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)\n",
+ strerror(errno), errno);
+ return (-1);
+ }
+
+ /* Setup L2CAP options according to BNEP spec */
+ memset(&l2o, 0, sizeof(l2o));
+ olen = sizeof(l2o);
+ getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen);
+ l2o.imtu = l2o.omtu = BNEP_MTU;
+ setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o));
+
+ memset(&l2a, 0, sizeof(l2a));
+ l2a.l2_family = AF_BLUETOOTH;
+ bacpy(&l2a.l2_bdaddr, &src_addr);
+
+ if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) {
+ syslog(LOG_ERR, "Bind failed. %s(%d)\n",
+ strerror(errno), errno);
+ close(sk);
+ return (-1);
+ }
+
+ memset(&l2a, 0, sizeof(l2a));
+ l2a.l2_family = AF_BLUETOOTH;
+ str2ba(host, &l2a.l2_bdaddr);
+ l2a.l2_psm = htobs(BNEP_PSM);
+
+ if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) &&
+ (!bnep_create_connection(sk, role, service, netdev))) {
+ syslog(LOG_INFO, "%s connected\n", netdev);
+ (*iface) = (char*)malloc(IFACE_NAME_LENGTH);
+ if (!(*iface)) {
+ syslog(LOG_ERR, "Can't allocate memory\n");
+ ret_val = -1;
+ } else {
+ strncpy((*iface), netdev, IFACE_NAME_LENGTH);
+ if(enable_interface((const char*)netdev)) {
+ syslog(LOG_ERR,"Setting UP interface flag error.");
+ }
+#ifdef ENABLE_BRIDGE
+ if(bridge) {
+ if(!btbr_bridge_enabled()) {
+ /* TODO Ignore bridge create error???*/
+ btbr_create_bridge();
+ if(btbr_add_iface(netdev)) {
+ syslog(LOG_INFO, "%s can't be added to bridge\n", netdev);
+ }
+ if(udhcp) {
+ run_udhcp(btbr_get_bridge_name());
+ }
+ } else {
+ if(btbr_add_iface(netdev)) {
+ syslog(LOG_INFO, "%s can't be added to bridge\n", netdev);
+ }
+ }
+ }
+#else
+ if(udhcp) {
+ run_udhcp(netdev);
+ }
+#endif
+ /* reseting netdev mask */
+ strcpy(netdev, "bnep%d");
+ ret_val = 0;
+ }
+ } else {
+ syslog(LOG_ERR, "Connect to %s failed. %s(%d)\n",
+ host, strerror(errno), errno);
+ ret_val = (-1);
+ }
+ close(sk);
+ return ret;
+}
+
--- bluez-utils-2.18.orig/daemon/sdp_dbus.c 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/sdp_dbus.c 2005-07-26 11:42:08.062259800 -0300
@@ -0,0 +1,169 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+#include "bluetoothd_internal.h"
+
+
+
+
+/*****************************************************************
+ *
+ * Section reserved to local prototypes
+ *
+ *****************************************************************/
+
+static DBusHandlerResult sdp_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data);
+
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_search_req(DBusMessage *msg, void *data);
+
+
+/*****************************************************************
+ *
+ * Section reserved to local variables
+ *
+ *****************************************************************/
+
+static DBusConnection *bus_conn;
+
+
+/**
+ * Virtual table that implements the handlers
+ * of the object path hierarchy
+ **/
+static DBusObjectPathVTable sdp_vtable = {
+ NULL,
+ &sdp_msg_func,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static service_table_t sdp_services[] = {
+{SDP_LIST_SERVICES_REQ, handle_list_services_req, SDP_LIST_SERVICES_REQ_SIGNATURE },
+{SDP_SEARCH_REQ, handle_search_req, SDP_SEARCH_REQ_SIGNATURE },
+{NULL, NULL, NULL}
+};
+
+
+/*****************************************************************
+ *
+ * Section reserved to bluetoothd public functions
+ *
+ *****************************************************************/
+
+int8_t sdp_dbus_register(DBusConnection* conn)
+{
+ int8_t ret = 0;
+
+ bus_conn = conn;
+
+ if(!dbus_connection_register_fallback (conn, SDP_DBUS_PATH, &sdp_vtable, NULL)) {
+ syslog(LOG_ERR,"DBUS failed to register %s object", SDP_DBUS_PATH);
+ }
+ // TODO add filter
+ return ret;
+}
+
+
+int8_t sdp_dbus_unregister(DBusConnection* conn)
+{
+ int8_t ret = 0;
+
+ if(!dbus_connection_unregister_object_path(conn, SDP_DBUS_PATH)) {
+ syslog(LOG_ERR,"DBUS failed to unregister %s object", SDP_DBUS_PATH);
+ }
+ // TODO remove filters
+
+ return ret;
+}
+
+/*****************************************************************
+ *
+ * Section reserved to D-Bus message handlers
+ *
+ *****************************************************************/
+
+static DBusHandlerResult sdp_msg_func(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ service_table_t *ptr_handlers = sdp_services;
+ DBusMessage *reply = NULL;
+ DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ uint16_t type;
+ const char *iface;
+ const char *method;
+
+ syslog(LOG_INFO, "%s - line:%d",__PRETTY_FUNCTION__, __LINE__ );
+
+ type = dbus_message_get_type(msg);
+ iface = dbus_message_get_interface(msg);
+ method = dbus_message_get_member (msg);
+
+ if((type == DBUS_MESSAGE_TYPE_METHOD_CALL) &&
+ (strcmp(iface, SDP_DBUS_IFACE_REQ) == 0) &&
+ (method != NULL)){
+ for (;ptr_handlers->name; ptr_handlers++) {
+ if (strcmp(method, ptr_handlers->name) == 0) {
+ if (strcmp(ptr_handlers->signature,dbus_message_get_signature(msg)) == 0) {
+ reply = (ptr_handlers->handler_func)(msg, data);
+ if (reply) {
+ if (!dbus_connection_send (conn, reply, NULL)) {
+ syslog(LOG_ERR, "%s line:%d Can't send reply message!",
+ __PRETTY_FUNCTION__, __LINE__) ;
+ }
+ dbus_message_unref (reply);
+ }
+ ret = DBUS_HANDLER_RESULT_HANDLED;
+ break;
+ }
+ }
+ }
+ }
+ return ret;
+}
+
+static DBusMessage* handle_list_services_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ syslog(LOG_INFO, "%s - line:%d",__PRETTY_FUNCTION__, __LINE__ );
+
+ reply = dbus_message_new_method_return(msg);
+
+ common_list_services(reply, sdp_services);
+
+ return reply;
+}
+
+
+static DBusMessage* handle_search_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ syslog(LOG_INFO, "%s - line:%d",__PRETTY_FUNCTION__, __LINE__ );
+
+
+ return reply;
+}
--- bluez-utils-2.18.orig/daemon/scripts/bluetoothd.conf 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/scripts/bluetoothd.conf 2005-07-26 11:42:08.021266032 -0300
@@ -0,0 +1,19 @@
+<!-- This configuration file specifies the required security policies
+ for bluez-pand to work. -->
+
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <!-- ../system.conf have denied everything, so we just punch some holes -->
+
+ <policy context="default">
+ <allow own="org.bluez.bluetoothd"/>
+
+ <allow send_destination="org.bluez.bluetoothd"/>
+ <allow receive_sender="org.bluez.bluetoothd"/>
+
+ <allow send_path="/org/bluez/bluetoothd"/>
+ </policy>
+
+</busconfig>
--- bluez-utils-2.18.orig/daemon/scripts/bluetoothd.service 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/scripts/bluetoothd.service 2005-07-26 11:42:08.021266032 -0300
@@ -0,0 +1,4 @@
+# Service description file
+[D-BUS Service]
+Name=org.bluez.bluetoothd
+Exec=/etc/bluetooth/run-bluetoothd.sh
\ No newline at end of file
--- bluez-utils-2.18.orig/daemon/scripts/run-bluetoothd.sh 1969-12-31 21:00:00.000000000 -0300
+++ bluetoothd-0.0.6/daemon/scripts/run-bluetoothd.sh 2005-07-26 11:42:08.020266184 -0300
@@ -0,0 +1,2 @@
+#!/bin/sh
+bluetoothd
\ No newline at end of file
next prev parent reply other threads:[~2005-07-26 16:31 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-07-12 20:47 [Bluez-devel] bluetoothd specification Claudio Takahasi
2005-07-15 17:37 ` [Bluez-devel] " Claudio Takahasi
2005-07-18 16:12 ` Frederic Danis
2005-07-18 16:46 ` Claudio Takahasi
2005-07-26 16:31 ` Claudio Takahasi [this message]
2005-07-26 17:18 ` [Bluez-devel] Re: bluetoothd specification - new patch Marcel Holtmann
2005-07-26 19:06 ` Claudio Takahasi
2005-07-26 21:57 ` Marcel Holtmann
2005-07-28 14:08 ` Claudio Takahasi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e1effdeb05072609312aa92cc0@mail.gmail.com \
--to=cktakahasi@gmail.com \
--cc=bluez-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox