Ejemplo n.º 1
0
Archivo: gobex.c Proyecto: Fiend90/obex
gboolean g_obex_send(GObex *obex, GObexPacket *pkt, GError **err)
{
	struct pending_pkt *p;
	gboolean ret;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	if (obex == NULL || pkt == NULL) {
		g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_INVALID_ARGS,
				"Invalid arguments");
		g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", (*err)->message);
		return FALSE;
	}

	switch (obex->rx_last_op) {
	case G_OBEX_OP_CONNECT:
		prepare_connect_rsp(obex, pkt);
		break;
	case G_OBEX_OP_GET:
	case G_OBEX_OP_PUT:
		prepare_srm_rsp(obex, pkt);
		break;
	}

	p = g_new0(struct pending_pkt, 1);
	p->pkt = pkt;

	ret = g_obex_send_internal(obex, p, err);
	if (ret == FALSE)
		pending_pkt_free(p);

	return ret;
}
Ejemplo n.º 2
0
Archivo: gobex.c Proyecto: Fiend90/obex
static void handle_response(GObex *obex, GError *err, GObexPacket *rsp)
{
	struct pending_pkt *p = obex->pending_req;
	gboolean disconn = err ? TRUE : FALSE, final_rsp = TRUE;

	if (rsp != NULL)
		final_rsp = parse_response(obex, rsp);

	if (p->cancelled)
		err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
					"The operation was cancelled");

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

	if (p->rsp_func) {
		p->rsp_func(obex, err, rsp, p->rsp_data);

		/* Check if user callback removed the request */
		if (p != obex->pending_req)
			return;
	}

	if (p->cancelled)
		g_error_free(err);

	if (final_rsp) {
		pending_pkt_free(p);
		obex->pending_req = NULL;
	}

	if (!disconn && g_queue_get_length(obex->tx_queue) > 0)
		enable_tx(obex);
}
Ejemplo n.º 3
0
Archivo: gobex.c Proyecto: Fiend90/obex
void g_obex_unref(GObex *obex)
{
	gboolean last_ref;

	last_ref = g_atomic_int_dec_and_test(&obex->ref_count);

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "ref %u", obex->ref_count);

	if (!last_ref)
		return;

	g_slist_free_full(obex->req_handlers, g_free);

	g_queue_foreach(obex->tx_queue, (GFunc) pending_pkt_free, NULL);
	g_queue_free(obex->tx_queue);

	if (obex->io != NULL)
		g_io_channel_unref(obex->io);

	if (obex->io_source > 0)
		g_source_remove(obex->io_source);

	if (obex->write_source > 0)
		g_source_remove(obex->write_source);

	g_free(obex->rx_buf);
	g_free(obex->tx_buf);
	g_free(obex->srm);

	if (obex->pending_req)
		pending_pkt_free(obex->pending_req);

	g_free(obex);
}
Ejemplo n.º 4
0
Archivo: gobex.c Proyecto: Thread974/bz
void g_obex_unref(GObex *obex)
{
	int refs;

	refs = __sync_sub_and_fetch(&obex->ref_count, 1);

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "ref %u", refs);

	if (refs > 0)
		return;

	g_slist_free_full(obex->req_handlers, g_free);

	g_queue_foreach(obex->tx_queue, (GFunc) pending_pkt_free, NULL);
	g_queue_free(obex->tx_queue);

	if (obex->io != NULL)
		g_io_channel_unref(obex->io);

	if (obex->io_source > 0)
		g_source_remove(obex->io_source);

	if (obex->write_source > 0)
		g_source_remove(obex->write_source);

	g_free(obex->rx_buf);
	g_free(obex->tx_buf);
	g_free(obex->srm);

	if (obex->pending_req)
		pending_pkt_free(obex->pending_req);

	g_free(obex);
}
Ejemplo n.º 5
0
Archivo: gobex.c Proyecto: Fiend90/obex
guint g_obex_send_req(GObex *obex, GObexPacket *req, gint timeout,
			GObexResponseFunc func, gpointer user_data,
			GError **err)
{
	GObexHeader *hdr;
	struct pending_pkt *p;
	static guint id = 1;
	guint8 op;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	op = g_obex_packet_get_operation(req, NULL);
	if (op == G_OBEX_OP_PUT || op == G_OBEX_OP_GET) {
		/* Only enable SRM automatically for GET and PUT */
		prepare_srm_req(obex, req);
	}

	if (obex->conn_id == CONNID_INVALID)
		goto create_pending;

	if (obex->rx_last_op == G_OBEX_RSP_CONTINUE)
		goto create_pending;

	if (g_obex_srm_active(obex) && obex->pending_req != NULL)
		goto create_pending;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_CONNECTION);
	if (hdr != NULL)
		goto create_pending;

	hdr = g_obex_header_new_uint32(G_OBEX_HDR_CONNECTION, obex->conn_id);
	g_obex_packet_prepend_header(req, hdr);

