博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bluetooth数据收发
阅读量:2442 次
发布时间:2019-05-10

本文共 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()写入到ttybuffer中,

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) PUSHhci 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/

你可能感兴趣的文章
python快速排序_Python快速排序
查看>>
人工神经网络导论_神经网络导论
查看>>
C ++ STL无序多集– std :: unordered_multiset
查看>>
深度学习导论
查看>>
go-back-n_iMyFone D-Back iPhone数据恢复
查看>>
MailboxValidator –批量电子邮件列表清理服务
查看>>
机器学习中常见的最优化算法_最常见的机器学习算法
查看>>
css图片和边框之间有间隔_CSS和CSS3之间的区别
查看>>
iphone浏览器劫持修复_修复iPhone卡在Apple徽标问题上的问题
查看>>
5个最佳Python机器学习IDE
查看>>
c++中将字符串转化为数字_在C和C ++中将十进制数转换为罗马数字
查看>>
unity 粒子系统反弹_零反弹-最佳电子邮件验证系统
查看>>
rail_deviceid_C和C ++中的Rail Fence密码程序[加密和解密]
查看>>
数字转日期 pl/sql_交换两个数字的PL / SQL程序
查看>>
stl set容器_C ++ STL设置容器– std :: set
查看>>
HTML和HTML5之间的区别
查看>>
android mvp示例_Android使用SwipeRefreshLayout示例向下拉或向下滑动以刷新
查看>>
在Android中获取当前日期的4种方法
查看>>
使用Firebase教程的Android实时聊天应用程序
查看>>
evernote 云笔记_屏幕快照之旅:Windows版Evernote 4使记笔记变得很愉快
查看>>