예제 #1
0
static void session_process_queue(struct obc_session *session)
{
	struct pending_request *p;

	if (session->p != NULL)
		return;

	if (session->queue == NULL || g_queue_is_empty(session->queue))
		return;

	obc_session_ref(session);

	while ((p = g_queue_pop_head(session->queue))) {
		GError *gerr = NULL;

		DBG("Transfer(%p) started", p->transfer);

		if (obc_transfer_start(p->transfer, session->obex, &gerr)) {
			session->p = p;
			break;
		}

		if (p->func)
			p->func(session, p->transfer, gerr, p->data);

		g_clear_error(&gerr);

		pending_request_free(p);
	}

	obc_session_unref(session);
}
예제 #2
0
static void session_terminate_transfer(struct obc_session *session,
					struct obc_transfer *transfer,
					GError *gerr)
{
	struct pending_request *p = session->p;

	if (p == NULL || p->transfer != transfer) {
		GList *match;

		match = g_list_find_custom(session->queue->head, transfer,
						pending_transfer_cmptransfer);
		if (match == NULL)
			return;

		p = match->data;
		g_queue_delete_link(session->queue, match);
	} else
		session->p = NULL;

	obc_session_ref(session);

	if (p->func)
		p->func(session, p->transfer, gerr, p->data);

	pending_request_free(p);

	if (session->p == NULL)
		session_process_queue(session);

	obc_session_unref(session);
}
예제 #3
0
static void session_process_queue(struct obc_session *session)
{
	struct pending_request *p;

	if (session->p != NULL)
		return;

	if (session->queue == NULL || g_queue_is_empty(session->queue))
		return;

	obc_session_ref(session);

	while ((p = g_queue_pop_head(session->queue))) {
		GError *gerr = NULL;

		if (p->process(p, &gerr) == 0)
			break;

		if (p->func)
			p->func(session, p->transfer, gerr, p->data);

		g_clear_error(&gerr);

		pending_request_free(p);
	}

	obc_session_unref(session);
}
예제 #4
0
파일: map.c 프로젝트: alvarofagner/bluez
static int map_probe(struct obc_session *session)
{
	struct map_data *map;
	const char *path;

	path = obc_session_get_path(session);

	DBG("%s", path);

	map = g_try_new0(struct map_data, 1);
	if (!map)
		return -ENOMEM;

	map->session = obc_session_ref(session);
	map->messages = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
								map_msg_remove);

	set_notification_registration(map, true);

	if (!g_dbus_register_interface(conn, path, MAP_INTERFACE, map_methods,
					NULL, NULL, map, map_free)) {
		map_free(map);

		return -ENOMEM;
	}

	return 0;
}
예제 #5
0
파일: transfer.c 프로젝트: Sork007/obexd
struct obc_transfer *obc_transfer_register(DBusConnection *conn,
						const char *filename,
						const char *name,
						const char *type,
						struct obc_transfer_params *params,
						void *user_data)
{
	struct obc_session *session = user_data;
	struct obc_transfer *transfer;

	transfer = g_new0(struct obc_transfer, 1);
	transfer->session = obc_session_ref(session);
	transfer->filename = g_strdup(filename);
	transfer->name = g_strdup(name);
	transfer->type = g_strdup(type);
	transfer->params = params;

	/* for OBEX specific mime types we don't need to register a transfer */
	if (type != NULL &&
			(strncmp(type, "x-obex/", 7) == 0 ||
			strncmp(type, "x-bt/", 5) == 0))
		goto done;

	transfer->path = g_strdup_printf("%s/transfer%ju",
			TRANSFER_BASEPATH, counter++);

	transfer->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
	if (transfer->conn == NULL) {
		obc_transfer_free(transfer);
		return NULL;
	}

	if (g_dbus_register_interface(transfer->conn, transfer->path,
				TRANSFER_INTERFACE,
				obc_transfer_methods, NULL, NULL,
				transfer, NULL) == FALSE) {
		obc_transfer_free(transfer);
		return NULL;
	}

done:
	DBG("%p registered %s", transfer, transfer->path);

	obc_session_add_transfer(session, transfer);

	return transfer;
}
예제 #6
0
static struct pending_request *pending_request_new(struct obc_session *session,
						struct obc_transfer *transfer,
						session_callback_t func,
						void *data)
{
	struct pending_request *p;
	static guint id = 0;

	p = g_new0(struct pending_request, 1);
	p->id = ++id;
	p->session = obc_session_ref(session);
	p->transfer = transfer;
	p->func = func;
	p->data = data;

	return p;
}
예제 #7
0
void obc_session_shutdown(struct obc_session *session)
{
	struct pending_request *p;
	GError *err;

	DBG("%p", session);

	obc_session_ref(session);

	/* Unregister any pending transfer */
	err = g_error_new(OBEX_IO_ERROR, OBEX_IO_DISCONNECTED,
						"Session closed by user");

	if (session->p != NULL && session->p->id != 0) {
		p = session->p;
		session->p = NULL;

		if (p->func)
			p->func(session, p->transfer, err, p->data);

		pending_request_free(p);
	}

	while ((p = g_queue_pop_head(session->queue))) {
		if (p->func)
			p->func(session, p->transfer, err, p->data);

		pending_request_free(p);
	}

	g_error_free(err);

	/* Unregister interfaces */
	if (session->path)
		session_unregistered(session);

	/* Disconnect transport */
	if (session->id > 0 && session->transport != NULL) {
		session->transport->disconnect(session->id);
		session->id = 0;
	}

	obc_session_unref(session);
}
예제 #8
0
static int session_connect(struct obc_session *session,
				session_callback_t function, void *user_data)
{
	struct callback_data *callback;
	struct obc_transport *transport = session->transport;
	struct obc_driver *driver = session->driver;

	callback = g_try_malloc0(sizeof(*callback));
	if (callback == NULL)
		return -ENOMEM;

	callback->func = function;
	callback->data = user_data;
	callback->session = obc_session_ref(session);

	/* Connection completed */
	if (session->obex) {
		g_idle_add(connection_complete, callback);
		return 0;
	}

	/* Ongoing connection */
	if (session->id > 0) {
		obc_session_unref(callback->session);
		g_free(callback);
		return 0;
	}

	session->id = transport->connect(session->source, session->destination,
					driver->uuid, session->channel,
					transport_func, callback);
	if (session->id == 0) {
		obc_session_unref(callback->session);
		g_free(callback);
		return -EINVAL;
	}

	session->callback = callback;

	return 0;
}
예제 #9
0
static void session_terminate_transfer(struct obc_session *session,
					struct obc_transfer *transfer,
					GError *gerr)
{
	struct session_callback *callback = session->callback;

	if (callback) {
		callback->func(session, gerr, callback->data);
		return;
	}

	obc_session_ref(session);

	obc_transfer_unregister(transfer);

	if (session->pending)
		session_request(session, session_prepare_put,
				session->pending->data);

	obc_session_unref(session);
}
예제 #10
0
void obc_session_shutdown(struct obc_session *session)
{
	DBG("%p", session);

	obc_session_ref(session);

	/* Unregister any pending transfer */
	g_slist_foreach(session->pending, (GFunc) obc_transfer_unregister,
									NULL);

	/* Unregister interfaces */
	if (session->path)
		session_unregistered(session);

	/* Shutdown io */
	if (session->io) {
		int fd = g_io_channel_unix_get_fd(session->io);
		shutdown(fd, SHUT_RDWR);
	}

	obc_session_unref(session);
}
예제 #11
0
파일: pbap.c 프로젝트: Sork007/obexd
static int pbap_probe(struct obc_session *session)
{
	struct pbap_data *pbap;
	const char *path;

	path = obc_session_get_path(session);

	DBG("%s", path);

	pbap = g_try_new0(struct pbap_data, 1);
	if (!pbap)
		return -ENOMEM;

	pbap->session = obc_session_ref(session);

	if (!g_dbus_register_interface(conn, path, PBAP_INTERFACE, pbap_methods,
						NULL, NULL, pbap, pbap_free)) {
		pbap_free(pbap);
		return -ENOMEM;
	}

	return 0;
}
예제 #12
0
파일: session.c 프로젝트: hmallat/obexd
void obc_session_shutdown(struct obc_session *session)
{
	struct pending_request *p;
	GError *err;

	DBG("%p", session);

	if (session->disconnecting == TRUE) {
		DBG("%p already disconnecting", session);
		return;
	}
	session->disconnecting = TRUE;

	obc_session_ref(session);

	/* Unregister any pending transfer */
	err = g_error_new(OBEX_IO_ERROR, OBEX_IO_DISCONNECTED,
						"Session closed by user");

	if (session->p != NULL && session->p->id != 0) {
		p = session->p;
		session->p = NULL;

		if (p->func)
			p->func(session, p->transfer, err, p->data);

		pending_request_free(p);
	}

	while ((p = g_queue_pop_head(session->queue))) {
		if (p->func)
			p->func(session, p->transfer, err, p->data);

		pending_request_free(p);
	}

	g_error_free(err);

	/* Unregister interfaces */
	if (session->path)
		session_unregistered(session);

	DBG("Checking the need for disconnect request");
	/* Send a disconnect request and wait for reply */
	if (session->id > 0 && session->transport != NULL
			&& session->obex != NULL) {
		DBG("Generating disconnect request. ");
		err = NULL;
		p = pending_request_new(session, NULL, NULL, NULL);
		p->req_id = g_obex_disconnect(session->obex, disconnect_cb,
						p, &err);
		if (err != NULL) {
			DBG("Generating disconnect request failed. ");
			disconnect_cb(session->obex, NULL, NULL, p);
		} else {
			/* Finalize when reply arrives */
			DBG("Generating disconnect request succeeded. ");
		}
	} else {
		DBG("Unreferring without disconnect request.");
		obc_session_unref(session);
	}
}
예제 #13
0
struct obc_session *obc_session_create(const char *source,
						const char *destination,
						const char *service,
						uint8_t channel,
						const char *owner,
						session_callback_t function,
						void *user_data)
{
	struct obc_session *session;
	struct callback_data *callback;
	struct pending_req *req;
	struct obc_driver *driver;

	if (destination == NULL)
		return NULL;

	session = session_find(source, destination, service, channel, owner);
	if (session) {
		obc_session_ref(session);
		goto proceed;
	}

	driver = obc_driver_find(service);
	if (!driver)
		return NULL;

	session = g_try_malloc0(sizeof(*session));
	if (session == NULL)
		return NULL;

	session->refcount = 1;
	session->channel = channel;

	session->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
	if (session->conn == NULL) {
		session_free(session);
		return NULL;
	}

	session->conn_system = g_dbus_setup_bus(DBUS_BUS_SYSTEM, NULL, NULL);
	if (session->conn_system == NULL) {
		session_free(session);
		return NULL;
	}

	if (source == NULL)
		bacpy(&session->src, BDADDR_ANY);
	else
		str2ba(source, &session->src);

	str2ba(destination, &session->dst);
	session->driver = driver;

	DBG("driver %s", driver->service);

proceed:
	callback = g_try_malloc0(sizeof(*callback));
	if (callback == NULL) {
		obc_session_unref(session);
		return NULL;
	}

	callback->session = obc_session_ref(session);
	callback->func = function;
	callback->data = user_data;

	if (source) {
		req = send_method_call(session->conn_system,
				BT_BUS_NAME, BT_PATH,
				BT_MANAGER_IFACE, "FindAdapter",
				manager_reply, callback,
				DBUS_TYPE_STRING, &source,
				DBUS_TYPE_INVALID);
	} else {
		req = send_method_call(session->conn_system,
				BT_BUS_NAME, BT_PATH,
				BT_MANAGER_IFACE, "DefaultAdapter",
				manager_reply, callback,
				DBUS_TYPE_INVALID);
	}

	if (!req) {
		obc_session_unref(session);
		g_free(callback);
		return NULL;
	}

	session->pending_calls = g_slist_prepend(session->pending_calls, req);

	if (owner)
		obc_session_set_owner(session, owner, owner_disconnected);

	return session;
}