예제 #1
0
파일: btiotest.c 프로젝트: ghent360/bluez
static void rfcomm_connect(const char *src, const char *dst, uint8_t ch,
						int disconn, int sec)
{
	struct io_data *data;
	GError *err = NULL;

	printf("Connecting to %s RFCOMM channel %u\n", dst, ch);

	data = io_data_new(NULL, -1, disconn, -1);

	if (src)
		data->io = bt_io_connect(connect_cb, data,
						(GDestroyNotify) io_data_unref,
						&err,
						BT_IO_OPT_SOURCE, src,
						BT_IO_OPT_DEST, dst,
						BT_IO_OPT_CHANNEL, ch,
						BT_IO_OPT_SEC_LEVEL, sec,
						BT_IO_OPT_INVALID);
	else
		data->io = bt_io_connect(connect_cb, data,
						(GDestroyNotify) io_data_unref,
						&err,
						BT_IO_OPT_DEST, dst,
						BT_IO_OPT_CHANNEL, ch,
						BT_IO_OPT_SEC_LEVEL, sec,
						BT_IO_OPT_INVALID);

	if (!data->io) {
		printf("Connecting to %s failed: %s\n", dst, err->message);
		g_error_free(err);
		exit(EXIT_FAILURE);
	}
}
예제 #2
0
static GIOChannel *l2cap_connect(GObexTransportType transport, GError **err)
{
	if (option_source)
		return bt_io_connect(conn_callback,
					GUINT_TO_POINTER(transport),
					NULL, err,
					BT_IO_OPT_SOURCE, option_source,
					BT_IO_OPT_DEST, option_dest,
					BT_IO_OPT_PSM, option_channel,
					BT_IO_OPT_MODE, BT_IO_MODE_ERTM,
					BT_IO_OPT_OMTU, option_omtu,
					BT_IO_OPT_IMTU, option_imtu,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);

	return bt_io_connect(conn_callback,
					GUINT_TO_POINTER(transport),
					NULL, err,
					BT_IO_OPT_DEST, option_dest,
					BT_IO_OPT_PSM, option_channel,
					BT_IO_OPT_MODE, BT_IO_MODE_ERTM,
					BT_IO_OPT_OMTU, option_omtu,
					BT_IO_OPT_IMTU, option_imtu,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);
}
예제 #3
0
파일: btiotest.c 프로젝트: ghent360/bluez
static void sco_connect(const char *src, const char *dst, int disconn,
								int voice)
{
	struct io_data *data;
	GError *err = NULL;

	printf("Connecting SCO to %s\n", dst);

	data = io_data_new(NULL, -1, disconn, -1);

	if (src)
		data->io = bt_io_connect(connect_cb, data,
						(GDestroyNotify) io_data_unref,
						&err,
						BT_IO_OPT_SOURCE, src,
						BT_IO_OPT_DEST, dst,
						BT_IO_OPT_VOICE, voice,
						BT_IO_OPT_INVALID);
	else
		data->io = bt_io_connect(connect_cb, data,
						(GDestroyNotify) io_data_unref,
						&err,
						BT_IO_OPT_DEST, dst,
						BT_IO_OPT_VOICE, voice,
						BT_IO_OPT_INVALID);

	if (!data->io) {
		printf("Connecting to %s failed: %s\n", dst, err->message);
		g_error_free(err);
		exit(EXIT_FAILURE);
	}
}
예제 #4
0
파일: utils.c 프로젝트: HeatfanJohn/libgatt
GIOChannel *gatt_connect(const char *src, const char *dst,
				const char *dst_type, const char *sec_level,
				int psm, int mtu, BtIOConnect connect_cb,
				GError **gerr)
{
	GIOChannel *chan;
	bdaddr_t sba, dba;
	uint8_t dest_type;
	GError *tmp_err = NULL;
	BtIOSecLevel sec;

	str2ba(dst, &dba);

	/* Local adapter */
	if (src != NULL) {
		if (!strncmp(src, "hci", 3))
			hci_devba(atoi(src + 3), &sba);
		else
			str2ba(src, &sba);
	} else
		bacpy(&sba, BDADDR_ANY);

	/* Not used for BR/EDR */
	if (strcmp(dst_type, "random") == 0)
		dest_type = BDADDR_LE_RANDOM;
	else
		dest_type = BDADDR_LE_PUBLIC;

	if (strcmp(sec_level, "medium") == 0)
		sec = BT_IO_SEC_MEDIUM;
	else if (strcmp(sec_level, "high") == 0)
		sec = BT_IO_SEC_HIGH;
	else
		sec = BT_IO_SEC_LOW;

	if (psm == 0)
		chan = bt_io_connect(connect_cb, NULL, NULL, &tmp_err,
				BT_IO_OPT_SOURCE_BDADDR, &sba,
				BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
				BT_IO_OPT_DEST_BDADDR, &dba,
				BT_IO_OPT_DEST_TYPE, dest_type,
				BT_IO_OPT_CID, ATT_CID,
				BT_IO_OPT_SEC_LEVEL, sec,
				BT_IO_OPT_INVALID);
	else
		chan = bt_io_connect(connect_cb, NULL, NULL, &tmp_err,
				BT_IO_OPT_SOURCE_BDADDR, &sba,
				BT_IO_OPT_DEST_BDADDR, &dba,
				BT_IO_OPT_PSM, psm,
				BT_IO_OPT_IMTU, mtu,
				BT_IO_OPT_SEC_LEVEL, sec,
				BT_IO_OPT_INVALID);

	if (tmp_err) {
		g_propagate_error(gerr, tmp_err);
		return NULL;
	}

	return chan;
}
예제 #5
0
파일: btiotest.c 프로젝트: ghent360/bluez
static void l2cap_connect(const char *src, const char *dst, uint8_t addr_type,
				uint16_t psm, uint16_t cid, int disconn,
				int sec, int prio)
{
	struct io_data *data;
	GError *err = NULL;
	uint8_t src_type;

	printf("Connecting to %s L2CAP PSM %u\n", dst, psm);

	data = io_data_new(NULL, -1, disconn, -1);

	if (addr_type != BDADDR_BREDR)
		src_type = BDADDR_LE_PUBLIC;
	else
		src_type = BDADDR_BREDR;

	if (src)
		data->io = bt_io_connect(connect_cb, data,
					(GDestroyNotify) io_data_unref,
					&err,
					BT_IO_OPT_SOURCE, src,
					BT_IO_OPT_SOURCE_TYPE, src_type,
					BT_IO_OPT_DEST, dst,
					BT_IO_OPT_DEST_TYPE, addr_type,
					BT_IO_OPT_PSM, psm,
					BT_IO_OPT_CID, cid,
					BT_IO_OPT_SEC_LEVEL, sec,
					BT_IO_OPT_PRIORITY, prio,
					BT_IO_OPT_INVALID);
	else
		data->io = bt_io_connect(connect_cb, data,
					(GDestroyNotify) io_data_unref,
					&err,
					BT_IO_OPT_SOURCE_TYPE, src_type,
					BT_IO_OPT_DEST, dst,
					BT_IO_OPT_DEST_TYPE, addr_type,
					BT_IO_OPT_PSM, psm,
					BT_IO_OPT_CID, cid,
					BT_IO_OPT_SEC_LEVEL, sec,
					BT_IO_OPT_PRIORITY, prio,
					BT_IO_OPT_INVALID);

	if (!data->io) {
		printf("Connecting to %s failed: %s\n", dst, err->message);
		g_error_free(err);
		exit(EXIT_FAILURE);
	}
}
예제 #6
0
파일: device.c 프로젝트: blammit/bluez
static void dev_connect(struct input_device *idev,
			struct input_conn *iconn,
			GError **err)
{
	struct fake_input *fake;

	DBG("");

	fake = iconn->fake;

	if (fake) {
		/* Fake input device */
		if (fake->connect(iconn, err))
			fake->flags |= FI_FLAG_CONNECTED;
	} else {
		/* HID devices */
		GIOChannel *io;

		if (idev->disable_sdp)
			bt_clear_cached_session(&idev->src, &idev->dst);

		io = bt_io_connect(BT_IO_L2CAP, control_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_CTRL,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);
		iconn->ctrl_io = io;
	}

}
예제 #7
0
/* Connect and initiate BNEP session */
int connection_connect(struct btd_service *service)
{
	struct network_conn *nc = btd_service_get_user_data(service);
	struct network_peer *peer = nc->peer;
	uint16_t id = get_service_id(service);
	GError *err = NULL;
	const bdaddr_t *src;
	const bdaddr_t *dst;

	DBG("id %u", id);

	if (nc->state != DISCONNECTED)
		return -EALREADY;

	src = btd_adapter_get_address(device_get_adapter(peer->device));
	dst = device_get_address(peer->device);

	nc->io = bt_io_connect(connect_cb, nc,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR, dst,
				BT_IO_OPT_PSM, BNEP_PSM,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_OMTU, BNEP_MTU,
				BT_IO_OPT_IMTU, BNEP_MTU,
				BT_IO_OPT_INVALID);
	if (!nc->io)
		return -EIO;

	nc->state = CONNECTING;

	return 0;
}
예제 #8
0
파일: device.c 프로젝트: padelt/bluez
static int dev_connect(struct input_device *idev)
{
    GError *err = NULL;
    GIOChannel *io;

    if (idev->disable_sdp)
        bt_clear_cached_session(&idev->src, &idev->dst);

    io = bt_io_connect(control_connect_cb, idev,
                       NULL, &err,
                       BT_IO_OPT_SOURCE_BDADDR, &idev->src,
                       BT_IO_OPT_DEST_BDADDR, &idev->dst,
                       BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
                       BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
                       BT_IO_OPT_INVALID);
    idev->ctrl_io = io;

    if (err == NULL)
        return 0;

    error("%s", err->message);
    g_error_free(err);

    return -EIO;
}
예제 #9
0
파일: gateway.c 프로젝트: intgr/bluez
/* These are functions to be called from unix.c for audio system
 * ifaces (alsa, gstreamer, etc.) */
unsigned int gateway_request_stream(struct audio_device *dev,
				gateway_stream_cb_t cb, void *user_data)
{
	struct gateway *gw = dev->gateway;
	GError *err = NULL;
	GIOChannel *io;

	if (!gw->rfcomm) {
		if (get_records(dev) < 0)
			return 0;
	} else if (!gw->sco) {
		io = bt_io_connect(sco_connect_cb, dev, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &dev->src,
				BT_IO_OPT_DEST_BDADDR, &dev->dst,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_INVALID);
		if (!io) {
			error("%s", err->message);
			g_error_free(err);
			return 0;
		}
	} else
		g_idle_add(request_stream_cb, dev);

	return connect_cb_new(gw, cb, user_data);
}
예제 #10
0
파일: avctp.c 프로젝트: richardxu/panda-a4
struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
{
	struct avctp *session;
	GError *err = NULL;
	GIOChannel *io;

	session = avctp_get_internal(src, dst);
	if (!session)
		return NULL;

	if (session->state > AVCTP_STATE_DISCONNECTED)
		return session;

	avctp_set_state(session, AVCTP_STATE_CONNECTING);

	io = bt_io_connect(BT_IO_L2CAP, avctp_connect_cb, session, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &session->server->src,
				BT_IO_OPT_DEST_BDADDR, &session->dst,
				BT_IO_OPT_PSM, AVCTP_PSM,
				BT_IO_OPT_INVALID);
	if (err) {
		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
		error("%s", err->message);
		g_error_free(err);
		return NULL;
	}

	session->io = io;

	return session;
}
예제 #11
0
파일: port.c 프로젝트: Mcjesus15/Zio_Other
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 = failed(port->msg, strerror(-err));
		goto failed;
	}

	if (!recs || !recs->data) {
		error("No record found");
		reply = 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 = 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 = 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);
}
예제 #12
0
파일: port.c 프로젝트: Mcjesus15/Zio_Other
static int connect_port(struct serial_port *port)
{
	struct serial_device *device = port->device;
	uuid_t uuid;
	int err;

	if (!port->uuid)
		goto connect;

	err = bt_string2uuid(&uuid, port->uuid);
	if (err < 0)
		return err;

	sdp_uuid128_to_uuid(&uuid);

	return bt_search_service(&device->src, &device->dst, &uuid,
				get_record_cb, port, NULL);

connect:
	port->io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, port,
				NULL, NULL,
				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)
		return 0;

	return -errno;
}
예제 #13
0
struct avctp *avctp_connect(struct audio_device *device)
{
	struct avctp *session;
	GError *err = NULL;
	GIOChannel *io;

