Ejemplo n.º 1
0
guint g_obex_put_req_pkt(GObex *obex, GObexPacket *req,
			GObexDataProducer data_func, GObexFunc complete_func,
			gpointer user_data, GError **err)
{
	struct transfer *transfer;

	g_obex_debug(G_OBEX_DEBUG_TRANSFER, "obex %p", obex);

	if (g_obex_packet_get_operation(req, NULL) != G_OBEX_OP_PUT)
		return 0;

	transfer = transfer_new(obex, G_OBEX_OP_PUT, complete_func, user_data);
	transfer->data_producer = data_func;

	g_obex_packet_add_body(req, put_get_data, transfer);

	transfer->req_id = g_obex_send_req(obex, req, FIRST_PACKET_TIMEOUT,
					transfer_response, transfer, err);
	if (transfer->req_id == 0) {
		transfer_free(transfer);
		return 0;
	}

	g_obex_debug(G_OBEX_DEBUG_TRANSFER, "transfer %u", transfer->id);

	return transfer->id;
}
Ejemplo n.º 2
0
Archivo: gobex.c Proyecto: Fiend90/obex
static gboolean parse_response(GObex *obex, GObexPacket *rsp)
{
	struct pending_pkt *p = obex->pending_req;
	guint8 opcode, rspcode;
	gboolean final;

	rspcode = g_obex_packet_get_operation(rsp, &final);

	opcode = g_obex_packet_get_operation(p->pkt, NULL);
	if (opcode == G_OBEX_OP_CONNECT)
		parse_connect_data(obex, rsp);

	setup_srm(obex, rsp, FALSE);

	if (!g_obex_srm_active(obex))
		return final;

	/*
	 * Resposes have final bit set but in case of GET with SRM
	 * we should not remove the request since the remote side will
	 * continue sending responses until the transfer is finished
	 */
	if (opcode == G_OBEX_OP_GET && rspcode == G_OBEX_RSP_CONTINUE) {
		g_source_remove(p->timeout_id);
		p->timeout_id = g_timeout_add_seconds(p->timeout, req_timeout,
									obex);
		return FALSE;
	}

	return final;
}
Ejemplo n.º 3
0
static void async_cb(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct pending_request *p = user_data;
	struct obc_session *session = p->session;
	GError *gerr = NULL;
	uint8_t code;

	p->req_id = 0;

	if (err != NULL) {
		if (p->func)
			p->func(p->session, NULL, err, p->data);
		goto done;
	}

	code = g_obex_packet_get_operation(rsp, NULL);
	if (code != G_OBEX_RSP_SUCCESS)
		g_set_error(&gerr, OBEX_IO_ERROR, code, "%s",
							g_obex_strerror(code));

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

	if (gerr != NULL)
		g_clear_error(&gerr);

done:
	pending_request_free(p);
	session->p = NULL;

	session_process_queue(session);
}
Ejemplo n.º 4
0
static void connect_cb(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct callback_data *callback = user_data;
	GError *gerr = NULL;
	uint8_t rsp_code;

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

	rsp_code = g_obex_packet_get_operation(rsp, NULL);
	if (rsp_code != G_OBEX_RSP_SUCCESS)
		gerr = g_error_new(OBEX_IO_ERROR, -EIO,
				"OBEX Connect failed with 0x%02x", rsp_code);

done:
	callback->func(callback->session, NULL, gerr, callback->data);
	if (gerr != NULL)
		g_error_free(gerr);
	obc_session_unref(callback->session);
	g_free(callback);
}
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
static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct pending_request *p = user_data;
	struct setpath_data *data = p->data;
	char *next;
	char *current;
	guint8 code;

	p->req_id = 0;

	if (err != NULL) {
		setpath_complete(p->session, NULL, err, user_data);
		return;
	}

	code = g_obex_packet_get_operation(rsp, NULL);
	if (code != G_OBEX_RSP_SUCCESS) {
		GError *gerr = NULL;
		g_set_error(&gerr, OBEX_IO_ERROR, code, "%s",
							g_obex_strerror(code));
		setpath_complete(p->session, NULL, gerr, user_data);
		g_clear_error(&gerr);
		return;
	}

	current = data->remaining[data->index - 1];
	setpath_set_folder(p->session, current);

	/* Ignore empty folder names to avoid resetting the current path */
	while ((next = data->remaining[data->index]) && strlen(next) == 0)
		data->index++;

	if (next == NULL) {
		setpath_complete(p->session, NULL, NULL, user_data);
		return;
	}

	data->index++;

	p->req_id = g_obex_setpath(obex, next, setpath_cb, p, &err);
	if (err != NULL) {
		setpath_complete(p->session, NULL, err, user_data);
		g_error_free(err);
	}
}
Ejemplo n.º 7
0
Archivo: gobex.c Proyecto: Fiend90/obex
static gboolean g_obex_send_internal(GObex *obex, struct pending_pkt *p,
								GError **err)
{

	if (obex->io == NULL) {
		g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_DISCONNECTED,
					"The transport is not connected");
		g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", (*err)->message);
		return FALSE;
	}

	if (g_obex_packet_get_operation(p->pkt, NULL) == G_OBEX_OP_ABORT)
		g_queue_push_head(obex->tx_queue, p);
	else
		g_queue_push_tail(obex->tx_queue, p);

	if (obex->pending_req == NULL || p->id == 0)
		enable_tx(obex);

	return TRUE;
}
Ejemplo n.º 8
0
static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct pending_request *p = user_data;
	struct setpath_data *data = p->data;
	char *next;
	guint8 code;

	p->req_id = 0;

	if (err != NULL) {
		setpath_complete(p->session, NULL, err, user_data);
		return;
	}

	code = g_obex_packet_get_operation(rsp, NULL);
	if (code != G_OBEX_RSP_SUCCESS) {
		GError *gerr = NULL;
		g_set_error(&gerr, OBEX_IO_ERROR, code, "%s",
							g_obex_strerror(code));
		setpath_complete(p->session, NULL, err, user_data);
		g_clear_error(&gerr);
		return;
	}

	next = data->remaining[data->index];
	if (next == NULL) {
		setpath_complete(p->session, NULL, NULL, user_data);
		return;
	}

	data->index++;

	p->req_id = g_obex_setpath(obex, next, setpath_cb, p, &err);
	if (err != NULL) {
		setpath_complete(p->session, NULL, err, data);
		g_error_free(err);
	}
}
Ejemplo n.º 9
0
guint g_obex_put_req_pkt(GObex *obex, GObexPacket *req,
			GObexDataProducer data_func, GObexFunc complete_func,
			gpointer user_data, GError **err)
{
	struct transfer *transfer;

	if (g_obex_packet_get_operation(req, NULL) != G_OBEX_OP_PUT)
		return 0;

	transfer = transfer_new(obex, G_OBEX_OP_PUT, complete_func, user_data);
	transfer->data_producer = data_func;

	g_obex_packet_add_body(req, put_get_data, transfer);

	transfer->req_id = g_obex_send_req(obex, req, -1, transfer_response,
								transfer, err);
	if (transfer->req_id == 0) {
		transfer_free(transfer);
		return 0;
	}

	return transfer->id;
}
Ejemplo n.º 10
0
Archivo: gobex.c Proyecto: Fiend90/obex
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;
}