From c4e3f62cc11dc26d94407be2e369de58373af8f3 Mon Sep 17 00:00:00 2001 From: Maksim Yevmenkin Date: Wed, 17 May 2006 00:13:07 +0000 Subject: Add new SIOC_HCI_RAW_NODE_LIST_NAMES ioctl. User-space applications can use this ioctl to obtain the list of HCI nodes. User-space application is expected to preallocate 'ng_btsocket_hci_raw_node_list_names' structure and set limit in 'num_nodes' field. The 'nodes' field should be allocated as well and it should have space for at least 'num_nodes' elements. The SIOC_HCI_RAW_NODE_LIST_NAMES should be issued on bound raw HCI socket. It does not really really matter what HCI name the socket is bound to, as long as it is not empty. MFC after: 1 week --- sys/netgraph/bluetooth/include/ng_btsocket.h | 9 +++ sys/netgraph/bluetooth/include/ng_hci.h | 2 + .../bluetooth/socket/ng_btsocket_hci_raw.c | 65 +++++++++++++++++++++- 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/sys/netgraph/bluetooth/include/ng_btsocket.h b/sys/netgraph/bluetooth/include/ng_btsocket.h index 01822e3f0da3..7dc309a94378 100644 --- a/sys/netgraph/bluetooth/include/ng_btsocket.h +++ b/sys/netgraph/bluetooth/include/ng_btsocket.h @@ -189,6 +189,15 @@ struct ng_btsocket_hci_raw_node_role_switch { _IOWR('b', NGM_HCI_NODE_SET_ROLE_SWITCH, \ struct ng_btsocket_hci_raw_node_role_switch) +/* Get list of HCI node names */ +struct ng_btsocket_hci_raw_node_list_names { + u_int32_t num_names; + struct nodeinfo *names; +}; +#define SIOC_HCI_RAW_NODE_LIST_NAMES \ + _IOWR('b', NGM_HCI_NODE_LIST_NAMES, \ + struct ng_btsocket_hci_raw_node_list_names) + /* * XXX FIXME: probably does not belong here * Bluetooth version of struct sockaddr for L2CAP sockets (RAW and SEQPACKET) diff --git a/sys/netgraph/bluetooth/include/ng_hci.h b/sys/netgraph/bluetooth/include/ng_hci.h index b2d6da6084fe..5cdfd5cea53a 100644 --- a/sys/netgraph/bluetooth/include/ng_hci.h +++ b/sys/netgraph/bluetooth/include/ng_hci.h @@ -604,6 +604,8 @@ typedef u_int16_t ng_hci_node_packet_mask_ep; #define NGM_HCI_NODE_SET_ROLE_SWITCH 119 /* User -> HCI */ typedef u_int16_t ng_hci_node_role_switch_ep; +#define NGM_HCI_NODE_LIST_NAMES 200 /* HCI -> User */ + /************************************************************************** ************************************************************************** ** Link control commands and return parameters diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c b/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c index 04bf4262e920..922184a25bf0 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c @@ -257,7 +257,8 @@ ng_btsocket_hci_raw_node_rcvmsg(node_p node, item_p item, hook_p lasthook) */ if (msg != NULL && - msg->header.typecookie == NGM_HCI_COOKIE && + (msg->header.typecookie == NGM_HCI_COOKIE || + msg->header.typecookie == NGM_GENERIC_COOKIE) && msg->header.flags & NGF_RESP) { if (msg->header.token == 0) { NG_FREE_ITEM(item); @@ -1307,6 +1308,68 @@ ng_btsocket_hci_raw_control(struct socket *so, u_long cmd, caddr_t data, error = EPERM; } break; + case SIOC_HCI_RAW_NODE_LIST_NAMES: { + struct ng_btsocket_hci_raw_node_list_names *nl = + (struct ng_btsocket_hci_raw_node_list_names *) data; + struct nodeinfo *ni = nl->names; + + if (nl->num_names == 0) { + error = EINVAL; + break; + } + + NG_MKMESSAGE(msg, NGM_GENERIC_COOKIE, NGM_LISTNAMES, + 0, M_NOWAIT); + if (msg == NULL) { + error = ENOMEM; + break; + } + ng_btsocket_hci_raw_get_token(&msg->header.token); + pcb->token = msg->header.token; + pcb->msg = NULL; + + NG_SEND_MSG_PATH(error, ng_btsocket_hci_raw_node, msg, ".:", 0); + if (error != 0) { + pcb->token = 0; + break; + } + + error = msleep(&pcb->msg, &pcb->pcb_mtx, + PZERO|PCATCH, "hcictl", + ng_btsocket_hci_raw_ioctl_timeout * hz); + pcb->token = 0; + + if (error != 0) + break; + + if (pcb->msg != NULL && pcb->msg->header.cmd == NGM_LISTNAMES) { + /* Return data back to user space */ + struct namelist *nl1 = (struct namelist *) pcb->msg->data; + struct nodeinfo *ni1 = &nl1->nodeinfo[0]; + + while (nl->num_names > 0 && nl1->numnames > 0) { + if (strcmp(ni1->type, NG_HCI_NODE_TYPE) == 0) { + error = copyout((caddr_t) ni1, + (caddr_t) ni, + sizeof(*ni)); + if (error != 0) + break; + + nl->num_names --; + ni ++; + } + + nl1->numnames --; + ni1 ++; + } + + nl->num_names = ni - nl->names; + } else + error = EINVAL; + + NG_FREE_MSG(pcb->msg); /* checks for != NULL */ + } break; + default: error = EINVAL; break; -- cgit v1.3