summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2007-05-23 18:32:16 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2007-05-23 18:32:16 +0000
commit277e0363f2839a05b80c1bc4263cfeaf9909be8c (patch)
tree1a8830c7b7b030e9d4f5031ac08801f8f0474142
parent7cc971c79cd88798c5c40f9cdf85532a7aeab8a9 (diff)
Added device class tracking
-rw-r--r--hcid/dbus-adapter.c112
-rw-r--r--hcid/dbus-adapter.h1
-rw-r--r--hcid/dbus-api.txt13
-rw-r--r--hcid/dbus-hci.c49
-rw-r--r--hcid/dbus-hci.h1
-rw-r--r--hcid/device.c27
-rw-r--r--hcid/hcid.h1
-rw-r--r--hcid/security.c3
8 files changed, 98 insertions, 109 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c
index 27f7b1c8..ba8d1d90 100644
--- a/hcid/dbus-adapter.c
+++ b/hcid/dbus-adapter.c
@@ -768,8 +768,6 @@ static DBusHandlerResult adapter_get_major_class(DBusConnection *conn,
const struct adapter *adapter = data;
DBusMessage *reply;
const char *str_ptr = "computer";
- uint8_t cls[3];
- int dd;
if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
return error_invalid_arguments(conn, msg);
@@ -778,22 +776,8 @@ static DBusHandlerResult adapter_get_major_class(DBusConnection *conn,
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- dd = hci_open_dev(adapter->dev_id);
- if (dd < 0)
- return error_no_such_adapter(conn, msg);
-
- if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
- int err = errno;
- error("Can't read class of device on hci%d: %s(%d)",
- adapter->dev_id, strerror(errno), errno);
- hci_close_dev(dd);
- return error_failed(conn, msg, err);
- }
-
- hci_close_dev(dd);
-
/* FIXME: Currently, only computer major class is supported */
- if ((cls[1] & 0x1f) != 1)
+ if ((adapter->class[1] & 0x1f) != 1)
return error_unsupported_major_class(conn, msg);
dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr,
@@ -810,31 +794,13 @@ static DBusHandlerResult adapter_list_minor_classes(DBusConnection *conn,
DBusMessageIter iter;
DBusMessageIter array_iter;
const char **minor_ptr;
- uint8_t cls[3];
uint8_t major_class;
- int dd, size, i;
-
- if (!adapter->up)
- return error_not_ready(conn, msg);
+ int size, i;
if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
return error_invalid_arguments(conn, msg);
- dd = hci_open_dev(adapter->dev_id);
- if (dd < 0)
- return error_no_such_adapter(conn, msg);
-
- if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
- int err = errno;
- error("Can't read class of device on hci%d: %s(%d)",
- adapter->dev_id, strerror(errno), errno);
- hci_close_dev(dd);
- return error_failed(conn, msg, err);
- }
-
- hci_close_dev(dd);
-
- major_class = cls[1] & 0x1F;
+ major_class = adapter->class[1] & 0x1F;
switch (major_class) {
case 1: /* computer */
@@ -871,39 +837,20 @@ static DBusHandlerResult adapter_get_minor_class(DBusConnection *conn,
struct adapter *adapter = data;
DBusMessage *reply;
const char *str_ptr = "";
- uint8_t cls[3];
uint8_t minor_class;
- int dd;
-
- if (!adapter->up)
- return error_not_ready(conn, msg);
if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
return error_invalid_arguments(conn, msg);
- dd = hci_open_dev(adapter->dev_id);
- if (dd < 0)
- return error_no_such_adapter(conn, msg);
-
- if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
- int err = errno;
- error("Can't read class of device on hci%d: %s(%d)",
- adapter->dev_id, strerror(errno), errno);
- hci_close_dev(dd);
- return error_failed(conn, msg, err);
- }
-
- hci_close_dev(dd);
-
/* FIXME: Currently, only computer major class is supported */
- if ((cls[1] & 0x1f) != 1)
+ if ((adapter->class[1] & 0x1f) != 1)
return error_unsupported_major_class(conn, msg);
reply = dbus_message_new_method_return(msg);
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
- minor_class = cls[0] >> 2;
+ minor_class = adapter->class[0] >> 2;
/* Validate computer minor class */
if (minor_class > (sizeof(computer_minor_cls) / sizeof(*computer_minor_cls)))
@@ -923,9 +870,7 @@ static DBusHandlerResult adapter_set_minor_class(DBusConnection *conn,
{
struct adapter *adapter = data;
DBusMessage *reply;
- bdaddr_t bdaddr;
const char *minor;
- uint8_t cls[3];
uint32_t dev_class = 0xFFFFFFFF;
int i, dd;
@@ -944,18 +889,11 @@ static DBusHandlerResult adapter_set_minor_class(DBusConnection *conn,
if (dd < 0)
return error_no_such_adapter(conn, msg);
- if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
- int err = errno;
- error("Can't read class of device on hci%d: %s(%d)",
- adapter->dev_id, strerror(errno), errno);
- hci_close_dev(dd);
- return error_failed(conn, msg, err);
- }
-
/* Currently, only computer major class is supported */
- if ((cls[1] & 0x1f) != 1)
+ if ((adapter->class[1] & 0x1f) != 1) {
+ hci_close_dev(dd);
return error_unsupported_major_class(conn, msg);
-
+ }
for (i = 0; i < sizeof(computer_minor_cls) / sizeof(*computer_minor_cls); i++)
if (!strcasecmp(minor, computer_minor_cls[i])) {
/* Remove the format type */
@@ -964,18 +902,13 @@ static DBusHandlerResult adapter_set_minor_class(DBusConnection *conn,
}
/* Check if it's a valid minor class */
- if (dev_class == 0xFFFFFFFF)
+ if (dev_class == 0xFFFFFFFF) {
+ hci_close_dev(dd);
return error_invalid_arguments(conn, msg);
-
- /* update the minor class before store */
- cls[0] = (dev_class & 0xff);
+ }
/* set the service class and major class */
- dev_class |= (cls[2] << 16) | (cls[1] << 8);
-
- hci_devba(adapter->dev_id, &bdaddr);
-
- write_local_class(&bdaddr, cls);
+ dev_class |= (adapter->class[2] << 16) | (adapter->class[1] << 8);
if (hci_write_class_of_dev(dd, dev_class, 2000) < 0) {
int err = errno;
@@ -1006,8 +939,7 @@ static DBusHandlerResult adapter_get_service_classes(DBusConnection *conn,
DBusMessageIter iter;
DBusMessageIter array_iter;
const char *str_ptr;
- uint8_t cls[3];
- int dd, i;
+ int i;
if (!adapter->up)
return error_not_ready(conn, msg);
@@ -1015,19 +947,9 @@ static DBusHandlerResult adapter_get_service_classes(DBusConnection *conn,
if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING))
return error_invalid_arguments(conn, msg);
- dd = hci_open_dev(adapter->dev_id);
- if (dd < 0)
- return error_no_such_adapter(conn, msg);
-
- if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
- int err = errno;
- error("Can't read class of device on hci%d: %s(%d)",
- adapter->dev_id, strerror(errno), errno);
- hci_close_dev(dd);
- return error_failed(conn, msg, err);
- }
-
reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return DBUS_HANDLER_RESULT_NEED_MEMORY;
dbus_message_iter_init_append(reply, &iter);
@@ -1035,7 +957,7 @@ static DBusHandlerResult adapter_get_service_classes(DBusConnection *conn,
DBUS_TYPE_STRING_AS_STRING, &array_iter);
for (i = 0; i < (sizeof(service_cls) / sizeof(*service_cls)); i++) {
- if (cls[2] & (1 << i)) {
+ if (adapter->class[2] & (1 << i)) {
str_ptr = service_cls[i];
dbus_message_iter_append_basic(&array_iter,
DBUS_TYPE_STRING, &str_ptr);
@@ -1044,8 +966,6 @@ static DBusHandlerResult adapter_get_service_classes(DBusConnection *conn,
dbus_message_iter_close_container(&iter, &array_iter);
- hci_close_dev(dd);
-
return send_message_and_unref(conn, reply);
}
diff --git a/hcid/dbus-adapter.h b/hcid/dbus-adapter.h
index 6086787c..2c75c5dc 100644
--- a/hcid/dbus-adapter.h
+++ b/hcid/dbus-adapter.h
@@ -91,6 +91,7 @@ struct adapter {
guint timeout_id; /* discoverable timeout id */
uint32_t discov_timeout; /* discoverable time(msec) */
uint8_t mode; /* scan mode */
+ uint8_t class[3]; /* device class */
int discov_active; /* standard discovery active: includes name resolution step */
int pdiscov_active; /* periodic discovery active */
int pinq_idle; /* tracks the idle time for periodic inquiry */
diff --git a/hcid/dbus-api.txt b/hcid/dbus-api.txt
index 7f1ed3b6..9fc19578 100644
--- a/hcid/dbus-api.txt
+++ b/hcid/dbus-api.txt
@@ -434,9 +434,8 @@ Methods dict GetInfo()
For the other values, unsupported major class
error is returned.
- Possible errors: org.bluez.Error.NoSuchAdapter
+ Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.UnsupportedMajorClass
- org.bluez.Error.Failed
array{string} ListAvailableMinorClasses()
@@ -448,9 +447,7 @@ Methods dict GetInfo()
If the major class is not "computer" an error should
be returned.
- Possible errors: org.bluez.Error.NotReady
- org.bluez.Error.NoSuchAdapter
- org.bluez.Error.Failed
+ Possible errors: org.bluez.Error.InvalidArguments
org.bluez.Error.UnsupportedMajorClass
string GetMinorClass()
@@ -466,10 +463,8 @@ Methods dict GetInfo()
The default value is "uncategorized".
- Possible errors: org.bluez.Error.NotReady
- org.bluez.Error.NoSuchAdapter
- org.bluez.Error.Failed
- org.bluez.Error.UnsupportedMajorClass
+ Possible errors:org.bluez.Error.InvalidArguments
+ org.bluez.Error.UnsupportedMajorClass
void SetMinorClass(string minor)
diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c
index c0e3b5f3..242d8e3d 100644
--- a/hcid/dbus-hci.c
+++ b/hcid/dbus-hci.c
@@ -586,8 +586,11 @@ int hcid_dbus_start_device(uint16_t id)
if (err < 0)
goto failed;
- adapter_mode_changed(adapter, path, mode);
+ err = get_device_class(adapter->dev_id, adapter->class);
+ if (err < 0)
+ goto failed;
+ adapter_mode_changed(adapter, path, mode);
/*
* retrieve the active connections: address the scenario where
* the are active connections before the daemon've started
@@ -1838,6 +1841,50 @@ failed:
bt_free(local_addr);
}
+void hcid_dbus_write_class_complete(bdaddr_t *local)
+{
+ struct adapter *adapter;
+ char path[MAX_PATH_LENGTH];
+ char *local_addr;
+ bdaddr_t tmp;
+ int id, dd = -1;
+ uint8_t cls[3];
+
+ baswap(&tmp, local); local_addr = batostr(&tmp);
+ id = hci_devid(local_addr);
+ if (id < 0) {
+ error("No matching device id for %s", local_addr);
+ goto failed;
+ }
+
+ snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);
+ if (!dbus_connection_get_object_user_data(connection, path,
+ (void *) &adapter)) {
+ error("Getting %s path data failed!", path);
+ goto failed;
+ }
+
+ dd = hci_open_dev(id);
+ if (dd < 0) {
+ error("HCI device open failed: hci%d", id);
+ goto failed;
+ }
+
+ if (hci_read_class_of_dev(dd, cls, 1000) < 0) {
+ error("Can't read class of device on hci%d: %s(%d)",
+ id, strerror(errno), errno);
+ goto failed;
+ }
+
+ write_local_class(local, cls);
+ memcpy(adapter->class, cls, 3);
+failed:
+ if (dd >= 0)
+ hci_close_dev(dd);
+
+ bt_free(local_addr);
+}
+
void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr)
{
diff --git a/hcid/dbus-hci.h b/hcid/dbus-hci.h
index 5a7f9628..eb81415f 100644
--- a/hcid/dbus-hci.h
+++ b/hcid/dbus-hci.h
@@ -49,6 +49,7 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, uint16_t handle
void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status);
void hcid_dbus_setname_complete(bdaddr_t *local);
void hcid_dbus_setscan_enable_complete(bdaddr_t *local);
+void hcid_dbus_write_class_complete(bdaddr_t *local);
void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr);
int unregister_adapter_path(const char *path);
diff --git a/hcid/device.c b/hcid/device.c
index 4d2239ec..920a4dad 100644
--- a/hcid/device.c
+++ b/hcid/device.c
@@ -81,6 +81,7 @@ struct hci_dev {
uint16_t manufacturer;
uint8_t name[248];
+ uint8_t class[3];
struct hci_peer *peers;
struct hci_conn *conns;
@@ -203,7 +204,7 @@ int start_device(uint16_t dev_id)
struct hci_dev *dev;
struct hci_version ver;
uint8_t features[8], inqmode;
- int dd;
+ int dd, err;
ASSERT_DEV_ID;
@@ -233,15 +234,23 @@ int start_device(uint16_t dev_id)
dev->manufacturer = ver.manufacturer;
if (hci_read_local_features(dd, features, 1000) < 0) {
- int err = errno;
+ err = errno;
error("Can't read features for hci%d: %s (%d)",
- dev_id, strerror(errno), errno);
+ dev_id, strerror(err), err);
hci_close_dev(dd);
return -err;
}
memcpy(dev->features, features, 8);
+ if (hci_read_class_of_dev(dd, dev->class, 1000) < 0) {
+ err = errno;
+ error("Can't read class of device on hci%d: %s(%d)",
+ dev_id, strerror(err), err);
+ hci_close_dev(dd);
+ return -err;
+ }
+
inqmode = get_inquiry_mode(dev);
if (inqmode < 1)
goto done;
@@ -285,6 +294,18 @@ int get_device_address(uint16_t dev_id, char *address, size_t size)
return ba2str(&dev->bdaddr, address);
}
+int get_device_class(uint16_t dev_id, uint8_t *cls)
+{
+ struct hci_dev *dev;
+
+ ASSERT_DEV_ID;
+
+ dev = &devices[dev_id];
+ memcpy(cls, dev->class, 3);
+
+ return 0;
+}
+
int get_device_version(uint16_t dev_id, char *version, size_t size)
{
struct hci_dev *dev;
diff --git a/hcid/hcid.h b/hcid/hcid.h
index 86b21639..50451a6b 100644
--- a/hcid/hcid.h
+++ b/hcid/hcid.h
@@ -157,6 +157,7 @@ int start_device(uint16_t dev_id);
int stop_device(uint16_t dev_id);
int get_device_address(uint16_t dev_id, char *address, size_t size);
+int get_device_class(uint16_t dev_id, uint8_t *class);
int get_device_version(uint16_t dev_id, char *version, size_t size);
int get_device_revision(uint16_t dev_id, char *revision, size_t size);
int get_device_manufacturer(uint16_t dev_id, char *manufacturer, size_t size);
diff --git a/hcid/security.c b/hcid/security.c
index 77062dbd..3f72f5cd 100644
--- a/hcid/security.c
+++ b/hcid/security.c
@@ -436,6 +436,9 @@ static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr)
case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE):
hcid_dbus_setscan_enable_complete(sba);
break;
+ case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV):
+ hcid_dbus_write_class_complete(sba);
+ break;
case cmd_opcode_pack(OGF_LINK_CTL, OCF_PIN_CODE_REPLY):
case cmd_opcode_pack(OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY):
hcid_dbus_pin_code_reply(sba, ptr);