本文共 4598 字,大约阅读时间需要 15 分钟。
net/socket.c
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)->sock_create()->__sock_create()->
pf = rcu_dereference(net_families[family]);
err = pf->create(net, sock, protocol, kern);
bt_init()->
err = sock_register(&bt_sock_family_ops);
static struct net_proto_family bt_sock_family_ops = {
.owner = THIS_MODULE,
.family = PF_BLUETOOTH,
.create = bt_sock_create,
};
bt_sock_create()->
err = bt_proto[proto]->create(net, sock, proto, kern);
bt_proto[proto]注册如下:
bt_init()->hci_sock_init()->bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops)->
bt_proto[proto] = ops;
static const struct net_proto_family hci_sock_family_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.create = hci_sock_create,
};
hci_sock_create()->sock->ops = &hci_sock_ops
net/bluetooth/hci_sock.c
static const struct proto_ops hci_sock_ops = {
.family = PF_BLUETOOTH,
.owner = THIS_MODULE,
.release = hci_sock_release,
.bind = hci_sock_bind,
.getname = hci_sock_getname,
.sendmsg = hci_sock_sendmsg,
.recvmsg = hci_sock_recvmsg,
.ioctl = hci_sock_ioctl,
.poll = datagram_poll,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = hci_sock_setsockopt,
.getsockopt = hci_sock_getsockopt,
.connect = sock_no_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.mmap = sock_no_mmap
};
发送
hci_sock_sendmsg()->
hdev = hci_pi(sk)->hdev;//由bind函数确定的
skb_queue_tail(&hdev->raw_q, skb);
queue_work(hdev->workqueue, &hdev->tx_work);
hci_sock_bind()->
hdev = hci_dev_get(haddr.hci_dev);
hci_pi(sk)->hdev = hdev;
ioctl()--->hci_alloc_dev()->
INIT_WORK(&hdev->rx_work, hci_rx_work);
INIT_WORK(&hdev->cmd_work, hci_cmd_work);
INIT_WORK(&hdev->tx_work, hci_tx_work);
INIT_WORK(&hdev->power_on, hci_power_on);
hci_tx_work()->hci_send_frame()->
hci_send_to_sock(hdev, skb);
return hdev->send(skb);
ioctl()--->hci_uart_register_dev()->
hdev->open = hci_uart_open;
hdev->close = hci_uart_close;
hdev->flush = hci_uart_flush;
hdev->send = hci_uart_send_frame;
hdev->send即为hci_uart_send_frame。
hci_uart_send_frame()->
hci_set_drvdata(hdev, hu);
hu = hci_get_drvdata(hdev);
hu->proto->enqueue(hu, skb);
hci_uart_tx_wakeup(hu);
注意以后可以从tty->disc_data得到hu:
hci_uart_tty_open()->
tty->disc_data = hu;
hu->tty = tty;
hci_uart_tx_wakeup()->
len = tty->ops->write(tty, skb->data, skb->len);
hci_uart_tx_complete(hu, bt_cb(skb)->pkt_type);
uart_write()->uart_start(tty)->__uart_start()->(port->ops->start_tx(port))
平台相关,uart_add_one_port()时注册的。
接收
tty接收到数据,使用tty_insert_flip_char()写入到tty的buffer中,
uart_register_driver()->tty_port_init(port)->tty_buffer_init(port)//buf初始化
tty_buffer_request_room()->//find buffers
/* This is the slow path - looking for new buffers to use */
if ((n = tty_buffer_find(port, size)) != NULL) {
if (b != NULL) {
b->next = n;
b->commit = b->used;
} else
buf->head = n;
buf->tail = n;
}
tty_flip_buffer_push(tport) PUSH到hci uart。
tty_flip_buffer_push()->tty_flip_buffer_push()->tty_ldisc_ref()->
disc = tty_ldisc_ref(tty);
disc->ops->receive_buf(tty, char_buf,
flag_buf, count);
hci_uart_init()->
memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
hci_uart_ldisc.name = "n_hci";
hci_uart_ldisc.open = hci_uart_tty_open;
hci_uart_ldisc.close = hci_uart_tty_close;
hci_uart_ldisc.read = hci_uart_tty_read;
hci_uart_ldisc.write = hci_uart_tty_write;
hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
hci_uart_ldisc.poll = hci_uart_tty_poll;
hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup;
hci_uart_ldisc.owner = THIS_MODULE;
if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
BT_ERR("HCI line discipline registration failed. (%d)", err);
return err;
}
#ifdef CONFIG_BT_HCIUART_H4
h4_init();
#endif
#ifdef CONFIG_BT_HCIUART_BCSP
bcsp_init();
#endif
#ifdef CONFIG_BT_HCIUART_LL
ll_init();
#endif
#ifdef CONFIG_BT_HCIUART_ATH3K
ath_init();
#endif
#ifdef CONFIG_BT_HCIUART_3WIRE
h5_init();
#endif
hci_uart_tty_receive()->
hu->proto->recv(hu, (void *) data, count);
h4_init()->hci_uart_register_proto(&h4p)
static struct hci_uart_proto h4p = {
.id = HCI_UART_H4,
.open = h4_open,
.close = h4_close,
.recv = h4_recv,
.enqueue = h4_enqueue,
.dequeue = h4_dequeue,
.flush = h4_flush,
};
协议不同,recv()不同。
h4_recv()->hci_recv_stream_fragment()->hci_reassembly()->hci_recv_frame(skb)->
skb_queue_tail(&hdev->rx_q, skb);
queue_work(hdev->workqueue, &hdev->rx_work);
hci_rx_work()->hci_send_to_sock()->sock_queue_rcv_skb()->__skb_queue_tail(list, skb);
用hci_send_to_sock通过已经连接并且正在监听的sockt将数据拷贝发送给HAL,并且根据skb的类型作对应处理。
hci_sock_recvmsg()->
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
转载地址:http://fdsqb.baihongyu.com/