Пример #1
0
static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
					struct avdtp_stream *stream,
					struct avdtp_error *err, void *user_data)
{
	struct sink *sink = user_data;
	struct pending_request *pending;

	pending = sink->connect;

	if (stream) {
		DBusMessage *reply;
		sink->connect = NULL;
		reply = dbus_message_new_method_return(pending->msg);
		dbus_connection_send(pending->conn, reply, NULL);
		dbus_message_unref(reply);
		pending_request_free(pending);
		debug("Stream successfully created");
	} else {
		avdtp_unref(sink->session);
		sink->session = NULL;
		if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO
				&& avdtp_error_posix_errno(err) != EHOSTDOWN) {
			debug("connect:connect XCASE detected");
			g_timeout_add(STREAM_SETUP_RETRY_TIMER,
					stream_setup_retry, sink);
		} else {
			sink->connect = NULL;
			error_failed(pending->conn, pending->msg, "Stream setup failed");
			pending_request_free(pending);
			debug("Stream setup failed : %s", avdtp_strerror(err));
		}
	}
}
Пример #2
0
gboolean sink_shutdown(struct sink *sink)
{
	if (!sink->session)
		return FALSE;

	avdtp_set_device_disconnect(sink->session, TRUE);

	/* cancel pending connect */
	if (sink->connect) {
		struct pending_request *pending = sink->connect;

		if (pending->msg)
			error_failed(pending->conn, pending->msg,
							"Stream setup failed");
		pending_request_free(sink->dev, pending);
		sink->connect = NULL;

		avdtp_unref(sink->session);
		sink->session = NULL;

		return TRUE;
	}

	/* disconnect already ongoing */
	if (sink->disconnect)
		return TRUE;

	if (!sink->stream)
		return FALSE;

	if (avdtp_close(sink->session, sink->stream, FALSE) < 0)
		return FALSE;

	return TRUE;
}
Пример #3
0
static void select_complete(struct avdtp *session, struct a2dp_sep *sep,
			GSList *caps, void *user_data)
{
	struct sink *sink = user_data;
	struct pending_request *pending;
	int id;

	pending = sink->connect;
	pending->id = 0;

	id = a2dp_config(session, sep, stream_setup_complete, caps, sink);
	if (id == 0)
		goto failed;

	pending->id = id;
	return;

failed:
	if (pending->msg)
		error_failed(pending->conn, pending->msg, "Stream setup failed");
	pending_request_free(sink->dev, pending);
	sink->connect = NULL;
	avdtp_unref(sink->session);
	sink->session = NULL;
}
Пример #4
0
static gboolean stream_setup_retry(gpointer user_data)
{
	struct sink *sink = user_data;
	struct pending_request *pending = sink->connect;

	sink->retry_id = 0;

	if (sink->stream_state >= AVDTP_STATE_OPEN) {
		DBG("Stream successfully created, after XCASE connect:connect");
		if (pending->msg) {
			DBusMessage *reply;
			reply = dbus_message_new_method_return(pending->msg);
			g_dbus_send_message(pending->conn, reply);
		}
	} else {
		DBG("Stream setup failed, after XCASE connect:connect");
		if (pending->msg)
			error_failed(pending->conn, pending->msg, "Stream setup failed");
	}

	sink->connect = NULL;
	pending_request_free(sink->dev, pending);

	return FALSE;
}
Пример #5
0
static void records_cb(sdp_list_t *recs, int err, gpointer data)
{
	struct pending_reply *pr = data;
	int len;
	sdp_data_t *d;
	sdp_record_t *rec = NULL;
	char name[MAX_NAME_SIZE], *desc = NULL;

	if (err < 0) {
		error_connection_attempt_failed(pr->conn, pr->msg, -err);
		goto fail;
	}

	if (!recs || !recs->data) {
		error_not_supported(pr->conn, pr->msg);
		error("Invalid PAN service record");
		goto fail;
	}

	rec = recs->data;

	/* Concat remote name and service name */
	memset(name, 0, MAX_NAME_SIZE);
	if (read_remote_name(&pr->src, &pr->dst, name, MAX_NAME_SIZE) < 0)
		len = 0;
	else
		len = strlen(name);

	d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY);
	if (d) {
		snprintf(name + len, MAX_NAME_SIZE - len,
			len ? " (%.*s)" : "%.*s", d->unitSize, d->val.str);
	}

	/* Extract service description from record */
	d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY);
	if (d) {
		desc = g_new0(char, d->unitSize);
		snprintf(desc, d->unitSize, "%.*s",
				d->unitSize, d->val.str);
	}

	sdp_list_free(recs, (sdp_free_func_t) sdp_record_free);

	if (connection_register(pr->path, &pr->src, &pr->dst, pr->id, name,
				desc) < 0) {
		error_failed(pr->conn, pr->msg, "D-Bus path registration failed");
		goto fail;
	}

	connection_store(pr->path, FALSE);
	connection_paths = g_slist_append(connection_paths, g_strdup(pr->path));

	create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated");

