Diff between a5783264f7975b4e8f1d012bc033a10ee6e5b19c and 7cfcd11a958f785dcb7bd053b19972df7ef10336

Changed Files

File Additions Deletions Status
plugins/hciops.c +107 -98 modified
plugins/mgmtops.c +64 -53 modified
src/adapter.c +24 -14 modified
src/adapter.h +3 -0 modified

Full Patch

diff --git a/plugins/hciops.c b/plugins/hciops.c
index 00b9006..3d68796 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -647,13 +647,111 @@ static int hciops_stop_inquiry(int index)
 	return 0;
 }
 
+static void update_ext_inquiry_response(int index)
+{
+	struct dev_info *dev = &devs[index];
+	write_ext_inquiry_response_cp cp;
+
+	DBG("hci%d", index);
+
+	if (!(dev->features[6] & LMP_EXT_INQ))
+		return;
+
+	if (dev->ssp_mode == 0)
+		return;
+
+	if (dev->cache_enable)
+		return;
+
+	memset(&cp, 0, sizeof(cp));
+
+	eir_create(dev->name, dev->tx_power, dev->did_vendor, dev->did_product,
+					dev->did_version, dev->uuids, cp.data);
+
+	if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0)
+		return;
+
+	memcpy(dev->eir, cp.data, sizeof(cp.data));
+
+	if (hci_send_cmd(dev->sk, OGF_HOST_CTL,
+				OCF_WRITE_EXT_INQUIRY_RESPONSE,
+				WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &cp) < 0)
+		error("Unable to write EIR data: %s (%d)",
+						strerror(errno), errno);
+}
+
+static int hciops_set_name(int index, const char *name)
+{
+	struct dev_info *dev = &devs[index];
+	change_local_name_cp cp;
+
+	DBG("hci%d, name %s", index, name);
+
+	memset(&cp, 0, sizeof(cp));
+	strncpy((char *) cp.name, name, sizeof(cp.name));
+
+	if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME,
+				CHANGE_LOCAL_NAME_CP_SIZE, &cp) < 0)
+		return -errno;
+
+	memcpy(dev->name, cp.name, 248);
+	update_ext_inquiry_response(index);
+
+	return 0;
+}
+
+static int write_class(int index, uint32_t class)
+{
+	struct dev_info *dev = &devs[index];
+	write_class_of_dev_cp cp;
+
+	DBG("hci%d class 0x%06x", index, class);
+
+	memcpy(cp.dev_class, &class, 3);
+
+	if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV,
+					WRITE_CLASS_OF_DEV_CP_SIZE, &cp) < 0)
+		return -errno;
+
+	dev->pending_cod = class;
+
+	return 0;
+}
+
+static int hciops_set_dev_class(int index, uint8_t major, uint8_t minor)
+{
+	struct dev_info *dev = &devs[index];
+	int err;
+
+	DBG("hci%d major %u minor %u", index, major, minor);
+
+	/* Update only the major and minor class bits keeping remaining bits
+	 * intact*/
+	dev->wanted_cod &= 0xffe000;
+	dev->wanted_cod |= ((major & 0x1f) << 8) | minor;
+
+	if (dev->wanted_cod == dev->current_cod ||
+			dev->cache_enable || dev->pending_cod)
+		return 0;
+
+	DBG("Changing Major/Minor class to 0x%06x", dev->wanted_cod);
+
+	err = write_class(index, dev->wanted_cod);
+	if (err < 0)
+		error("Adapter class update failed: %s (%d)",
+						strerror(-err), -err);
+
+	return err;
+}
+
 static gboolean init_adapter(int index)
 {
 	struct dev_info *dev = &devs[index];
 	struct btd_adapter *adapter = NULL;
 	gboolean existing_adapter = dev->registered;
-	uint8_t mode, on_mode;
+	uint8_t mode, on_mode, major, minor;
 	gboolean pairable, discoverable;
+	const char *name;
 
 	if (!dev->registered) {
 		adapter = btd_manager_register_adapter(index, TRUE);
@@ -679,6 +777,14 @@ static gboolean init_adapter(int index)
 	}
 
 	start_adapter(index);
+
+	name = btd_adapter_get_name(adapter);
+	if (name)
+		hciops_set_name(index, name);
+
+	btd_adapter_get_class(adapter, &major, &minor);
+	hciops_set_dev_class(index, major, minor);
+
 	btd_adapter_start(adapter);
 
 	discoverable = (mode == MODE_DISCOVERABLE);
@@ -1495,39 +1601,6 @@ static void read_local_features_complete(int index,
 		init_adapter(index);
 }
 
-static void update_ext_inquiry_response(int index)
-{
-	struct dev_info *dev = &devs[index];
-	write_ext_inquiry_response_cp cp;
-
-	DBG("hci%d", index);
-
-	if (!(dev->features[6] & LMP_EXT_INQ))
-		return;
-
-	if (dev->ssp_mode == 0)
-		return;
-
-	if (dev->cache_enable)
-		return;
-
-	memset(&cp, 0, sizeof(cp));
-
-	eir_create(dev->name, dev->tx_power, dev->did_vendor, dev->did_product,
-					dev->did_version, dev->uuids, cp.data);
-
-	if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0)
-		return;
-
-	memcpy(dev->eir, cp.data, sizeof(cp.data));
-
-	if (hci_send_cmd(dev->sk, OGF_HOST_CTL,
-				OCF_WRITE_EXT_INQUIRY_RESPONSE,
-				WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE, &cp) < 0)
-		error("Unable to write EIR data: %s (%d)",
-						strerror(errno), errno);
-}
-
 static void update_name(int index, const char *name)
 {
 	struct btd_adapter *adapter;
@@ -1666,24 +1739,6 @@ static void read_scan_complete(int index, uint8_t status, void *ptr)
 	adapter_mode_changed(adapter, rp->enable);
 }
 
