38#include <sys/bitstring.h>
39#include <sys/domain.h>
40#include <sys/endian.h>
42#include <sys/filedesc.h>
43#include <sys/ioccom.h>
44#include <sys/kernel.h>
46#include <sys/malloc.h>
49#include <sys/protosw.h>
51#include <sys/socket.h>
52#include <sys/socketvar.h>
53#include <sys/sysctl.h>
54#include <sys/taskqueue.h>
67#ifdef NG_SEPARATE_MALLOC
69 "Netgraph Bluetooth SCO sockets");
71#define M_NETGRAPH_BTSOCKET_SCO M_NETGRAPH
108static struct mtx ng_btsocket_sco_rt_mtx;
109static struct task ng_btsocket_sco_rt_task;
110static struct timeval ng_btsocket_sco_lasttime;
111static int ng_btsocket_sco_curpps;
114SYSCTL_DECL(_net_bluetooth_sco_sockets);
115static SYSCTL_NODE(_net_bluetooth_sco_sockets, OID_AUTO, seq,
116 CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
117 "Bluetooth SEQPACKET SCO sockets family");
118SYSCTL_UINT(_net_bluetooth_sco_sockets_seq, OID_AUTO, debug_level,
121 "Bluetooth SEQPACKET SCO sockets debug level");
122SYSCTL_UINT(_net_bluetooth_sco_sockets_seq, OID_AUTO, queue_len,
125 "Bluetooth SEQPACKET SCO sockets input queue length");
126SYSCTL_UINT(_net_bluetooth_sco_sockets_seq, OID_AUTO, queue_maxlen,
129 "Bluetooth SEQPACKET SCO sockets input queue max. length");
130SYSCTL_UINT(_net_bluetooth_sco_sockets_seq, OID_AUTO, queue_drops,
133 "Bluetooth SEQPACKET SCO sockets input queue drops");
136#define NG_BTSOCKET_SCO_INFO \
137 if (ng_btsocket_sco_debug_level >= NG_BTSOCKET_INFO_LEVEL && \
138 ppsratecheck(&ng_btsocket_sco_lasttime, &ng_btsocket_sco_curpps, 1)) \
141#define NG_BTSOCKET_SCO_WARN \
142 if (ng_btsocket_sco_debug_level >= NG_BTSOCKET_WARN_LEVEL && \
143 ppsratecheck(&ng_btsocket_sco_lasttime, &ng_btsocket_sco_curpps, 1)) \
146#define NG_BTSOCKET_SCO_ERR \
147 if (ng_btsocket_sco_debug_level >= NG_BTSOCKET_ERR_LEVEL && \
148 ppsratecheck(&ng_btsocket_sco_lasttime, &ng_btsocket_sco_curpps, 1)) \
151#define NG_BTSOCKET_SCO_ALERT \
152 if (ng_btsocket_sco_debug_level >= NG_BTSOCKET_ALERT_LEVEL && \
153 ppsratecheck(&ng_btsocket_sco_lasttime, &ng_btsocket_sco_curpps, 1)) \
197#define ng_btsocket_sco_wakeup_input_task() \
198 taskqueue_enqueue(taskqueue_swi, &ng_btsocket_sco_queue_task)
200#define ng_btsocket_sco_wakeup_route_task() \
201 taskqueue_enqueue(taskqueue_swi, &ng_btsocket_sco_rt_task)
234"%s: Could not create Netgraph node, error=%d\n", __func__, error);
245"%s: Could not name Netgraph node, error=%d\n", __func__, error);
321"%s: Input queue is full (msg)\n", __func__);
356"%s: Input queue is full (data)\n", __func__);
402"%s: Got LP_ConnectCfm response, src bdaddr=%x:%x:%x:%x:%x:%x, " \
403"dst bdaddr=%x:%x:%x:%x:%x:%x, status=%d, handle=%d, state=%d\n",
405 pcb->
src.b[5], pcb->
src.b[4], pcb->
src.b[3],
406 pcb->
src.b[2], pcb->
src.b[1], pcb->
src.b[0],
407 pcb->
dst.b[5], pcb->
dst.b[4], pcb->
dst.b[3],
408 pcb->
dst.b[2], pcb->
dst.b[1], pcb->
dst.b[0],
428 soisconnected(pcb->
so);
434 pcb->
so->so_error = ECONNREFUSED;
436 soisdisconnected(pcb->
so);
465"%s: Got LP_ConnectInd indicator, src bdaddr=%x:%x:%x:%x:%x:%x, " \
466"dst bdaddr=%x:%x:%x:%x:%x:%x\n",
468 rt->
src.b[5], rt->
src.b[4], rt->
src.b[3],
469 rt->
src.b[2], rt->
src.b[1], rt->
src.b[0],
481 CURVNET_SET(pcb->
so->so_vnet);
482 so1 = sonewconn(pcb->
so, 0);
498 KASSERT((pcb1 != NULL),
499(
"%s: pcb1 == NULL\n", __func__));
501 mtx_lock(&pcb1->pcb_mtx);
504 bcopy(&pcb->
src, &pcb1->src,
sizeof(pcb1->src));
506 bcopy(&rt->
src, &pcb1->src,
sizeof(pcb1->src));
508 pcb1->flags &= ~NG_BTSOCKET_SCO_CLIENT;
510 bcopy(&ep->
bdaddr, &pcb1->dst,
sizeof(pcb1->dst));
520 pcb1->so->so_error = error;
522 soisdisconnected(pcb1->so);
525 soisconnecting(pcb1->so);
530 mtx_unlock(&pcb1->pcb_mtx);
575"%s: Got LP_DisconnectInd indicator, src bdaddr=%x:%x:%x:%x:%x:%x, " \
576"dst bdaddr=%x:%x:%x:%x:%x:%x, handle=%d, state=%d\n",
578 pcb->
src.b[5], pcb->
src.b[4], pcb->
src.b[3],
579 pcb->
src.b[2], pcb->
src.b[1], pcb->
src.b[0],
580 pcb->
dst.b[5], pcb->
dst.b[4], pcb->
dst.b[3],
581 pcb->
dst.b[2], pcb->
dst.b[1], pcb->
dst.b[0],
588 soisdisconnected(pcb->
so);
607 mtx_assert(&pcb->
pcb_mtx, MA_OWNED);
609 if (pcb->
rt == NULL ||
614 sizeof(*ep), M_NOWAIT);
642 sizeof(*ep), M_NOWAIT);
667 mtx_assert(&pcb->
pcb_mtx, MA_OWNED);
669 if (pcb->
rt == NULL ||
674 sizeof(*ep), M_NOWAIT);
700 ng_hci_scodata_pkt_t *hdr = NULL;
703 u_int16_t con_handle;
707"%s: Invalid source hook for SCO data packet\n", __func__);
714"%s: Could not find out source bdaddr for SCO data packet\n", __func__);
719 if (m->m_pkthdr.len <
sizeof(*hdr)) {
721"%s: SCO data packet too small, len=%d\n", __func__, m->m_pkthdr.len);
725 if (m->m_len <
sizeof(*hdr)) {
726 m = m_pullup(m,
sizeof(*hdr));
732 hdr = mtod(m, ng_hci_scodata_pkt_t *);
733 m_adj(m,
sizeof(*hdr));
735 if (hdr->length != m->m_pkthdr.len) {
737"%s: Bad SCO data packet length, len=%d, length=%d\n",
738 __func__, m->m_pkthdr.len, hdr->length);
749"%s: Received SCO data packet: src bdaddr=%x:%x:%x:%x:%x:%x, handle=%d, " \
750"length=%d\n", __func__,
751 rt->
src.b[5], rt->
src.b[4], rt->
src.b[3],
752 rt->
src.b[2], rt->
src.b[1], rt->
src.b[0],
753 con_handle, hdr->length);
768"%s: No connected socket found, src bdaddr=%x:%x:%x:%x:%x:%x, state=%d\n",
770 rt->
src.b[5], rt->
src.b[4], rt->
src.b[3],
771 rt->
src.b[2], rt->
src.b[1], rt->
src.b[0],
780 if (m->m_pkthdr.len > sbspace(&pcb->
so->so_rcv)) {
782"%s: Not enough space in socket receive queue. Dropping SCO data packet, " \
783"src bdaddr=%x:%x:%x:%x:%x:%x, len=%d, space=%ld\n",
785 rt->
src.b[5], rt->
src.b[4], rt->
src.b[3],
786 rt->
src.b[2], rt->
src.b[1], rt->
src.b[0],
788 sbspace(&pcb->
so->so_rcv));
796 sbappendrecord(&pcb->
so->so_rcv, m);
833 rt = malloc(
sizeof(*rt),
840 mtx_lock(&ng_btsocket_sco_rt_mtx);
842 LIST_INSERT_HEAD(&ng_btsocket_sco_rt, rt, next);
844 mtx_lock(&ng_btsocket_sco_rt_mtx);
851 mtx_unlock(&ng_btsocket_sco_rt_mtx);
854"%s: Updating hook \"%s\", src bdaddr=%x:%x:%x:%x:%x:%x, pkt_size=%d, " \
856 rt->
src.b[5], rt->
src.b[4], rt->
src.b[3],
857 rt->
src.b[2], rt->
src.b[1], rt->
src.b[0],
873"%s: Pending packet counter is out of sync! bdaddr=%x:%x:%x:%x:%x:%x, " \
874"handle=%d, pending=%d, completed=%d\n",
876 rt->
src.b[5], rt->
src.b[4], rt->
src.b[3],
877 rt->
src.b[2], rt->
src.b[1], rt->
src.b[0],
902 sbdroprecord(&pcb->
so->so_snd);
905 if (sbavail(&pcb->
so->so_snd) > 0)
919"%s: Unknown message, cmd=%d\n", __func__, msg->
header.
cmd);
937"%s: Invalid source hook for LP message\n", __func__);
944"%s: Could not find out source bdaddr for LP message\n", __func__);
965"%s: Unknown LP message, cmd=%d\n", __func__, msg->
header.
cmd);
996 struct mbuf *m = NULL;
1051 for(pcb = LIST_FIRST(&ng_btsocket_sco_sockets); pcb != NULL; ) {
1053 pcb_next = LIST_NEXT(pcb, next);
1055 if (pcb->
rt != NULL &&
1061 pcb->
so->so_error = ENETDOWN;
1063 soisdisconnected(pcb->
so);
1076 mtx_lock(&ng_btsocket_sco_rt_mtx);
1078 for (rt = LIST_FIRST(&ng_btsocket_sco_rt); rt != NULL; ) {
1082 LIST_REMOVE(rt, next);
1087 bzero(rt,
sizeof(*rt));
1094 mtx_unlock(&ng_btsocket_sco_rt_mtx);
1113"%s: Could not register Netgraph node type, error=%d\n", __func__, error);
1122"%s: Could not create Netgraph node, error=%d\n", __func__, error);
1132"%s: Could not name Netgraph node, error=%d\n", __func__, error);
1143 "btsocks_sco_queue_mtx", NULL, MTX_DEF);
1148 LIST_INIT(&ng_btsocket_sco_sockets);
1150 "btsocks_sco_sockets_mtx", NULL, MTX_DEF);
1153 LIST_INIT(&ng_btsocket_sco_rt);
1154 mtx_init(&ng_btsocket_sco_rt_mtx,
1155 "btsocks_sco_rt_mtx", NULL, MTX_DEF);
1156 TASK_INIT(&ng_btsocket_sco_rt_task, 0,
1169 so->so_error = ECONNABORTED;
1206 return (EPROTONOSUPPORT);
1207 if (so->so_type != SOCK_SEQPACKET)
1208 return (ESOCKTNOSUPPORT);
1213 return (EPROTONOSUPPORT);
1220 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) {
1228 pcb = malloc(
sizeof(*pcb),
1234 so->so_pcb = (caddr_t) pcb;
1238 callout_init(&pcb->
timo, 1);
1247 mtx_init(&pcb->
pcb_mtx,
"btsocks_sco_pcb_mtx", NULL,
1274 LIST_INSERT_HEAD(&ng_btsocket_sco_sockets, pcb, next);
1300 return (EAFNOSUPPORT);
1301 if (sa->
sco_len !=
sizeof(*sa))
1312 LIST_FOREACH(pcb, &ng_btsocket_sco_sockets, next) {
1315 if (bcmp(&pcb->
src, &sa->
sco_bdaddr,
sizeof(bdaddr_t)) == 0) {
1319 return (EADDRINUSE);
1352 int have_src, error = 0;
1364 return (EAFNOSUPPORT);
1365 if (sa->
sco_len !=
sizeof(*sa))
1368 return (EDESTADDRREQ);
1377 mtx_lock(&ng_btsocket_sco_rt_mtx);
1382 mtx_unlock(&ng_btsocket_sco_rt_mtx);
1384 return (EINPROGRESS);
1389 mtx_unlock(&ng_btsocket_sco_rt_mtx);
1400 LIST_FOREACH(rt, &ng_btsocket_sco_rt, next) {
1406 if (bcmp(&pcb->
src, &rt->
src,
sizeof(rt->
src)) == 0)
1409 if (bcmp(&pcb->
dst, &rt->
src,
sizeof(rt->
src)) != 0)
1418 bcopy(&rt->
src, &pcb->
src,
sizeof(pcb->
src));
1420 error = EHOSTUNREACH;
1431 soisconnecting(pcb->
so);
1438 mtx_unlock(&ng_btsocket_sco_rt_mtx);
1449 struct ifnet *ifp,
struct thread *td)
1469 if (sopt->sopt_level !=
SOL_SCO)
1474 switch (sopt->sopt_dir) {
1481 switch (sopt->sopt_name) {
1484 error = sooptcopyout(sopt, &tmp,
sizeof(tmp));
1489 error = sooptcopyout(sopt, &tmp,
sizeof(tmp));
1499 error = ENOPROTOOPT;
1521 KASSERT(pcb != NULL, (
"ng_btsocket_sco_detach: pcb == NULL"));
1537 LIST_REMOVE(pcb, next);
1543 bzero(pcb,
sizeof(*pcb));
1546 soisdisconnected(so);
1569 return (EINPROGRESS);
1579 soisdisconnecting(so);
1584 soisdisconnected(so);
1610 error = solisten_proto_check(so);
1615 error = EDESTADDRREQ;
1619 solisten_proto(so, backlog);
1649 *nam = sodupsockaddr((
struct sockaddr *) &sa, M_NOWAIT);
1651 return ((*nam == NULL)? ENOMEM : 0);
1660 struct sockaddr *nam,
struct mbuf *
control,
struct thread *td)
1671 if (pcb == NULL || m == NULL ||
control != NULL) {
1686 if (pcb->
rt == NULL ||
1696"%s: Packet too big, len=%d, pkt_size=%d\n",
1697 __func__, m->m_pkthdr.len, pcb->
rt->
pkt_size);
1711 sbappendrecord(&pcb->
so->so_snd, m);
1719 sbdroprecord(&pcb->
so->so_snd);
1737 struct mbuf *m = NULL;
1738 ng_hci_scodata_pkt_t *hdr = NULL;
1741 mtx_assert(&pcb->
pcb_mtx, MA_OWNED);
1744 sbavail(&pcb->
so->so_snd) > 0) {
1746 m = m_dup(pcb->
so->so_snd.sb_mb, M_NOWAIT);
1753 M_PREPEND(m,
sizeof(*hdr), M_NOWAIT);
1755 if (m->m_len <
sizeof(*hdr))
1756 m = m_pullup(m,
sizeof(*hdr));
1764 hdr = mtod(m, ng_hci_scodata_pkt_t *);
1767 hdr->length = m->m_pkthdr.len -
sizeof(*hdr);
1777 return ((pcb->
rt->
pending > 0)? 0 : error);
1802 *nam = sodupsockaddr((
struct sockaddr *) &sa, M_NOWAIT);
1804 return ((*nam == NULL)? ENOMEM : 0);
1827 LIST_FOREACH(p, &ng_btsocket_sco_sockets, next) {
1830 if (p->
so == NULL || !SOLISTENING(p->
so)) {
1835 if (bcmp(&p->
src, bdaddr,
sizeof(p->
src)) == 0)
1845 mtx_lock(&p1->pcb_mtx);
1863 LIST_FOREACH(p, &ng_btsocket_sco_sockets, next) {
1867 bcmp(src, &p->
src,
sizeof(p->
src)) == 0)
1889 LIST_FOREACH(p, &ng_btsocket_sco_sockets, next) {
1893 bcmp(src, &p->
src,
sizeof(p->
src)) == 0 &&
1894 bcmp(dst, &p->
dst,
sizeof(p->
dst)) == 0)
1910 mtx_assert(&pcb->
pcb_mtx, MA_OWNED);
1918(
"%s: Duplicated socket timeout?!\n", __func__));
1928 mtx_assert(&pcb->
pcb_mtx, MA_OWNED);
1931 callout_stop(&pcb->
timo);
1932 pcb->
flags &= ~NG_BTSOCKET_SCO_TIMO;
1935(
"%s: No socket timeout?!\n", __func__));
1949 pcb->
flags &= ~NG_BTSOCKET_SCO_TIMO;
1950 pcb->
so->so_error = ETIMEDOUT;
1952 switch (pcb->
state) {
1956 soisdisconnected(pcb->
so);
1961 sbdroprecord(&pcb->
so->so_snd);
1969 soisdisconnected(pcb->
so);
1974"%s: Invalid socket state=%d\n", __func__, pcb->
state);
#define NGI_SET_HOOK(i, h)
int ng_connect_t(hook_p hook)
#define NGI_GET_HOOK(i, h)
#define NG_HOOK_UNREF(hook)
#define NG_HOOK_NOT_VALID(hook)
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
int ng_disconnect_t(hook_p hook)
int ng_newtype(struct ng_type *tp)
#define NG_HOOK_PEER(hook)
#define NG_NODE_UNREF(node)
#define NG_HOOK_SET_PRIVATE(hook, val)
#define NG_SEND_DATA_ONLY(error, hook, m)
#define NG_HOOK_FORCE_QUEUE(hook)
#define NG_HOOK_REF(hook)
int ng_rcvdata_t(hook_p hook, item_p item)
int ng_shutdown_t(node_p node)
#define NG_HOOK_NAME(hook)
#define NG_FREE_ITEM(item)
int ng_make_node_common(struct ng_type *typep, node_p *nodep)
int ng_name_node(node_p node, const char *name)
int ng_constructor_t(node_p node)
#define NGI_GET_MSG(i, m)
#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr)
int ng_newhook_t(node_p node, hook_p hook, const char *name)
#define NG_HOOK_PRIVATE(hook)
SYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "Bluetooth family")
u_int32_t bluetooth_sco_rtx_timeout(void)
SYSCTL_UINT(_net_bluetooth_hci, OID_AUTO, max_neighbor_age, CTLFLAG_RW, &bluetooth_hci_max_neighbor_age_value, 600, "Maximal HCI neighbor cache entry age (sec)")
#define NG_BT_ITEMQ_ENQUEUE(q, i)
#define NG_BT_ITEMQ_FULL(q)
#define NG_BT_ITEMQ_INIT(q, _maxlen)
#define NG_BT_ITEMQ_DEQUEUE(q, i)
#define NG_BT_ITEMQ_DROP(q)
#define NG_BTSOCKET_SCO_NODE_TYPE
#define BLUETOOTH_PROTO_SCO
#define NG_BTSOCKET_WARN_LEVEL
static int ng_btsocket_sco_send_lp_con_req(ng_btsocket_sco_pcb_p pcb)
static int ng_btsocket_sco_process_lp_con_ind(struct ng_mesg *msg, ng_btsocket_sco_rtentry_p rt)
#define ng_btsocket_sco_wakeup_input_task()
static ng_btsocket_sco_pcb_p ng_btsocket_sco_pcb_by_addrs(bdaddr_p src, bdaddr_p dst)
static int ng_btsocket_sco_send_lp_con_rsp(ng_btsocket_sco_rtentry_p rt, bdaddr_p dst, int status)
int ng_btsocket_sco_disconnect(struct socket *so)
static void ng_btsocket_sco_timeout(ng_btsocket_sco_pcb_p pcb)
#define ng_btsocket_sco_wakeup_route_task()
int ng_btsocket_sco_ctloutput(struct socket *so, struct sockopt *sopt)
static void ng_btsocket_sco_rtclean(void *, int)
static u_int32_t ng_btsocket_sco_debug_level
static struct mtx ng_btsocket_sco_queue_mtx
static void ng_btsocket_sco_init(void *arg __unused)
void ng_btsocket_sco_abort(struct socket *so)
static ng_btsocket_sco_pcb_p ng_btsocket_sco_pcb_by_addr(bdaddr_p bdaddr)
static LIST_HEAD(ng_btsocket_sco_pcb)
static void ng_btsocket_sco_data_input(struct mbuf *m, hook_p hook)
int ng_btsocket_sco_listen(struct socket *so, int backlog, struct thread *td)
static ng_connect_t ng_btsocket_sco_node_connect
static struct ng_type typestruct
static struct mtx ng_btsocket_sco_sockets_mtx
static int ng_btsocket_sco_send2(ng_btsocket_sco_pcb_p pcb)
void ng_btsocket_sco_close(struct socket *so)
int ng_btsocket_sco_accept(struct socket *so, struct sockaddr **nam)
static int ng_btsocket_sco_send_lp_discon_req(ng_btsocket_sco_pcb_p pcb)
static void ng_btsocket_sco_process_timeout(void *xpcb)
SYSINIT(ng_btsocket_sco_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ng_btsocket_sco_init, NULL)
static void ng_btsocket_sco_default_msg_input(struct ng_mesg *msg, hook_p hook)
#define NG_BTSOCKET_SCO_WARN
static int ng_btsocket_sco_process_lp_discon_ind(struct ng_mesg *msg, ng_btsocket_sco_rtentry_p rt)
int ng_btsocket_sco_attach(struct socket *so, int proto, struct thread *td)
static ng_shutdown_t ng_btsocket_sco_node_shutdown
static ng_disconnect_t ng_btsocket_sco_node_disconnect
static void ng_btsocket_sco_lp_msg_input(struct ng_mesg *msg, hook_p hook)
int ng_btsocket_sco_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, struct mbuf *control, struct thread *td)
#define NG_BTSOCKET_SCO_INFO
int ng_btsocket_sco_sockaddr(struct socket *so, struct sockaddr **nam)
static ng_rcvdata_t ng_btsocket_sco_node_rcvdata
static node_p ng_btsocket_sco_node
void ng_btsocket_sco_detach(struct socket *so)
#define NG_BTSOCKET_SCO_ALERT
static void ng_btsocket_sco_untimeout(ng_btsocket_sco_pcb_p pcb)
int ng_btsocket_sco_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
#define M_NETGRAPH_BTSOCKET_SCO
static ng_rcvmsg_t ng_btsocket_sco_node_rcvmsg
static ng_constructor_t ng_btsocket_sco_node_constructor
static int ng_btsocket_sco_process_lp_con_cfm(struct ng_mesg *msg, ng_btsocket_sco_rtentry_p rt)
int ng_btsocket_sco_peeraddr(struct socket *so, struct sockaddr **nam)
static struct task ng_btsocket_sco_queue_task
static struct ng_bt_itemq ng_btsocket_sco_queue
#define NG_BTSOCKET_SCO_ERR
static ng_btsocket_sco_pcb_p ng_btsocket_sco_pcb_by_handle(bdaddr_p src, int con_handle)
int ng_btsocket_sco_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
static void ng_btsocket_sco_input(void *, int)
int ng_btsocket_sco_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
static ng_newhook_t ng_btsocket_sco_node_newhook
struct ng_btsocket_sco_pcb * ng_btsocket_sco_pcb_p
#define NG_BTSOCKET_SCO_CLOSED
struct ng_btsocket_sco_rtentry * ng_btsocket_sco_rtentry_p
#define NG_BTSOCKET_SCO_TIMO
#define NG_BTSOCKET_SCO_DISCONNECTING
#define NG_BTSOCKET_SCO_OPEN
#define NG_BTSOCKET_SCO_CLIENT
#define NG_BTSOCKET_SCO_SENDSPACE
#define NG_BTSOCKET_SCO_CONNECTING
#define NG_BTSOCKET_SCO_RECVSPACE
MALLOC_DEFINE(M_NG_CCATM, "ng_ccatm", "netgraph uni api node")
#define NGM_HCI_LP_CON_IND
#define NG_HCI_BDADDR_ANY
#define NGM_HCI_SYNC_CON_QUEUE
#define NGM_HCI_LP_CON_RSP
#define NGM_HCI_LP_CON_CFM
#define NGM_HCI_LP_DISCON_REQ
#define NGM_HCI_LP_DISCON_IND
#define NG_HCI_SCO_DATA_PKT
#define NGM_HCI_LP_CON_REQ
#define NG_HCI_CON_HANDLE(h)
#define NG_HCI_MK_CON_HANDLE(h, pb, bc)
#define NG_MKMESSAGE(msg, cookie, cmdid, len, how)
ng_btsocket_sco_rtentry_p rt
struct ng_mesg::ng_msghdr header