summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-10-22 12:56:13 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-10-22 12:56:13 +0000
commitd2506e5078e02804484d5e416e23a49fb646151b (patch)
treec57cf3822556660b1b4afdc233237a29b87f0235
parent97a6bcbbe32c89438f4f54e47b376c75e2949763 (diff)
Make the remote name resolve non-blocking
-rw-r--r--hcid/dbus.c108
-rw-r--r--hcid/dbus.h1
-rw-r--r--hcid/hcid.h2
-rw-r--r--hcid/security.c18
4 files changed, 104 insertions, 25 deletions
diff --git a/hcid/dbus.c b/hcid/dbus.c
index 60958f3b..59d45634 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -513,6 +513,53 @@ failed:
return;
}
+void hcid_dbus_remote_name_failed(bdaddr_t *local, bdaddr_t *peer, uint8_t status)
+{
+ DBusMessage *message = NULL;
+ char path[MAX_PATH_LENGTH];
+ char *local_addr, *peer_addr;
+ bdaddr_t tmp;
+ 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_REMOTE_NAME_FAILED);
+ 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:
+ dbus_message_unref(message);
+
+ bt_free(local_addr);
+ bt_free(peer_addr);
+
+ return;
+}
+
void hcid_dbus_conn_complete(bdaddr_t *local, bdaddr_t *peer)
{
}
@@ -1207,6 +1254,7 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data)
DBusMessageIter iter;
DBusMessage *reply = NULL;
inquiry_cp cp;
+ evt_cmd_status rp;
struct hci_request rq;
struct hci_dbus_data *dbus_data = data;
int dev_id = -1, dd = -1;
@@ -1250,6 +1298,9 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data)
rq.ocf = OCF_INQUIRY;
rq.cparam = &cp;
rq.clen = INQUIRY_CP_SIZE;
+ rq.rparam = &rp;
+ rq.rlen = EVT_CMD_STATUS_SIZE;
+ rq.event = EVT_CMD_STATUS;
if (hci_send_req(dd, &rq, 100) < 0) {
syslog(LOG_ERR, "Unable to start inquiry: %s", strerror(errno));
@@ -1257,6 +1308,12 @@ static DBusMessage* handle_inq_req(DBusMessage *msg, void *data)
goto failed;
}
+ if (rp.status) {
+ syslog(LOG_ERR, "Inquiry command failed with status 0x%02X", rp.status);
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + EIO);
+ goto failed;
+ }
+
reply = dbus_message_new_method_return(msg);
failed:
@@ -1322,8 +1379,6 @@ failed:
static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data)
{
- char name[64];
- const char *pname = name;
DBusMessageIter iter;
DBusMessage *reply = NULL;
struct hci_dbus_data *dbus_data = data;
@@ -1331,6 +1386,9 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data)
int dd = -1;
const char *str_bdaddr;
bdaddr_t bdaddr;
+ struct hci_request rq;
+ remote_name_req_cp cp;
+ evt_cmd_status rp;
dbus_message_iter_init(msg, &iter);
dbus_message_iter_get_basic(&iter, &str_bdaddr);
@@ -1343,27 +1401,47 @@ static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data)
reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);
goto failed;
}
- } else {
+ } else
dev_id = dbus_data->id;
- }
dd = hci_open_dev(dev_id);
- if (dd >= 0) {
- if (hci_read_remote_name(dd, &bdaddr, sizeof(name), name, READ_REMOTE_NAME_TIMEOUT) ==0) {
- reply = dbus_message_new_method_return(msg);
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &pname);
- } else {
- reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
- }
- } else {
+ 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(&cp, 0, sizeof(cp));
+ cp.bdaddr = bdaddr;
+ cp.pscan_rep_mode = 0x01;
+
+ memset(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LINK_CTL;
+ rq.ocf = OCF_REMOTE_NAME_REQ;
+ rq.cparam = &cp;
+ rq.clen = REMOTE_NAME_REQ_CP_SIZE;
+ rq.rparam = &rp;
+ rq.rlen = EVT_CMD_STATUS_SIZE;
+ rq.event = EVT_CMD_STATUS;
+
+ if (hci_send_req(dd, &rq, 100) < 0) {
+ syslog(LOG_ERR, "Unable to send remote name request: %s", strerror(errno));
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + errno);
+ goto failed;
}
- if (dd > 0)
- close(dd);
+ if (rp.status) {
+ syslog(LOG_ERR, "Remote name command failed with status 0x%02X", rp.status);
+ reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_OFFSET + EIO);
+ goto failed;
+ }
+
+ reply = dbus_message_new_method_return(msg);
failed:
+ if (dd >= 0)
+ hci_close_dev(dd);
+
return reply;
}
diff --git a/hcid/dbus.h b/hcid/dbus.h
index faa19ea4..8ba4af91 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -116,6 +116,7 @@
#define BLUEZ_HCI_INQ_COMPLETE "InquiryComplete"
#define BLUEZ_HCI_INQ_RESULT "InquiryResult"
#define BLUEZ_HCI_REMOTE_NAME "RemoteName"
+#define BLUEZ_HCI_REMOTE_NAME_FAILED "RemoteNameFailed"
//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 d407c4c7..048a0aed 100644
--- a/hcid/hcid.h
+++ b/hcid/hcid.h
@@ -132,6 +132,7 @@ 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_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);
#else
@@ -139,6 +140,7 @@ 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_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) {}
#endif
diff --git a/hcid/security.c b/hcid/security.c
index eb50ee32..f53d33d1 100644
--- a/hcid/security.c
+++ b/hcid/security.c
@@ -496,20 +496,18 @@ static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr)
static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr)
{
evt_remote_name_req_complete *evt = ptr;
- char name[249];
bdaddr_t dba;
- if (evt->status)
- return;
-
- memset(name, 0, sizeof(name));
- memcpy(name, evt->name, 248);
-
bacpy(&dba, &evt->bdaddr);
- hcid_dbus_remote_name(sba, &dba, name);
-
- write_device_name(sba, &dba, name);
+ if (!evt->status) {
+ char name[249];
+ memset(name, 0, sizeof(name));
+ memcpy(name, evt->name, 248);
+ write_device_name(sba, &dba, name);
+ hcid_dbus_remote_name(sba, &dba, name);
+ } else
+ hcid_dbus_remote_name_failed(sba, &dba, evt->status);
}
static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr)