diff options
-rw-r--r-- | sys/netgraph/bluetooth/include/ng_btsocket.h | 9 | ||||
-rw-r--r-- | sys/netgraph/bluetooth/include/ng_hci.h | 2 | ||||
-rw-r--r-- | sys/netgraph/bluetooth/socket/ng_btsocket_hci_raw.c | 65 |
3 files changed, 75 insertions, 1 deletions
diff --git a/sys/netgraph/bluetooth/include/ng_btsocket.h b/sys/netgraph/bluetooth/include/ng_btsocket.h index 01822e3..7dc309a 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 b2d6da6..5cdfd5c 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 04bf426..922184a 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; |