コード例 #1
0
ファイル: player.c プロジェクト: AwxiVYTHUIiMOol/bluez
static DBusMessage *media_folder_list_items(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct media_player *mp = data;
	struct media_folder *folder = mp->scope;
	struct player_callback *cb = mp->cb;
	DBusMessageIter iter;
	uint32_t start, end;
	int err;

	dbus_message_iter_init(msg, &iter);

	if (parse_filters(mp, &iter, &start, &end) < 0)
		return btd_error_invalid_args(msg);

	if (cb->cbs->list_items == NULL)
		return btd_error_not_supported(msg);

	if (folder->msg != NULL)
		return btd_error_failed(msg, strerror(EBUSY));

	err = cb->cbs->list_items(mp, folder->item->name, start, end,
							cb->user_data);
	if (err < 0)
		return btd_error_failed(msg, strerror(-err));

	folder->msg = dbus_message_ref(msg);

	return NULL;
}
コード例 #2
0
static DBusMessage *sink_connect(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct audio_device *dev = data;
	struct sink *sink = dev->sink;
	struct pending_request *pending;

	if (!sink->session)
		sink->session = avdtp_get(&dev->src, &dev->dst);

	if (!sink->session)
		return btd_error_failed(msg, "Unable to get a session");

	if (sink->connect || sink->disconnect)
		return btd_error_busy(msg);

	if (sink->stream_state >= AVDTP_STATE_OPEN)
		return btd_error_already_connected(msg);

	if (!sink_setup_stream(sink, NULL))
		return btd_error_failed(msg, "Failed to create a stream");

	dev->auto_connect = FALSE;

	pending = sink->connect;

	pending->conn = dbus_connection_ref(conn);
	pending->msg = dbus_message_ref(msg);

	DBG("stream creation in progress");

	return NULL;
}
コード例 #3
0
static DBusMessage *characteristic_read_value(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct characteristic *chrc = user_data;
	struct bt_gatt_client *gatt = chrc->service->client->gatt;
	struct async_dbus_op *op;

	if (chrc->read_id)
		return btd_error_in_progress(msg);

	op = new0(struct async_dbus_op, 1);
	if (!op)
		return btd_error_failed(msg, "Failed to initialize request");

	op->msg = dbus_message_ref(msg);
	op->data = chrc;

	chrc->read_id = bt_gatt_client_read_value(gatt, chrc->value_handle,
							chrc_read_cb,
							async_dbus_op_ref(op),
							async_dbus_op_unref);
	if (chrc->read_id)
		return NULL;

	async_dbus_op_free(op);

	return btd_error_failed(msg, "Failed to send read request");
}
コード例 #4
0
ファイル: gatt-client.c プロジェクト: Klamath233/BlueZ
static DBusMessage *descriptor_read_value(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct descriptor *desc = user_data;
	struct bt_gatt_client *gatt = desc->chrc->service->client->gatt;
	struct async_dbus_op *op;

	if (!gatt)
		return btd_error_failed(msg, "Not connected");

	if (desc->read_id)
		return btd_error_in_progress(msg);

	op = new0(struct async_dbus_op, 1);
	op->msg = dbus_message_ref(msg);
	op->data = desc;

	desc->read_id = bt_gatt_client_read_value(gatt, desc->handle,
							desc_read_cb,
							async_dbus_op_ref(op),
							async_dbus_op_unref);
	if (desc->read_id)
		return NULL;

	async_dbus_op_free(op);

	return btd_error_failed(msg, "Failed to send read request");
}
コード例 #5
0
static void controlpoint_method_reply(struct controlpoint_req *req,
								uint8_t code)
{
	DBusMessage *reply;

	switch (code) {
	case RSP_SUCCESS:
		reply = dbus_message_new_method_return(req->msg);
		break;
	case RSP_NOT_SUPPORTED:
		reply = btd_error_not_supported(req->msg);
		break;
	case RSP_INVALID_PARAM:
		reply = btd_error_invalid_args(req->msg);
		break;
	case RSP_FAILED:
		reply = btd_error_failed(req->msg, "Failed");
		break;
	default:
		reply = btd_error_failed(req->msg, "Unknown error");
		break;
	}

	g_dbus_send_message(btd_get_dbus_connection(), reply);

	dbus_message_unref(req->msg);
}
コード例 #6
0
ファイル: server.c プロジェクト: sancane/BlueZ
static DBusMessage *register_server(DBusConnection *conn,
				DBusMessage *msg, void *data)
{
	struct network_server *ns = data;
	DBusMessage *reply;
	const char *uuid, *bridge;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &uuid,
				DBUS_TYPE_STRING, &bridge, DBUS_TYPE_INVALID))
		return NULL;

	if (g_strcmp0(uuid, "nap"))
		return btd_error_failed(msg, "Invalid UUID");

	if (ns->record_id)
		return btd_error_already_exists(msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return NULL;

	ns->record_id = register_server_record(ns);
	if (!ns->record_id)
		return btd_error_failed(msg, "SDP record registration failed");

	g_free(ns->bridge);
	ns->bridge = g_strdup(bridge);

	ns->watch_id = g_dbus_add_disconnect_watch(conn,
					dbus_message_get_sender(msg),
					server_disconnect, ns, NULL);

	return reply;
}
コード例 #7
0
static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
{
	struct serial_port *port = user_data;
	struct serial_device *device = port->device;
	sdp_record_t *record = NULL;
	sdp_list_t *protos;
	DBusMessage *reply;
	GError *gerr = NULL;

	if (!port->listener_id) {
		reply = NULL;
		goto failed;
	}

	if (err < 0) {
		error("Unable to get service record: %s (%d)", strerror(-err),
			-err);
		reply = btd_error_failed(port->msg, strerror(-err));
		goto failed;
	}

	if (!recs || !recs->data) {
		error("No record found");
		reply = btd_error_failed(port->msg, "No record found");
		goto failed;
	}

	record = recs->data;

	if (sdp_get_access_protos(record, &protos) < 0) {
		error("Unable to get access protos from port record");
		reply = btd_error_failed(port->msg, "Invalid channel");
		goto failed;
	}

	port->channel = sdp_get_proto_port(protos, RFCOMM_UUID);

	sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
	sdp_list_free(protos, NULL);

	port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
				NULL, &gerr,
				BT_IO_OPT_SOURCE_BDADDR, &device->src,
				BT_IO_OPT_DEST_BDADDR, &device->dst,
				BT_IO_OPT_CHANNEL, port->channel,
				BT_IO_OPT_INVALID);
	if (!port->io) {
		error("%s", gerr->message);
		reply = btd_error_failed(port->msg, gerr->message);
		g_error_free(gerr);
		goto failed;
	}

	return;

