static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *req;
	gboolean rspcode, final;
	guint id;

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

	id = transfer->req_id;
	transfer->req_id = 0;

	if (err != NULL) {
		transfer_complete(transfer, err);
		return;
	}

	rspcode = g_obex_packet_get_operation(rsp, &final);
	if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) {
		err = g_error_new(G_OBEX_ERROR, rspcode, "%s",
						g_obex_strerror(rspcode));
		goto failed;
	}

	if (transfer->opcode == G_OBEX_OP_GET) {
		handle_get_body(transfer, rsp, &err);
		if (err != NULL)
			goto failed;
	}

	if (rspcode == G_OBEX_RSP_SUCCESS) {
		transfer_complete(transfer, NULL);
		return;
	}

	if (transfer->opcode == G_OBEX_OP_PUT) {
		req = g_obex_packet_new(transfer->opcode, FALSE,
							G_OBEX_HDR_INVALID);
		g_obex_packet_add_body(req, put_get_data, transfer);
	} else if (!g_obex_srm_active(transfer->obex)) {
		req = g_obex_packet_new(transfer->opcode, TRUE,
							G_OBEX_HDR_INVALID);
	} else {
		/* Keep id since request still outstanting */
		transfer->req_id = id;
		return;
	}

	transfer->req_id = g_obex_send_req(obex, req, -1, transfer_response,
							transfer, &err);
failed:
	if (err != NULL) {
		g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", err->message);
		transfer_complete(transfer, err);
		g_error_free(err);
	}
}
Пример #2
0
static void transfer_response(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *req;
	gboolean rspcode, final;

	transfer->req_id = 0;

	if (err != NULL) {
		transfer_complete(transfer, err);
		return;
	}

	rspcode = g_obex_packet_get_operation(rsp, &final);
	if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) {
		err = g_error_new(G_OBEX_ERROR, rspcode,
					"Transfer failed (0x%02x)", rspcode);
		goto failed;
	}

	if (transfer->opcode == G_OBEX_OP_GET) {
		handle_get_body(transfer, rsp, &err);
		if (err != NULL)
			goto failed;
	}

	if (rspcode == G_OBEX_RSP_SUCCESS) {
		transfer_complete(transfer, NULL);
		return;
	}

	if (transfer->opcode == G_OBEX_OP_PUT) {
		req = g_obex_packet_new(transfer->opcode, FALSE,
							G_OBEX_HDR_INVALID);
		g_obex_packet_add_body(req, put_get_data, transfer);
	} else {
		req = g_obex_packet_new(transfer->opcode, TRUE,
							G_OBEX_HDR_INVALID);
	}

	transfer->req_id = g_obex_send_req(obex, req, -1, transfer_response,
							transfer, &err);
failed:
	if (err != NULL) {
		transfer_complete(transfer, err);
		g_error_free(err);
	}
}
Пример #3
0
static gssize put_get_data(void *buf, gsize len, gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *req;
	GError *err = NULL;
	gssize ret;

	ret = transfer->data_producer(buf, len, transfer->user_data);
	if (ret >= 0)
		return ret;

	if (ret == -EAGAIN)
		return ret;

	req = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, G_OBEX_HDR_INVALID);
	transfer->req_id = g_obex_send_req(transfer->obex, req, -1,
						transfer_abort_response,
						transfer, &err);
	if (err != NULL) {
		transfer_complete(transfer, err);
		g_error_free(err);
	}

	return ret;
}
Пример #4
0
guint g_obex_setpath(GObex *obex, const char *path, GObexResponseFunc func,
					gpointer user_data, GError **err)
{
	GObexPacket *req;
	struct setpath_data data;
	const char *folder;

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

	req = g_obex_packet_new(G_OBEX_OP_SETPATH, TRUE, G_OBEX_HDR_INVALID);

	memset(&data, 0, sizeof(data));

	if (path != NULL && strncmp("..", path, 2) == 0) {
		data.flags = 0x03;
		folder = (path[2] == '/') ? &path[3] : NULL;
	} else {
		data.flags = 0x02;
		folder = path;
	}

	if (folder != NULL) {
		GObexHeader *hdr;
		hdr = g_obex_header_new_unicode(G_OBEX_HDR_NAME, folder);
		g_obex_packet_add_header(req, hdr);
	}

	g_obex_packet_set_data(req, &data, sizeof(data), G_OBEX_DATA_COPY);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}