fail:
	g_free(desc);
	pending_reply_free(pr);
}
Пример #6
0
static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err,
				void *user_data)
{
	struct sink *sink = user_data;
	struct pending_request *pending;
	struct avdtp_local_sep *lsep;
	struct avdtp_remote_sep *rsep;
	GSList *caps = NULL;
	int id;

	pending = sink->connect;

	if (err) {
		avdtp_unref(sink->session);
		sink->session = NULL;
		if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO
				&& avdtp_error_posix_errno(err) != EHOSTDOWN) {
			debug("connect:connect XCASE detected");
			g_timeout_add(STREAM_SETUP_RETRY_TIMER,
					stream_setup_retry, sink);
		} else
			goto failed;
		return;
	}

	debug("Discovery complete");

	if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK, AVDTP_MEDIA_TYPE_AUDIO,
				A2DP_CODEC_SBC, &lsep, &rsep) < 0) {
		error("No matching ACP and INT SEPs found");
		goto failed;
	}

	if (!select_capabilities(session, rsep, &caps)) {
		error("Unable to select remote SEP capabilities");
		goto failed;
	}

	id = a2dp_source_config(sink->session, stream_setup_complete,
				caps, sink);
	if (id == 0)
		goto failed;

	pending->id = id;
	return;

failed:
	pending_request_free(pending);
	sink->connect = NULL;
	avdtp_unref(sink->session);
	sink->session = NULL;
	error_failed(pending->conn, pending->msg, "Stream setup failed");
}
Пример #7
0
static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err,
				void *user_data)
{
	struct sink *sink = user_data;
	struct pending_request *pending;
	int id;

	if (!sink->connect) {
		avdtp_unref(sink->session);
		sink->session = NULL;
		return;
	}

	pending = sink->connect;

	if (err) {
		avdtp_unref(sink->session);
		sink->session = NULL;
		if (avdtp_error_category(err) == AVDTP_ERRNO
				&& avdtp_error_posix_errno(err) != EHOSTDOWN) {
			DBG("connect:connect XCASE detected");
			sink->retry_id =
				g_timeout_add_seconds(STREAM_SETUP_RETRY_TIMER,
							stream_setup_retry,
							sink);
		} else
			goto failed;
		return;
	}

	DBG("Discovery complete");

	id = a2dp_select_capabilities(sink->session, AVDTP_SEP_TYPE_SINK, NULL,
						select_complete, sink);
	if (id == 0)
		goto failed;

	pending->id = id;
	return;

failed:
	if (pending->msg)
		error_failed(pending->conn, pending->msg, "Stream setup failed");
	pending_request_free(sink->dev, pending);
	sink->connect = NULL;
	avdtp_unref(sink->session);
	sink->session = NULL;
}
Пример #8
0
static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
					struct avdtp_stream *stream,
					struct avdtp_error *err, void *user_data)
{
	struct sink *sink = user_data;
	struct pending_request *pending;

	pending = sink->connect;

	pending->id = 0;

	if (stream) {
		DBG("Stream successfully created");

		if (pending->msg) {
			DBusMessage *reply;
			reply = dbus_message_new_method_return(pending->msg);
			g_dbus_send_message(pending->conn, reply);
		}

		sink->connect = NULL;
		pending_request_free(sink->dev, pending);

		return;
	}