failed:
	g_dbus_remove_watch(device->conn, port->listener_id);
	port->listener_id = 0;
	g_dbus_send_message(device->conn, reply);
}
コード例 #8
0
ファイル: player.c プロジェクト: AwxiVYTHUIiMOol/bluez
static DBusMessage *media_folder_search(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	struct media_player *mp = data;
	struct media_folder *folder = mp->scope;
	struct player_callback *cb = mp->cb;
	DBusMessageIter iter;
	const char *string;
	int err;

	dbus_message_iter_init(msg, &iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
		return btd_error_invalid_args(msg);

	dbus_message_iter_get_basic(&iter, &string);

	if (!mp->searchable || folder != mp->folder || !cb->cbs->search)
		return btd_error_not_supported(msg);

	if (folder->msg != NULL)
		return btd_error_failed(msg, strerror(EINVAL));

	err = cb->cbs->search(mp, string, cb->user_data);
	if (err < 0)
		return btd_error_failed(msg, strerror(-err));

	folder->msg = dbus_message_ref(msg);

	return NULL;
}
コード例 #9
0
static void write_result_cb(bool success, bool reliable_error,
					uint8_t att_ecode, void *user_data)
{
	struct async_dbus_op *op = user_data;
	DBusMessage *reply;

	if (op->complete && !op->complete(op->data)) {
		reply = btd_error_failed(op->msg, "Operation failed");
		goto done;
	}

	if (!success) {
		if (reliable_error)
			reply = btd_error_failed(op->msg,
						"Reliable write failed");
		else
			reply = create_gatt_dbus_error(op->msg, att_ecode);

		goto done;
	}

	reply = g_dbus_create_reply(op->msg, DBUS_TYPE_INVALID);
	if (!reply) {
		error("Failed to allocate D-Bus message reply");
		return;
	}

done:
	g_dbus_send_message(btd_get_dbus_connection(), reply);
}
コード例 #10
0
static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err,
							gpointer user_data)
{
	struct serial_port *port = user_data;
	struct serial_device *device = port->device;
	struct rfcomm_dev_req req;
	int sk, fd;
	DBusMessage *reply;

	/* Owner exited? */
	if (!port->listener_id)
		return;

	if (conn_err) {
		error("%s", conn_err->message);
		reply = btd_error_failed(port->msg, conn_err->message);
		goto fail;
	}

	memset(&req, 0, sizeof(req));
	req.dev_id = -1;
	req.flags = (1 << RFCOMM_REUSE_DLC);
	bacpy(&req.src, &device->src);
	bacpy(&req.dst, &device->dst);
	req.channel = port->channel;

	g_io_channel_unref(port->io);
	port->io = NULL;

	sk = g_io_channel_unix_get_fd(chan);
	port->id = ioctl(sk, RFCOMMCREATEDEV, &req);
	if (port->id < 0) {
		int err = -errno;
		error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(-err), -err);
		reply = btd_error_failed(port->msg, strerror(-err));
		g_io_channel_shutdown(chan, TRUE, NULL);
		goto fail;
	}

	port->dev = g_strdup_printf("/dev/rfcomm%d", port->id);

	DBG("Serial port %s created", port->dev);

	g_io_channel_shutdown(chan, TRUE, NULL);

	/* Addressing connect port */
	fd = port_open(port);
	if (fd < 0)
		/* Open in progress: Wait the callback */
		return;

	open_notify(fd, 0, port);
	return;