Пример #5
0
static void handle_connect(GObex *obex, GObexPacket *req, gpointer user_data)
{
	GObexPacket *rsp;

	g_print("connect\n");

	rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE, G_OBEX_HDR_INVALID);
	g_obex_send(obex, rsp, NULL);
}
Пример #6
0
static void get_buf_xfer_progress(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct obc_transfer *transfer = user_data;
	struct transfer_callback *callback = transfer->callback;
	GObexPacket *req;
	GObexHeader *hdr;
	const guint8 *buf;
	gsize len;
	guint8 rspcode;
	gboolean final;

	if (err != NULL) {
		get_buf_xfer_complete(obex, err, transfer);
		return;
	}

	rspcode = g_obex_packet_get_operation(rsp, &final);
	if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) {
		err = g_error_new(OBEX_IO_ERROR, rspcode,
					"Transfer failed (0x%02x)", rspcode);
		get_buf_xfer_complete(obex, err, transfer);
		g_error_free(err);
		return;
	}

	hdr = g_obex_packet_get_header(rsp, G_OBEX_HDR_APPARAM);
	if (hdr) {
		g_obex_header_get_bytes(hdr, &buf, &len);
		if (len != 0) {
			transfer->params->data = g_memdup(buf, len);
			transfer->params->size = len;
		}
	}

	hdr = g_obex_packet_get_body(rsp);
	if (hdr) {
		g_obex_header_get_bytes(hdr, &buf, &len);
		if (len != 0)
			obc_transfer_read(transfer, buf, len);
	}

	if (rspcode == G_OBEX_RSP_SUCCESS) {
		get_buf_xfer_complete(obex, err, transfer);
		return;
	}

	req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);

	transfer->xfer = g_obex_send_req(obex, req, -1, get_buf_xfer_progress,
							transfer, &err);

	if (callback)
		callback->func(transfer, transfer->transferred, err,
							callback->data);
}
Пример #7
0
static void test_pkt(void)
{
	GObexPacket *pkt;

	pkt = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, G_OBEX_HDR_INVALID);

	g_assert(pkt != NULL);

	g_obex_packet_free(pkt);
}
Пример #8
0
guint g_obex_delete(GObex *obex, const char *name, GObexResponseFunc func,
					gpointer user_data, GError **err)
{
	GObexPacket *req;

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

	req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, G_OBEX_HDR_NAME, name,
							G_OBEX_HDR_INVALID);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}
Пример #9
0
static gssize put_get_data(void *buf, gsize len, gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *req;
	GError *err = NULL;
	gssize ret;

	ret = transfer->data_producer(buf, len, transfer->user_data);
	if (ret == 0 || ret == -EAGAIN)
		return ret;

	if (ret > 0) {
		/* Check if SRM is active */
		if (!g_obex_srm_active(transfer->obex))
			return ret;

		/* Generate next packet */
		req = g_obex_packet_new(transfer->opcode, FALSE,
							G_OBEX_HDR_INVALID);
		g_obex_packet_add_body(req, put_get_data, transfer);
		transfer->req_id = g_obex_send_req(transfer->obex, req, -1,
						transfer_response, transfer,
						&err);
		goto done;
	}

	req = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, G_OBEX_HDR_INVALID);

	transfer->req_id = g_obex_send_req(transfer->obex, req, -1,
						transfer_abort_response,
						transfer, &err);
done:
	if (err != NULL) {
		transfer_complete(transfer, err);
		g_error_free(err);
	}

	return ret;
}
Пример #10
0
static void transfer_abort_req(GObex *obex, GObexPacket *req, gpointer user_data)
{
	struct transfer *transfer = user_data;
	GObexPacket *rsp;
	GError *err;

	err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
						"Request was aborted");
	rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE, G_OBEX_HDR_INVALID);
	g_obex_send(obex, rsp, NULL);

	transfer_complete(transfer, err);
	g_error_free(err);
}
Пример #11
0
static void test_encode_on_demand_fail(void)
{
	GObexPacket *pkt;
	uint8_t buf[255];
	gssize len;

	pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_INVALID);
	g_obex_packet_add_body(pkt, get_body_data_fail, NULL);

	len = g_obex_packet_encode(pkt, buf, sizeof(buf));

	g_assert_cmpint(len, ==, -EIO);

	g_obex_packet_free(pkt);
}
Пример #12
0
guint g_obex_mkdir(GObex *obex, const char *path, GObexResponseFunc func,
					gpointer user_data, GError **err)
{
	GObexPacket *req;
	struct setpath_data data;

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

	req = g_obex_packet_new(G_OBEX_OP_SETPATH, TRUE, G_OBEX_HDR_NAME, path,
							G_OBEX_HDR_INVALID);

	memset(&data, 0, sizeof(data));
	g_obex_packet_set_data(req, &data, sizeof(data), G_OBEX_DATA_COPY);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}