-static int write_class(int index, uint32_t class)
-{
-	struct dev_info *dev = &devs[index];
-	write_class_of_dev_cp cp;
-
-	DBG("hci%d class 0x%06x", index, class);
-
-	memcpy(cp.dev_class, &class, 3);
-
-	if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV,
-					WRITE_CLASS_OF_DEV_CP_SIZE, &cp) < 0)
-		return -errno;
-
-	dev->pending_cod = class;
-
-	return 0;
-}
-
 /* Limited Discoverable bit mask in CoD */
 #define LIMITED_BIT			0x002000
 
@@ -3034,32 +3089,6 @@ static int hciops_set_powered(int index, gboolean powered)
 	return err;
 }
 
-static int hciops_set_dev_class(int index, uint8_t major, uint8_t minor)
-{
-	struct dev_info *dev = &devs[index];
-	int err;
-
-	DBG("hci%d major %u minor %u", index, major, minor);
-
-	/* Update only the major and minor class bits keeping remaining bits
-	 * intact*/
-	dev->wanted_cod &= 0xffe000;
-	dev->wanted_cod |= ((major & 0x1f) << 8) | minor;
-
-	if (dev->wanted_cod == dev->current_cod ||
-			dev->cache_enable || dev->pending_cod)
-		return 0;
-
-	DBG("Changing Major/Minor class to 0x%06x", dev->wanted_cod);
-
-	err = write_class(index, dev->wanted_cod);
-	if (err < 0)
-		error("Adapter class update failed: %s (%d)",
-						strerror(-err), -err);
-
-	return err;
-}
-
 static int start_inquiry(int index, uint8_t length)
 {
 	struct dev_info *dev = &devs[index];
@@ -3157,26 +3186,6 @@ static int hciops_stop_scanning(int index)
 	return le_set_scan_enable(index, 0);
 }
 
-static int hciops_set_name(int index, const char *name)
-{
-	struct dev_info *dev = &devs[index];
-	change_local_name_cp cp;
-
-	DBG("hci%d, name %s", index, name);
-
-	memset(&cp, 0, sizeof(cp));
-	strncpy((char *) cp.name, name, sizeof(cp.name));
-
-	if (hci_send_cmd(dev->sk, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME,
-				CHANGE_LOCAL_NAME_CP_SIZE, &cp) < 0)
-		return -errno;
-
-	memcpy(dev->name, cp.name, 248);
-	update_ext_inquiry_response(index);
-
-	return 0;
-}
-
 static int cancel_resolve_name(int index)
 {
 	struct dev_info *info = &devs[index];
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 0b5a940..975f17e 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -971,12 +971,64 @@ static int mgmt_set_powered(int index, gboolean powered)
 	return mgmt_set_mode(index, MGMT_OP_SET_POWERED, powered);
 }
 