fail:
	g_dbus_send_message(device->conn, reply);
	g_dbus_remove_watch(device->conn, port->listener_id);
	port->listener_id = 0;
}
コード例 #11
0
ファイル: advertising.c プロジェクト: AlanApter/steamlink-sdk
static DBusMessage *refresh_advertisement(struct advertisement *ad)
{
	struct mgmt_cp_add_advertising *cp;
	uint8_t param_len;
	uint8_t *adv_data;
	size_t adv_data_len;
	uint32_t flags = 0;

	DBG("Refreshing advertisement: %s", ad->path);

	if (ad->type == AD_TYPE_PERIPHERAL)
		flags = MGMT_ADV_FLAG_CONNECTABLE | MGMT_ADV_FLAG_DISCOV;

	if (ad->include_tx_power)
		flags |= MGMT_ADV_FLAG_TX_POWER;

	adv_data = bt_ad_generate(ad->data, &adv_data_len);

	if (!adv_data || (adv_data_len > calc_max_adv_len(ad, flags))) {
		error("Advertising data too long or couldn't be generated.");

		return g_dbus_create_error(ad->reg, ERROR_INTERFACE
						".InvalidLength",
						"Advertising data too long.");
	}

	param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len;

	cp = malloc0(param_len);

	if (!cp) {
		error("Couldn't allocate for MGMT!");

		free(adv_data);

		return btd_error_failed(ad->reg, "Failed");
	}

	cp->flags = flags;
	cp->instance = ad->instance;
	cp->adv_data_len = adv_data_len;
	memcpy(cp->data, adv_data, adv_data_len);

	free(adv_data);

	if (!mgmt_send(ad->manager->mgmt, MGMT_OP_ADD_ADVERTISING,
					ad->manager->mgmt_index, param_len, cp,
					add_advertising_callback, ad, NULL)) {
		error("Failed to add Advertising Data");

		free(cp);

		return btd_error_failed(ad->reg, "Failed");
	}

	free(cp);

	return NULL;
}
コード例 #12
0
ファイル: player.c プロジェクト: AwxiVYTHUIiMOol/bluez
static DBusMessage *media_folder_change_folder(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct media_player *mp = data;
	struct media_folder *folder = mp->scope;
	struct player_callback *cb = mp->cb;
	const char *path;
	int err;

	if (!dbus_message_get_args(msg, NULL,
					DBUS_TYPE_OBJECT_PATH, &path,
					DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	if (folder->msg != NULL)
		return btd_error_failed(msg, strerror(EBUSY));

	folder = media_player_find_folder(mp, path);
	if (folder == NULL)
		return btd_error_invalid_args(msg);

	if (mp->scope == folder)
		return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);

	if (folder == mp->playlist || folder == mp->folder ||
						folder == mp->search) {
		media_player_change_scope(mp, folder);
		return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
	}

	/*
	 * ChangePath can only navigate one level up/down so check if folder
	 * is direct child or parent of the current folder otherwise fail.
	 */
	if (!g_slist_find(mp->folder->subfolders, folder) &&
				!g_slist_find(folder->subfolders, mp->folder))
		return btd_error_invalid_args(msg);

	if (cb->cbs->change_folder == NULL)
		return btd_error_not_supported(msg);

	err = cb->cbs->change_folder(mp, folder->item->name, folder->item->uid,
								cb->user_data);
	if (err < 0)
		return btd_error_failed(msg, strerror(-err));

	mp->scope->msg = dbus_message_ref(msg);

	return NULL;
}
コード例 #13
0
ファイル: device.c プロジェクト: blammit/bluez
static void control_connect_cb(GIOChannel *chan, GError *conn_err,
							gpointer user_data)
{
	struct input_conn *iconn = user_data;
	struct input_device *idev = iconn->idev;
	DBusMessage *reply = NULL;
	GIOChannel *io;
	GError *err = NULL;

	DBG("");

	if (conn_err) {
		error("%s", conn_err->message);
		if (iconn->pending_connect)
			reply = btd_error_failed(iconn->pending_connect,
							conn_err->message);
		goto failed;
	}

	/* Connect to the HID interrupt channel */
	io = bt_io_connect(BT_IO_L2CAP, interrupt_connect_cb, iconn,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &idev->src,
				BT_IO_OPT_DEST_BDADDR, &idev->dst,
				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	if (!io) {
		error("%s", err->message);
		if (iconn->pending_connect)
			reply = btd_error_failed(iconn->pending_connect,
							err->message);
		g_error_free(err);
		goto failed;
	}

	iconn->intr_io = io;

	return;

failed:
	g_io_channel_unref(iconn->ctrl_io);
	iconn->ctrl_io = NULL;
	if (reply)
		g_dbus_send_message(idev->conn, reply);
	if (iconn->pending_connect) {
		dbus_message_unref(iconn->pending_connect);
		iconn->pending_connect = NULL;
	}
}
コード例 #14
0
ファイル: advertising.c プロジェクト: AlanApter/steamlink-sdk
static DBusMessage *register_advertisement(DBusConnection *conn,
						DBusMessage *msg,
						void *user_data)
{
	struct btd_advertising *manager = user_data;
	DBusMessageIter args;
	struct advertisement *ad;
	struct dbus_obj_match match;
	uint8_t instance;

	DBG("RegisterAdvertisement");

	if (!dbus_message_iter_init(msg, &args))
		return btd_error_invalid_args(msg);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
		return btd_error_invalid_args(msg);

	dbus_message_iter_get_basic(&args, &match.path);

	match.owner = dbus_message_get_sender(msg);

	if (queue_find(manager->ads, match_advertisement, &match))
		return btd_error_already_exists(msg);

	instance = util_get_uid(&manager->instance_bitmap, manager->max_ads);
	if (!instance)
		return btd_error_failed(msg, "Maximum advertisements reached");

	dbus_message_iter_next(&args);

	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
		return btd_error_invalid_args(msg);

	ad = advertisement_create(conn, msg, match.path);
	if (!ad)
		return btd_error_failed(msg,
					"Failed to register advertisement");

	DBG("Registered advertisement at path %s", match.path);

	ad->instance = instance;
	ad->manager = manager;

	queue_push_tail(manager->ads, ad);

	return NULL;
}
コード例 #15
0
ファイル: port.c プロジェクト: BloodLiker/bluez
static DBusMessage *port_connect(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct serial_device *device = user_data;
	struct serial_port *port;
	const char *pattern;
	int err;

	if (dbus_message_has_member(msg, "ConnectFD") && DBUS_TYPE_UNIX_FD < 0)
		return btd_error_not_supported(msg);

	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
						DBUS_TYPE_INVALID) == FALSE)
		return NULL;

	port = find_port(device->ports, pattern);
	if (!port) {
		char *endptr = NULL;
		int channel;

		channel = strtol(pattern, &endptr, 10);
		if ((endptr && *endptr != '\0') || channel < 1 || channel > 30)
			return btd_error_does_not_exist(msg);

		port = create_port(device, NULL, channel);
	}

	if (port->listener_id)
		return btd_error_failed(msg, "Port already in use");

	port->listener_id = g_dbus_add_disconnect_watch(conn,
						dbus_message_get_sender(msg),
						port_owner_exited, port,
						NULL);

	port->msg = dbus_message_ref(msg);

	err = connect_port(port);
	if (err < 0) {
		error("%s", strerror(-err));
		g_dbus_remove_watch(conn, port->listener_id);
		port->listener_id = 0;

		return btd_error_failed(msg, strerror(-err));
	}

	return NULL;
}
コード例 #16
0
static DBusMessage *create_gatt_dbus_error(DBusMessage *msg, uint8_t att_ecode)
{
	switch (att_ecode) {
	case BT_ATT_ERROR_READ_NOT_PERMITTED:
		return btd_error_not_permitted(msg, "Read not permitted");
	case BT_ATT_ERROR_WRITE_NOT_PERMITTED:
		return btd_error_not_permitted(msg, "Write not permitted");
	case BT_ATT_ERROR_AUTHENTICATION:
	case BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
	case BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
		return btd_error_not_permitted(msg, "Not paired");
	case BT_ATT_ERROR_INVALID_OFFSET:
		return btd_error_invalid_args_str(msg, "Invalid offset");
	case BT_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN:
		return btd_error_invalid_args_str(msg, "Invalid Length");
	case BT_ATT_ERROR_AUTHORIZATION:
		return btd_error_not_authorized(msg);
	case BT_ATT_ERROR_REQUEST_NOT_SUPPORTED:
		return btd_error_not_supported(msg);
	case 0:
		return btd_error_failed(msg, "Operation failed");
	default:
		return g_dbus_create_error(msg, ERROR_INTERFACE,
				"Operation failed with ATT error: 0x%02x",
				att_ecode);
	}

	return NULL;
}
コード例 #17
0
static DBusMessage *input_device_disconnect(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
//+++ BRCM
#ifdef BT_ALT_STACK
	struct input_device *idev = data;
	tDTUN_DEVICE_METHOD method;

	method.hh_bdaddr.hdr.id = DTUN_METHOD_HH_CLOSE;
	method.hh_bdaddr.hdr.len = sizeof(tDTUN_METHOD_HH_BDADDR) - sizeof(tDTUN_HDR);
	memcpy(&method.hh_bdaddr.bdaddr, &idev->dst, 6);

	dtun_client_call_method(&method);
	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
#else
	struct input_device *idev = data;
	int err;

	err = disconnect(idev, 0);
	if (err < 0)
		return btd_error_failed(msg, strerror(-err));

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
#endif
//--- BRCM
}
コード例 #18
0
static DBusMessage *add_remote_data(DBusConnection *conn, DBusMessage *msg,
								void *data)
{
	struct btd_adapter *adapter = data;
	uint8_t *hash, *randomizer;
	int32_t hlen, rlen;
	const char *addr;
	bdaddr_t bdaddr;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &addr,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hlen,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &rlen,
			DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	if (hlen != 16 || rlen != 16 || bachk(addr))
		return btd_error_invalid_args(msg);

	str2ba(addr, &bdaddr);

	if (btd_adapter_add_remote_oob_data(adapter, &bdaddr, hash, randomizer))
		return btd_error_failed(msg, "Request failed");

	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
コード例 #19
0
ファイル: server.c プロジェクト: luetzel/bluez
static DBusMessage *unregister_server(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct network_adapter *na = data;
	struct network_server *ns;
	DBusMessage *reply;
	const char *uuid;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &uuid,
							DBUS_TYPE_INVALID))
		return btd_error_invalid_args(msg);

	ns = find_server_by_uuid(na->servers, uuid);
	if (!ns)
		return btd_error_failed(msg, "Invalid UUID");

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return NULL;

	g_dbus_remove_watch(conn, ns->watch_id);

	server_disconnect(conn, ns);

	return reply;
}
コード例 #20
0
ファイル: service.c プロジェクト: 520lly/bluez
static DBusMessage *add_service_record(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct service_adapter *serv_adapter = data;
	DBusMessage *reply;
	const char *sender, *record;
	dbus_uint32_t handle;
	int err;

	if (dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &record, DBUS_TYPE_INVALID) == FALSE)
		return NULL;

	sender = dbus_message_get_sender(msg);
	err = add_xml_record(conn, sender, serv_adapter, record, &handle);
	if (err < 0)
		return btd_error_failed(msg, strerror(-err));

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return NULL;

	dbus_message_append_args(reply, DBUS_TYPE_UINT32, &handle,
							DBUS_TYPE_INVALID);

	return reply;
}
コード例 #21
0
ファイル: service.c プロジェクト: 520lly/bluez
static DBusMessage *update_xml_record(DBusConnection *conn,
				DBusMessage *msg,
				struct service_adapter *serv_adapter)
{
	struct record_data *user_record;
	sdp_record_t *sdp_record;
	const char *record;
	dbus_uint32_t handle;
	int len;

