[PATCH 6/8] Moving all adapter initialization code to hciops plugin.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



---
 plugins/hciops.c |  248 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/hcid.h       |   11 +++
 src/main.c       |  249 +-----------------------------------------------------
 3 files changed, 259 insertions(+), 249 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index 32f82d0..25f5171 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -24,10 +24,19 @@
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
+
+#include <stdio.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
+#include <sys/wait.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
@@ -35,10 +44,235 @@
 
 #include <glib.h>
 
+#include <dbus/dbus.h>
+
 #include "hcid.h"
+#include "sdpd.h"
+#include "adapter.h"
 #include "plugin.h"
 #include "logging.h"
+#include "manager.h"
+#include "storage.h"
+
+static int child_pipe[2];
+
+static gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data)
+{
+	int status, fd = g_io_channel_unix_get_fd(io);
+	pid_t child_pid;
+
+	if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) {
+		error("child_exit: unable to read child pid from pipe");
+		return TRUE;
+	}
+
+	if (waitpid(child_pid, &status, 0) != child_pid)
+		error("waitpid(%d) failed", child_pid);
+	else
+		debug("child %d exited", child_pid);
+
+	return TRUE;
+}
+
+static void at_child_exit(void)
+{
+	pid_t pid = getpid();
+
+	if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid))
+		error("unable to write to child pipe");
+}
+
+static void configure_device(int dev_id)
+{
+	struct hci_dev_info di;
+	uint16_t policy;
+	int dd;
+
+	if (hci_devinfo(dev_id, &di) < 0)
+		return;
+
+	if (hci_test_bit(HCI_RAW, &di.flags))
+		return;
+
+	dd = hci_open_dev(dev_id);
+	if (dd < 0) {
+		error("Can't open device hci%d: %s (%d)",
+						dev_id, strerror(errno), errno);
+		return;
+	}
+
+	/* Set device name */
+	if ((main_opts.flags & (1 << HCID_SET_NAME)) && main_opts.name) {
+		change_local_name_cp cp;
+
+		memset(cp.name, 0, sizeof(cp.name));
+		expand_name((char *) cp.name, sizeof(cp.name),
+						main_opts.name, dev_id);
+
+		hci_send_cmd(dd, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME,
+					CHANGE_LOCAL_NAME_CP_SIZE, &cp);
+	}
+
+	/* Set device class */
+	if ((main_opts.flags & (1 << HCID_SET_CLASS))) {
+		write_class_of_dev_cp cp;
+		uint32_t class;
+		uint8_t cls[3];
+
+		if (read_local_class(&di.bdaddr, cls) < 0) {
+			class = htobl(main_opts.class);
+			cls[2] = get_service_classes(&di.bdaddr);
+			memcpy(cp.dev_class, &class, 3);
+		} else {
+			if (!(main_opts.scan & SCAN_INQUIRY))
+				cls[1] &= 0xdf; /* Clear discoverable bit */
+			cls[2] = get_service_classes(&di.bdaddr);
+			memcpy(cp.dev_class, cls, 3);
+		}
+
+		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV,
+					WRITE_CLASS_OF_DEV_CP_SIZE, &cp);
+	}
+
+	/* Set page timeout */
+	if ((main_opts.flags & (1 << HCID_SET_PAGETO))) {
+		write_page_timeout_cp cp;
+
+		cp.timeout = htobs(main_opts.pageto);
+		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT,
+					WRITE_PAGE_TIMEOUT_CP_SIZE, &cp);
+	}
+
+	/* Set default link policy */
+	policy = htobs(main_opts.link_policy);
+	hci_send_cmd(dd, OGF_LINK_POLICY,
+				OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy);
+
+	hci_close_dev(dd);
+}
+
+static void init_device(int dev_id)
+{
+	struct hci_dev_req dr;
+	struct hci_dev_info di;
+	pid_t pid;
+	int dd;
+
+	/* Do initialization in the separate process */
+	pid = fork();
+	switch (pid) {
+		case 0:
+			atexit(at_child_exit);
+			break;
+		case -1:
+			error("Fork failed. Can't init device hci%d: %s (%d)",
+					dev_id, strerror(errno), errno);
+		default:
+			debug("child %d forked", pid);
+			return;
+	}
+
+	dd = hci_open_dev(dev_id);
+	if (dd < 0) {
+		error("Can't open device hci%d: %s (%d)",
+					dev_id, strerror(errno), errno);
+		exit(1);
+	}
 
+	memset(&dr, 0, sizeof(dr));
+	dr.dev_id = dev_id;
+
+	/* Set link mode */
+	dr.dev_opt = main_opts.link_mode;
+	if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) {
+		error("Can't set link mode on hci%d: %s (%d)",
+					dev_id, strerror(errno), errno);
+	}
+
+	/* Set link policy */
+	dr.dev_opt = main_opts.link_policy;
+	if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
+							errno != ENETDOWN) {
+		error("Can't set link policy on hci%d: %s (%d)",
+					dev_id, strerror(errno), errno);
+	}
+
+	/* Start HCI device */
+	if (ioctl(dd, HCIDEVUP, dev_id) < 0 && errno != EALREADY) {
+		error("Can't init device hci%d: %s (%d)",
+					dev_id, strerror(errno), errno);
+		goto fail;
+	}
+
+	if (hci_devinfo(dev_id, &di) < 0)
+		goto fail;
+
+	if (hci_test_bit(HCI_RAW, &di.flags))
+		goto done;
+
+done:
+	hci_close_dev(dd);
+	exit(0);
+
+fail:
+	hci_close_dev(dd);
+	exit(1);
+}
+
+static void device_devreg_setup(int dev_id)
+{
+	struct hci_dev_info di;
+	gboolean devup;
+
+	init_device(dev_id);
+
+	memset(&di, 0, sizeof(di));
+
+	if (hci_devinfo(dev_id, &di) < 0)
+		return;
+
+	devup = hci_test_bit(HCI_UP, &di.flags);
+
+	if (!hci_test_bit(HCI_RAW, &di.flags))
+		manager_register_adapter(dev_id, devup);
+}
+
+static void device_devup_setup(int dev_id)
+{
+	configure_device(dev_id);
+
+	start_security_manager(dev_id);
+
+	/* Return value 1 means ioctl(DEVDOWN) was performed */
+	if (manager_start_adapter(dev_id) == 1)
+		stop_security_manager(dev_id);
+}
+
+void device_event(int event, int dev_id)
+{
+	switch (event) {
+	case HCI_DEV_REG:
+		info("HCI dev %d registered", dev_id);
+		device_devreg_setup(dev_id);
+		break;
+
+	case HCI_DEV_UNREG:
+		info("HCI dev %d unregistered", dev_id);
+		manager_unregister_adapter(dev_id);
+		break;
+
+	case HCI_DEV_UP:
+		info("HCI dev %d up", dev_id);
+		device_devup_setup(dev_id);
+		break;
+
+	case HCI_DEV_DOWN:
+		info("HCI dev %d down", dev_id);
+		manager_stop_adapter(dev_id);
+		stop_security_manager(dev_id);
+		break;
+	}
+}
 
 static int init_all_devices(int ctl)
 {
@@ -125,9 +359,21 @@ static int hciops_init(void)
 {
 	struct sockaddr_hci addr;
 	struct hci_filter flt;
-	GIOChannel *ctl_io;
+	GIOChannel *ctl_io, *child_io;;
 	int sock;
 
+	if (pipe(child_pipe) < 0) {
+		error("pipe(): %s (%d)", strerror(errno), errno);
+		return errno;
+	}
+
+	child_io = g_io_channel_unix_new(child_pipe[0]);
+	g_io_channel_set_close_on_unref(child_io, TRUE);
+	g_io_add_watch(child_io,
+			G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+			child_exit, NULL);
+	g_io_channel_unref(child_io);
+
 	/* Create and bind HCI socket */
 	sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
 	if (sock < 0) {
diff --git a/src/hcid.h b/src/hcid.h
index 236449d..e6f85d3 100644
--- a/src/hcid.h
+++ b/src/hcid.h
@@ -42,6 +42,8 @@
 #define MODE_LIMITED		0x03
 #define MODE_UNKNOWN		0xff
 
+#define HCID_DEFAULT_DISCOVERABLE_TIMEOUT 180 /* 3 minutes */
+
 /* Timeout for hci_send_req (milliseconds) */
 #define HCI_REQ_TIMEOUT		5000
 
@@ -66,8 +68,17 @@ struct main_opts {
 	int		sock;
 };
 
+enum {
+	HCID_SET_NAME,
+	HCID_SET_CLASS,
+	HCID_SET_PAGETO,
+	HCID_SET_DISCOVTO,
+};
+
 extern struct main_opts main_opts;
 
+char *expand_name(char *dst, int size, char *str, int dev_id);
+
 void device_event(int event, int dev_id);
 void hci_req_queue_remove(int dev_id, bdaddr_t *dba);
 
diff --git a/src/main.c b/src/main.c
index 309d4bb..a5a728c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,17 +28,13 @@
 #endif
 
 #include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
-#include <signal.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
-#include <sys/wait.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
@@ -57,21 +53,9 @@
 #include "dbus-common.h"
 #include "agent.h"
 #include "manager.h"
-#include "storage.h"
-
-#define HCID_DEFAULT_DISCOVERABLE_TIMEOUT 180 /* 3 minutes */
-
-enum {
-	HCID_SET_NAME,
-	HCID_SET_CLASS,
-	HCID_SET_PAGETO,
-	HCID_SET_DISCOVTO,
-};
 
 struct main_opts main_opts;
 
-static int child_pipe[2];
-
 static gboolean starting = TRUE;
 
 static GKeyFile *load_config(const char *file)
@@ -260,7 +244,7 @@ static void update_service_classes(const bdaddr_t *bdaddr, uint8_t value)
  * Device name expansion
  *   %d - device id
  */
-static char *expand_name(char *dst, int size, char *str, int dev_id)
+char *expand_name(char *dst, int size, char *str, int dev_id)
 {
 	register int sp, np, olen;
 	char *opt, buf[10];
@@ -314,198 +298,6 @@ static char *expand_name(char *dst, int size, char *str, int dev_id)
 	return dst;
 }
 
-static gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data)
-{
-	int status, fd = g_io_channel_unix_get_fd(io);
-	pid_t child_pid;
-
-	if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) {
-		error("child_exit: unable to read child pid from pipe");
-		return TRUE;
-	}
-
-	if (waitpid(child_pid, &status, 0) != child_pid)
-		error("waitpid(%d) failed", child_pid);
-	else
-		debug("child %d exited", child_pid);
-
-	return TRUE;
-}
-
-static void at_child_exit(void)
-{
-	pid_t pid = getpid();
-
-	if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid))
-		error("unable to write to child pipe");
-}
-
-static void configure_device(int dev_id)
-{
-	struct hci_dev_info di;
-	uint16_t policy;
-	int dd;
-
-	if (hci_devinfo(dev_id, &di) < 0)
-		return;
-
-	if (hci_test_bit(HCI_RAW, &di.flags))
-		return;
-
-	dd = hci_open_dev(dev_id);
-	if (dd < 0) {
-		error("Can't open device hci%d: %s (%d)",
-						dev_id, strerror(errno), errno);
-		return;
-	}
-
-	/* Set device name */
-	if ((main_opts.flags & (1 << HCID_SET_NAME)) && main_opts.name) {
-		change_local_name_cp cp;
-
-		memset(cp.name, 0, sizeof(cp.name));
-		expand_name((char *) cp.name, sizeof(cp.name),
-						main_opts.name, dev_id);
-
-		hci_send_cmd(dd, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME,
-					CHANGE_LOCAL_NAME_CP_SIZE, &cp);
-	}
-
-	/* Set device class */
-	if ((main_opts.flags & (1 << HCID_SET_CLASS))) {
-		write_class_of_dev_cp cp;
-		uint32_t class;
-		uint8_t cls[3];
-
-		if (read_local_class(&di.bdaddr, cls) < 0) {
-			class = htobl(main_opts.class);
-			cls[2] = get_service_classes(&di.bdaddr);
-			memcpy(cp.dev_class, &class, 3);
-		} else {
-			if (!(main_opts.scan & SCAN_INQUIRY))
-				cls[1] &= 0xdf; /* Clear discoverable bit */
-			cls[2] = get_service_classes(&di.bdaddr);
-			memcpy(cp.dev_class, cls, 3);
-		}
-
-		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV,
-					WRITE_CLASS_OF_DEV_CP_SIZE, &cp);
-	}
-
-	/* Set page timeout */
-	if ((main_opts.flags & (1 << HCID_SET_PAGETO))) {
-		write_page_timeout_cp cp;
-
-		cp.timeout = htobs(main_opts.pageto);
-		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_PAGE_TIMEOUT,
-					WRITE_PAGE_TIMEOUT_CP_SIZE, &cp);
-	}
-
-	/* Set default link policy */
-	policy = htobs(main_opts.link_policy);
-	hci_send_cmd(dd, OGF_LINK_POLICY,
-				OCF_WRITE_DEFAULT_LINK_POLICY, 2, &policy);
-
-	hci_close_dev(dd);
-}
-
-static void init_device(int dev_id)
-{
-	struct hci_dev_req dr;
-	struct hci_dev_info di;
-	pid_t pid;
-	int dd;
-
-	/* Do initialization in the separate process */
-	pid = fork();
-	switch (pid) {
-		case 0:
-			atexit(at_child_exit);
-			break;
-		case -1:
-			error("Fork failed. Can't init device hci%d: %s (%d)",
-					dev_id, strerror(errno), errno);
-		default:
-			debug("child %d forked", pid);
-			return;
-	}
-
-	dd = hci_open_dev(dev_id);
-	if (dd < 0) {
-		error("Can't open device hci%d: %s (%d)",
-					dev_id, strerror(errno), errno);
-		exit(1);
-	}
-
-	memset(&dr, 0, sizeof(dr));
-	dr.dev_id = dev_id;
-
-	/* Set link mode */
-	dr.dev_opt = main_opts.link_mode;
-	if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) {
-		error("Can't set link mode on hci%d: %s (%d)",
-					dev_id, strerror(errno), errno);
-	}
-
-	/* Set link policy */
-	dr.dev_opt = main_opts.link_policy;
-	if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
-							errno != ENETDOWN) {
-		error("Can't set link policy on hci%d: %s (%d)",
-					dev_id, strerror(errno), errno);
-	}
-
-	/* Start HCI device */
-	if (ioctl(dd, HCIDEVUP, dev_id) < 0 && errno != EALREADY) {
-		error("Can't init device hci%d: %s (%d)",
-					dev_id, strerror(errno), errno);
-		goto fail;
-	}
-
-	if (hci_devinfo(dev_id, &di) < 0)
-		goto fail;
-
-	if (hci_test_bit(HCI_RAW, &di.flags))
-		goto done;
-
-done:
-	hci_close_dev(dd);
-	exit(0);
-
-fail:
-	hci_close_dev(dd);
-	exit(1);
-}
-
-static void device_devreg_setup(int dev_id)
-{
-	struct hci_dev_info di;
-	gboolean devup;
-
-	init_device(dev_id);
-
-	memset(&di, 0, sizeof(di));
-
-	if (hci_devinfo(dev_id, &di) < 0)
-		return;
-
-	devup = hci_test_bit(HCI_UP, &di.flags);
-
-	if (!hci_test_bit(HCI_RAW, &di.flags))
-		manager_register_adapter(dev_id, devup);
-}
-
-static void device_devup_setup(int dev_id)
-{
-	configure_device(dev_id);
-
-	start_security_manager(dev_id);
-
-	/* Return value 1 means ioctl(DEVDOWN) was performed */
-	if (manager_start_adapter(dev_id) == 1)
-		stop_security_manager(dev_id);
-}
-
 static void init_defaults(void)
 {
 	/* Default HCId settings */
@@ -521,32 +313,6 @@ static void init_defaults(void)
 		strcpy(main_opts.host_name, "noname");
 }
 