+static int mgmt_set_name(int index, const char *name)
+{
+	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)];
+	struct mgmt_hdr *hdr = (void *) buf;
+	struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)];
+
+	DBG("index %d, name %s", index, name);
+
+	memset(buf, 0, sizeof(buf));
+	hdr->opcode = htobs(MGMT_OP_SET_LOCAL_NAME);
+	hdr->len = htobs(sizeof(*cp));
+	hdr->index = htobs(index);
+
+	strncpy((char *) cp->name, name, sizeof(cp->name) - 1);
+
+	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
+		return -errno;
+
+	return 0;
+}
+
+static int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor)
+{
+	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_dev_class)];
+	struct mgmt_hdr *hdr = (void *) buf;
+	struct mgmt_cp_set_dev_class *cp = (void *) &buf[sizeof(*hdr)];
+	struct controller_info *info = &controllers[index];
+
+	DBG("index %d major %u minor %u", index, major, minor);
+
+	if (info->pending_uuid) {
+		info->major = major;
+		info->minor = minor;
+		info->pending_class = TRUE;
+		return 0;
+	}
+
+	memset(buf, 0, sizeof(buf));
+	hdr->opcode = htobs(MGMT_OP_SET_DEV_CLASS);
+	hdr->len = htobs(sizeof(*cp));
+	hdr->index = htobs(index);
+
+	cp->major = major;
+	cp->minor = minor;
+
+	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
+		return -errno;
+
+	return 0;
+}
+
 static void read_info_complete(int sk, uint16_t index, void *buf, size_t len)
 {
 	struct mgmt_rp_read_info *rp = buf;
 	struct controller_info *info;
 	struct btd_adapter *adapter;
-	uint8_t mode;
+	const char *name;
+	uint8_t mode, major, minor;
 	char addr[18];
 
 	if (len < sizeof(*rp)) {
@@ -1021,7 +1073,17 @@ static void read_info_complete(int sk, uint16_t index, void *buf, size_t len)
 
 	update_settings(adapter, info->current_settings);
 
-	adapter_name_changed(adapter, (char *) rp->name);
+	name = btd_adapter_get_name(adapter);
+
+	error("mgmtops setting name %s", name);
+
+	if (name)
+		mgmt_set_name(index, name);
+	else
+		adapter_name_changed(adapter, (char *) rp->name);
+
+	btd_adapter_get_class(adapter, &major, &minor);
+	mgmt_set_dev_class(index, major, minor);
 
 	btd_adapter_get_mode(adapter, &mode, NULL, NULL);
 	if (mode == MODE_OFF && mgmt_powered(info->current_settings)) {
@@ -1203,36 +1265,6 @@ static void read_local_oob_data_failed(int sk, uint16_t index)
 		oob_read_local_data_complete(adapter, NULL, NULL);
 }
 
-static int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor)
-{
-	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_dev_class)];
-	struct mgmt_hdr *hdr = (void *) buf;
-	struct mgmt_cp_set_dev_class *cp = (void *) &buf[sizeof(*hdr)];
-	struct controller_info *info = &controllers[index];
-
-	DBG("index %d major %u minor %u", index, major, minor);
-
-	if (info->pending_uuid) {
-		info->major = major;
-		info->minor = minor;
-		info->pending_class = TRUE;
-		return 0;
-	}
-
-	memset(buf, 0, sizeof(buf));
-	hdr->opcode = htobs(MGMT_OP_SET_DEV_CLASS);
-	hdr->len = htobs(sizeof(*cp));
-	hdr->index = htobs(index);
-
-	cp->major = major;
-	cp->minor = minor;
-
-	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
-		return -errno;
-
-	return 0;
-}
-
 static void mgmt_add_uuid_complete(int sk, uint16_t index, void *buf,
 								size_t len)
 {
@@ -1902,27 +1934,6 @@ static int mgmt_stop_discovery(int index)
 	return 0;
 }
 
-static int mgmt_set_name(int index, const char *name)
-{
-	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_local_name)];
-	struct mgmt_hdr *hdr = (void *) buf;
-	struct mgmt_cp_set_local_name *cp = (void *) &buf[sizeof(*hdr)];
-
-	DBG("index %d, name %s", index, name);
-
-	memset(buf, 0, sizeof(buf));
-	hdr->opcode = htobs(MGMT_OP_SET_LOCAL_NAME);
-	hdr->len = htobs(sizeof(*cp));
-	hdr->index = htobs(index);
-
-	strncpy((char *) cp->name, name, sizeof(cp->name) - 1);
-
-	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
-		return -errno;
-
-	return 0;
-}
-
 static int mgmt_set_fast_connectable(int index, gboolean enable)
 {
 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_mode)];
diff --git a/src/adapter.c b/src/adapter.c
index 6cbf27a..d9ab4fd 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -168,9 +168,9 @@ static void dev_info_free(void *data)
 }
 
 int btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major,
-								uint8_t minor)
+							uint8_t minor)
 {
-	return adapter_ops->set_dev_class(adapter->dev_id, major, minor);
+       return adapter_ops->set_dev_class(adapter->dev_id, major, minor);
 }
 
 static const char *mode2str(uint8_t mode)
@@ -811,6 +811,9 @@ int adapter_set_name(struct btd_adapter *adapter, const char *name)
 		int err = adapter_ops->set_name(adapter->dev_id, maxname);
 		if (err < 0)
 			return err;
+	} else {
+		g_free(adapter->name);
+		adapter->name = g_strdup(maxname);
 	}
 
 	write_local_name(&adapter->bdaddr, maxname);
@@ -2213,10 +2216,28 @@ void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode,
 		*pairable = adapter->pairable;
 }
 
+void btd_adapter_get_class(struct btd_adapter *adapter, uint8_t *major,
+								uint8_t *minor)
+{
+	uint8_t cls[3];
+
+	if (read_local_class(&adapter->bdaddr, cls) < 0) {
+		uint32_t class = htobl(main_opts.class);
+		memcpy(cls, &class, 3);
+	}
+
+	*major = cls[1];
+	*minor = cls[0];
+}
+
+const char *btd_adapter_get_name(struct btd_adapter *adapter)
+{
+	return adapter->name;
+}
+
 void btd_adapter_start(struct btd_adapter *adapter)
 {
 	char address[18];
-	uint8_t cls[3];
 	gboolean powered;
 
 	ba2str(&adapter->bdaddr, address);
@@ -2229,17 +2250,6 @@ void btd_adapter_start(struct btd_adapter *adapter)
 	adapter->mode = MODE_CONNECTABLE;
 	adapter->off_timer = 0;
 
-	/* Forcing: Name is lost when adapter is powered off */
-	if (adapter->name)
-		adapter_ops->set_name(adapter->dev_id, adapter->name);
-
-	if (read_local_class(&adapter->bdaddr, cls) < 0) {
-		uint32_t class = htobl(main_opts.class);
-		memcpy(cls, &class, 3);
-	}
-
-	btd_adapter_set_class(adapter, cls[1], cls[0]);
-
 	powered = TRUE;
 	emit_property_changed(connection, adapter->path,
 					ADAPTER_INTERFACE, "Powered",
diff --git a/src/adapter.h b/src/adapter.h
index 22bb0bb..e6ee2da 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -89,6 +89,9 @@ int btd_adapter_stop(struct btd_adapter *adapter);
 void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode,
 					uint8_t *on_mode, gboolean *pairable);
 
+void btd_adapter_get_class(struct btd_adapter *adapter, uint8_t *major,
+							uint8_t *minor);
+const char *btd_adapter_get_name(struct btd_adapter *adapter);
 struct btd_device *adapter_get_device(DBusConnection *conn,
 				struct btd_adapter *adapter, const char *address);