	session = avctp_get_internal(device->btd_dev);
	if (!session)
		return NULL;

	if (session->state > AVCTP_STATE_DISCONNECTED)
		return session;

	avctp_set_state(session, AVCTP_STATE_CONNECTING);

	io = bt_io_connect(avctp_connect_cb, session, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR,
				adapter_get_address(session->server->adapter),
				BT_IO_OPT_DEST_BDADDR,
				device_get_address(session->device),
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
				BT_IO_OPT_INVALID);
	if (err) {
		avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
		error("%s", err->message);
		g_error_free(err);
		return NULL;
	}

	session->control = avctp_channel_create(session, io, NULL);
	g_io_channel_unref(io);

	return session;
}
예제 #14
0
파일: avctp.c 프로젝트: MDomagala/bluez
int avctp_connect_browsing(struct avctp *session)
{
	GError *err = NULL;
	GIOChannel *io;

	if (session->state != AVCTP_STATE_CONNECTED)
		return -ENOTCONN;

	if (session->browsing != NULL)
		return 0;

	avctp_set_state(session, AVCTP_STATE_BROWSING_CONNECTING);

	io = bt_io_connect(avctp_connect_browsing_cb, session, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR,
				adapter_get_address(session->server->adapter),
				BT_IO_OPT_DEST_BDADDR,
				device_get_address(session->device),
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_PSM, AVCTP_BROWSING_PSM,
				BT_IO_OPT_MODE, L2CAP_MODE_ERTM,
				BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		return -EIO;
	}

	session->browsing = avctp_channel_create(session, io,
						avctp_destroy_browsing);
	g_io_channel_unref(io);

	return 0;
}
예제 #15
0
gboolean avrcp_connect(struct audio_device *dev)
{
	struct control *control = dev->control;
	GError *err = NULL;
	GIOChannel *io;

	if (control->state > AVCTP_STATE_DISCONNECTED)
		return TRUE;

	avctp_set_state(control, AVCTP_STATE_CONNECTING);

	io = bt_io_connect(BT_IO_L2CAP, avctp_connect_cb, control, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &dev->src,
				BT_IO_OPT_DEST_BDADDR, &dev->dst,
				BT_IO_OPT_PSM, AVCTP_PSM,
				BT_IO_OPT_INVALID);
	if (err) {
		avctp_set_state(control, AVCTP_STATE_DISCONNECTED);
		error("%s", err->message);
		g_error_free(err);
		return FALSE;
	}

	control->io = io;

	return TRUE;
}
예제 #16
0
/* These are functions to be called from unix.c for audio system
 * ifaces (alsa, gstreamer, etc.) */
