如果编译linux内核时,配置了CONFIG_BLUEZ,
则linux系统执行的第一个有关bluez的函数是bluez_init(net/socket.c)
调用路径main.c->init->do_basic_setup->sock_init->bluez_init
int bluez_init(void)
{
BT_INFO(“BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc”,
VERSION);
BT_INFO(“Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>”);
proc_mkdir(“bluetooth”, NULL);
sock_register(&bluez_sock_family_ops);//struct net_proto_family bluez_sock_family_ops =
{
PF_BLUETOOTH, bluez_sock_create
};
/* Init HCI Core *///空函数
hci_core_init();
/* Init sockets */
hci_sock_init();
return 0;
}
/*
* This function is called by a protocol handler that wants to
* advertise its address family, and have it linked into the
* SOCKET module.
*/
//注册一个协议族的ops,操作函数。
int sock_register(struct net_proto_family *ops)
{
int err;
if (ops->family >= NPROTO) {
printk(KERN_CRIT “protocol %d >= NPROTO(%d)\n”, ops->family, NPROTO);
return -ENOBUFS;
}
net_family_write_lock();
err = -EEXIST;
if (net_families[ops->family] == NULL) {
net_families[ops->family]=ops;
err = 0;
}
net_family_write_unlock();
return err;
}
struct net_proto_family
{//重要的是create函数,
int family;
int (*create)(struct socket *sock, int protocol);
/* These are counters for the number of different methods of
each we support */
short authentication;
short encryption;
short encrypt_net;
};
int hci_sock_init(void)
{//hci socket是bluez蓝牙协议栈的最底层的socket,
if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
BT_ERR(“Can’t register HCI socket”);
return -EPROTO;
}
hci_register_notifier(&hci_sock_nblock);
return 0;
}
//说明bluez蓝牙协议族有7个协议分支
/* Bluetooth sockets */
#define BLUEZ_MAX_PROTO 7
static struct net_proto_family *bluez_proto[BLUEZ_MAX_PROTO];
int bluez_sock_register(int proto, struct net_proto_family *ops)
{
if (proto >= BLUEZ_MAX_PROTO)
return -EINVAL;
if (bluez_proto[proto])
return -EEXIST;
bluez_proto[proto] = ops;
return 0;
}
struct net_proto_family hci_sock_family_ops = {
family: PF_BLUETOOTH,
create: hci_sock_create
};
//注意hci_sock_family_ops和hci_sock_ops的区别,
//family ops只提供create方法,
//sock ops提供socket的一般方法,
struct proto_ops hci_sock_ops = {
family: PF_BLUETOOTH,
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
};
static int hci_sock_create(struct socket *sock, int protocol)
{
struct sock *sk;
BT_DBG(“sock %p”, sock);
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
sock->ops = &hci_sock_ops;
if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
return -ENOMEM;
sock->state = SS_UNCONNECTED;
sock_init_data(sock, sk);
memset(&sk->protinfo, 0, sizeof(struct hci_pinfo));
sk->destruct = NULL;
sk->protocol = protocol;
sk->state = BT_OPEN;
bluez_sock_link(&hci_sk_list, sk);
MOD_INC_USE_COUNT;
return 0;
}
关于模块加载bnep模块加载的函数在/net/bluetooth/bnep/core.c