	if (dbus_message_get_args(msg, NULL,
				DBUS_TYPE_UINT32, &handle,
				DBUS_TYPE_STRING, &record,
				DBUS_TYPE_INVALID) == FALSE)
		return NULL;

	len = (record ? strlen(record) : 0);
	if (len == 0)
		return btd_error_invalid_args(msg);

	user_record = find_record(serv_adapter, handle,
				dbus_message_get_sender(msg));
	if (!user_record)
		return btd_error_not_available(msg);

	sdp_record = sdp_xml_parse_record(record, len);
	if (!sdp_record) {
		error("Parsing of XML service record failed");
		return btd_error_failed(msg,
					"Parsing of XML service record failed");
	}

	return update_record(conn, msg, serv_adapter, handle, sdp_record);
}
コード例 #22
0
ファイル: service.c プロジェクト: 520lly/bluez
static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg,
		struct service_adapter *serv_adapter,
		dbus_uint32_t handle, sdp_record_t *sdp_record)
{
	bdaddr_t src;
	int err;

	if (remove_record_from_server(handle) < 0) {
		sdp_record_free(sdp_record);
		return btd_error_not_available(msg);
	}

	if (serv_adapter->adapter)
		adapter_get_address(serv_adapter->adapter, &src);
	else
		bacpy(&src, BDADDR_ANY);

	sdp_record->handle = handle;
	err = add_record_to_server(&src, sdp_record);
	if (err < 0) {
		sdp_record_free(sdp_record);
		error("Failed to update the service record");
		return btd_error_failed(msg, strerror(-err));
	}

	return dbus_message_new_method_return(msg);
}
コード例 #23
0
ファイル: client.c プロジェクト: richardxu/panda-a4
static void attio_disconnected(gpointer user_data)
{
	struct gatt_service *gatt = user_data;

	if (gatt->query && gatt->query->msg) {
		DBusMessage *reply;

		reply = btd_error_failed(gatt->query->msg,
					"ATT IO channel was disconnected");
		g_dbus_send_message(gatt->conn, reply);
		dbus_message_unref(gatt->query->msg);
		gatt->query->msg = NULL;
	}

	if (gatt->query) {
		g_slist_free_full(gatt->query->list, g_free);
		gatt->query = NULL;
	}

	if (gatt->attrib) {
		g_attrib_cancel_all(gatt->attrib);
		g_attrib_unref(gatt->attrib);
		gatt->attrib = NULL;
	}
}
コード例 #24
0
static void read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
				uint8_t *randomizer)
{
	struct DBusMessage *reply;
	struct oob_request *oob_request;

	oob_request = find_oob_request(adapter);
	if (!oob_request)
		return;

	if (hash && randomizer)
		reply = g_dbus_create_reply(oob_request->msg,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, 16,
			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, 16,
			DBUS_TYPE_INVALID);
	else
		reply = btd_error_failed(oob_request->msg,
					"Failed to read local OOB data.");

	oob_requests = g_slist_remove(oob_requests, oob_request);
	dbus_message_unref(oob_request->msg);
	g_free(oob_request);

	if (!reply) {
		error("Couldn't allocate D-Bus message");
		return;
	}

	if (!g_dbus_send_message(connection, reply))
		error("D-Bus send failed");
}
コード例 #25
0
ファイル: device.c プロジェクト: blammit/bluez
/*
 * Input Device methods
 */
