diff options
Diffstat (limited to 'hcid')
-rw-r--r-- | hcid/dbus.c | 47 | ||||
-rw-r--r-- | hcid/dbus.h | 1 | ||||
-rw-r--r-- | hcid/hcid.h | 2 | ||||
-rw-r--r-- | hcid/security.c | 16 |
4 files changed, 65 insertions, 1 deletions
diff --git a/hcid/dbus.c b/hcid/dbus.c index b7271f0d..8c324bcd 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -668,6 +668,51 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t reason) { } +void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status) +{ + DBusMessage *message = NULL; + char *local_addr, *peer_addr; + bdaddr_t tmp; + char path[MAX_PATH_LENGTH]; + int id; + + baswap(&tmp, local); local_addr = batostr(&tmp); + baswap(&tmp, peer); peer_addr = batostr(&tmp); + + id = hci_devid(local_addr); + if (id < 0) { + syslog(LOG_ERR, "No matching device id for %s", local_addr); + goto failed; + } + + snprintf(path, sizeof(path), "%s/hci%d/%s", MANAGER_PATH, id, BLUEZ_HCI); + + message = dbus_message_new_signal(path, BLUEZ_HCI_INTERFACE, BLUEZ_HCI_AUTH_COMPLETE); + if (message == NULL) { + syslog(LOG_ERR, "Can't allocate D-BUS remote name message"); + goto failed; + } + + dbus_message_append_args(message, + DBUS_TYPE_STRING, &peer_addr, + DBUS_TYPE_BYTE, &status, + DBUS_TYPE_INVALID); + + if (dbus_connection_send(connection, message, NULL) == FALSE) { + syslog(LOG_ERR, "Can't send D-BUS remote name message"); + goto failed; + } + + dbus_connection_flush(connection); + +failed: + if (message) + dbus_message_unref(message); + + bt_free(local_addr); + bt_free(peer_addr); +} + gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data) { DBusWatch *watch = (DBusWatch *) data; @@ -1697,7 +1742,7 @@ static DBusMessage* handle_auth_req(DBusMessage *msg, void *data) rq.rlen = EVT_CMD_STATUS_SIZE; rq.event = EVT_CMD_STATUS; - if (hci_send_req(dd, &rq, 25000) < 0) { + if (hci_send_req(dd, &rq, 100) < 0) { syslog(LOG_ERR, "Unable to send authentication request: %s", strerror(errno)); reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno); goto failed; diff --git a/hcid/dbus.h b/hcid/dbus.h index 0e18aea3..45ead04d 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -96,6 +96,7 @@ #define BLUEZ_HCI_INQ_RESULT "InquiryResult" #define BLUEZ_HCI_REMOTE_NAME "RemoteName" #define BLUEZ_HCI_REMOTE_NAME_FAILED "RemoteNameFailed" +#define BLUEZ_HCI_AUTH_COMPLETE "AuthenticationComplete" //HCI signals sent in the BLUEZ_HCI_PATH #define BLUEZ_HCI_DEV_ADDED "DeviceAdded" diff --git a/hcid/hcid.h b/hcid/hcid.h index 0e5a673e..e7dfeb82 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -137,6 +137,7 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name); void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status); 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); +void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status); #else static inline void hcid_dbus_inquiry_start(bdaddr_t *local) {} static inline void hcid_dbus_inquiry_complete(bdaddr_t *local) {} @@ -145,6 +146,7 @@ static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char * static inline void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status) {} 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) {} +static inline void hcid_dbus_auth_complete(bdaddr_t *local, bdaddr_t *peer, const uint8_t status) {} #endif int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); diff --git a/hcid/security.c b/hcid/security.c index 0bcb8d38..1c363906 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -644,6 +644,18 @@ static inline void disconn_complete(int dev, bdaddr_t *sba, void *ptr) hcid_dbus_disconn_complete(sba, &dba, evt->reason); } +static inline void auth_complete(int dev, bdaddr_t *sba, void *ptr) +{ + evt_auth_complete *evt = ptr; + bdaddr_t dba; + + if (get_bdaddr(dev, sba, evt->handle, &dba) < 0) + return; + + hcid_dbus_auth_complete(sba, &dba, evt->status); +} + + static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data) { unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; @@ -726,6 +738,9 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer case EVT_DISCONN_COMPLETE: disconn_complete(dev, &di->bdaddr, ptr); break; + case EVT_AUTH_COMPLETE: + auth_complete(dev, &di->bdaddr, ptr); + break; } if (hci_test_bit(HCI_SECMGR, &di->flags)) @@ -789,6 +804,7 @@ void start_security_manager(int hdev) 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); + hci_filter_set_event(EVT_AUTH_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); |