Пример #13
0
gboolean g_obex_pending_req_abort(GObex *obex, GError **err)
{
	struct pending_pkt *p = obex->pending_req;
	GObexPacket *req;

	if (p->cancelled)
		return TRUE;

	p->cancelled = TRUE;

	g_source_remove(p->timeout_id);
	p->timeout = G_OBEX_ABORT_TIMEOUT;
	p->timeout_id = g_timeout_add_seconds(p->timeout, req_timeout, obex);

	req = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, G_OBEX_HDR_INVALID);

	return g_obex_send(obex, req, err);
}
Пример #14
0
static void test_encode_on_demand(void)
{
	GObexPacket *pkt;
	uint8_t buf[255];
	gssize len;

	pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_INVALID);
	g_obex_packet_add_body(pkt, get_body_data, NULL);

	len = g_obex_packet_encode(pkt, buf, sizeof(buf));
	if (len < 0) {
		g_printerr("Encoding failed: %s\n", g_strerror(-len));
		g_assert_not_reached();
	}

	assert_memequal(pkt_put_body, sizeof(pkt_put_body), buf, len);

	g_obex_packet_free(pkt);
}
Пример #15
0
static void test_create_args(void)
{
	GObexPacket *pkt;
	guint8 buf[255], body[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
	gssize len;

	pkt = g_obex_packet_new(G_OBEX_OP_PUT, FALSE,
			G_OBEX_HDR_CONNECTION, 0x01020304,
			G_OBEX_HDR_TYPE, "foo/bar", strlen("foo/bar") + 1,
			G_OBEX_HDR_NAME, "file.txt",
			G_OBEX_HDR_ACTION, 0xab,
			G_OBEX_HDR_BODY, body, sizeof(body),
			G_OBEX_HDR_INVALID);

	g_assert(pkt != NULL);

	len = g_obex_packet_encode(pkt, buf, sizeof(buf));
	g_assert(len > 0);

	assert_memequal(pkt_put_long, sizeof(pkt_put_long), buf, len);

	g_obex_packet_free(pkt);
}
Пример #16
0
int obc_transfer_put(struct obc_transfer *transfer, transfer_callback_t func,
			void *user_data)
{
	struct obc_session *session = transfer->session;
	GError *err = NULL;
	GObex *obex;
	GObexPacket *req;
	GObexDataProducer data_cb;
	struct stat st;
	int fd;

	if (transfer->xfer != 0)
		return -EALREADY;

	if (transfer->buffer) {
		data_cb = put_buf_xfer_progress;
		goto done;
	}

	fd = open(transfer->filename, O_RDONLY);
	if (fd < 0) {
		error("open(): %s(%d)", strerror(errno), errno);
		return -errno;
	}

	if (fstat(fd, &st) < 0) {
		close(fd);
		error("fstat(): %s(%d)", strerror(errno), errno);
		return -errno;
	}

	transfer->fd = fd;
	transfer->size = st.st_size;
	data_cb = put_xfer_progress;

done:
	obex = obc_session_get_obex(session);
	req = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_INVALID);

	if (transfer->name != NULL)
		g_obex_packet_add_unicode(req, G_OBEX_HDR_NAME,
							transfer->name);

	if (transfer->type != NULL)
		g_obex_packet_add_bytes(req, G_OBEX_HDR_TYPE, transfer->type,
						strlen(transfer->type) + 1);

	if (transfer->size < UINT32_MAX)
		g_obex_packet_add_uint32(req, G_OBEX_HDR_LENGTH, transfer->size);

	if (transfer->params != NULL)
		g_obex_packet_add_bytes(req, G_OBEX_HDR_APPARAM,
						transfer->params->data,
						transfer->params->size);

	transfer->xfer = g_obex_put_req_pkt(obex, req, data_cb, xfer_complete,
							transfer, &err);
	if (transfer->xfer == 0)
		return -ENOTCONN;

	if (func)
		obc_transfer_set_callback(transfer, func, user_data);

	return 0;
}
Пример #17
0
int obc_transfer_get(struct obc_transfer *transfer, transfer_callback_t func,
			void *user_data)
{
	struct obc_session *session = transfer->session;
	GError *err = NULL;
	GObex *obex;
	GObexPacket *req;
	GObexDataConsumer data_cb;
	GObexFunc complete_cb;
	GObexResponseFunc rsp_cb = NULL;

	if (transfer->xfer != 0)
		return -EALREADY;

	if (transfer->type != NULL &&
			(strncmp(transfer->type, "x-obex/", 7) == 0 ||
			strncmp(transfer->type, "x-bt/", 5) == 0)) {
		rsp_cb = get_buf_xfer_progress;
	} else {
		int fd = open(transfer->name ? : transfer->filename,
				O_WRONLY | O_CREAT, 0600);

		if (fd < 0) {
			error("open(): %s(%d)", strerror(errno), errno);
			return -errno;
		}
		transfer->fd = fd;
		data_cb = get_xfer_progress;
		complete_cb = xfer_complete;
	}

	obex = obc_session_get_obex(session);

	req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);

	if (transfer->filename != NULL)
		g_obex_packet_add_unicode(req, G_OBEX_HDR_NAME,
							transfer->filename);

	if (transfer->type != NULL)
		g_obex_packet_add_bytes(req, G_OBEX_HDR_TYPE, transfer->type,
						strlen(transfer->type) + 1);

	if (transfer->params != NULL)
		g_obex_packet_add_bytes(req, G_OBEX_HDR_APPARAM,
						transfer->params->data,
						transfer->params->size);

	if (rsp_cb)
		transfer->xfer = g_obex_send_req(obex, req, -1, rsp_cb,
							transfer, &err);
	else
		transfer->xfer = g_obex_get_req_pkt(obex, req, data_cb,
							complete_cb, transfer,
							&err);

	if (transfer->xfer == 0)
		return -ENOTCONN;

	if (func)
		obc_transfer_set_callback(transfer, func, user_data);

	return 0;
}