/*
 * step_listen.c — bisect the listen(2) double fault on L2CAP SEQPACKET.
 * Prints progress to the serial console (/dev/console) so the last
 * completed step is visible in the boot log even after a panic.
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#define AF_BT		33
#define PROTO_L2CAP	135

struct sockaddr_l2cap_bt {
	u_char	l2cap_len;
	u_char	l2cap_family;
	u_short	l2cap_psm;
	u_char	l2cap_bdaddr[6];
};

static int cfd = -1;

static void
mark(const char *s)
{
	char buf[128];
	int n;

	n = snprintf(buf, sizeof(buf), "STEP: %s\n", s);
	if (cfd < 0)
		cfd = open("/dev/console", O_WRONLY);
	if (cfd >= 0)
		write(cfd, buf, n);
	write(1, buf, n);
}

int
main(int argc, char **argv)
{
	struct sockaddr_l2cap_bt sa;
	int fd, r;

	mark("start");
	fd = socket(AF_BT, SOCK_SEQPACKET, PROTO_L2CAP);
	mark("socket done");
	if (fd < 0)
		return (1);

	memset(&sa, 0, sizeof(sa));
	sa.l2cap_len = sizeof(sa);
	sa.l2cap_family = AF_BT;
	sa.l2cap_psm = 0x3412;
	r = bind(fd, (struct sockaddr *)&sa, sizeof(sa));
	mark("bind done");
	if (r != 0)
		return (1);

	r = listen(fd, 4);
	mark("listen done");
	if (r != 0)
		return (1);

	mark("ALL OK");
	return (0);
}
