mirror of
https://github.com/Stichting-MINIX-Research-Foundation/netbsd.git
synced 2025-09-06 21:57:22 -04:00
192 lines
5.5 KiB
C
192 lines
5.5 KiB
C
/* $NetBSD: btplay.c,v 1.1 2010/03/22 12:21:37 pooka Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2010 Antti Kantee. All Rights Reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*/
|
|
|
|
/*
|
|
* Little demo showing how to use bluetooth stack in rump. Searches
|
|
* for a peer and prints a little info for it.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/time.h>
|
|
#include <sys/socket.h>
|
|
|
|
#include <rump/rump.h>
|
|
#include <rump/rump_syscalls.h>
|
|
|
|
#include <netbt/bluetooth.h>
|
|
#include <netbt/hci.h>
|
|
|
|
#include <bluetooth.h>
|
|
#include <err.h>
|
|
#include <paths.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
const char *btclasses[] = {
|
|
"misc.",
|
|
"computer",
|
|
"phone",
|
|
"LAN",
|
|
"audio-video",
|
|
"peripheral",
|
|
"imaging",
|
|
"wearable",
|
|
"toy",
|
|
};
|
|
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
struct sockaddr_bt sbt;
|
|
bdaddr_t peeraddr;
|
|
uint8_t msg[1024];
|
|
hci_inquiry_cp inq;
|
|
hci_cmd_hdr_t *cmd;
|
|
hci_event_hdr_t *evp;
|
|
struct hci_filter filt;
|
|
struct btreq btr;
|
|
int s, gotpeer = 0;
|
|
|
|
rump_boot_sethowto(RUMP_AB_VERBOSE);
|
|
rump_init();
|
|
|
|
s = rump_sys_socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
|
|
if (s == -1)
|
|
err(1, "socket");
|
|
|
|
/* enable first device, print name and address */
|
|
memset(&btr, 0, sizeof(btr));
|
|
if (rump_sys_ioctl(s, SIOCNBTINFO, &btr) == -1)
|
|
err(1, "no bt device?");
|
|
|
|
btr.btr_flags |= BTF_UP;
|
|
if (rump_sys_ioctl(s, SIOCSBTFLAGS, &btr) == -1)
|
|
err(1, "raise interface");
|
|
if (rump_sys_ioctl(s, SIOCGBTINFO, &btr) == -1)
|
|
err(1, "reget info");
|
|
|
|
memset(&sbt, 0, sizeof(sbt));
|
|
sbt.bt_len = sizeof(sbt);
|
|
sbt.bt_family = AF_BLUETOOTH;
|
|
bdaddr_copy(&sbt.bt_bdaddr, &btr.btr_bdaddr);
|
|
|
|
if (rump_sys_bind(s, (struct sockaddr *)&sbt, sizeof(sbt)) == -1)
|
|
err(1, "bind");
|
|
if (rump_sys_connect(s, (struct sockaddr *)&sbt, sizeof(sbt)) == -1)
|
|
err(1, "connect");
|
|
|
|
printf("device %s, addr %s\n",
|
|
btr.btr_name, bt_ntoa(&btr.btr_bdaddr, NULL));
|
|
|
|
/* allow to receive various messages we need later */
|
|
memset(&filt, 0, sizeof(filt));
|
|
hci_filter_set(HCI_EVENT_COMMAND_COMPL, &filt);
|
|
hci_filter_set(HCI_EVENT_INQUIRY_RESULT, &filt);
|
|
hci_filter_set(HCI_EVENT_INQUIRY_COMPL, &filt);
|
|
hci_filter_set(HCI_EVENT_REMOTE_NAME_REQ_COMPL, &filt);
|
|
if (rump_sys_setsockopt(s, BTPROTO_HCI, SO_HCI_EVT_FILTER,
|
|
&filt, sizeof(filt)) == -1)
|
|
err(1, "setsockopt");
|
|
|
|
cmd = (void *)msg;
|
|
evp = (void *)msg;
|
|
|
|
/* discover peer. first, send local access profile general inquiry */
|
|
inq.lap[0] = 0x33;
|
|
inq.lap[1] = 0x8b;
|
|
inq.lap[2] = 0x9e;
|
|
inq.inquiry_length = 4;
|
|
inq.num_responses = 1;
|
|
|
|
cmd->type = HCI_CMD_PKT;
|
|
cmd->opcode = htole16(HCI_CMD_INQUIRY);
|
|
cmd->length = sizeof(inq);
|
|
memcpy(cmd+1, &inq, sizeof(inq));
|
|
|
|
if (rump_sys_sendto(s, msg, sizeof(*cmd)+sizeof(inq), 0, NULL, 0) == -1)
|
|
err(1, "send inquiry");
|
|
memset(msg, 0, sizeof(msg));
|
|
if (rump_sys_recvfrom(s, msg, sizeof(msg), 0, NULL, NULL) == -1)
|
|
err(1, "recv inq response");
|
|
if (evp->event != HCI_EVENT_COMMAND_COMPL)
|
|
errx(1, "excepted command compl");
|
|
|
|
/* then, wait for response */
|
|
for (;;) {
|
|
if (rump_sys_recvfrom(s, msg, sizeof(msg), 0, NULL, NULL) == -1)
|
|
err(1, "recv inq result");
|
|
|
|
if (evp->event == HCI_EVENT_INQUIRY_COMPL)
|
|
break;
|
|
if (evp->event == HCI_EVENT_INQUIRY_RESULT) {
|
|
hci_inquiry_response *r;
|
|
unsigned class;
|
|
|
|
r = (void *)(msg + sizeof(hci_event_hdr_t)
|
|
+ sizeof(hci_inquiry_result_ep));
|
|
bdaddr_copy(&peeraddr, &r[0]. bdaddr);
|
|
printf("my peer: %s, ", bt_ntoa(&peeraddr, NULL));
|
|
class = r[0].uclass[1] & 0x1f;
|
|
printf("major class: %d (%s)\n", class,
|
|
class < __arraycount(btclasses)
|
|
? btclasses[class] : "unknown");
|
|
gotpeer = 1;
|
|
}
|
|
}
|
|
|
|
/* found peer. ask for its name */
|
|
if (gotpeer) {
|
|
hci_remote_name_req_cp nreq;
|
|
hci_remote_name_req_compl_ep *nresp;
|
|
|
|
memset(&nreq, 0, sizeof(nreq));
|
|
bdaddr_copy(&nreq.bdaddr, &peeraddr);
|
|
|
|
cmd->type = HCI_CMD_PKT;
|
|
cmd->opcode = htole16(HCI_CMD_REMOTE_NAME_REQ);
|
|
cmd->length = sizeof(nreq);
|
|
memcpy(cmd+1, &nreq, sizeof(nreq));
|
|
|
|
if (rump_sys_sendto(s, msg, sizeof(*cmd)+sizeof(nreq), 0,
|
|
NULL, 0) == -1)
|
|
err(1, "send name req");
|
|
memset(msg, 0, sizeof(msg));
|
|
if (rump_sys_recvfrom(s, msg, sizeof(msg), 0, NULL, NULL) == -1)
|
|
err(1, "recv inq response");
|
|
if (evp->event != HCI_EVENT_REMOTE_NAME_REQ_COMPL)
|
|
errx(1, "excepted nreq compl");
|
|
|
|
nresp = (void *)(evp+1);
|
|
printf("peer name: %s\n", nresp->name);
|
|
}
|
|
|
|
return 0;
|
|
}
|