NG_HCI(4)

πŸ’– NG_HCI πŸ’–

ng_hci β€” a Netgraph node type that is also a Bluetooth Host Controller Interface (HCI) layer. yes bestie, it's section 4 of the manual and it's doing two jobs at once and honestly? iconic πŸ’…


🌸 NAME 🌸

ng_hci β€” the Netgraph node type that is also a Bluetooth Host Controller Interface (HCI) layer. she contains multitudes fr fr πŸ¦‹


✨ SYNOPSIS ✨

#include <sys/types.h>
#include <netgraph/bluetooth/include/ng_hci.h>

πŸŽ€ DESCRIPTION πŸŽ€

okay so the hci node type is a Netgraph node type that implements the Bluetooth Host Controller Interface (HCI) layer, exactly as laid out in chapter H1 of the Bluetooth Specification Book v1.1. no cap, that's the spec she's following πŸ“–βœ¨


🌈 INTRODUCTION TO BLUETOOTH 🌈

Bluetooth is a short-range radio link whose whole entire purpose is to replace the cable(s) connecting portable and/or fixed electronic devices. she operates in the unlicensed ISM band at 2.4 GHz. the Bluetooth protocol uses a combination of circuit and packet switching. Bluetooth can support an asynchronous data channel, up to three simultaneous synchronous voice channels, or a channel that simultaneously supports asynchronous data and synchronous voice. each voice channel supports a 64 kb/s synchronous (voice) channel in each direction. the asynchronous channel can support maximal 723.2 kb/s asymmetric (and still up to 57.6 kb/s in the return direction), or 433.9 kb/s symmetric. numbers! we love numbers 🫢

The Bluetooth system provides a point-to-point connection (only two Bluetooth units involved), or a point-to-multipoint connection. in the point-to-multipoint connection, the channel is shared among several Bluetooth units. two or more units sharing the same channel form a β€œpiconet” 🫧. one Bluetooth unit acts as the master of the piconet, whereas the other unit(s) act as slave(s). up to seven slaves can be active in the piconet. in addition, many more slaves can remain locked to the master in a so-called parked state. these parked slaves cannot be active on the channel, but they remain synchronized to the master. both for active and parked slaves, the channel access is controlled by the master. it's giving monarchy but make it wireless πŸ‘‘

Multiple piconets with overlapping coverage areas form a β€œscatternet”. each piconet can only have a single master. however, slaves can participate in different piconets on a time-division multiplex basis. in addition, a master in one piconet can be a slave in another piconet. the piconets shall not be frequency-synchronized. each piconet has its own hopping channel πŸ¦‹

⏰ Time Slots ⏰

the channel is divided into time slots, each 625 usec in length. the time slots are numbered according to the Bluetooth clock of the piconet master. the slot numbering ranges from 0 to 2^27 -1 and is cyclic with a cycle length of 2^27. in the time slots, master and slave can transmit packets. ticking like a little clock, obsessed ⏳

the SCO link is a symmetric, point-to-point link between the master and a specific slave. the SCO link reserves slots and can therefore be considered as a circuit-switched connection between the master and the slave. the SCO link typically supports time-bounded information like voice. the master can support up to three SCO links to the same slave or to different slaves. a slave can support up to three SCO links from the same master, or two SCO links if the links originate from different masters. SCO packets are never retransmitted. periodt πŸ’€

in the slots not reserved for SCO links, the master can exchange packets with any slave on a per-slot basis. the ACL link provides a packet-switched connection between the master and all active slaves participating in the piconet. both asynchronous and isochronous services are supported. between a master and a slave only a single ACL link can exist. for most ACL packets, packet retransmission is applied to assure data integrity. she retries so you don't have to πŸ™ˆ


πŸ‘‘ HOST CONTROLLER INTERFACE (HCI) πŸ‘‘

the HCI provides a command interface to the baseband controller and link manager, and access to hardware status and control registers. this interface provides a uniform method of accessing the Bluetooth baseband capabilities. one interface to rule them all ✨

The HCI layer on the Host exchanges data and commands with the HCI firmware on the Bluetooth hardware. the Host Controller Transport Layer (i.e., physical bus) driver provides both HCI layers with the ability to exchange information with each other.

The Host will receive asynchronous notifications of HCI events independent of which Host Controller Transport Layer is used. HCI events are used for notifying the Host when something occurs. when the Host discovers that an event has occurred it will then parse the received event packet to determine which event occurred. the next sections specify the HCI packet formats πŸ‘‡

🧾 HCI Command Packet 🧾

#define NG_HCI_CMD_PKT 0x01
typedef struct {
        uint8_t  type;   /* MUST be 0x1 */
        uint16_t opcode; /* OpCode */
        uint8_t  length; /* parameter(s) length in bytes */
} __attribute__ ((packed)) ng_hci_cmd_pkt_t;

The HCI command packet is used to send commands to the Host Controller from the Host. when the Host Controller completes most of the commands, a Command Complete event is sent to the Host. some commands do not receive a Command Complete event when they have been completed. instead, when the Host Controller receives one of these commands the Host Controller sends a Command Status event back to the Host when it has begun to execute the command. later on, when the actions associated with the command have finished, an event that is associated with the sent command will be sent by the Host Controller to the Host. two-step confirmation, very "read at 2:34pm" of her πŸ“±

πŸ”” HCI Event Packet πŸ””

#define NG_HCI_EVENT_PKT 0x04
typedef struct {
        uint8_t type;   /* MUST be 0x4 */
        uint8_t event;  /* event */
        uint8_t length; /* parameter(s) length in bytes */
} __attribute__ ((packed)) ng_hci_event_pkt_t;

The HCI event packet is used by the Host Controller to notify the Host when events occur. it's literally just her texting you "hey something happened" πŸ’¬

πŸ“¨ HCI ACL Data Packet πŸ“¨

#define NG_HCI_ACL_DATA_PKT 0x02
typedef struct {
        uint8_t  type;       /* MUST be 0x2 */
        uint16_t con_handle; /* connection handle + PB + BC flags */
        uint16_t length;     /* payload length in bytes */
} __attribute__ ((packed)) ng_hci_acldata_pkt_t;

HCI ACL data packets are used to exchange ACL data between the Host and Host Controller 🫢

πŸŽ™οΈ HCI SCO Data Packet πŸŽ™οΈ

#define NG_HCI_SCO_DATA_PKT 0x03
typedef struct {
        uint8_t  type;       /* MUST be 0x3 */
        uint16_t con_handle; /* connection handle + reserved bits */
        uint8_t  length;     /* payload length in bytes */
} __attribute__ ((packed)) ng_hci_scodata_pkt_t;

HCI SCO data packets are used to exchange SCO data between the Host and Host Controller 🎧


🌱 HCI INITIALIZATION 🌱

on initialization, the HCI control application must issue the following HCI commands (in any order β€” she's flexible like that πŸ’…):

  • Read_BD_ADDR β€” to obtain the BD_ADDR of the Bluetooth unit.
  • Read_Local_Supported_Features β€” to obtain the list of features supported by the Bluetooth unit.
  • Read_Buffer_Size β€” to determine the maximum size of HCI ACL and SCO HCI data packets (excluding header) that can be sent from the Host to the Host Controller. there are also two additional return parameters that specify the total number of HCI ACL and SCO data packets that the Host Controller can have waiting for transmission in its buffers.

as soon as HCI initialization has been successfully performed, the HCI control application must turn on the β€œinited” bit for the node. once the HCI node has been initialized all upstream hooks will receive a NGM_HCI_NODE_UP Netgraph message defined as follows ✨

#define NGM_HCI_NODE_UP 112 /* HCI -> Upper */
typedef struct {
        uint16_t  pkt_size; /* max. ACL/SCO packet size (w/o hdr) */
        uint16_t  num_pkts; /* ACL/SCO packet queue size */
        uint16_t  reserved; /* place holder */
        bdaddr_t  bdaddr;   /* bdaddr */
} ng_hci_node_up_ep;

🚦 HCI FLOW CONTROL 🚦

the HCI layer performs flow control on a baseband connection basis (i.e., ACL and SCO link). each baseband connection has a β€œconnection handle” and a queue of outgoing data packets. upper layers protocols are allowed to send up to (num_pkts - pending) packets at one time. the HCI layer will send NGM_HCI_SYNC_CON_QUEUE Netgraph messages to inform upper layers about the current queue state for each connection handle. the NGM_HCI_SYNC_CON_QUEUE Netgraph message is defined as follows πŸ“¬

#define NGM_HCI_SYNC_CON_QUEUE 113 /* HCI -> Upper */
typedef struct {
        uint16_t con_handle; /* connection handle */
        uint16_t completed;  /* number of completed packets */
} ng_hci_sync_con_queue_ep;

πŸͺ HOOKS πŸͺ

this node type supports the following hooks:

  • drv β€” the Bluetooth Host Controller Transport Layer hook. single HCI packet contained in single mbuf structure.
  • acl β€” upper layer protocol/node is connected to the hook. single HCI ACL data packet contained in single mbuf structure.
  • sco β€” upper layer protocol/node is connected to the hook. single HCI SCO data packet contained in single mbuf structure.
  • raw β€” raw hook. every HCI frame (including HCI command frame) that goes in or out will be delivered to the hook. usually the Bluetooth raw HCI socket layer is connected to the hook. single HCI frame contained in single mbuf structure. the voyeur hook, no cap πŸ‘€

πŸ’œ BLUETOOTH UPPER LAYER PROTOCOLS INTERFACE (LP CONTROL MESSAGES) πŸ’œ

  • NGM_HCI_LP_CON_REQ β€” requests the lower protocol to create a connection. if a physical link to the remote device does not exist, this message must be sent to the lower protocol (baseband) to establish the physical connection.
  • NGM_HCI_LP_DISCON_REQ β€” requests the lower protocol (baseband) to terminate a connection.
  • NGM_HCI_LP_CON_CFM β€” confirms success or failure of the NGM_HCI_LP_CON_REQ request to establish a lower layer (baseband) connection. this includes passing the authentication challenge if authentication is required to establish the physical link.
  • NGM_HCI_LP_CON_IND β€” indicates the lower protocol (baseband) has successfully established an incoming connection.
  • NGM_HCI_LP_CON_RSP β€” a response accepting or rejecting the previous connection indication request.
  • NGM_HCI_LP_DISCON_IND β€” indicates the lower protocol (baseband) has terminated connection. this could be a response to NGM_HCI_LP_DISCON_REQ or a timeout event.
  • NGM_HCI_LP_QOS_REQ β€” requests the lower protocol (baseband) to accommodate a particular QoS parameter set.
  • NGM_HCI_LP_QOS_CFM β€” confirms success or failure of the request for a given quality of service.
  • NGM_HCI_LP_QOS_IND β€” indicates the lower protocol (baseband) has detected a violation of the QoS agreement. she caught you slippin' 🚨

🌸 NETGRAPH CONTROL MESSAGES 🌸

So this node type is a social node β€” it speaks the generic control messages like everyone else, plus it's got its own little collection of extra ones. Here's the whole lineup, no skips, no cap:

  • NGM_HCI_NODE_GET_STATE β€” hands you the current state of the node. like, what's the vibe rn.
  • NGM_HCI_NODE_INIT β€” flips the β€œinited” bit on for this node. turning it up fr.
  • NGM_HCI_NODE_GET_DEBUG β€” gives you back an integer with the node's current debug level.
  • NGM_HCI_NODE_SET_DEBUG β€” takes an integer argument and sets the current debug level for the node. dial that dial πŸ’…
  • NGM_HCI_NODE_GET_BUFFER β€” returns the current state of the data buffers.
  • NGM_HCI_NODE_GET_BDADDR β€” returns the BD_ADDR exactly as it's cached in the node.
  • NGM_HCI_NODE_GET_FEATURES β€” returns the list of features your hardware supports (as cached by the node, bestie).
  • NGM_HCI_NODE_GET_NEIGHBOR_CACHE β€” returns the contents of the neighbor cache.
  • NGM_HCI_NODE_FLUSH_NEIGHBOR_CACHE β€” removes all the neighbor cache entries. gone. bye. ✨
  • NGM_HCI_NODE_GET_CON_LIST β€” returns the list of active baseband connections (that's ACL and SCO links, iykyk).
  • NGM_HCI_NODE_GET_STAT β€” returns the various statistic counters.
  • NGM_HCI_NODE_RESET_STAT β€” resets all those statistic counters back to zero. fresh start energy πŸ”₯
  • NGM_HCI_NODE_SET_LINK_POLICY_SETTINGS_MASK β€” sets the current link policy settings mask. Here's the tea: after a new ACL connection gets created, the HCI node will try to set the link policy for that ACL connection. By default, every supported Link Manager (LM) mode is enabled. You can override that by setting the link policy settings mask, which specifies which LM modes get enabled.
  • NGM_HCI_NODE_GET_LINK_POLICY_SETTINGS_MASK β€” returns the current link policy settings mask.
  • NGM_HCI_NODE_SET_PACKET_MASK β€” sets the current packet mask. When a new baseband connection (ACL or SCO) is created, the HCI node will specify every packet type supported by the device. You can override this by setting the packet mask, which specifies which packet types get used for new baseband connections.
  • NGM_HCI_NODE_GET_PACKET_MASK β€” returns the current packet mask.
  • NGM_HCI_NODE_SET_ROLE_SWITCH β€” sets the value of the role switch. Role switch is enabled when this value is not zero β€” and that's the default state, btw. Just know that an actual role switch at the Bluetooth link level only happens if the hardware supports role switch and it was enabled. so like, no promises 🫢
  • NGM_HCI_NODE_GET_ROLE_SWITCH β€” returns the value of the role switch for the node.

πŸ¦‹ SHUTDOWN πŸ¦‹

This node shuts down when it receives an NGM_SHUTDOWN control message, or when all the hooks have been disconnected. it's giving "we're done here" πŸ’€


πŸ‘‘ SEE ALSO πŸ‘‘


⭐ HISTORY ⭐

The hci node type was implemented in FreeBSD 5.0. an icon, honestly.


πŸ’– AUTHORS πŸ’–

Maksim Yevmenkin <m_evmenkin@yahoo.com> β€” thank you for your service, legend 🫑


πŸ™ˆ BUGS πŸ™ˆ

Most likely. Please report if found. (not the vaguest bug section I've ever seen, but close πŸ’€)


okay that's the whole page bestie, you're officially certified in NG_HCI β€” go forth and connect some Bluetooth devices, slay ✨

πŸ’… this one's from the Debian manual pages, dated June 25, 2002 β€” yes, she's vintage, and she ATE πŸ’…

πŸ“¦ where this page comes from