-void device_event(int event, int dev_id)
-{
-	switch (event) {
-	case HCI_DEV_REG:
-		info("HCI dev %d registered", dev_id);
-		device_devreg_setup(dev_id);
-		break;
-
-	case HCI_DEV_UNREG:
-		info("HCI dev %d unregistered", dev_id);
-		manager_unregister_adapter(dev_id);
-		break;
-
-	case HCI_DEV_UP:
-		info("HCI dev %d up", dev_id);
-		device_devup_setup(dev_id);
-		break;
-
-	case HCI_DEV_DOWN:
-		info("HCI dev %d down", dev_id);
-		manager_stop_adapter(dev_id);
-		stop_security_manager(dev_id);
-		break;
-	}
-}
-
 static GMainLoop *event_loop;
 
 static void sig_term(int sig)
@@ -576,7 +342,6 @@ int main(int argc, char *argv[])
 	GOptionContext *context;
 	GError *err = NULL;
 	struct sigaction sa;
-	GIOChannel *child_io;
 	uint16_t mtu = 0;
 	GKeyFile *config;
 
@@ -628,18 +393,6 @@ int main(int argc, char *argv[])
 
 	parse_config(config);
 
-	if (pipe(child_pipe) < 0) {
-		error("pipe(): %s (%d)", strerror(errno), errno);
-		exit(1);
-	}
-
-	child_io = g_io_channel_unix_new(child_pipe[0]);
-	g_io_channel_set_close_on_unref(child_io, TRUE);
-	g_io_add_watch(child_io,
-			G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
-			child_exit, NULL);
-	g_io_channel_unref(child_io);
-
 	agent_init();
 
 	if (hcid_dbus_init() < 0) {
-- 
1.5.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux