summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-10-23 21:27:41 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-10-23 21:27:41 +0000
commit55b5343679121898bbc999c38a670c444f602e17 (patch)
tree6cb7075583a53d9b65f1e90b40678708d6d05c9e
parent6ebb0299dc72b9b6141be5f2712b1319eb0ac1c1 (diff)
Add support for inquiry cancel functionality
-rw-r--r--hcid/dbus.c44
-rw-r--r--hcid/dbus.h5
-rw-r--r--hcid/security.c12
3 files changed, 60 insertions, 1 deletions
diff --git a/hcid/dbus.c b/hcid/dbus.c
index 8f0217ec..ce6f4e70 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -285,6 +285,7 @@ static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *m
static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data);
static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data);
static DBusMessage* handle_inq_req(DBusMessage *msg, void *data);
+static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data);
static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data);
static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data);
static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data);
@@ -295,6 +296,7 @@ static const struct service_data hci_services[] = {
{ HCI_CANCEL_PERIODIC_INQ, handle_cancel_periodic_inq_req, HCI_CANCEL_PERIODIC_INQ_SIGNATURE },
{ HCI_ROLE_SWITCH, handle_role_switch_req, HCI_ROLE_SWITCH_SIGNATURE },
{ HCI_INQ, handle_inq_req, HCI_INQ_SIGNATURE },
+ { HCI_CANCEL_INQ, handle_cancel_inq_req, HCI_CANCEL_INQ_SIGNATURE },
{ HCI_REMOTE_NAME, handle_remote_name_req, HCI_REMOTE_NAME_SIGNATURE },
{ HCI_CONNECTIONS, handle_display_conn_req, HCI_CONNECTIONS_SIGNATURE },
{ HCI_AUTHENTICATE, handle_auth_req, HCI_AUTHENTICATE_SIGNATURE },
@@ -1383,6 +1385,48 @@ failed:
return reply;
}
+static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data)
+{
+ DBusMessage *reply = NULL;
+ struct hci_request rq;
+ struct hci_dbus_data *dbus_data = data;
+ int dev_id = -1, dd = -1;
+
+ if (dbus_data->id == DEFAULT_DEVICE_PATH_ID) {
+ if ((dev_id = hci_get_route(NULL)) < 0) {
+ syslog(LOG_ERR, "Bluetooth device is not available");
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
+ goto failed;
+ }
+ } else
+ dev_id = dbus_data->id;
+
+ dd = hci_open_dev(dev_id);
+ if (dd < 0) {
+ syslog(LOG_ERR, "Unable to open device %d: %s", dev_id, strerror(errno));
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
+ goto failed;
+ }
+
+ memset(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LINK_CTL;
+ rq.ocf = OCF_INQUIRY_CANCEL;
+
+ if (hci_send_req(dd, &rq, 100) < 0) {
+ syslog(LOG_ERR, "Unable to cancel inquiry: %s", strerror(errno));
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
+ goto failed;
+ }
+
+ reply = dbus_message_new_method_return(msg);
+
+failed:
+ if (dd >= 0)
+ hci_close_dev(dd);
+
+ return reply;
+}
+
static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data)
{
DBusMessageIter iter;
diff --git a/hcid/dbus.h b/hcid/dbus.h
index b12934b3..0e18aea3 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -105,10 +105,11 @@
#define HCI_PERIODIC_INQ "PeriodicInquiry"
#define HCI_CANCEL_PERIODIC_INQ "CancelPeriodic"
#define HCI_INQ "Inquiry"
+#define HCI_CANCEL_INQ "CancelInquiry"
#define HCI_ROLE_SWITCH "RoleSwitch"
#define HCI_REMOTE_NAME "RemoteName"
#define HCI_CONNECTIONS "Connections"
-#define HCI_AUTHENTICATE "Authenticate"
+#define HCI_AUTHENTICATE "Authenticate"
#define HCI_PERIODIC_INQ_SIGNATURE DBUS_TYPE_BYTE_AS_STRING\
@@ -122,6 +123,8 @@
DBUS_TYPE_BYTE_AS_STRING\
__END_SIG__
+#define HCI_CANCEL_INQ_SIGNATURE __END_SIG__
+
#define HCI_ROLE_SWITCH_SIGNATURE DBUS_TYPE_STRING_AS_STRING\
DBUS_TYPE_BYTE_AS_STRING\
__END_SIG__
diff --git a/hcid/security.c b/hcid/security.c
index f53d33d1..670f8dde 100644
--- a/hcid/security.c
+++ b/hcid/security.c
@@ -493,6 +493,14 @@ static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr)
hcid_dbus_inquiry_start(sba);
}
+static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr)
+{
+ evt_cmd_complete *evt = ptr;
+
+ if (evt->opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL))
+ hcid_dbus_inquiry_complete(sba);
+}
+
static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr)
{
evt_remote_name_req_complete *evt = ptr;
@@ -679,6 +687,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer
cmd_status(dev, &di->bdaddr, ptr);
break;
+ case EVT_CMD_COMPLETE:
+ cmd_complete(dev, &di->bdaddr, ptr);
+ break;
+
case EVT_REMOTE_NAME_REQ_COMPLETE:
remote_name_information(dev, &di->bdaddr, ptr);
break;