	avdtp_unref(sink->session);
	sink->session = NULL;
	if (avdtp_error_category(err) == AVDTP_ERRNO
			&& avdtp_error_posix_errno(err) != EHOSTDOWN) {
		DBG("connect:connect XCASE detected");
		sink->retry_id = g_timeout_add_seconds(STREAM_SETUP_RETRY_TIMER,
							stream_setup_retry,
							sink);
	} else {
		if (pending->msg)
			error_failed(pending->conn, pending->msg, "Stream setup failed");
		sink->connect = NULL;
		pending_request_free(sink->dev, pending);
		DBG("Stream setup failed : %s", avdtp_strerror(err));
	}
}
Пример #9
0
static gboolean stream_setup_retry(gpointer user_data)
{
	struct sink *sink = user_data;
	struct pending_request *pending = sink->connect;

	if (sink->state >= AVDTP_STATE_OPEN) {
		DBusMessage *reply;
		debug("Stream successfully created, after XCASE connect:connect");
		reply = dbus_message_new_method_return(pending->msg);
		dbus_connection_send(pending->conn, reply, NULL);
		dbus_message_unref(reply);
	} else {
		debug("Stream setup failed, after XCASE connect:connect");
		error_failed(pending->conn, pending->msg, "Stream setup failed");
	}

	sink->connect = NULL;
	pending_request_free(pending);

	return FALSE;
}
Пример #10
0
/*
 * A Phdc Manager requests to be added to the manager list.
 * - parse the parameters
 *
 * Initial version: the PHDC manager calls dbus_register_phdc_manager,
 * sending a simple path and a service name
 * TODO: check for DBUS_TYPE_UNIX_FD   ((int) 'h')
 */
static DBusMessage *dbus_register_phdc_agent(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct near_phdc_data *phdc_mgr;
	int err;

	DBG("conn %p", conn);

	/* Allocate the phdc_mgr struct */
	phdc_mgr = g_try_malloc0(sizeof(struct near_phdc_data));
	if (!phdc_mgr) {
		err = -ENOMEM;
		goto error;
	}

	/* Allocate a default p2p_driver */
	phdc_mgr->p2p_driver = g_try_malloc0(sizeof(struct near_p2p_driver));
	if (!phdc_mgr->p2p_driver) {
		err = -ENOMEM;
		goto error;
	}

	/* Get the the sender name */
	phdc_mgr->sender = g_strdup(dbus_message_get_sender(msg));

	DBG("%s", phdc_mgr->sender);

	/* default p2p values */
	phdc_mgr->p2p_driver->fallback_service_name = NULL;
	phdc_mgr->p2p_driver->sock_type = SOCK_STREAM;
	phdc_mgr->p2p_driver->single_connection = FALSE;
	phdc_mgr->p2p_driver->new_client = phdc_p2p_newclient;
	phdc_mgr->p2p_driver->close = phdc_p2p_close;

	/* look for dict values and fill the struct */
	err = parse_dictionary(msg, data, phdc_mgr, phdc_mgr->p2p_driver);
	if (err < 0)
		goto error;

	/* TODO: At this time, there's no support for Role == Agent */
	if (phdc_mgr->role == ROLE_AGENT) {
		err = -ENOTSUP;
		goto error;
	}

	/* No correct role ? */
	if (phdc_mgr->role == ROLE_UNKNOWN) {
		err = -EINVAL;
		goto error;
	}

	/* No path ? */
	if (!phdc_mgr->path) {
		err = -EINVAL;
		goto error;
	}

	/* defaulting the p2p driver */
	if (!phdc_mgr->p2p_driver->service_name)
		phdc_mgr->p2p_driver->service_name =
						g_strdup(DEFAULT_PHDC_SERVICE);

	/* p2p internal name */
	phdc_mgr->p2p_driver->name = g_strdup_printf("{%s-%s}",
			(phdc_mgr->role == ROLE_MANAGER ? ROLE_MANAGER_TEXT :
							ROLE_AGENT_TEXT),
					phdc_mgr->p2p_driver->service_name);

	/* if one pointer is null, memory failed ! */
	if ((!phdc_mgr->p2p_driver->name) ||
				(!phdc_mgr->p2p_driver->service_name)) {
		err = -ENOMEM;
		goto error;
	}

	/* Watch the Phdc Manager */
	phdc_mgr->watch = g_dbus_add_disconnect_watch(phdc_conn,
							phdc_mgr->sender,
							phdc_manager_disconnect,
							phdc_mgr, NULL);
	/* Add to the existing Manager list */
	err = manager_add_to_list(phdc_mgr);
	if (err < 0)
		goto error;

	/* and register the p2p driver for the specified service */
	err = near_p2p_register(phdc_mgr->p2p_driver);
	if (err < 0)
		goto error;

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);

error:
	/* free memory */
	free_mgr_data(phdc_mgr);
	return error_failed(msg, -err);
}
Пример #11
0
int lock_ctl(struct gpio *gpio, int ctl, va_list args)
{
	return error_failed(ERROR_CORE_INVAL);
}