Пример #1
0
/* Connect and initiate BNEP session */
static DBusMessage *connection_connect(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct network_peer *peer = data;
	struct network_conn *nc;
	const char *svc;
	uint16_t id;
	GError *err = NULL;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &svc,
						DBUS_TYPE_INVALID) == FALSE)
		return NULL;

	id = bnep_service_id(svc);
	nc = find_connection(peer->connections, id);
	if (!nc)
		return btd_error_not_supported(msg);

	if (nc->state != DISCONNECTED)
		return btd_error_already_connected(msg);

	nc->io = bt_io_connect(BT_IO_L2CAP, connect_cb, nc,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &peer->src,
				BT_IO_OPT_DEST_BDADDR, &peer->dst,
				BT_IO_OPT_PSM, BNEP_PSM,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_OMTU, BNEP_MTU,
				BT_IO_OPT_IMTU, BNEP_MTU,
				BT_IO_OPT_INVALID);
	if (!nc->io) {
		DBusMessage *reply;
		error("%s", err->message);
		reply = btd_error_failed(msg, err->message);
		g_error_free(err);
		return reply;
	}

	nc->state = CONNECTING;
	nc->msg = dbus_message_ref(msg);
	nc->watch = g_dbus_add_disconnect_watch(conn,
						dbus_message_get_sender(msg),
						connection_destroy,
						nc, NULL);

	return NULL;
}
Пример #2
0
static DBusMessage *local_connect(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct network_peer *peer = data;
	struct btd_service *service;
	struct network_conn *nc;
	const char *svc;
	const char *uuid;
	uint16_t id;
	int err;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &svc,
						DBUS_TYPE_INVALID) == FALSE)
		return btd_error_invalid_args(msg);

	id = bnep_service_id(svc);
	uuid = bnep_uuid(id);

	if (uuid == NULL)
		return btd_error_invalid_args(msg);

	service = btd_device_get_service(peer->device, uuid);
	if (service == NULL)
		return btd_error_not_supported(msg);

	nc = btd_service_get_user_data(service);

	if (nc->connect != NULL)
		return btd_error_busy(msg);

	err = connection_connect(nc->service);
	if (err < 0)
		return btd_error_failed(msg, strerror(-err));

	nc->connect = dbus_message_ref(msg);

	return NULL;
}
Пример #3
0
static DBusMessage *create_connection(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct pending_reply *pr;
	const char *addr;
	const char *str;
	bdaddr_t src;
	uint16_t id;
	int dev_id, err;
	char key[32];
	GSList *l;
	uuid_t uuid;

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
			DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID) == FALSE)
		return NULL;

	id = bnep_service_id(str);
	if (id != BNEP_SVC_GN && id != BNEP_SVC_NAP && id != BNEP_SVC_PANU)
		return not_supported(msg);

	snprintf(key, 32, "%s#%s", addr, bnep_name(id));

	/* Checks if the connection was already been made */
	for (l = connection_paths; l; l = l->next) {
		if (connection_find_data(l->data, key) == 0)
			return already_exists(msg);
	}

	bacpy(&src, BDADDR_ANY);
	dev_id = hci_get_route(&src);
	if (dev_id < 0 || hci_devba(dev_id, &src) < 0)
		return adapter_not_available(msg);

	pr = g_new0(struct pending_reply, 1);

	/* FIXME just to maintain compatibility */
	pr->adapter_path = g_strdup_printf("/org/bluez/hci%d", dev_id);
	if (!pr->adapter_path) {
		pending_reply_free (pr);
		return adapter_not_available(msg);
	}

	pr->conn = dbus_connection_ref(conn);
	pr->msg = dbus_message_ref(msg);
	bacpy(&pr->src, &src);
	str2ba(addr, &pr->dst);
	pr->addr = g_strdup(addr);
	pr->id = id;
	pr->path = g_new0(char, MAX_PATH_LENGTH);
	snprintf(pr->path, MAX_PATH_LENGTH,
				NETWORK_PATH "/connection%d", net_uid++);

	sdp_uuid16_create(&uuid, pr->id);
	err = bt_search_service(&pr->src, &pr->dst, &uuid, records_cb, pr,
				NULL);
	if (err < 0) {
		pending_reply_free(pr);
		return not_supported(msg);
	}

	return NULL;
}
Пример #4
0
static uint16_t get_service_id(struct btd_service *service)
{
	return bnep_service_id(btd_service_get_profile(service)->remote_uuid);
}