summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hcid/dbus.c114
-rw-r--r--hcid/hcid.h16
-rw-r--r--hcid/security.c59
3 files changed, 167 insertions, 22 deletions
diff --git a/hcid/dbus.c b/hcid/dbus.c
index de51eee6..b6f516c0 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -112,7 +112,6 @@ error:
OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);
}
-
static void free_pin_req(void *req)
{
free(req);
@@ -173,15 +172,93 @@ failed:
OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr);
}
-void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi)
+void hcid_dbus_inquiry_start(bdaddr_t *local)
{
DBusMessage *message;
- char local_addr[18], peer_addr[18];
+#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS
+ DBusMessageIter iter;
+#endif
+ char local_addr[18];
+
+ ba2str(local, local_addr);
+
+ message = dbus_message_new_signal("/org/bluez/DevAgent",
+ "org.bluez.DevAgent", "InquiryStart");
+ if (message == NULL) {
+ syslog(LOG_ERR, "Can't allocate D-BUS inquiry start message");
+ goto failed;
+ }
+
#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS
- char *local_ptr = local_addr, *peer_ptr = peer_addr;
+ dbus_message_append_args(message,
+ DBUS_TYPE_STRING, local_addr,
+ DBUS_TYPE_INVALID);
#else
+ dbus_message_append_iter_init(message, &iter);
+
+ dbus_message_iter_append_string(&iter, local_addr);
+#endif
+
+ if (dbus_connection_send(connection, message, NULL) == FALSE) {
+ syslog(LOG_ERR, "Can't send D-BUS inquiry start message");
+ goto failed;
+ }
+
+ dbus_connection_flush(connection);
+
+failed:
+ dbus_message_unref(message);
+
+ return;
+}
+
+void hcid_dbus_inquiry_complete(bdaddr_t *local)
+{
+ DBusMessage *message;
+#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS
DBusMessageIter iter;
#endif
+ char local_addr[18];
+
+ ba2str(local, local_addr);
+
+ message = dbus_message_new_signal("/org/bluez/DevAgent",
+ "org.bluez.DevAgent", "InquiryComplete");
+ if (message == NULL) {
+ syslog(LOG_ERR, "Can't allocate D-BUS inquiry complete message");
+ goto failed;
+ }
+
+#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS
+ dbus_message_append_args(message,
+ DBUS_TYPE_STRING, local_addr,
+ DBUS_TYPE_INVALID);
+#else
+ dbus_message_append_iter_init(message, &iter);
+
+ dbus_message_iter_append_string(&iter, local_addr);
+#endif
+
+ if (dbus_connection_send(connection, message, NULL) == FALSE) {
+ syslog(LOG_ERR, "Can't send D-BUS inquiry complete message");
+ goto failed;
+ }
+
+ dbus_connection_flush(connection);
+
+failed:
+ dbus_message_unref(message);
+
+ return;
+}
+
+void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi)
+{
+ DBusMessage *message;
+#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS
+ DBusMessageIter iter;
+#endif
+ char local_addr[18], peer_addr[18];
ba2str(local, local_addr);
ba2str(peer, peer_addr);
@@ -195,10 +272,10 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i
#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS
dbus_message_append_args(message,
- DBUS_TYPE_STRING, &local_ptr,
- DBUS_TYPE_STRING, &peer_ptr,
- DBUS_TYPE_UINT32, &class,
- DBUS_TYPE_INT32, &rssi,
+ DBUS_TYPE_STRING, local_addr,
+ DBUS_TYPE_STRING, peer_addr,
+ DBUS_TYPE_UINT32, class,
+ DBUS_TYPE_INT32, rssi,
DBUS_TYPE_INVALID);
#else
dbus_message_append_iter_init(message, &iter);
@@ -225,13 +302,10 @@ failed:
void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
{
DBusMessage *message;
- char local_addr[18], peer_addr[18];
-#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS
- char *local_ptr = local_addr, *peer_ptr = peer_addr;
- char *name_ptr = name;
-#else
+#ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS
DBusMessageIter iter;
#endif
+ char local_addr[18], peer_addr[18];
ba2str(local, local_addr);
ba2str(peer, peer_addr);
@@ -245,9 +319,9 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
#ifdef HAVE_DBUS_MESSAGE_APPEND_ARGS
dbus_message_append_args(message,
- DBUS_TYPE_STRING, &local_ptr,
- DBUS_TYPE_STRING, &peer_ptr,
- DBUS_TYPE_STRING, &name_ptr,
+ DBUS_TYPE_STRING, local_addr,
+ DBUS_TYPE_STRING, peer_addr,
+ DBUS_TYPE_STRING, name,
DBUS_TYPE_INVALID);
#else
dbus_message_append_iter_init(message, &iter);
@@ -270,6 +344,14 @@ failed:
return;
}
+void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer)
+{
+}
+
+void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason)
+{
+}
+
gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
{
DBusWatch *watch = (DBusWatch *) data;
diff --git a/hcid/hcid.h b/hcid/hcid.h
index 4a433984..39b2cd09 100644
--- a/hcid/hcid.h
+++ b/hcid/hcid.h
@@ -123,15 +123,19 @@ void toggle_pairing(int enable);
#ifdef ENABLE_DBUS
gboolean hcid_dbus_init(void);
void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci);
+void hcid_dbus_inquiry_start(bdaddr_t *local);
+void hcid_dbus_inquiry_complete(bdaddr_t *local);
void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi);
void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name);
+void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer);
+void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason);
#else
-static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi)
-{
-}
-static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name)
-{
-}
+static inline void hcid_dbus_inquiry_start(bdaddr_t *local) {}
+static inline void hcid_dbus_inquiry_complete(bdaddr_t *local) {}
+static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) {}
+static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) {}
+static inline void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer) {}
+static inline void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) {}
#endif
int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name);
diff --git a/hcid/security.c b/hcid/security.c
index 7eec9e76..00204ace 100644
--- a/hcid/security.c
+++ b/hcid/security.c
@@ -482,6 +482,17 @@ reject:
return;
}
+static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr)
+{
+ evt_cmd_status *evt = ptr;
+
+ if (evt->status)
+ return;
+
+ if (evt->opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY))
+ hcid_dbus_inquiry_start(sba);
+}
+
static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr)
{
evt_remote_name_req_complete *evt = ptr;
@@ -516,6 +527,11 @@ static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr)
evt->lmp_ver, btohs(evt->lmp_subver));
}
+static inline void inquiry_complete(int dev, bdaddr_t *sba, void *ptr)
+{
+ hcid_dbus_inquiry_complete(sba);
+}
+
static inline void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr)
{
uint8_t num = *(uint8_t *) ptr++;
@@ -599,6 +615,29 @@ static inline void remote_features_information(int dev, bdaddr_t *sba, void *ptr
write_features_info(sba, &dba, evt->features);
}
+static inline void conn_complete(int dev, bdaddr_t *sba, void *ptr)
+{
+ evt_conn_complete *evt = ptr;
+
+ if (evt->status)
+ return;
+
+ hcid_dbus_conn_complete(sba, &evt->bdaddr);
+}
+
+static inline void disconn_complete(int dev, bdaddr_t *sba, void *ptr)
+{
+ evt_disconn_complete *evt = ptr;
+ bdaddr_t dba;
+
+ if (evt->status)
+ return;
+
+ bacpy(&dba, BDADDR_ANY);
+
+ hcid_dbus_disconn_complete(sba, &dba, evt->reason);
+}
+
static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf;
@@ -638,6 +677,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer
return TRUE;
switch (eh->evt) {
+ case EVT_CMD_STATUS:
+ cmd_status(dev, &di->bdaddr, ptr);
+ break;
+
case EVT_REMOTE_NAME_REQ_COMPLETE:
remote_name_information(dev, &di->bdaddr, ptr);
break;
@@ -650,6 +693,10 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer
remote_features_information(dev, &di->bdaddr, ptr);
break;
+ case EVT_INQUIRY_COMPLETE:
+ inquiry_complete(dev, &di->bdaddr, ptr);
+ break;
+
case EVT_INQUIRY_RESULT:
inquiry_result(dev, &di->bdaddr, eh->plen, ptr);
break;
@@ -661,6 +708,14 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer
case EVT_EXTENDED_INQUIRY_RESULT:
extended_inquiry_result(dev, &di->bdaddr, eh->plen, ptr);
break;
+
+ case EVT_CONN_COMPLETE:
+ conn_complete(dev, &di->bdaddr, ptr);
+ break;
+
+ case EVT_DISCONN_COMPLETE:
+ disconn_complete(dev, &di->bdaddr, ptr);
+ break;
}
if (hci_test_bit(HCI_SECMGR, &di->flags))
@@ -709,6 +764,7 @@ void start_security_manager(int hdev)
/* Set filter */
hci_filter_clear(&flt);
hci_filter_set_ptype(HCI_EVENT_PKT, &flt);
+ hci_filter_set_event(EVT_CMD_STATUS, &flt);
hci_filter_set_event(EVT_PIN_CODE_REQ, &flt);
hci_filter_set_event(EVT_LINK_KEY_REQ, &flt);
hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt);
@@ -716,9 +772,12 @@ void start_security_manager(int hdev)
hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt);
hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt);
hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt);
+ hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt);
hci_filter_set_event(EVT_INQUIRY_RESULT, &flt);
hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt);
hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt);
+ hci_filter_set_event(EVT_CONN_COMPLETE, &flt);
+ hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt);
if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
syslog(LOG_ERR, "Can't set filter on hci%d: %s (%d)",
hdev, strerror(errno), errno);