gboolean gateway_request_stream(struct audio_device *dev,
				gateway_stream_cb_t cb, void *user_data)
{
	struct gateway *gw = dev->gateway;
	GError *err = NULL;
	GIOChannel *io;

	if (!gw->rfcomm) {
		gw->sco_start_cb = cb;
		gw->sco_start_cb_data = user_data;
		get_records(dev);
	} else if (!gw->sco) {
		gw->sco_start_cb = cb;
		gw->sco_start_cb_data = user_data;
		io = bt_io_connect(BT_IO_SCO, sco_connect_cb, dev, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &dev->src,
				BT_IO_OPT_DEST_BDADDR, &dev->dst,
				BT_IO_OPT_INVALID);
		if (!io) {
			error("%s", err->message);
			g_error_free(err);
			return FALSE;
		}
	} else if (cb)
		cb(dev, err, user_data);

	return TRUE;
}
예제 #17
0
static GIOChannel *do_connect(GError **err)
{
	if (fragment)
		return bt_io_connect(connect_cb, NULL, NULL, err,
					BT_IO_OPT_SOURCE_BDADDR, &src,
					BT_IO_OPT_DEST_BDADDR, &dst,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_PSM, AVDTP_PSM,
					BT_IO_OPT_MTU, 48,
					BT_IO_OPT_INVALID);

	return bt_io_connect(connect_cb, NULL, NULL, err,
				BT_IO_OPT_SOURCE_BDADDR, &src,
				BT_IO_OPT_DEST_BDADDR, &dst,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_PSM, AVDTP_PSM,
				BT_IO_OPT_INVALID);
}
예제 #18
0
//          0    1        2      3        4   5
// gatt_write hci0 destaddr handle filename mtu
int main(int argc, char *argv[])
{
	if (argc != 5 && argc != 6) {
		std::cout << "Usage: " << argv[0] << " adapter destaddr handle filename [mtu]" << std::endl;
		std::cout << "e.g.): " << argv[0] << " hci0 01:23:45:67:89:AB 0x000b test.txt 100" << std::endl;
		exit(EXIT_FAILURE);
	}

	GError *gerr = NULL;

	char const* src = argv[1];
	bdaddr_t sba;
	if (!strncmp(src, "hci", 3))
		hci_devba(atoi(src + 3), &sba);
	else
		str2ba(src, &sba);

	char const* dst = argv[2];
	bdaddr_t dba;
	str2ba(dst, &dba);

	int handle = std::strtol(argv[3], nullptr, 0);
	char const* fn = argv[4];
	std::ifstream ifs(fn, std::ifstream::in | std::ifstream::binary);
	std::vector<std::uint8_t> content = std::vector<std::uint8_t>(
		std::istreambuf_iterator<char>(ifs),
		std::istreambuf_iterator<char>());

	uint8_t dest_type = BDADDR_LE_PUBLIC; // OR BDADDR_RANDOM
	BtIOSecLevel sec = BT_IO_SEC_LOW;  // OR BT_IO_SEC_HIGH, BT_IO_SEC_LOW

	user_data_t ud { handle , content, ATT_DEFAULT_LE_MTU };
	if (argc == 6) {
		ud.mtu = std::strtol(argv[5], nullptr, 0);
	}
	GIOChannel* chan = bt_io_connect(
		connect_cb, &ud, NULL, &gerr,
		BT_IO_OPT_SOURCE_BDADDR, &sba,
		BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
		BT_IO_OPT_DEST_BDADDR, &dba,
		BT_IO_OPT_DEST_TYPE, dest_type,
		BT_IO_OPT_CID, ATT_CID,
		BT_IO_OPT_SEC_LEVEL, sec,
		BT_IO_OPT_INVALID);

	if (chan == NULL) {
		std::cout <<  gerr->message << std::endl;
		exit(EXIT_FAILURE);
	}

	event_loop = g_main_loop_new(NULL, FALSE);
	g_main_loop_run(event_loop);
	g_main_loop_unref(event_loop);
	exit(EXIT_SUCCESS);
}
예제 #19
0
static GIOChannel *rfcomm_connect(GObexTransportType transport, GError **err)
{
	if (option_source)
		return bt_io_connect(conn_callback,
					GUINT_TO_POINTER(transport),
					NULL, err,
					BT_IO_OPT_SOURCE, option_source,
					BT_IO_OPT_DEST, option_dest,
					BT_IO_OPT_CHANNEL, option_channel,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);

	return bt_io_connect(conn_callback,
					GUINT_TO_POINTER(transport),
					NULL, err,
					BT_IO_OPT_DEST, option_dest,
					BT_IO_OPT_CHANNEL, option_channel,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);
}
예제 #20
0
//          0    1        2      3     4   5
// gatt_write hci0 destaddr handle value mtu
int main(int argc, char *argv[])
{
	if (argc != 5 && argc != 6) {
		std::cout << "Usage: " << argv[0] << " adapter destaddr handle value [mtu]" << std::endl;
		std::cout << "e.g.): " << argv[0] << " hci0 01:23:45:67:89:AB 0x000c 0x0300 100" << std::endl;
		std::cout << "value: " << argv[0] << " 0x0100: start notify, 0x0200 start indicate, 0x0300 both" << std::endl;
		exit(EXIT_FAILURE);
	}

	GError *gerr = NULL;

	char const* src = argv[1];
	bdaddr_t sba;
	if (!strncmp(src, "hci", 3))
		hci_devba(atoi(src + 3), &sba);
	else
		str2ba(src, &sba);

	char const* dst = argv[2];
	bdaddr_t dba;
	str2ba(dst, &dba);

	int handle = std::strtol(argv[3], nullptr, 0);
	uint16_t value = std::strtol(argv[4], nullptr, 0);

	uint8_t dest_type = BDADDR_LE_PUBLIC; // OR BDADDR_RANDOM
	BtIOSecLevel sec = BT_IO_SEC_LOW;  // OR BT_IO_SEC_HIGH, BT_IO_SEC_LOW

	user_data_t ud { handle, value, ATT_DEFAULT_LE_MTU };
	if (argc == 6) {
		ud.mtu = std::strtol(argv[5], nullptr, 0);
	}
	ud.chan = bt_io_connect(
		connect_cb, &ud, NULL, &gerr,
		BT_IO_OPT_SOURCE_BDADDR, &sba,
		BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
		BT_IO_OPT_DEST_BDADDR, &dba,
		BT_IO_OPT_DEST_TYPE, dest_type,
		BT_IO_OPT_CID, ATT_CID,
		BT_IO_OPT_SEC_LEVEL, sec,
		BT_IO_OPT_INVALID);

	if (ud.chan == NULL) {
		std::cout <<  gerr->message << std::endl;
		exit(EXIT_FAILURE);
	}

	event_loop = g_main_loop_new(NULL, FALSE);
	g_main_loop_run(event_loop);
	g_main_loop_unref(event_loop);
	exit(EXIT_SUCCESS);
}
예제 #21
0
static DBusMessage *input_device_connect(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct input_device *idev = data;
	struct input_conn *iconn;
	struct fake_input *fake;
	DBusMessage *reply;
	GError *err = NULL;

	iconn = find_connection(idev->connections, "HID");
	if (!iconn)
		return not_supported(msg);

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

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

	iconn->pending_connect = dbus_message_ref(msg);
	fake = iconn->fake;

	if (fake) {
		/* Fake input device */
		if (fake->connect(iconn, &err))
			fake->flags |= FI_FLAG_CONNECTED;
	} else {
		/* HID devices */
		GIOChannel *io;

		io = bt_io_connect(BT_IO_L2CAP, control_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_CTRL,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);
		iconn->ctrl_io = io;
	}

	if (err == NULL)
		return NULL;

	error("%s", err->message);
	dbus_message_unref(iconn->pending_connect);
	iconn->pending_connect = NULL;
	reply = connection_attempt_failed(msg, err->message);
	g_error_free(err);
	return reply;
}
예제 #22
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;
	}
}
예제 #23
0
static GIOChannel *transport_connect(const bdaddr_t *src, const bdaddr_t *dst,
					uint16_t port, BtIOConnect function,
					gpointer user_data)
{
	GIOChannel *io;
	GError *err = NULL;

	DBG("port %u", port);

	if (port > 31) {
		io = bt_io_connect(BT_IO_L2CAP, function, user_data,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR, dst,
				BT_IO_OPT_PSM, port,
				BT_IO_OPT_MODE, BT_IO_MODE_ERTM,
				BT_IO_OPT_OMTU, BT_TX_MTU,
				BT_IO_OPT_IMTU, BT_RX_MTU,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	} else {
		io = bt_io_connect(BT_IO_RFCOMM, function, user_data,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR, dst,
				BT_IO_OPT_CHANNEL, port,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	}

	if (io != NULL)
		return io;

	error("%s", err->message);
	g_error_free(err);
	return NULL;
}
예제 #24
0
/* Connect and initiate BNEP session */
static DBusMessage *connection_connect(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct network_peer *peer = data;
	struct network_conn *nc;
	const char *svc;
	uint16_t id;
	GError *err = NULL;

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

	id = bnep_service_id(svc);
	nc = find_connection(peer->connections, id);
	if (!nc)
		return btd_error_not_supported(msg);

	if (nc->state != DISCONNECTED)
		return btd_error_already_connected(msg);

	nc->io = bt_io_connect(BT_IO_L2CAP, connect_cb, nc,
				NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, &peer->src,
				BT_IO_OPT_DEST_BDADDR, &peer->dst,
				BT_IO_OPT_PSM, BNEP_PSM,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
				BT_IO_OPT_OMTU, BNEP_MTU,
				BT_IO_OPT_IMTU, BNEP_MTU,
				BT_IO_OPT_INVALID);
	if (!nc->io) {
		DBusMessage *reply;
		error("%s", err->message);
		reply = btd_error_failed(msg, err->message);
		g_error_free(err);
		return reply;
	}

	nc->state = CONNECTING;
	nc->msg = dbus_message_ref(msg);
	nc->watch = g_dbus_add_disconnect_watch(conn,
						dbus_message_get_sender(msg),
						connection_destroy,
						nc, NULL);

	return NULL;
}
예제 #25
0
static gboolean rfcomm_connect(struct input_conn *iconn, GError **err)
{
	struct input_device *idev = iconn->idev;
	GIOChannel *io;

	io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, iconn,
				NULL, err,
				BT_IO_OPT_SOURCE_BDADDR, &idev->src,
				BT_IO_OPT_DEST_BDADDR, &idev->dst,
				BT_IO_OPT_INVALID);
	if (!io)
		return FALSE;

	g_io_channel_unref(io);

	return TRUE;
}
예제 #26
0
파일: avrcp.c 프로젝트: mjbshaw/bluez
static bool avrcp_device_connect(struct avrcp_device *dev, BtIOConnect cb)
{
	GError *err = NULL;

	dev->io = bt_io_connect(cb, dev, NULL, &err,
					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
					BT_IO_OPT_DEST_BDADDR, &dev->dst,
					BT_IO_OPT_PSM, L2CAP_PSM_AVCTP,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
					BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		return false;
	}

	return true;
}
예제 #27
0
static int cmd_connect(const char *dst, gpointer user_data)
{
  bdaddr_t sba, dba;
  uint8_t dest_type;
  BtIOSecLevel sec;

  if (get_state() != STATE_DISCONNECTED) {
    return -1;
  }

  set_state(STATE_CONNECTING);

  str2ba(dst, &dba);
  bacpy(&sba, BDADDR_ANY);            /* {0, 0, 0, 0, 0, 0} */
  dest_type = BDADDR_LE_PUBLIC;       /* 0x01 */
  sec = BT_IO_SEC_LOW;                /* Connection happens at low security. Change later */

  GError *gerr = NULL;

  /* iochannel is declared global for now
   * source: src/device.c in bluez tree for more details
   */
  iochannel = bt_io_connect(connect_cb, user_data, NULL, &gerr,
              BT_IO_OPT_SOURCE_BDADDR, &sba,
              BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
              BT_IO_OPT_DEST_BDADDR, &dba,
              BT_IO_OPT_DEST_TYPE, dest_type,
              BT_IO_OPT_CID, ATT_CID,
              BT_IO_OPT_SEC_LEVEL, sec,
              BT_IO_OPT_INVALID);

  if (gerr) {
    set_state(STATE_DISCONNECTED);
    set_error(ERR_CONNECT_FAILED, gerr->message, user_data);
    printf("Error: %d  %s\n", gerr->code, gerr->message);
    g_error_free(gerr);
    return -2;
  } else {
    g_io_add_watch(iochannel, G_IO_HUP, channel_hangup_watcher, user_data);
    g_main_loop_run(event_loop);
  }

  return 0;
}
예제 #28
0
파일: device.c 프로젝트: BirdAndEarth/RPi
static void control_connect_cb(GIOChannel *chan, GError *conn_err,
							gpointer user_data)
{
	struct input_device *idev = user_data;
	GIOCondition cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
	GIOChannel *io;
	GError *err = NULL;

	if (conn_err) {
		error("%s", conn_err->message);
		goto failed;
	}

	/* Connect to the HID interrupt channel */
	io = bt_io_connect(interrupt_connect_cb, idev,
				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);
		g_error_free(err);
		goto failed;
	}

	idev->intr_io = io;

	if (idev->uhid)
		cond |= G_IO_IN;

	idev->ctrl_watch = g_io_add_watch(idev->ctrl_io, cond, ctrl_watch_cb,
									idev);

	return;

failed:
	btd_service_connecting_complete(idev->service, -EIO);
	g_io_channel_unref(idev->ctrl_io);
	idev->ctrl_io = NULL;
}
예제 #29
0
파일: session.c 프로젝트: Commers/obexd
static GIOChannel *rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst,
					uint8_t channel, BtIOConnect function,
					gpointer user_data)
{
	GIOChannel *io;
	GError *err = NULL;

	io = bt_io_connect(BT_IO_RFCOMM, function, user_data, NULL, &err,
				BT_IO_OPT_SOURCE_BDADDR, src,
				BT_IO_OPT_DEST_BDADDR, dst,
				BT_IO_OPT_CHANNEL, channel,
				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
				BT_IO_OPT_INVALID);
	if (io != NULL)
		return io;

	error("%s", err->message);
	g_error_free(err);
	return NULL;
}
예제 #30
0
파일: hidhost.c 프로젝트: aguedes/bluez
static void control_connect_cb(GIOChannel *chan, GError *conn_err,
							gpointer user_data)
{
	struct hid_device *dev = user_data;
	GError *err = NULL;

	DBG("");

	if (conn_err) {
		bt_hid_notify_state(dev, HAL_HIDHOST_STATE_DISCONNECTED);
		error("hidhost: Failed to connect control channel (%s)",
							conn_err->message);
		goto failed;
	}

	/* Connect to the HID interrupt channel */
	dev->intr_io = bt_io_connect(interrupt_connect_cb, dev, NULL, &err,
					BT_IO_OPT_SOURCE_BDADDR, &adapter_addr,
					BT_IO_OPT_DEST_BDADDR, &dev->dst,
					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
					BT_IO_OPT_INVALID);
	if (!dev->intr_io) {
		error("hidhost: Failed to connect interrupt channel (%s)",
								err->message);
		g_error_free(err);
		goto failed;
	}

	dev->ctrl_watch = g_io_add_watch(dev->ctrl_io,
				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
				ctrl_watch_cb, dev);

	return;

failed:
	hid_device_remove(dev);
}