static DBusMessage *input_device_connect(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct input_device *idev = data;
	struct input_conn *iconn;
	DBusMessage *reply;
	GError *err = NULL;

	DBG("idev %p", idev);

	iconn = find_connection(idev->connections, HID_UUID);
	if (!iconn)
		return btd_error_not_supported(msg);

	if (iconn->pending_connect)
		return btd_error_in_progress(msg);

	if (is_connected(iconn))
		return btd_error_already_connected(msg);

	iconn->pending_connect = dbus_message_ref(msg);

	dev_connect(idev, iconn, &err);

	if (err == NULL)
		return NULL;

	error("%s", err->message);
	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;
	reply = btd_error_failed(msg, err->message);
	g_error_free(err);
	return reply;
}
コード例 #26
0
ファイル: connection.c プロジェクト: ExPeacer/6.1.A.0.452
static void cancel_connection(struct network_conn *nc, const char *err_msg)
{
	DBusMessage *reply;

	if (nc->timeout_source > 0) {
		g_source_remove(nc->timeout_source);
		nc->timeout_source = 0;
	}

	if (nc->watch) {
		g_dbus_remove_watch(connection, nc->watch);
		nc->watch = 0;
	}

	if (nc->msg && err_msg) {
		reply = btd_error_failed(nc->msg, err_msg);
		g_dbus_send_message(connection, reply);
	}

	g_io_channel_shutdown(nc->io, TRUE, NULL);
	g_io_channel_unref(nc->io);
	nc->io = NULL;

	nc->state = DISCONNECTED;
}
コード例 #27
0
static DBusMessage *disconnect_device(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	DBusMessage *reply;
	struct network_server *ns = data;
	struct network_session *session;
	const char *addr, *devname;
	bdaddr_t dst_addr;

	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
						DBUS_TYPE_STRING, &devname,
						DBUS_TYPE_INVALID))
		return NULL;

	str2ba(addr, &dst_addr);
	session = find_session_by_addr(ns->sessions, dst_addr);

	if (!session)
		return btd_error_failed(msg, "No active session");

	if (session->io) {
                bnep_if_down(devname);
                bnep_kill_connection(&dst_addr);
	} else
		return btd_error_not_connected(msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return NULL;
	return reply;
}
コード例 #28
0
static DBusMessage *sink_disconnect(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct audio_device *device = data;
	struct sink *sink = device->sink;
	struct pending_request *pending;
	int err;

	if (!sink->session)
		return btd_error_not_connected(msg);

	if (sink->connect || sink->disconnect)
		return btd_error_busy(msg);

	if (sink->stream_state < AVDTP_STATE_OPEN) {
		DBusMessage *reply = dbus_message_new_method_return(msg);
		if (!reply)
			return NULL;
		avdtp_unref(sink->session);
		sink->session = NULL;
		return reply;
	}

	err = avdtp_close(sink->session, sink->stream, FALSE);
	if (err < 0)
		return btd_error_failed(msg, strerror(-err));

	pending = g_new0(struct pending_request, 1);
	pending->conn = dbus_connection_ref(conn);
	pending->msg = dbus_message_ref(msg);
	sink->disconnect = pending;

	return NULL;
}
コード例 #29
0
static void controlpoint_write_cb(guint8 status, const guint8 *pdu, guint16 len,
							gpointer user_data)
{
	struct controlpoint_req *req = user_data;

	if (status == 0) {
		req->timeout = g_timeout_add_seconds(ATT_TIMEOUT,
							controlpoint_timeout,
							req);
		return;
	}

	error("SC Control Point write failed (opcode=%d)", req->opcode);

	if (req->opcode == UPDATE_SENSOR_LOC) {
		g_dbus_pending_property_error(req->reply_id,
					ERROR_INTERFACE ".Failed",
					"Operation failed (%d)", status);
	} else if  (req->opcode == SET_CUMULATIVE_VALUE) {
		DBusMessage *reply;

		reply = btd_error_failed(req->msg, "Operation failed");

		g_dbus_send_message(btd_get_dbus_connection(), reply);

		dbus_message_unref(req->msg);
	}

	req->csc->pending_req = NULL;
	g_free(req);
}
コード例 #30
0
ファイル: device.c プロジェクト: blammit/bluez
static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
{
	struct input_conn *iconn = user_data;
	struct input_device *idev = iconn->idev;
	struct fake_input *fake = iconn->fake;
	DBusMessage *reply;

	if (err) {
		reply = btd_error_failed(iconn->pending_connect, err->message);
		goto failed;
	}

	fake->rfcomm = g_io_channel_unix_get_fd(chan);

	/*
	 * FIXME: Some headsets required a sco connection
	 * first to report volume gain key events
	 */
	fake->uinput = uinput_create(idev->name);
	if (fake->uinput < 0) {
		int err = fake->uinput;

		g_io_channel_shutdown(chan, TRUE, NULL);
		reply = btd_error_failed(iconn->pending_connect,
							strerror(-err));
		goto failed;
	}

	fake->io = g_io_channel_unix_new(fake->rfcomm);
	g_io_channel_set_close_on_unref(fake->io, TRUE);
	g_io_add_watch(fake->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
						(GIOFunc) rfcomm_io_cb, fake);

	/* Replying to the requestor */
	reply = dbus_message_new_method_return(iconn->pending_connect);
	g_dbus_send_message(idev->conn, reply);

	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;

	return;

failed:
	g_dbus_send_message(idev->conn, reply);
	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;
}