diff -urNaw bluez-utils-2.17.orig/pand/dbus_services.h bluez-utils-2.17-dbus/pand/dbus_services.h --- bluez-utils-2.17.orig/pand/dbus_services.h 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/dbus_services.h 2005-05-20 16:39:06.407796864 -0300 @@ -0,0 +1,206 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005 Claudio Takahasi + * 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: pand_dbus_services.h,v 1.12 2005/05/22 13:00:00 holtmann Exp $ + */ +#ifndef __H_PAND_DBUS_SERVICES_H__ +#define __H_PAND_DBUS_SERVICES_H__ + +#include +#include + +#define ORG_BLUEZ_DBUS_NAME "org.bluez" + +#define ORG_BLUEZ_PAND_DBUS_IFACE "org.bluez.pandIface" +#define ORG_BLUEZ_HCI_DBUS_IFACE "org.bluez.hciIface" + +#define ORG_BLUEZ_PAND_OBJ "/org/bluez/pand" +#define ORG_BLUEZ_HCI_OBJ "/org/bluez/hci" + + +// See pand_dbus_conn_req_t, used by actions attribute +#define PAND_CREATE_BRIDGE_MASK 0x01 +#define PAND_LLA_MASK 0x02 + + +// status of request operations +#define PAND_RESULT_SUCCESS 0x00 +#define PAND_RESULT_FAILED 0x01 + +// see pand_dev_info_t +#define PAND_DEV_STATE_READY 0x01 +#define PAND_DEV_STATE_CONNECTED 0x02 + + +typedef enum __attribute__((packed)) +{ + PAND_DBUS_INVALID_TYPE, + PAND_DBUS_CHANGE_ROLE_REQ_TYPE, + PAND_DBUS_CHANGE_ROLE_REQ_CNF_TYPE, + PAND_DBUS_CONN_REQ_TYPE, + PAND_DBUS_CONN_REQ_CNF_TYPE, + PAND_DBUS_DISCONN_REQ_TYPE, + PAND_DBUS_DISCONN_REQ_CNF_TYPE, + PAND_DBUS_DISCONN_ALL_REQ_TYPE, + PAND_DBUS_DISCONN_ALL_REQ_CNF_TYPE, + PAND_DBUS_GET_ACTIVE_CONN_REQ_TYPE, + PAND_DBUS_GET_ACTIVE_CONN_REQ_CNF_TYPE, + PAND_DBUS_SEARCH_REQ_TYPE, /* request search for a PAN service */ + PAND_DBUS_SEARCH_REQ_CNF_TYPE, + PAND_DBUS_GET_DEV_INFO_REQ_TYPE, /* request local bluetooth devices */ + PAND_DBUS_GET_DEV_INFO_CNF_TYPE, + PAND_DBUS_LISTEN_REQ_TYPE, + PAND_DBUS_LISTEN_REQ_CNF_TYPE, + PAND_DBUS_LISTEN_STOP_REQ_TYPE, + PAND_DBUS_LISTEN_STOP_REQ_CNF_TYPE +}PAND_MESSAGE_TYPE; + + +typedef enum __attribute__((packed)) +{ + DISABLE_BRIDGE, + ENABLE_BRIDGE +}BRIDGE_MODE; + +typedef enum __attribute__((packed)) +{ + PAND_STATUS_BUSY, + PAND_STATUS_CONNECTED, + PAND_STATUS_LISTENNING, + PAND_STATUS_IDLE +}PAND_DBUS_STATUS; + + +typedef struct __attribute__((packed)) +{ + PAND_MESSAGE_TYPE type; + void *data; +}pand_dbus_message_format_t; + +typedef struct __attribute__((packed)) +{ + uint16_t dev_id; /* for address more than one device */ + uint16_t role; + uint16_t service; + char actions; + char bdaddr[18]; +}pand_dbus_conn_req_t; + +typedef struct __attribute__((packed)) +{ + uint16_t dev_id; /* for address more than one device */ + char bdaddr[18]; +}pand_dbus_disconn_req_t; + +typedef struct __attribute__((packed)) +{ + uint16_t dev_id; /* for address more than one device */ +}pand_dbus_disconn_all_req_t,pand_dbus_get_active_conn_req_t; + +/* Generic confirmation result */ +typedef struct __attribute__((packed)) +{ + PAND_MESSAGE_TYPE type; + char result; + char data[0]; +}pand_dbus_req_cnf_t; + + +typedef struct __attribute__((packed)) +{ + uint16_t dev_id; /* for address more than one device */ + uint16_t role; + BRIDGE_MODE bridge_mode; + char master; + char secure; + char encrypt; + char ipv4[16]; + char ipv4subnet[16]; +}pand_dbus_listen_req_t; + +typedef struct __attribute__((packed)) +{ + uint16_t dev_id; /* for address more than one device */ +}pand_dbus_listen_stop_req_t; + +typedef struct __attribute__((packed)) +{ + uint16_t dev_id; /* for address more than one device */ + uint16_t role; /* new role*/ + char bdaddr[18]; +}pand_dbus_change_role_req_t; + +typedef struct __attribute__((packed)) +{ + uint16_t dev_id; /* for address more than one device */ + uint16_t service; +}pand_dbus_search_req_t; + +typedef struct __attribute__((packed)) +{ + char status; /* 0-success 1-failed */ + char *ip; /* ip address if lla was requested */ +}pand_dbus_conn_req_cnf_t; + +typedef struct __attribute__((packed)) +{ + char status; + /* device list ???*/ +}pand_dbus_search_cnf_t; + +typedef struct __attribute__((packed)) +{ + uint16_t dev_id; + char name[8]; + char bdaddr[18]; + uint16_t state; /* see PAND_DEV_STATE_XXXX TODO */ +}pand_dev_info_t; + +/* Addressing more than one bluetooth device */ +typedef struct __attribute__((packed)) +{ + //TODO add support for more than one device + char num_dev; + pand_dev_info_t devices[0]; +}pand_dbus_get_dev_cnf_t; + +typedef struct __attribute__((packed)) +{ + char bdaddr[18]; + char link_type; + char handle; + char state; + char master; +}pand_active_conn_t; +typedef struct __attribute__((packed)) +{ + //TODO add support for more than one device + char num_conn; + pand_active_conn_t conn[0]; +}pand_dbus_get_active_conn_cnf_t; + + +#endif /* __H_PAND_DBUS_SERVICES_H__*/ diff -urNaw bluez-utils-2.17.orig/pand/DBUS.TXT bluez-utils-2.17-dbus/pand/DBUS.TXT --- bluez-utils-2.17.orig/pand/DBUS.TXT 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/DBUS.TXT 2005-05-20 11:48:59.000000000 -0300 @@ -0,0 +1,65 @@ + +HOWTO setup DBUS environment + +The BLUEZ DBUS PAN service uses the system bus. In order +to run the + +1. checking dbus-daemon + type: $ps -ef | grep dbus + "dbus-daemon --system" should be displayed + +2. check dbus service configuration file + The file bluez.conf must be located at: /etc/dbus-1/system.d/ + See Appendix 1. + + +3. running the bluez pan daemon (requires root permission) + type $pand --dbus or pand -b + check if the pand process is running: $ps -ef | grep pand + if not, read the system log: $tail /var/log/syslog + +4. calling bluez dbus service(user mode app) + See call examples in the file:xxxx + Now, any user mode app(games, UPnP, ...) is able to control + Bluetooth connections. + +****** Appendix 1: + + + + + + + + + + + + + + + + + + + + +****** Appendix 2: + +Advantages: + + * user mode app are able to control BT connections + * security: the configuration file can be used to specify permissions + +Disadvantages: + * D-BUS is not stable + * programming using D-BUS is not trivial + +****** TODO + -add search service + -add bridge control + - Notify D-BUS connected client regarding incomming conn + -add bt device functions: see hcitoool + -add local link address support: zeroconf diff -urNaw bluez-utils-2.17.orig/pand/main.c bluez-utils-2.17-dbus/pand/main.c --- bluez-utils-2.17.orig/pand/main.c 2005-05-09 15:33:24.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/main.c 2005-05-18 19:08:33.000000000 -0300 @@ -54,6 +54,10 @@ #include "pand.h" +#ifdef ENABLE_DBUS +#include "pand_dbus.h" +#endif + static uint16_t role = BNEP_SVC_PANU; /* Local role (ie service) */ static uint16_t service = BNEP_SVC_NAP; /* Remote service */ @@ -88,7 +92,10 @@ SHOW, LISTEN, CONNECT, - KILL + KILL, +#ifdef ENABLE_DBUS + DBUS, +#endif } modes; static void run_devup(char *dev, char *dst, int sk, int nsk) @@ -417,6 +424,9 @@ void sig_term(int sig) { terminate = 1; +#ifdef ENABLE_DBUS + pand_dbus_stop(); +#endif } int write_pidfile(void) @@ -488,6 +498,9 @@ { "help", 0, 0, 'h' }, { "listen", 0, 0, 's' }, { "connect", 1, 0, 'c' }, +#ifdef ENABLE_DBUS + { "dbus", 0, 0, 'b' }, +#endif { "search", 2, 0, 'Q' }, { "kill", 1, 0, 'k' }, { "killall", 0, 0, 'K' }, @@ -510,7 +523,7 @@ { 0, 0, 0, 0 } }; -static char main_sopts[] = "hsc:k:Kr:e:i:lnp::DQ::AESMC::P:z"; +static char main_sopts[] = "hsc:bk:Kr:e:i:lnp::DQ::AESMC::P:z"; static char main_help[] = "Bluetooth PAN daemon version " VERSION " \n" @@ -520,6 +533,9 @@ "\t--show --list -l Show active PAN connections\n" "\t--listen -s Listen for PAN connections\n" "\t--connect -c Create PAN connection\n" +#ifdef ENABLE_DBUS + "\t--dbus -b Enable dbus service\n" +#endif "\t--autozap -z Disconnect automatically on exit\n" "\t--search -Q[duration] Search and connect\n" "\t--kill -k Kill PAN connection\n" @@ -560,7 +576,11 @@ mode = CONNECT; dst = strdup(optarg); break; - +#ifdef ENABLE_DBUS + case 'b': + mode = DBUS; + break; +#endif case 'Q': mode = CONNECT; if (optarg) @@ -729,8 +749,12 @@ case LISTEN: do_listen(); break; +#ifdef ENABLE_DBUS + case DBUS: + pand_dbus_start(); + break; +#endif } - if (pidfile) unlink(pidfile); diff -urNaw bluez-utils-2.17.orig/pand/Makefile.am bluez-utils-2.17-dbus/pand/Makefile.am --- bluez-utils-2.17.orig/pand/Makefile.am 2005-05-09 15:33:24.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/Makefile.am 2005-05-18 19:00:45.000000000 -0300 @@ -2,12 +2,31 @@ # $Id: Makefile.am,v 1.5 2005/04/21 21:34:10 holtmann Exp $ # +if DBUS + pand_dbus_inc_hdr = dbus_services.h + pand_dbus_sources = pand_dbus.c pand_dbus_util.c pand_dbus_commands.c + pand_dbus_libs = @DBUS_LIBS@ -ldbus-glib-1 -lbridge -lpthread + pand_dbus_cflags = -DENABLE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE + pand_dbus_inc = -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/local/include +else + pand_dbus_inc_hdr = + pand_dbus_sources = + pand_dbus_libs = + pand_dbus_cflags = + pand_dbus_inc = +endif + + + bin_PROGRAMS = pand -pand_SOURCES = main.c pand.h bnep.c sdp.c -pand_LDADD = @BLUEZ_LIBS@ +pand_SOURCES = main.c pand.h bnep.c sdp.c $(pand_dbus_sources) +pand_LDADD = @BLUEZ_LIBS@ $(pand_dbus_libs) +INCLUDES = $(pand_dbus_inc) +includedir = @includedir@/bluetooth +include_HEADERS = $(pand_dbus_inc_hdr) -AM_CFLAGS = @BLUEZ_CFLAGS@ +AM_CFLAGS = @BLUEZ_CFLAGS@ $(pand_dbus_cflags) man_MANS = pand.1 diff -urNaw bluez-utils-2.17.orig/pand/pand_dbus.c bluez-utils-2.17-dbus/pand/pand_dbus.c --- bluez-utils-2.17.orig/pand/pand_dbus.c 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/pand_dbus.c 2005-05-20 16:43:53.590138512 -0300 @@ -0,0 +1,721 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005 Claudio Takahasi + * 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: pand_dbus.c,v 1.12 2005/05/22 13:00:00 holtmann Exp $ + */ + + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + + +#include "pand_dbus.h" +#include "dbus_services.h" +#include "pand_dbus_util.h" +#include "pand_dbus_commands.h" + + + +static void pand_dbus_unregistered_func (DBusConnection *dbus_conn, + gpointer user_data); + +static DBusHandlerResult pand_dbus_msg_func (DBusConnection *dbus_conn, + DBusMessage *msg, gpointer user_data); + +static DBusObjectPathVTable pand_vtable = { + pand_dbus_unregistered_func, + pand_dbus_msg_func, + NULL, + NULL, + NULL, + NULL +}; + + +typedef DBusHandlerResult (*pand_services_handler)(DBusConnection *, DBusMessage *, void *); + + +static DBusHandlerResult handle_change_role_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data); +static DBusHandlerResult handle_connect_req(DBusConnection *dbus_conn, DBusMessage *msg, void* data); +static DBusHandlerResult handle_disconnect_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data); +static DBusHandlerResult handle_disconnect_all_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data); +static DBusHandlerResult handle_get_active_conn_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data); +static DBusHandlerResult handle_get_devices_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data); +static DBusHandlerResult handle_listen_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data); +static DBusHandlerResult handle_listen_stop_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data); +static DBusHandlerResult handle_search_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data); + + +typedef struct +{ + char *name; + pand_services_handler handle_func; +}pand_services_data_t; + + +static pand_services_data_t pand_services[] = { + {"ChangeRoleReq", handle_change_role_req }, + {"ConnectReq", handle_connect_req }, + {"DisconnectReq", handle_disconnect_req}, + {"DisconnectAllReq", handle_disconnect_all_req}, + {"GetActiveConnectionsReq", handle_get_active_conn_req}, + {"GetDevicesReq", handle_get_devices_req}, + {"ListenReq", handle_listen_req}, + {"ListenStopReq", handle_listen_stop_req}, + {"SearchReq", handle_search_req}, + {NULL, NULL} +}; + +static DBusConnection *dbus_conn; +static GMainLoop *main_loop = NULL ; + +/** + * Initialize D-BUS connection + * @param + * @return + */ +int +pand_dbus_start() +{ + + DBusError dbus_error; + //TODO pthread_t thread_id; + int result = 0; + + /* TODO check for other pand instance running + * Only one instance is allowed! + */ + + + dbus_error_init(&dbus_error); + dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); + + if (!dbus_conn) { + syslog(LOG_ERR, "Failed to open connection to system message bus: %s\n", + dbus_error.message); + dbus_error_free(&dbus_error); + return -1; + } +#ifdef DBUS_033 + if(!dbus_bus_request_name(dbus_conn, ORG_BLUEZ_DBUS_NAME, 0, &dbus_error)) { +#else + if(!dbus_bus_acquire_service(dbus_conn, ORG_BLUEZ_DBUS_NAME, 0, &dbus_error)) { +#endif + syslog(LOG_ERR,"DBUS acquire service error: %s\n", dbus_error.message); + dbus_error_free (&dbus_error); + result = -1; + goto skip_label; + } + + if (!dbus_connection_register_object_path (dbus_conn, ORG_BLUEZ_PAND_OBJ, + &pand_vtable, NULL)) { + syslog(LOG_ERR,"DBUS failed to register org/bluez/pand object\n"); + result = -1; + goto skip_label; + } + + main_loop = g_main_loop_new (NULL, FALSE); + + dbus_connection_setup_with_g_main (dbus_conn, NULL) ; + + g_main_loop_run (main_loop) ; + + +skip_label: + return result; +} + +/** + * Close D-BUS connection and the main loop + * @param + * @return + */ +int +pand_dbus_stop() +{ + if(main_loop){ + g_main_loop_quit(main_loop); + } + if (dbus_conn) { + dbus_connection_disconnect(dbus_conn); + dbus_conn = NULL; + } + return 0; +} + + +/** + * TODO method not implemented + * @param + * @return + */ +static DBusHandlerResult +handle_change_role_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + const unsigned char *ptr; + DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED; + pand_dbus_change_role_req_t req; + pand_dbus_req_cnf_t cnf_result; + int ret_val = 0, size; + + syslog(LOG_INFO, "%s line:%d - method not implemented", __PRETTY_FUNCTION__, __LINE__); + + memset(&req, 0, sizeof(pand_dbus_change_role_req_t)); + + cnf_result.type = PAND_DBUS_CHANGE_ROLE_REQ_CNF_TYPE; + + if(!pand_util_get_req_attr(msg, PAND_DBUS_CHANGE_ROLE_REQ_TYPE, sizeof(pand_dbus_change_role_req_t),&req)){ + + //TODO check current daemon status + //ret_val = cmd_change_role(&req); + cnf_result.result = (!ret_val?PAND_RESULT_SUCCESS:PAND_RESULT_FAILED); + } else { + cnf_result.result = PAND_RESULT_FAILED; + } + + + size = sizeof(pand_dbus_req_cnf_t); + ptr = (const unsigned char*)&cnf_result; + + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init(reply, &iter); + dbus_message_append_iter_init(reply, &iter); + dbus_message_iter_append_byte_array(&iter, ptr, size); + + + //TODO check iter results + + if (!dbus_connection_send (dbus_conn, reply, NULL)) { + syslog(LOG_ERR, "fatal error at %s:%d\n", + __PRETTY_FUNCTION__, __LINE__) ; + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto skip_label; + } + +skip_label: + return result; +} + +/** + * TODO + * @param + * @return + */ +static DBusHandlerResult +handle_connect_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + const unsigned char *ptr; + DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED; + int ret_val, size; + pand_dbus_conn_req_t req; + pand_dbus_req_cnf_t cnf_result; + + memset(&req, 0, sizeof(pand_dbus_conn_req_t)); + + cnf_result.type = PAND_DBUS_CONN_REQ_CNF_TYPE; + + if(!pand_util_get_req_attr(msg, PAND_DBUS_CONN_REQ_TYPE, sizeof(pand_dbus_conn_req_t), &req)){ + + //TODO check the current daemon status + //check role, if is connected. scatternet are not allowed + ret_val = cmd_connect(req.bdaddr, req.role, req.service); + cnf_result.result = (!ret_val?PAND_RESULT_SUCCESS:PAND_RESULT_FAILED); + } else { + cnf_result.result = PAND_RESULT_FAILED; + + } + + size = sizeof(pand_dbus_req_cnf_t); + ptr = (const unsigned char*)&cnf_result; + + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init(reply, &iter); + dbus_message_append_iter_init(reply, &iter); + dbus_message_iter_append_byte_array(&iter, ptr, size); + + if (!dbus_connection_send (dbus_conn, reply, NULL)) { + syslog(LOG_ERR, "fatal error at %s:%d\n", + __PRETTY_FUNCTION__, __LINE__) ; + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto skip_label; + } + +skip_label: + if (reply) { + dbus_message_unref (reply) ; + reply = NULL ; + } + + return result; +} + +/** + * TODO + * @param + * @return + */ +static DBusHandlerResult +handle_disconnect_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + const unsigned char *ptr; + DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED; + pand_dbus_disconn_req_t req; + pand_dbus_req_cnf_t cnf_result; + int ret_val, size; + + memset(&req, 0, sizeof(pand_dbus_disconn_req_t)); + + cnf_result.type = PAND_DBUS_DISCONN_REQ_CNF_TYPE; + + if(!pand_util_get_req_attr(msg, PAND_DBUS_DISCONN_REQ_TYPE, sizeof(pand_dbus_disconn_req_t),&req)){ + + //TODO check current daemon status + ret_val = cmd_disconnect(&req); + cnf_result.result = (!ret_val?PAND_RESULT_SUCCESS:PAND_RESULT_FAILED); + + } else { + cnf_result.result = PAND_RESULT_FAILED; + } + + size = sizeof(pand_dbus_req_cnf_t); + ptr = (const unsigned char*)&cnf_result; + + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init(reply, &iter); + dbus_message_append_iter_init(reply, &iter); + dbus_message_iter_append_byte_array(&iter, ptr, size); + + + //TODO check iter results + if (!dbus_connection_send (dbus_conn, reply, NULL)) { + syslog(LOG_ERR, "fatal error at %s:%d\n", + __PRETTY_FUNCTION__, __LINE__) ; + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto skip_label; + } + +skip_label: + if (reply) { + dbus_message_unref (reply) ; + reply = NULL ; + } + + return result; +} + +/** + * TODO + * @param + * @return + */ +static DBusHandlerResult +handle_disconnect_all_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + const unsigned char *ptr; + DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED; + pand_dbus_disconn_all_req_t req; + pand_dbus_req_cnf_t cnf_result; + int ret_val, size; + + memset(&req, 0, sizeof(pand_dbus_disconn_all_req_t)); + + //HOW address when the dbus client app send data? + // suggestion: pass the wanted size:P + + cnf_result.type = PAND_DBUS_DISCONN_ALL_REQ_CNF_TYPE; + + if(!pand_util_get_req_attr(msg, PAND_DBUS_DISCONN_ALL_REQ_TYPE, sizeof(pand_dbus_disconn_all_req_t),&req)){ + + //TODO check current daemon status + ret_val = cmd_disconnect(NULL); + cnf_result.result = (!ret_val?PAND_RESULT_SUCCESS:PAND_RESULT_FAILED); + } else { + cnf_result.result = PAND_RESULT_FAILED; + } + + size = sizeof(pand_dbus_req_cnf_t); + ptr = (const unsigned char*)&cnf_result; + + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init(reply, &iter); + dbus_message_append_iter_init(reply, &iter); + dbus_message_iter_append_byte_array(&iter, ptr, size); + + //TODO check iter results + + if (!dbus_connection_send (dbus_conn, reply, NULL)) { + syslog(LOG_ERR, "fatal error at %s:%d\n", + __PRETTY_FUNCTION__, __LINE__) ; + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto skip_label; + } + +skip_label: + if (reply) { + dbus_message_unref (reply) ; + reply = NULL ; + } + + return result; +} + +/** + * TODO + * @param + * @return + */ +static DBusHandlerResult +handle_get_active_conn_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + const unsigned char *ptr; + DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED; + pand_dbus_get_active_conn_req_t req; + pand_dbus_get_active_conn_cnf_t *cnf_data = NULL; + pand_dbus_req_cnf_t *cnf_result = NULL; + int ret_val = -1; + int cnf_res_size = 0; + int data_size = 0; + + + + if(!pand_util_get_req_attr(msg, PAND_DBUS_GET_ACTIVE_CONN_REQ_TYPE, sizeof(pand_dbus_get_active_conn_req_t),&req)){ + + //TODO check current daemon status + ret_val = cmd_get_active_conn(&req, &cnf_data); + } + + cnf_res_size = sizeof(pand_dbus_req_cnf_t); + + if(!ret_val) { + + data_size = (cnf_data->num_conn )* sizeof(pand_active_conn_t) + sizeof(pand_dbus_get_active_conn_cnf_t); + cnf_result = (pand_dbus_req_cnf_t*)malloc(cnf_res_size + data_size); + cnf_result -> type = PAND_DBUS_GET_ACTIVE_CONN_REQ_CNF_TYPE; + cnf_result -> result = PAND_RESULT_SUCCESS; + memcpy(cnf_result->data, cnf_data,data_size); + cnf_res_size += data_size; + } else { + cnf_result = (pand_dbus_req_cnf_t*)malloc(cnf_res_size); + cnf_result -> type = PAND_DBUS_GET_ACTIVE_CONN_REQ_CNF_TYPE; + cnf_result -> result = PAND_RESULT_FAILED; + } + + ptr = (const unsigned char*)cnf_result; + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init(reply, &iter); + dbus_message_append_iter_init(reply, &iter); + dbus_message_iter_append_byte_array(&iter, ptr, cnf_res_size); + + //TODO check iter results + + if (!dbus_connection_send (dbus_conn, reply, NULL)) { + syslog(LOG_ERR, "fatal error at %s:%d\n", + __PRETTY_FUNCTION__, __LINE__) ; + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto skip_label; + } + +skip_label: + if (reply) { + dbus_message_unref (reply) ; + reply = NULL ; + } + + if(cnf_result) { + free(cnf_result); + } + + if(cnf_data) { + free(cnf_data); + } + + return result; +} + +/** + * TODO + * @param + * @return + */ +static DBusHandlerResult +handle_get_devices_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + const unsigned char *ptr; + DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED; + char req; + pand_dbus_req_cnf_t *cnf_result = NULL; + pand_dbus_get_dev_cnf_t *cnf_data = NULL; + int ret_val = -1; + int cnf_res_size, data_size; + + + if(!pand_util_get_req_attr(msg, PAND_DBUS_GET_DEV_INFO_REQ_TYPE, 0, &req)){ + + ret_val = cmd_get_devices(&cnf_data); + + } + + cnf_res_size = sizeof(pand_dbus_req_cnf_t); + + if(!ret_val) { + data_size = (cnf_data->num_dev )* sizeof(pand_dev_info_t) + sizeof(pand_dbus_get_dev_cnf_t); + cnf_result = (pand_dbus_req_cnf_t*)malloc(cnf_res_size + data_size); + cnf_result->type = PAND_DBUS_GET_DEV_INFO_CNF_TYPE; + cnf_result->result = PAND_RESULT_SUCCESS; + memcpy(cnf_result->data, cnf_data,data_size); + cnf_res_size += data_size; + } else { + cnf_result = (pand_dbus_req_cnf_t*)malloc(cnf_res_size); + cnf_result->type = PAND_DBUS_GET_DEV_INFO_CNF_TYPE; + cnf_result->result = PAND_RESULT_FAILED; + } + + ptr = (const unsigned char*)cnf_result; + + reply = dbus_message_new_method_return(msg); + + dbus_message_iter_init(reply, &iter); + dbus_message_append_iter_init(reply, &iter); + dbus_message_iter_append_byte_array(&iter, ptr, cnf_res_size); + + if (!dbus_connection_send (dbus_conn, reply, NULL)) { + syslog(LOG_ERR, "fatal error at %s:%d\n", + __PRETTY_FUNCTION__, __LINE__) ; + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto skip_label; + } + +skip_label: + if (reply) { + dbus_message_unref (reply) ; + reply = NULL ; + } + if(cnf_result) { + free(cnf_result); + } + + if(cnf_data) { + free(cnf_data); + } + + return result; +} + +/** + * TODO + * @param + * @return + */ +static DBusHandlerResult +handle_listen_req(DBusConnection *dbus_conn, DBusMessage *msg, void* data) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + const unsigned char *ptr; + DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED; + pand_dbus_listen_req_t req; + pand_dbus_req_cnf_t cnf_result; + int ret_val, size; + + + memset(&req, 0, sizeof(pand_dbus_listen_req_t)); + + cnf_result.type = PAND_DBUS_LISTEN_REQ_CNF_TYPE; + + + if(!pand_util_get_req_attr(msg, PAND_DBUS_LISTEN_REQ_TYPE, sizeof(pand_dbus_listen_req_t),&req)){ + ret_val = cmd_listen(&req); + cnf_result.result = (!ret_val?PAND_RESULT_SUCCESS:PAND_RESULT_FAILED); + }else{ + cnf_result.result = PAND_RESULT_FAILED; + } + + size = sizeof(pand_dbus_req_cnf_t); + ptr = (const unsigned char*)&cnf_result; + + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init(reply, &iter); + dbus_message_append_iter_init(reply, &iter); + dbus_message_iter_append_byte_array(&iter, ptr, size); + + + if (!dbus_connection_send (dbus_conn, reply, NULL)) { + syslog(LOG_ERR, "fatal error at %s:%d\n", + __FILE__, __LINE__) ; + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto skip_label; + } + +skip_label: + if (reply) { + dbus_message_unref (reply) ; + reply = NULL ; + } + return result; +} + +/** + * TODO + * @param + * @return + */ +static DBusHandlerResult +handle_listen_stop_req(DBusConnection *dbus_conn, DBusMessage *msg, void* data) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + const unsigned char *ptr; + DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED; + pand_dbus_listen_stop_req_t req; + pand_dbus_req_cnf_t cnf_result; + int ret_val, size; + + memset(&req, 0, sizeof(pand_dbus_listen_stop_req_t)); + + cnf_result.type = PAND_DBUS_LISTEN_STOP_REQ_CNF_TYPE; + + if(!pand_util_get_req_attr(msg, PAND_DBUS_LISTEN_STOP_REQ_TYPE, sizeof(pand_dbus_listen_stop_req_t),&req)){ + ret_val = cmd_listen_stop(&req); + cnf_result.result = (!ret_val?PAND_RESULT_SUCCESS:PAND_RESULT_FAILED); + }else{ + cnf_result.result = PAND_RESULT_FAILED; + } + + size = sizeof(pand_dbus_req_cnf_t); + ptr = (const unsigned char*)&cnf_result; + + reply = dbus_message_new_method_return(msg); + dbus_message_iter_init(reply, &iter); + dbus_message_append_iter_init(reply, &iter); + dbus_message_iter_append_byte_array(&iter, ptr, size); + + if (!dbus_connection_send (dbus_conn, reply, NULL)) { + syslog(LOG_ERR, "fatal error at %s:%d\n", + __FILE__, __LINE__) ; + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + goto skip_label; + } +skip_label: + if (reply) { + dbus_message_unref (reply) ; + reply = NULL ; + } + return result; +} +/** + * TODO + * @param + * @return + */ +static DBusHandlerResult +handle_search_req(DBusConnection *dbus_conn, DBusMessage *msg, void *data) +{ + DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + syslog(LOG_INFO, "%s - line: %d\n", __PRETTY_FUNCTION__, __LINE__); + + return result; +} + +/** + * TODO + * @param + * @return + */ +static void +pand_dbus_unregistered_func (DBusConnection *dbus_conn, + gpointer user_data) +{ + return; + +} + +/** + * TODO + * @param + * @return + */ +static DBusHandlerResult +pand_dbus_msg_func (DBusConnection *dbus_conn, DBusMessage *msg, gpointer user_data) +{ + pand_services_data_t *ptr_handlers = pand_services; + DBusHandlerResult result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + const char *method; + const char *path; + + method = dbus_message_get_member (msg); + path = dbus_message_get_path (msg); + + for (;ptr_handlers->name; ptr_handlers++) { + if(dbus_message_is_method_call(msg , ORG_BLUEZ_PAND_DBUS_IFACE, ptr_handlers->name)) + { + result = (ptr_handlers->handle_func)(dbus_conn, msg, user_data); + + if(result == DBUS_HANDLER_RESULT_HANDLED) { + dbus_message_unref (msg) ; + msg = NULL ; + } + break; + } + } + return result; + +} diff -urNaw bluez-utils-2.17.orig/pand/pand_dbus_commands.c bluez-utils-2.17-dbus/pand/pand_dbus_commands.c --- bluez-utils-2.17.orig/pand/pand_dbus_commands.c 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/pand_dbus_commands.c 2005-05-20 16:38:43.628259880 -0300 @@ -0,0 +1,514 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005 Claudio Takahasi + * 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: pand_dbus_commands.c,v 1.12 2005/05/22 13:00:00 holtmann Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include + +#include + +#include "pand_dbus_commands.h" +#include "pand.h" + + +//TODO +static char netdev[16] = "bnep%d"; +extern int terminate; +static pthread_t threadid = 0; + +typedef struct { + int role; + int sk; + struct sockaddr_l2 *l2a; +}listen_args_t; + + +/** + * Get list of connected devices + * @param + * @return + */ +static int get_conn_list(int s, int dev_id, pand_dbus_get_active_conn_cnf_t **preq_cnf) +{ + struct hci_conn_list_req *cl; + struct hci_conn_info *ci; + pand_active_conn_t conn; + int i; + int ret_val = -1; + + if (dev_id < 0) + return -1; + + if (!(cl = malloc(10 * sizeof(*ci) + sizeof(*cl)))) { + syslog(LOG_ERR,"Can't allocate memory"); + return -1; + } + cl->dev_id = dev_id; + cl->conn_num = 10; + ci = cl->conn_info; + + if (ioctl(s, HCIGETCONNLIST, (void *) cl)) { + syslog(LOG_ERR,"Can't get connection list"); + goto cleanup; + } + + *preq_cnf = (pand_dbus_get_active_conn_cnf_t*) malloc(sizeof(pand_dbus_get_active_conn_cnf_t)); + (*preq_cnf)->num_conn = 0; + + + for (i = 0; i < cl->conn_num; i++, ci++) { + char addr[18]; + ba2str(&ci->bdaddr, addr); + memset(&conn, 0, sizeof(pand_active_conn_t)); + strcpy(conn.bdaddr, addr); + conn.link_type = ci->type; + conn.handle = ci->handle; + conn.state = ci->state; + conn.master = ci->link_mode; + + *preq_cnf = (pand_dbus_get_active_conn_cnf_t*)realloc \ + (*preq_cnf, ((*preq_cnf)->num_conn + 1) * \ + sizeof(pand_active_conn_t) + \ + sizeof(pand_dbus_get_active_conn_cnf_t)); + + memcpy((*preq_cnf)->conn + (*preq_cnf)->num_conn, &conn, sizeof(pand_active_conn_t)); + + (*preq_cnf)->num_conn++; + } + ret_val = 0; +cleanup: + return ret_val; +} + +/** + * Dealocate thread parameters + * @param + * @return + */ +static +void deallocate_thread_param(void* param) +{ + listen_args_t *p = (listen_args_t*)param; + + close(p->sk); + free (p->l2a); + free (p); +} + +/** + * Listen thread function + * @param + * @return + */ +void *listen_thread (void *param) +{ + listen_args_t *p = (listen_args_t*)param; + + + pthread_cleanup_push (deallocate_thread_param, p); + while (!terminate) { + int alen = sizeof(struct sockaddr_l2); + int nsk; + + nsk = accept(p->sk, (struct sockaddr *) p->l2a, &alen); + + if (nsk < 0) { + syslog(LOG_ERR, "Accept failed. %s(%d)\n", strerror(errno), errno); + continue; + } + + switch (fork()) { + case 0: + break; + case -1: + syslog(LOG_ERR, "Fork failed. %s(%d)\n", strerror(errno), errno); + default: + close(nsk); + continue; + } + + if (!bnep_accept_connection(nsk, p->role, netdev)) { + char str[40]; + ba2str(&(p->l2a->l2_bdaddr), str); + + syslog(LOG_INFO, "New connection from %s %s\n", str, netdev); + /* TODO for GN and NAP add the new device to the bridge */ + /* TODO notify all dbus connected clients */ + } else { + syslog(LOG_ERR, "Connection failed. %s(%d)\n", + strerror(errno), errno); + } + + close(nsk); + syslog(LOG_INFO,"%s line:%d", __PRETTY_FUNCTION__, __LINE__); + exit(0); + } + close(p->sk); + pthread_cleanup_pop(1); + bnep_sdp_unregister(); + + return NULL; +} + + + +/** + * Connect and initiate BNEP session + * @param + * @return + * -1 - critical error (exit persist mode) + * 1 - non critical error + * 0 - success + */ +int cmd_connect(char *dst, uint16_t role, uint16_t service) +{ + struct l2cap_options l2o; + struct sockaddr_l2 l2a; + bdaddr_t src_addr = *BDADDR_ANY; + int sk, olen, ret_val = 0; + + syslog(LOG_INFO, "Connecting to %s\n", dst); + + sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (sk < 0) { + syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", + strerror(errno), errno); + return -1; + } + + /* Setup L2CAP options according to BNEP spec */ + 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))) + syslog(LOG_ERR, "Bind failed. %s(%d)", + strerror(errno), errno); + + memset(&l2a, 0, sizeof(l2a)); + l2a.l2_family = AF_BLUETOOTH; + //bacpy(&l2a.l2_bdaddr, bdaddr); + str2ba(dst, &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", netdev); + //run_devup(netdev, dst, sk, -1); + ret_val = 0; + } else { + syslog(LOG_ERR, "Connect to %s failed. %s(%d)", + dst, strerror(errno), errno); + ret_val = 1; + } + + close(sk); + return ret_val; +} + +/** + * Disconnect from one or all connected devices + * @param + * @return + */ +int cmd_disconnect (pand_dbus_disconn_req_t *pdc) +{ + int ret_val = -1; + bdaddr_t *dst; + + + if(pdc) { + if(pdc->bdaddr[0] != 0) { + dst = strtoba(pdc->bdaddr); + ret_val = bnep_kill_connection((uint8_t*)dst); + } + + }else + { + ret_val = bnep_kill_all_connections(); + } + return ret_val; +} + +/** + * Returns active connections + * @param + * @return + */ +int cmd_get_active_conn(pand_dbus_get_active_conn_req_t *preq, pand_dbus_get_active_conn_cnf_t **preq_cnf) +{ + int ret_val = -1; + + struct hci_dev_list_req *dl = NULL; + struct hci_dev_req *dr = NULL; + int i, sk; + + if(!preq || !preq_cnf) { + return -1; + } + + memset(preq_cnf,0,sizeof(pand_dbus_get_active_conn_cnf_t)); + + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) + return -1; + + if(preq->dev_id != 0) { + get_conn_list(sk, preq->dev_id, preq_cnf); + }else { + dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); + if (!dl) { + goto cleanup; + } + + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(sk, HCIGETDEVLIST, (void *) dl)) + goto cleanup; + + for (i = 0; i < dl->dev_num; i++, dr++) { + if (hci_test_bit(HCI_UP, &dr->dev_opt)) + ret_val = get_conn_list(sk, dr->dev_id, preq_cnf); + } + } + +cleanup: + close(sk); + if(dl) { + free(dl); + } + + return ret_val; +} + +/** + * Gets local Bluetooth devices + * @param + * @return + */ +int cmd_get_devices(pand_dbus_get_dev_cnf_t **preq_cnf) +{ + struct hci_dev_list_req *dl = NULL; + struct hci_dev_req *dr = NULL; + pand_dev_info_t *pdev = NULL; + struct hci_dev_info di; + int i, sk, size; + char addr[18]; + int ret_val = 0; + + if(!preq_cnf) { + return -1; + } + + sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (sk < 0) + return -1; + + dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); + + if (!dl) { + ret_val = -1; + goto cleanup; + } + + dl->dev_num = HCI_MAX_DEV; + dr = dl->dev_req; + + if (ioctl(sk, HCIGETDEVLIST, (void *) dl)) { + ret_val = -1; + goto cleanup; + } + + size = sizeof(pand_dbus_get_dev_cnf_t); + *preq_cnf = (pand_dbus_get_dev_cnf_t*)realloc(*preq_cnf, size); + (*preq_cnf)->num_dev = 0; + + for (i = 0; i < dl->dev_num; i++, dr++) { + if (hci_test_bit(HCI_UP, &dr->dev_opt)) { + memset(&di, 0 , sizeof(struct hci_dev_info)); + di.dev_id = dr->dev_id; + if (!ioctl(sk, HCIGETDEVINFO, (void *) &di)) { + size = ((*preq_cnf)->num_dev +1)* sizeof(pand_dev_info_t)+ sizeof(pand_dbus_get_dev_cnf_t); + *preq_cnf = (pand_dbus_get_dev_cnf_t*)realloc(*preq_cnf, size); + pdev = ((pand_dev_info_t*)(*preq_cnf)->devices); + pdev = pdev + (*preq_cnf)->num_dev; + pdev->dev_id = di.dev_id; + strcpy(pdev->name, di.name); + ba2str(&di.bdaddr, addr); + strcpy(pdev->bdaddr, addr); + (*preq_cnf)->num_dev++; + } + } + } + +cleanup: + close(sk); + if(dl) { + free(dl); + } + + return ret_val; +} + +/** + * Listen for incomming connections + * @param + * @return + */ +int +cmd_listen(pand_dbus_listen_req_t *preq) { + + struct l2cap_options l2o; + struct sockaddr_l2 *pl2a = NULL; + listen_args_t *listen_arguments; + bdaddr_t src_addr = *BDADDR_ANY; + //pthread_t threadid; + int sk, olen, lm; + + /* TODO Check if the thread is running */ + + /* TODO Create the bridge */ + if(preq->role != BNEP_SVC_PANU) { + if(preq->bridge_mode == ENABLE_BRIDGE) { + + } + } + + //TODO validate parameters + if(bnep_sdp_register(preq->role)) + { + syslog(LOG_ERR, "BNEP register failed. %s(%d)", + strerror(errno), errno); + return -1; + } + + /* Create L2CAP socket and bind it to PSM BNEP */ + sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (sk < 0) { + syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)", + strerror(errno), errno); + return -1; + } + + pl2a = (struct sockaddr_l2*)malloc(sizeof(struct sockaddr_l2)); + memset(pl2a, 0, sizeof(struct sockaddr_l2)); + pl2a->l2_family = AF_BLUETOOTH; + bacpy(&(pl2a->l2_bdaddr), &src_addr); + pl2a->l2_psm = htobs(BNEP_PSM); + + if (bind(sk, (struct sockaddr *) pl2a, sizeof(struct sockaddr_l2))) { + syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno); + return -1; + } + + /* Setup L2CAP options according to BNEP spec */ + memset(&l2o, 0, sizeof(l2o)); + olen = sizeof(l2o); + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) { + syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)", + strerror(errno), errno); + return -1; + } + + l2o.imtu = l2o.omtu = BNEP_MTU; + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) { + syslog(LOG_ERR, "Failed to set L2CAP options. %s(%d)", + strerror(errno), errno); + return -1; + } + + /* Set link mode */ + lm = 0; + if (preq->master) + lm |= L2CAP_LM_MASTER; + if (preq->encrypt) + lm |= L2CAP_LM_ENCRYPT; + if (preq->secure) + lm |= L2CAP_LM_SECURE; + + if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { + syslog(LOG_ERR, "Failed to set link mode. %s(%d)", strerror(errno), errno); + return -1; + } + listen(sk, 10); + + listen_arguments = (listen_args_t*)malloc(sizeof(listen_args_t)); + listen_arguments->role = preq->role; + listen_arguments->sk = sk; + listen_arguments->l2a = pl2a; + + terminate = 0; + + return pthread_create (&threadid, NULL, &listen_thread, listen_arguments); +} +/** + * Cancel listen thread + * @param + * @return + */ +int +cmd_listen_stop(pand_dbus_listen_stop_req_t *preq) +{ + int ret_val = -1; + terminate = 1; + if(threadid) { + pthread_cancel(threadid); + threadid = 0; + ret_val = 0; + } + return ret_val; + +} + diff -urNaw bluez-utils-2.17.orig/pand/pand_dbus_commands.h bluez-utils-2.17-dbus/pand/pand_dbus_commands.h --- bluez-utils-2.17.orig/pand/pand_dbus_commands.h 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/pand_dbus_commands.h 2005-05-20 16:38:43.667253952 -0300 @@ -0,0 +1,45 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005 Claudio Takahasi + * 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: pand_dbus_commands.h,v 1.12 2005/05/22 13:00:00 holtmann Exp $ + */ + +#ifndef __H_PAND_DBUS_COMMANDS_H__ +#define __H_PAND_DBUS_COMMANDS_H__ + +#include "dbus_services.h" + +#define PAND_SIGNAL_STOP 0x01 + +int cmd_connect(char *dst, uint16_t role, uint16_t service); +int cmd_disconnect (pand_dbus_disconn_req_t *pdc); +int cmd_listen(pand_dbus_listen_req_t *preq); +int cmd_listen_stop(pand_dbus_listen_stop_req_t *preq); +int cmd_get_active_conn(pand_dbus_get_active_conn_req_t *preq, pand_dbus_get_active_conn_cnf_t**preq_cnf); +int cmd_get_devices(pand_dbus_get_dev_cnf_t **preq_cnf); + + +#endif diff -urNaw bluez-utils-2.17.orig/pand/pand_dbus.h bluez-utils-2.17-dbus/pand/pand_dbus.h --- bluez-utils-2.17.orig/pand/pand_dbus.h 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/pand_dbus.h 2005-05-20 17:12:06.456783664 -0300 @@ -0,0 +1,41 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005 Claudio Takahasi + * 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: pand_dbus.h,v 1.12 2005/05/22 13:00:00 holtmann Exp $ + */ +#ifndef __H_PAND_DBUS_H__ +#define __H_PAND_DBUS_H__ + +#include + + + + + +int pand_dbus_start(); +int pand_dbus_stop(); + +#endif /* __H_PAND_DBUS_H__*/ diff -urNaw bluez-utils-2.17.orig/pand/pand_dbus_util.c bluez-utils-2.17-dbus/pand/pand_dbus_util.c --- bluez-utils-2.17.orig/pand/pand_dbus_util.c 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/pand_dbus_util.c 2005-05-20 16:32:46.420563704 -0300 @@ -0,0 +1,102 @@ + +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005 Claudio Takahasi + * 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: pand_dbus_util.c,v 1.12 2005/05/22 13:00:00 holtmann Exp $ + */ + +#include +#include +#include +#include +#include + +#include "pand_dbus_util.h" +#include "dbus_services.h" + +/** + * Get message type + * @param + * @return + */ +PAND_MESSAGE_TYPE +pand_util_get_msg_type(DBusMessage * msg) +{ + PAND_MESSAGE_TYPE ret_type = PAND_DBUS_INVALID_TYPE; + DBusError error; + uint8_t type; + + dbus_error_init(&error); + + if(dbus_message_get_args (msg,&error,DBUS_TYPE_BYTE, &type, DBUS_TYPE_INVALID)) { + ret_type = type; + } + + dbus_error_free(&error); + + return ret_type; +} + +/** + * Get message attributes + * @param + * @return + */ +int pand_util_get_req_attr(DBusMessage *msg, PAND_MESSAGE_TYPE type, int size, void *preq_attr) +{ + const unsigned char *ptr; + DBusMessageIter iter; + int n, ret_val = -1; + PAND_MESSAGE_TYPE msg_type; + + if(msg) { + dbus_message_iter_init(msg, &iter); + //Get the fisrt byte in order to check the code + msg_type = dbus_message_iter_get_byte(&iter); + + if(msg_type == type) { + /* check wanted size to avoid memory access violation */ + if(size > 0) { + if(dbus_message_iter_next(&iter)) { + //TODO check return result + dbus_message_iter_get_byte_array(&iter,(void*) &ptr, &n); + if(n == size) { + memcpy(preq_attr, ptr, n); + ret_val = 0; + } + }else { + preq_attr = NULL; + } + }else if(size == 0) { + /* if the request doesn't have data, just return true */ + ret_val = 0; + } + } + } + return ret_val; +} + + diff -urNaw bluez-utils-2.17.orig/pand/pand_dbus_util.h bluez-utils-2.17-dbus/pand/pand_dbus_util.h --- bluez-utils-2.17.orig/pand/pand_dbus_util.h 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-2.17-dbus/pand/pand_dbus_util.h 2005-05-18 18:56:26.000000000 -0300 @@ -0,0 +1,55 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005 Claudio Takahasi + * 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: pand_dbus_util.h,v 1.12 2005/05/22 13:00:00 holtmann Exp $ + */ +#ifndef __H_PAND_DBUS_UTIL_H__ +#define __H_PAND_DBUS_UTIL_H__ + +#include "dbus_services.h" + + +/** + * + * + * + */ +PAND_MESSAGE_TYPE pand_util_get_msg_type(DBusMessage *); +/** + * + * + * size: wanted body size + */ +int pand_util_get_req_attr(DBusMessage *msg, PAND_MESSAGE_TYPE type, int size, void *preq_attr); +/** + * + * + * + */ +int pand_util_get_conn_req_attr(DBusMessage *, pand_dbus_conn_req_t*); + + +#endif /* __H_PAND_DBUS_UTIL_H__ */