Exemple #1
0
static void transport_func(GIOChannel *io, GError *err, gpointer user_data)
{
    struct callback_data *callback = user_data;
    struct obc_session *session = callback->session;
    struct obc_driver *driver = session->driver;
    struct obc_transport *transport = session->transport;
    GObex *obex;
    GObexTransportType type;
    int tx_mtu = -1;
    int rx_mtu = -1;

    DBG("");

    if (err != NULL) {
        error("%s", err->message);
        goto done;
    }

    g_io_channel_set_close_on_unref(io, FALSE);

    if (transport->getpacketopt &&
            transport->getpacketopt(io, &tx_mtu, &rx_mtu) == 0)
        type = G_OBEX_TRANSPORT_PACKET;
    else
        type = G_OBEX_TRANSPORT_STREAM;

    obex = g_obex_new(io, type, tx_mtu, rx_mtu);
    if (obex == NULL)
        goto done;

    g_io_channel_set_close_on_unref(io, TRUE);

    if (driver->target != NULL)
        g_obex_connect(obex, connect_cb, callback, &err,
                       G_OBEX_HDR_TARGET, driver->target, driver->target_len,
                       G_OBEX_HDR_INVALID);
    else
        g_obex_connect(obex, connect_cb, callback, &err,
                       G_OBEX_HDR_INVALID);

    if (err != NULL) {
        error("%s", err->message);
        g_obex_unref(obex);
        goto done;
    }

    session->obex = obex;
    sessions = g_slist_prepend(sessions, session);

    g_obex_set_disconnect_function(obex, session_disconnected, session);

    return;
done:
    callback->func(callback->session, NULL, err, callback->data);
    obc_session_unref(callback->session);
    g_free(callback);
}
Exemple #2
0
static void pending_pkt_free(struct pending_pkt *p)
{
	if (p->obex != NULL)
		g_obex_unref(p->obex);

	if (p->timeout_id > 0)
		g_source_remove(p->timeout_id);

	g_obex_packet_free(p->pkt);

	g_free(p);
}
Exemple #3
0
int main(int argc, char *argv[])
{
	GOptionContext *context;
	GError *err = NULL;
	struct sigaction sa;
	GIOChannel *io;
	GObexTransportType transport;

	context = g_option_context_new(NULL);
	g_option_context_add_main_entries(context, options, NULL);

	g_option_context_parse(context, &argc, &argv, &err);
	if (err != NULL) {
		g_printerr("%s\n", err->message);
		g_error_free(err);
		g_option_context_free(context);
		exit(EXIT_FAILURE);
	}

	if (option_packet)
		transport = G_OBEX_TRANSPORT_PACKET;
	else
		transport = G_OBEX_TRANSPORT_STREAM;

	if (option_bluetooth)
		io = bluetooth_connect(transport);
	else
		io = unix_connect(transport);

	if (io == NULL) {
		g_option_context_free(context);
		exit(EXIT_FAILURE);
	}

	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sig_term;
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);

	main_loop = g_main_loop_new(NULL, FALSE);

	g_main_loop_run(main_loop);

	rl_callback_handler_remove();
	clear_history();
	g_obex_unref(obex);
	g_option_context_free(context);
	g_main_loop_unref(main_loop);

	exit(EXIT_SUCCESS);
}
Exemple #4
0
static void session_free(struct obc_session *session)
{
	DBG("%p", session);

	if (session->process_id != 0)
		g_source_remove(session->process_id);

	if (session->queue) {
		g_queue_foreach(session->queue, (GFunc) pending_request_free,
									NULL);
		g_queue_free(session->queue);
	}

	if (session->watch)
		g_dbus_remove_watch(session->conn, session->watch);

	if (session->obex) {
		g_obex_set_disconnect_function(session->obex, NULL, NULL);
		g_obex_unref(session->obex);
	}

	if (session->id > 0 && session->transport != NULL)
		session->transport->disconnect(session->id);

	if (session->path)
		session_unregistered(session);

	if (session->conn)
		dbus_connection_unref(session->conn);

	if (session->p)
		pending_request_free(session->p);

	g_free(session->path);
	g_free(session->owner);
	g_free(session->source);
	g_free(session->destination);
	g_free(session->folder);
	g_free(session);
}
static void transfer_free(struct transfer *transfer)
{
	transfers = g_slist_remove(transfers, transfer);

	if (transfer->req_id > 0)
		g_obex_cancel_req(transfer->obex, transfer->req_id, TRUE);

	if (transfer->put_id > 0)
		g_obex_remove_request_function(transfer->obex,
							transfer->put_id);

	if (transfer->get_id > 0)
		g_obex_remove_request_function(transfer->obex,
							transfer->req_id);

	if (transfer->abort_id > 0)
		g_obex_remove_request_function(transfer->obex,
							transfer->abort_id);

	g_obex_unref(transfer->obex);
	g_free(transfer);
}
Exemple #6
0
static void transfer_free(struct transfer *transfer)
{
	g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);

	transfers = g_slist_remove(transfers, transfer);

	if (transfer->req_id > 0)
		g_obex_cancel_req(transfer->obex, transfer->req_id, TRUE);

	if (transfer->put_id > 0)
		g_obex_remove_request_function(transfer->obex,
							transfer->put_id);

	if (transfer->get_id > 0)
		g_obex_remove_request_function(transfer->obex,
							transfer->get_id);

	if (transfer->abort_id > 0)
		g_obex_remove_request_function(transfer->obex,
							transfer->abort_id);

	g_obex_unref(transfer->obex);
	g_free(transfer);
}
Exemple #7
0
static void disconn_func(GObex *obex, GError *err, gpointer user_data)
{
	g_print("Client disconnected: %s\n", err ? err->message : "<no err>");
	clients = g_slist_remove(clients, obex);
	g_obex_unref(obex);
}
Exemple #8
0
GObex *g_obex_new(GIOChannel *io, GObexTransportType transport_type,
					gssize io_rx_mtu, gssize io_tx_mtu)
{
	GObex *obex;
	GIOCondition cond;

	if (gobex_debug == 0) {
		const char *env = g_getenv("GOBEX_DEBUG");

		if (env) {
			gobex_debug = g_parse_debug_string(env, keys, 7);
			g_setenv("G_MESSAGES_DEBUG", "gobex", FALSE);
		} else
			gobex_debug = G_OBEX_DEBUG_NONE;
	}

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "");

	if (io == NULL)
		return NULL;

	if (io_rx_mtu >= 0 && io_rx_mtu < G_OBEX_MINIMUM_MTU)
		return NULL;

	if (io_tx_mtu >= 0 && io_tx_mtu < G_OBEX_MINIMUM_MTU)
		return NULL;

	obex = g_new0(GObex, 1);

	obex->io = g_io_channel_ref(io);
	obex->ref_count = 1;
	obex->conn_id = CONNID_INVALID;
	obex->rx_last_op = G_OBEX_OP_NONE;

	obex->io_rx_mtu = io_rx_mtu;
	obex->io_tx_mtu = io_tx_mtu;

	if (io_rx_mtu > G_OBEX_MAXIMUM_MTU)
		obex->rx_mtu = G_OBEX_MAXIMUM_MTU;
	else if (io_rx_mtu < G_OBEX_MINIMUM_MTU)
		obex->rx_mtu = G_OBEX_DEFAULT_MTU;
	else
		obex->rx_mtu = io_rx_mtu;

	obex->tx_mtu = G_OBEX_MINIMUM_MTU;

	obex->tx_queue = g_queue_new();
	obex->rx_buf = g_malloc(obex->rx_mtu);
	obex->tx_buf = g_malloc(obex->tx_mtu);

	switch (transport_type) {
	case G_OBEX_TRANSPORT_STREAM:
		obex->read = read_stream;
		obex->write = write_stream;
		break;
	case G_OBEX_TRANSPORT_PACKET:
		obex->use_srm = TRUE;
		obex->read = read_packet;
		obex->write = write_packet;
		break;
	default:
		g_obex_unref(obex);
		return NULL;
	}

	g_io_channel_set_encoding(io, NULL, NULL);
	g_io_channel_set_buffered(io, FALSE);
	cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
	obex->io_source = g_io_add_watch(io, cond, incoming_data, obex);

	return obex;
}
Exemple #9
0
static gboolean incoming_data(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	GObex *obex = user_data;
	GObexPacket *pkt;
	ssize_t header_offset;
	GError *err = NULL;
	guint8 opcode;

	if (cond & G_IO_NVAL)
		return FALSE;

	if (cond & (G_IO_HUP | G_IO_ERR)) {
		err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_DISCONNECTED,
					"Transport got disconnected");
		goto failed;
	}

	if (!obex->read(obex, &err))
		goto failed;

	if (obex->rx_data < 3 || obex->rx_data < obex->rx_pkt_len)
		return TRUE;

	obex->rx_last_op = obex->rx_buf[0] & ~FINAL_BIT;

	if (obex->pending_req) {
		struct pending_pkt *p = obex->pending_req;
		opcode = g_obex_packet_get_operation(p->pkt, NULL);
		header_offset = rsp_header_offset(opcode);
	} else {
		opcode = obex->rx_last_op;
		/* Unexpected response -- fail silently */
		if (opcode > 0x1f && opcode != G_OBEX_OP_ABORT) {
			obex->rx_data = 0;
			return TRUE;
		}
		header_offset = req_header_offset(opcode);
	}

	if (header_offset < 0) {
		err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR,
				"Unknown header offset for opcode 0x%02x",
				opcode);
		goto failed;
	}

	pkt = g_obex_packet_decode(obex->rx_buf, obex->rx_data, header_offset,
							G_OBEX_DATA_REF, &err);
	if (pkt == NULL)
		goto failed;

	/* Protect against user callback freeing the object */
	g_obex_ref(obex);

	if (obex->pending_req)
		handle_response(obex, NULL, pkt);
	else
		handle_request(obex, pkt);

	obex->rx_data = 0;

	g_obex_unref(obex);

	if (err != NULL)
		g_error_free(err);

	if (pkt != NULL)
		g_obex_packet_free(pkt);

	return TRUE;

