コード例 #1
0
ファイル: sco.c プロジェクト: LucidOne/Rovio
int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
{
	struct sock *sk = sock->sk;
	struct sco_options opts;
	struct sco_conninfo cinfo;
	int len, err = 0; 

	//BT_DBG
	printf("%s: sk %p\n", __FUNCTION__, sk);

	if (get_user(&len, optlen))
		return -EFAULT;

	lock_sock(sk);

	switch (optname) {
	case SCO_OPTIONS:
		if (sk->state != BT_CONNECTED) {
			err = -ENOTCONN;
			break;
		}
		
		opts.mtu = sco_pi(sk)->conn->mtu;

		BT_DBG("mtu %d", opts.mtu);

		len = MIN(len, sizeof(opts));
		if (copy_to_user(optval, (char *)&opts, len))
			err = -EFAULT;

		break;

	case SCO_CONNINFO:
		if (sk->state != BT_CONNECTED) {
			err = -ENOTCONN;
			break;
		}

		cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;

		len = MIN(len, sizeof(cinfo));
		if (copy_to_user(optval, (char *)&cinfo, len))
			err = -EFAULT;

		break;

	default:
		err = -ENOPROTOOPT;
		break;
	};

	release_sock(sk);
	return err;
}
コード例 #2
0
ファイル: sco.c プロジェクト: niubl/camera_project
/* Close socket.
 * Must be called on unlocked socket.
 */
static void sco_sock_close(struct sock *sk)
{
	struct sco_conn *conn;

	sco_sock_clear_timer(sk);

	lock_sock(sk);

	conn = sco_pi(sk)->conn;

	BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);

	switch (sk->state) {
	case BT_LISTEN:
		sco_sock_cleanup_listen(sk);
		break;

	case BT_CONNECTED:
	case BT_CONFIG:
	case BT_CONNECT:
	case BT_DISCONN:
		sco_chan_del(sk, ECONNRESET);
		break;

	default:
		sk->zapped = 1;
		break;
	};

	release_sock(sk);
}
コード例 #3
0
ファイル: sco.c プロジェクト: niubl/camera_project
static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
{
	struct sco_conn *conn = sco_pi(sk)->conn;
	struct sk_buff *skb;
	int err, count;

	/* Check outgoing MTU */
	if (len > conn->mtu)
		return -EINVAL;

	BT_DBG("sk %p len %d", sk, len);

	count = MIN(conn->mtu, len);
	if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
		return err;

	if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
		err = -EFAULT;
		goto fail;
	}

	if ((err = hci_send_sco(conn->hcon, skb)) < 0)
		goto fail;

	return count;

fail:
	kfree_skb(skb);
	return err;
}
コード例 #4
0
ファイル: sco.c プロジェクト: niubl/camera_project
static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
{
	BT_DBG("conn %p", conn);

	sco_pi(sk)->conn = conn;
	conn->sk = sk;

	if (parent)
		bluez_accept_enqueue(parent, sk);
}
コード例 #5
0
ファイル: sco.c プロジェクト: niubl/camera_project
/* Delete channel. 
 * Must be called on the locked socket. */
static void sco_chan_del(struct sock *sk, int err)
{
	struct sco_conn *conn;

	conn = sco_pi(sk)->conn;

	BT_DBG("sk %p, conn %p, err %d", sk, conn, err);

	if (conn) { 
		sco_conn_lock(conn);
		conn->sk = NULL;
		sco_pi(sk)->conn = NULL;
		sco_conn_unlock(conn);
		hci_conn_put(conn->hcon);
	}

	sk->state = BT_CLOSED;
	sk->err   = err;
	sk->state_change(sk);

	sk->zapped = 1;
}
コード例 #6
0
ファイル: sco.c プロジェクト: niubl/camera_project
/* ----- Proc fs support ------ */
static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
{
	struct sco_pinfo *pi;
	struct sock *sk;
	char *ptr = buf;

	write_lock_bh(&list->lock);

	for (sk = list->head; sk; sk = sk->next) {
		pi = sco_pi(sk);
		ptr += sprintf(ptr, "%s %s %d\n",
				batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
				sk->state); 
	}

	write_unlock_bh(&list->lock);

	ptr += sprintf(ptr, "\n");

	return ptr - buf;
}