⬢ DragonFlyBSD Kernel Audit
DF-5735 / hci_stub.c
← back to finding ↓ download raw
/*
 * hci_stub.c -- minimal L2CAP/SCO/socket stubs for the hci_event_harness KLD.
 *
 * The production netbt code (sys/netbt/hci_event.c, hci_link.c, hci_misc.c,
 * hci_unit.c, bt_input.c) is compiled VERBATIM into this module.  Everything
 * it needs from the layers we do not compile (l2cap_*.c, sco_*.c,
 * hci_socket.c, bt_proto.c) is stubbed here with the minimum behaviour for
 * the real event/state-machine code to run unmodified:
 *
 *   - M_BLUETOOTH malloc type (lives in bt_proto.c normally)
 *   - l2cap_pdu_pool / l2cap_req_pool vm_zones (bt_proto.c netbt_init)
 *   - l2cap_active_list (l2cap_misc.c)
 *   - l2cap_close/l2cap_start/l2cap_request_free/l2cap_recv_frame
 *   - sco_pcb listener list (sco_upper.c) -- empty: no SCO listeners
 *   - hci_mtap/hci_drop (hci_socket.c) -- no raw HCI sockets in the harness
 */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <net/if.h>

#include <netbt/bluetooth.h>
#include <netbt/hci.h>
#include <netbt/l2cap.h>
#include <netbt/sco.h>

/* real malloc type lives in bt_proto.c which we do not compile in */
MALLOC_DEFINE(M_BLUETOOTH, "Bluetooth", "Bluetooth system memory");

/* zones normally created by netbt_init() in bt_proto.c */
vm_zone_t l2cap_pdu_pool;
vm_zone_t l2cap_req_pool;

/* channel list normally in l2cap_misc.c */
struct l2cap_channel_list l2cap_active_list = LIST_HEAD_INITIALIZER(l2cap_active_list);

/* sco listener list normally in sco_upper.c -- deliberately empty */
struct sco_pcb_list sco_pcb = LIST_HEAD_INITIALIZER(sco_pcb);

int
sco_detach(struct sco_pcb **handle)
{
	*handle = NULL;
	return 0;
}

void
hci_mtap(struct mbuf *m, struct hci_unit *unit)
{
	/* no raw HCI sockets attached in the harness */
}

void
hci_drop(void *arg)
{
	/* no socket bookkeeping to drop */
}

void
l2cap_close(struct l2cap_channel *chan, int err)
{
	if (chan->lc_lcid != L2CAP_NULL_CID) {
		LIST_REMOVE(chan, lc_ncid);
		chan->lc_lcid = L2CAP_NULL_CID;
	}
}

int
l2cap_start(struct l2cap_channel *chan)
{
	return 0;
}

void
l2cap_request_free(struct l2cap_req *req)
{
	kfree(req, M_BLUETOOTH);
}

void
l2cap_recv_frame(struct mbuf *m, struct hci_link *link)
{
	m_freem(m);
}

/* signalling senders used by hci_acl_linkmode() (l2cap_signal.c) */
int
l2cap_send_connect_req(struct l2cap_channel *chan)
{
	return 0;
}

int
l2cap_send_connect_rsp(struct hci_link *link, uint8_t ident,
    uint16_t dcid, uint16_t scid, uint16_t result)
{
	return 0;
}

int
l2cap_send_config_req(struct l2cap_channel *chan)
{
	return 0;
}