create_pending:
	p = g_new0(struct pending_pkt, 1);

	p->pkt = req;
	p->id = id++;
	p->rsp_func = func;
	p->rsp_data = user_data;

	if (timeout < 0)
		p->timeout = G_OBEX_DEFAULT_TIMEOUT;
	else
		p->timeout = timeout;

	if (!g_obex_send_internal(obex, p, err)) {
		pending_pkt_free(p);
		return 0;
	}

	return p->id;
}
Ejemplo n.º 6
0
Archivo: gobex.c Proyecto: Fiend90/obex
static gboolean cancel_complete(gpointer user_data)
{
	struct pending_pkt *p = user_data;
	GObex *obex = p->obex;
	GError *err;

	g_assert(p->rsp_func != NULL);

	err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
					"The request was cancelled");
	p->rsp_func(obex, err, NULL, p->rsp_data);

	g_error_free(err);

	pending_pkt_free(p);

	return FALSE;
}
Ejemplo n.º 7
0
Archivo: gobex.c Proyecto: Fiend90/obex
gboolean g_obex_cancel_req(GObex *obex, guint req_id, gboolean remove_callback)
{
	GList *match;
	struct pending_pkt *p;

	if (obex->pending_req && obex->pending_req->id == req_id) {
		if (!g_obex_pending_req_abort(obex, NULL)) {
			p = obex->pending_req;
			obex->pending_req = NULL;
			goto immediate_completion;
		}

		if (remove_callback)
			obex->pending_req->rsp_func = NULL;

		return TRUE;
	}

	match = g_queue_find_custom(obex->tx_queue, GUINT_TO_POINTER(req_id),
							pending_pkt_cmp);
	if (match == NULL)
		return FALSE;

	p = match->data;

	g_queue_delete_link(obex->tx_queue, match);

immediate_completion:
	p->cancelled = TRUE;
	p->obex = g_obex_ref(obex);

	if (remove_callback || p->rsp_func == NULL)
		pending_pkt_free(p);
	else
		g_idle_add(cancel_complete, p);

	return TRUE;
}
Ejemplo n.º 8
0
Archivo: gobex.c Proyecto: Fiend90/obex
static gboolean req_timeout(gpointer user_data)
{
	GObex *obex = user_data;
	struct pending_pkt *p = obex->pending_req;
	GError *err;

	g_assert(p != NULL);

	obex->pending_req = NULL;

	err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_TIMEOUT,
					"Timed out waiting for response");

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

	if (p->rsp_func)
		p->rsp_func(obex, err, NULL, p->rsp_data);

	g_error_free(err);
	pending_pkt_free(p);

	return FALSE;
}
Ejemplo n.º 9
0
Archivo: gobex.c Proyecto: Fiend90/obex
static gboolean write_data(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	GObex *obex = user_data;

	if (cond & G_IO_NVAL)
		return FALSE;

	if (cond & (G_IO_HUP | G_IO_ERR))
		goto stop_tx;

	if (obex->tx_data == 0) {
		struct pending_pkt *p = g_queue_pop_head(obex->tx_queue);
		ssize_t len;

		if (p == NULL)
			goto stop_tx;

		setup_srm(obex, p->pkt, TRUE);

		if (g_obex_srm_active(obex))
			goto encode;

		/* Can't send a request while there's a pending one */
		if (obex->pending_req && p->id > 0) {
			g_queue_push_head(obex->tx_queue, p);
			goto stop_tx;
		}

encode:
		len = g_obex_packet_encode(p->pkt, obex->tx_buf, obex->tx_mtu);
		if (len == -EAGAIN) {
			g_queue_push_head(obex->tx_queue, p);
			g_obex_suspend(obex);
			goto stop_tx;
		}

		if (len < 0) {
			pending_pkt_free(p);
			goto done;
		}

		if (p->id > 0) {
			if (obex->pending_req != NULL)
				pending_pkt_free(obex->pending_req);
			obex->pending_req = p;
			p->timeout_id = g_timeout_add_seconds(p->timeout,
							req_timeout, obex);
		} else {
			/* During packet encode final bit can be set */
			if (obex->tx_buf[0] & FINAL_BIT)
				check_srm_final(obex,
						obex->tx_buf[0] & ~FINAL_BIT);
			pending_pkt_free(p);
		}

		obex->tx_data = len;
		obex->tx_sent = 0;
	}

	if (obex->suspended) {
		obex->write_source = 0;
		return FALSE;
	}

	if (!obex->write(obex, NULL))
		goto stop_tx;

done:
	if (obex->tx_data > 0 || g_queue_get_length(obex->tx_queue) > 0)
		return TRUE;

stop_tx:
	obex->rx_last_op = G_OBEX_OP_NONE;
	obex->tx_data = 0;
	obex->write_source = 0;
	return FALSE;
}