Ejemplo n.º 1
0
static DBusMessage *profile_new_connection(DBusConnection *conn,
					DBusMessage *msg, void *user_data)
{
	struct hfp *hfp;
	struct ofono_modem *modem;
	struct sockaddr_rc saddr;
	socklen_t optlen;
	DBusMessageIter entry;
	const char *device, *driver;
	char local[18], remote[18];
	uint16_t version = HFP_VERSION_1_5;
	int fd, err;

	DBG("Profile handler NewConnection");

	if (dbus_message_iter_init(msg, &entry) == FALSE)
		goto invalid;

	if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_OBJECT_PATH)
		goto invalid;

	dbus_message_iter_get_basic(&entry, &device);

	dbus_message_iter_next(&entry);
	if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_UNIX_FD)
		goto invalid;

	dbus_message_iter_get_basic(&entry, &fd);
	if (fd < 0)
		goto invalid;

	dbus_message_iter_next(&entry);
	if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_ARRAY)
		goto invalid;

	if (get_version(&entry, &version) < 0)
		goto invalid;

	DBG("version: %hd", version);

	modem = ofono_modem_find(device_path_compare, (void *) device);
	if (modem == NULL) {
		close(fd);
		return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
					".Rejected",
					"Unknown Bluetooth device");
	}

	err = service_level_connection(modem, fd, version);
	if (err < 0 && err != -EINPROGRESS) {
		close(fd);
		return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
					".Rejected",
					"Not enough resources");
	}

	memset(&saddr, 0, sizeof(saddr));
	optlen = sizeof(saddr);

	if (getsockname(fd, (struct sockaddr *) &saddr, &optlen) < 0) {
		err = errno;
		ofono_error("RFCOMM getsockname(): %s (%d)", strerror(err),
									err);
		close(fd);
		goto invalid;
	}

	bt_ba2str(&saddr.rc_bdaddr, local);

	memset(&saddr, 0, sizeof(saddr));
	optlen = sizeof(saddr);

	if (getpeername(fd, (struct sockaddr *) &saddr, &optlen) < 0) {
		err = errno;
		ofono_error("RFCOMM getpeername(): %s (%d)", strerror(err),
									err);
		close(fd);
		goto invalid;
	}

	bt_ba2str(&saddr.rc_bdaddr, remote);

	hfp = ofono_modem_get_data(modem);
	hfp->msg = dbus_message_ref(msg);

	driver = NULL;

	if (version >= HFP_VERSION_1_6)
		driver = HFP16_HF_DRIVER;

	hfp->card = ofono_handsfree_card_create(0, driver, hfp);
	ofono_handsfree_card_set_data(hfp->card, hfp);

	ofono_handsfree_card_set_local(hfp->card, local);
	ofono_handsfree_card_set_remote(hfp->card, remote);

	return NULL;

invalid:
	return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE ".Rejected",
					"Invalid arguments in method call");
}
Ejemplo n.º 2
0
static gboolean sco_accept(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	struct ofono_handsfree_card *card;
	struct sockaddr_sco saddr;
	socklen_t alen;
	int sk, nsk;
	char local[18], remote[18];

	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
		return FALSE;

	sk = g_io_channel_unix_get_fd(io);

	memset(&saddr, 0, sizeof(saddr));
	alen = sizeof(saddr);

	nsk = accept(sk, (struct sockaddr *) &saddr, &alen);
	if (nsk < 0)
		return TRUE;

	if (agent == NULL) {
		ofono_error("Reject SCO: Agent not registered");
		close(nsk);
		return TRUE;
	}

	bt_ba2str(&saddr.sco_bdaddr, remote);

	memset(&saddr, 0, sizeof(saddr));
	alen = sizeof(saddr);

	if (getsockname(nsk, (struct sockaddr *) &saddr, &alen) < 0) {
		ofono_error("SCO getsockname(): %s (%d)",
						strerror(errno), errno);
		close(nsk);
		return TRUE;
	}

	bt_ba2str(&saddr.sco_bdaddr, local);

	card = card_find(remote, local);
	if (card == NULL || card->path == NULL) {
		ofono_error("Rejecting SCO: Audio Card not found!");
		close(nsk);
		return TRUE;
	}

	if (apply_settings_from_codec(nsk, card->selected_codec) == FALSE) {
		close(nsk);
		return TRUE;
	}

	DBG("SCO connection setup between local: %s and remote: %s",
		local, remote);

	send_new_connection(card->path, nsk, card->selected_codec);
	close(nsk);

	if (card->driver->sco_connected_hint)
		card->driver->sco_connected_hint(card);

	return TRUE;
}