--- bluez-utils-cvs.orig/hcid/Makefile.am 2005-09-14 08:51:58.000000000 -0300 +++ bluez-utils-cvs-hcid-dbus/hcid/Makefile.am 2005-09-15 17:03:22.000000000 -0300 @@ -13,7 +13,7 @@ sbin_PROGRAMS = hcid if DBUS -dbus_hcid_sources = dbus.c +dbus_hcid_sources = common.c dbus.c dbus_hcid_libs = @DBUS_LIBS@ dbus_hcid_cflags = -DENABLE_DBUS -DDBUS_API_SUBJECT_TO_CHANGE else --- bluez-utils-cvs.orig/hcid/dbus-internal.h 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-cvs-hcid-dbus/hcid/dbus-internal.h 2005-09-16 11:33:09.049265392 -0300 @@ -0,0 +1,71 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id: dbus-internal.h,v 0.1 2005/09/16 08:00:00 holtmann Exp $ + */ + +#ifndef __H_BLUEZ_DBUS_INTERNAL_H__ +#define __H_BLUEZ_DBUS_INTERNAL_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "dbus.h" + +typedef DBusMessage* (service_handler_func_t)(DBusMessage *, void *); + +typedef struct +{ + const char *name; + service_handler_func_t *handler_func; + const char *signature; +}__attribute__((packed))service_table_t; + +typedef enum +{ + RESULT_SUCCESS = 0, + RESULT_FAILED = 0x01, + RESULT_WRONG_PARAM = 0x02, + RESULT_BUSY = 0x04, + RESULT_ADAPTER_NOT_FOUND = 0x08, + RESULT_WRONG_SIG = 0x10, + RESULT_UNKNOWN_METHOD = 0x20, + RESULT_SVC_NOT_FOUND = 0x40, +}__attribute__((packed)) EXEC_RESULT; + + +DBusMessage *create_error_reply_message(DBusMessage *msg, const char *iface, EXEC_RESULT result); + +#endif /*__H_BLUEZ_DBUS_INTERNAL_H__*/ --- bluez-utils-cvs.orig/hcid/dbus.h 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-cvs-hcid-dbus/hcid/dbus.h 2005-09-16 11:33:38.448795984 -0300 @@ -0,0 +1,86 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id: dbus.h,v 0.1 2005/09/16 08:00:00 holtmann Exp $ + */ + +#ifndef __H_BLUEZ_DBUS_H__ +#define __H_BLUEZ_DBUS_H__ + +#define __END_SIG__ DBUS_TYPE_INVALID_AS_STRING + +/* bluetoothd Bus name */ +#define BLUEZ_DBUS_NAME "org.bluez" + +/* HCI definitions */ +#define BLUEZ_DBUS_HCI_PATH "/org/bluez/hci" +#define BLUEZ_DBUS_HCI_INTERFACE BLUEZ_DBUS_NAME".hci" + +//HCI signals +#define BLUEZ_DBUS_HCI_SIG_INQ_START "InquiryStartSig" +#define BLUEZ_DBUS_HCI_SIG_INQ_COMPLETE "InquiryCompleteSig" +#define BLUEZ_DBUS_HCI_SIG_INQ_RESULT "InquiryResultSig" +#define BLUEZ_DBUS_HCI_SIG_REMOTE_NAME "RemoteNameSig" + +//HCI Provided services +#define HCI_PERIODIC_INQ_REQ "PeriodicInqReq" +#define HCI_CANCEL_PERIODIC_INQ_REQ "CancelPeriodicInqReq" +#define HCI_INQ_REQ "InquiryReq" +#define HCI_ROLE_SWITCH_REQ "RoleSwitchReq" + +//HCI signatures +#define HCI_PERIODIC_INQ_REQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + __END_SIG__ +#define HCI_CANCEL_PERIODIC_INQ_REQ_SIGNATURE __END_SIG__ +#define HCI_INQ_REQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\ + __END_SIG__ +#define HCI_ROLE_SWITCH_REQ_SIGNATURE DBUS_TYPE_STRING_AS_STRING\ + DBUS_TYPE_BYTE_AS_STRING\ + __END_SIG__ + + +/* Common Error messages */ +#define ERR_UNKNOWN_METHOD ".error.UnknowMethod" +#define ERR_WRONG_SIGNATURE ".error.WrongSignature" +#define ERR_WRONG_PARAM ".error.WrongParam" +#define ERR_FAILED ".error.Failed" +#define ERR_REC_NOT_FOUND ".error.RecordNotFound" +#define ERR_BUSY ".error.Busy" +#define ERR_NO_DEV_FOUND ".error.NoDevFound" + +#define ERR_MSG_INVALID_PARAMETERS "Invalid parameters" +#define ERR_MSG_NO_SVC_FOUND "No service found" +#define ERR_MSG_DEV_BUSY "Device is busy" +#define ERR_MSG_FAILED "Operation failed" +#define ERR_MSG_NO_DEV_FOUND "Active Bluetooth adapter not found" +#define ERR_MSG_WRONG_SIG "Wrong method signature" +#define ERR_MSG_METHOD_NOT_FOUND "Method not found on the interface" + + +#endif /*__H_BLUEZ_DBUS_H__*/ --- bluez-utils-cvs.orig/hcid/dbus.c 2005-09-15 18:05:23.000000000 -0300 +++ bluez-utils-cvs-hcid-dbus/hcid/dbus.c 2005-09-16 11:36:41.362988800 -0300 @@ -45,6 +45,7 @@ #include "glib-ectomy.h" #include "hcid.h" +#include "dbus-internal.h" static DBusConnection *connection; @@ -62,6 +63,32 @@ bdaddr_t bda; }; +static DBusHandlerResult hci_msg_func(DBusConnection *conn, + DBusMessage *msg, void *data); + +static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data); +static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data); +static DBusMessage* handle_inq_req(DBusMessage *msg, void *data); +static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data); + + +static const DBusObjectPathVTable hci_vtable = { + NULL, + &hci_msg_func, + NULL, + NULL, + NULL, + NULL +}; + +static const service_table_t hci_services[] = { + {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_ROLE_SWITCH_REQ, handle_role_switch_req, HCI_ROLE_SWITCH_REQ_SIGNATURE}, + {HCI_INQ_REQ, handle_inq_req, HCI_INQ_REQ_SIGNATURE}, + {NULL, NULL, NULL} +}; + static void reply_handler_function(DBusPendingCall *call, void *user_data) { struct pin_request *req = (struct pin_request *) user_data; @@ -169,8 +196,9 @@ baswap(&tmp, local); local_addr = batostr(&tmp); - message = dbus_message_new_signal("/org/bluez/DevAgent", - "org.bluez.DevAgent", "InquiryStart"); + message = dbus_message_new_signal(BLUEZ_DBUS_HCI_PATH, + BLUEZ_DBUS_HCI_INTERFACE, + BLUEZ_DBUS_HCI_SIG_INQ_START); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry start message"); goto failed; @@ -203,8 +231,9 @@ baswap(&tmp, local); local_addr = batostr(&tmp); - message = dbus_message_new_signal("/org/bluez/DevAgent", - "org.bluez.DevAgent", "InquiryComplete"); + message = dbus_message_new_signal(BLUEZ_DBUS_HCI_PATH, + BLUEZ_DBUS_HCI_INTERFACE, + BLUEZ_DBUS_HCI_SIG_INQ_COMPLETE); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message"); goto failed; @@ -238,8 +267,9 @@ baswap(&tmp, local); local_addr = batostr(&tmp); baswap(&tmp, peer); peer_addr = batostr(&tmp); - message = dbus_message_new_signal("/org/bluez/DevAgent", - "org.bluez.DevAgent", "InquiryResult"); + message = dbus_message_new_signal(BLUEZ_DBUS_HCI_PATH, + BLUEZ_DBUS_HCI_INTERFACE, + BLUEZ_DBUS_HCI_SIG_INQ_RESULT); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS inquiry result message"); goto failed; @@ -277,8 +307,9 @@ baswap(&tmp, local); local_addr = batostr(&tmp); baswap(&tmp, peer); peer_addr = batostr(&tmp); - message = dbus_message_new_signal("/org/bluez/DevAgent", - "org.bluez.DevAgent", "RemoteName"); + message = dbus_message_new_signal(BLUEZ_DBUS_HCI_PATH, + BLUEZ_DBUS_HCI_INTERFACE, + BLUEZ_DBUS_HCI_SIG_REMOTE_NAME); if (message == NULL) { syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); goto failed; @@ -388,15 +419,114 @@ dbus_error_init(&error); connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { fprintf(stderr, "Failed to open connection to system message bus: %s\n", error.message); dbus_error_free(&error); return FALSE; } + + dbus_bus_request_name(connection, BLUEZ_DBUS_NAME, + DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT, + &error); + + if (dbus_error_is_set (&error)) { + syslog(LOG_ERR,"D-Bus Error: %s\n", error.message); + dbus_error_free (&error); + return FALSE; + } + + if (!dbus_connection_register_object_path(connection, BLUEZ_DBUS_HCI_PATH, &hci_vtable, NULL)) { + syslog(LOG_ERR,"DBUS failed to register %s object", BLUEZ_DBUS_HCI_PATH); + return FALSE; + } dbus_connection_set_watch_functions(connection, add_watch, remove_watch, watch_toggled, NULL, NULL); - return TRUE; } + +/***************************************************************** + * + * Section reserved to D-Bus message handlers + * + *****************************************************************/ + +static DBusHandlerResult hci_msg_func(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const service_table_t *ptr_handlers = hci_services; + DBusMessage *reply = NULL; + uint16_t type; + const char *iface; + const char *method; + const char *signature; + EXEC_RESULT result = RESULT_UNKNOWN_METHOD; + DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;; + + type = dbus_message_get_type(msg); + iface = dbus_message_get_interface(msg); + method = dbus_message_get_member (msg); + signature = dbus_message_get_signature(msg); + + syslog(LOG_INFO, "%s - type:%d, iface:%s, method:%s, sig:%s",__PRETTY_FUNCTION__, type, iface, method, signature); + + if ((type == DBUS_MESSAGE_TYPE_METHOD_CALL) && + (strcmp(iface, BLUEZ_DBUS_HCI_INTERFACE) == 0) && + (method != NULL)) { + + for (; ptr_handlers->name; ptr_handlers++) { + if (strcmp(method, ptr_handlers->name) == 0) { + /* resetting unknown method. It's possible handle method overload */ + result = RESULT_WRONG_SIG; + if (strcmp(ptr_handlers->signature, signature) == 0) { + reply = (ptr_handlers->handler_func)(msg, data); + result = 0; /* resetting wrong signature*/ + break; + } + + } + } + + if (result) { + reply = create_error_reply_message(msg, BLUEZ_DBUS_HCI_INTERFACE, result); + } + + /* send an error or the success reply*/ + if (reply) { + if (!dbus_connection_send (conn, reply, NULL)) { + syslog(LOG_ERR, "%s line:%d Can't send reply message!", \ + __PRETTY_FUNCTION__, __LINE__) ; + } + dbus_message_unref (reply); + } + + ret = DBUS_HANDLER_RESULT_HANDLED; + } + return ret; +} + +static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data) +{ + syslog(LOG_INFO, "%s", __PRETTY_FUNCTION__); + return NULL; +} + +static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data) +{ + syslog(LOG_INFO, "%s", __PRETTY_FUNCTION__); + return NULL; +} + +static DBusMessage* handle_inq_req(DBusMessage *msg, void *data) +{ + syslog(LOG_INFO, "%s", __PRETTY_FUNCTION__); + return NULL; +} + +static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data) +{ + syslog(LOG_INFO, "%s", __PRETTY_FUNCTION__); + return NULL; +} --- bluez-utils-cvs.orig/hcid/common.c 1969-12-31 21:00:00.000000000 -0300 +++ bluez-utils-cvs-hcid-dbus/hcid/common.c 2005-09-16 11:33:26.074677136 -0300 @@ -0,0 +1,80 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2002-2005 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + * SOFTWARE IS DISCLAIMED. + * + * + * $Id: common.c ,v 0.1 2005/09/16 08:00:00 holtmann Exp $ + */ + +#include "dbus-internal.h" + +DBusMessage *create_error_reply_message(DBusMessage *msg, const char *iface, EXEC_RESULT result) +{ + DBusMessage *reply = NULL; + const char *error_msg = NULL; + char perror_name[128]; + + switch(result) { + case RESULT_FAILED: + sprintf(perror_name, "%s%s",iface, ERR_FAILED); + error_msg = ERR_MSG_FAILED; + break; + case RESULT_BUSY: + sprintf(perror_name, "%s%s",iface, ERR_BUSY); + error_msg = ERR_MSG_DEV_BUSY; + break; + case RESULT_WRONG_PARAM: + sprintf(perror_name, "%s%s",iface, ERR_WRONG_PARAM); + error_msg = ERR_MSG_INVALID_PARAMETERS; + break; + case RESULT_ADAPTER_NOT_FOUND: + sprintf(perror_name, "%s%s",iface, ERR_NO_DEV_FOUND); + error_msg = ERR_MSG_NO_DEV_FOUND; + break; + case RESULT_WRONG_SIG: + sprintf(perror_name, "%s%s",iface, ERR_WRONG_SIGNATURE); + error_msg = ERR_MSG_WRONG_SIG; + break; + case RESULT_UNKNOWN_METHOD: + sprintf(perror_name, "%s%s",iface, ERR_UNKNOWN_METHOD); + error_msg = ERR_MSG_METHOD_NOT_FOUND; + break; + case RESULT_SVC_NOT_FOUND: + sprintf(perror_name, "%s%s",iface, ERR_REC_NOT_FOUND); + error_msg = ERR_MSG_NO_SVC_FOUND; + break; + default: + error_msg = NULL; + break; + /* RESULT_SUCCESS: ignore, it must be created by the caller + break; + */ + } + + syslog(LOG_INFO, "%s - error:%s", __PRETTY_FUNCTION__, perror_name); + reply = dbus_message_new_error(msg, (const char*)perror_name, error_msg); + + return reply; +}