failed:
	if (err)
		g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", err->message);

	g_io_channel_unref(obex->io);
	obex->io = NULL;
	obex->io_source = 0;
	obex->rx_data = 0;

	/* Protect against user callback freeing the object */
	g_obex_ref(obex);

	if (obex->pending_req)
		handle_response(obex, err, NULL);

	if (obex->disconn_func)
		obex->disconn_func(obex, err, obex->disconn_func_data);

	g_obex_unref(obex);

	g_error_free(err);

	return FALSE;
}
Exemple #10
0
static void transport_func(GIOChannel *io, GError *err, gpointer user_data)
{
	struct callback_data *callback = user_data;
	struct obc_session *session = callback->session;
	struct obc_driver *driver = session->driver;
	struct obc_transport *transport = session->transport;
	GObex *obex;
	GObexApparam *apparam;
	GObexTransportType type;
	int tx_mtu = -1;
	int rx_mtu = -1;

	DBG("");

	if (err != NULL) {
		error("%s", err->message);
		goto done;
	}

	g_io_channel_set_close_on_unref(io, FALSE);

	if (transport->getpacketopt &&
			transport->getpacketopt(io, &tx_mtu, &rx_mtu) == 0)
		type = G_OBEX_TRANSPORT_PACKET;
	else
		type = G_OBEX_TRANSPORT_STREAM;

	obex = g_obex_new(io, type, tx_mtu, rx_mtu);
	if (obex == NULL)
		goto done;

	g_io_channel_set_close_on_unref(io, TRUE);

	apparam = NULL;

	if (driver->supported_features)
		apparam = driver->supported_features(session);

	if (apparam) {
		uint8_t buf[1024];
		ssize_t len;

		len = g_obex_apparam_encode(apparam, buf, sizeof(buf));
		if (driver->target)
			g_obex_connect(obex, connect_cb, callback, &err,
					G_OBEX_HDR_TARGET,
					driver->target, driver->target_len,
					G_OBEX_HDR_APPARAM,
					buf, len,
					G_OBEX_HDR_INVALID);
		else
			g_obex_connect(obex, connect_cb, callback, &err,
					G_OBEX_HDR_APPARAM, buf, len,
					G_OBEX_HDR_INVALID);
		g_obex_apparam_free(apparam);
	} else if (driver->target)
		g_obex_connect(obex, connect_cb, callback, &err,
			G_OBEX_HDR_TARGET, driver->target, driver->target_len,
			G_OBEX_HDR_INVALID);
	else
		g_obex_connect(obex, connect_cb, callback, &err,
							G_OBEX_HDR_INVALID);

	if (err != NULL) {
		error("%s", err->message);
		g_obex_unref(obex);
		goto done;
	}

	session->obex = obex;
	sessions = g_slist_prepend(sessions, session);

	g_obex_set_disconnect_function(obex, session_disconnected, session);

	return;
done:
	callback_destroy(callback, err);
}