HCI Connection Handle

 

 

HCI Connection Handle & Transport Layer – – bluetooth development in c
Deep dive into Bluetooth HCI — Connection Handles, UART Transport, Packet Indicators and HCI Packet Decoding
3.5.5
Connection Handle
4
Transport Layers
4
Packet Types

Keywords:

bluetooth development bluetooth programming in c connection handle HCI transport layer HCI UART packet indicator ACL data packet HCI command packet BLE programming

What You Will Learn

Hello students welcome to free bluetooth development course, in this lecture i will explain you about Hci connection handle In the previous sections we covered HCI commands, events, and flow control. Now we go one level deeper — understanding how the HCI layer identifies individual connections using a Connection Handle, and how packets actually travel between the Host and the Controller over a physical transport like UART.

This is essential knowledge for anyone doing Bluetooth programming in C, debugging HCI logs, or building a BlueZ-based application.

3.5.5 — Connection Handle

What Is a Connection Handle?

When the HCI layer establishes a new logical link between the Host and a remote device, it needs a way to refer to that specific connection for all future operations. It does this by assigning a unique Connection Handle.

Think of it like a file descriptor in Linux — once a connection is open, every operation (sending data, polling status, disconnecting) uses this handle instead of the full device address.

Key Rule: The Connection Handle is returned by the Controller inside the Connection_Complete_Event once the connection is successfully established. After that, the Host must use this handle for all subsequent operations on that connection.

Connection Handle — Lifecycle Diagram
  HOST                                             CONTROLLER
  ----                                             ----------

  Send HCI_Create_Connection (BD_ADDR)
  ─────────────────────────────────────────────►

                                                   (starts connection procedure)

                            ◄────────────────────────────────────────────────
                                  Command_Status_Event
                                  (cmd accepted, processing started)

                            ◄────────────────────────────────────────────────
                                  Connection_Complete_Event
                                  {
                                    Status         = 0x00 (success)
                                    Connection_Handle = 0x0040   ← assigned here
                                    BD_ADDR        = AA:BB:CC:DD:EE:FF
                                    Link_Type      = ACL
                                    Encryption     = 0x00
                                  }

  Host stores handle 0x0040
  ─────────────────────────────────────────────►  (send ACL data on handle 0x0040)
  ─────────────────────────────────────────────►  (disconnect on handle 0x0040)
Figure 3.22 — Connection Handle assignment and usage flow

Operations That Use the Connection Handle
Send ACL Data HCI_Disconnect HCI_Read_RSSI HCI_Read_Link_Quality HCI_Authentication_Requested HCI_Set_Connection_Encryption HCI_Change_Connection_Packet_Type

Every one of the above commands takes the Connection_Handle as a parameter so the controller knows which active connection the command targets.

Bluetooth Programming in C — Using the Connection Handle
📄 hci_connection_handle.c
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

/* -------------------------------------------------------
 * The connection handle is a 12-bit value (bits 11:0).
 * Bits 15:14 carry the Packet Boundary Flag and
 * Broadcast Flag in ACL data packets.
 * ------------------------------------------------------- */

#define CONN_HANDLE_MASK  0x0FFF

typedef struct {
    uint16_t  handle;           /* 12-bit connection handle from controller */
    bdaddr_t  remote_addr;      /* BD_ADDR of the remote device             */
    uint8_t   link_type;        /* 0x01 = ACL, 0x00 = SCO                  */
} hci_connection_t;

/* Called when Connection_Complete_Event (0x03) is received */
void on_connection_complete(const uint8_t *evt_buf, hci_connection_t *conn)
{
    /*
     * Connection Complete Event parameter layout:
     *   Byte  0   : Status
     *   Byte  1-2 : Connection_Handle (little-endian, 12 bits used)
     *   Byte  3-8 : BD_ADDR
     *   Byte  9   : Link_Type
     *   Byte  10  : Encryption_Mode
     */
    uint8_t  status = evt_buf[0];
    uint16_t raw_handle;

    if (status != 0x00) {
        printf("[HCI] Connection failed, status=0x%02X\n", status);
        return;
    }

    /* Extract 16-bit value; mask to 12 bits */
    memcpy(&raw_handle, &evt_buf[1], sizeof(raw_handle));
    conn->handle    = raw_handle & CONN_HANDLE_MASK;
    conn->link_type = evt_buf[9];

    /* BD_ADDR is stored LSB first in HCI (little-endian) */
    memcpy(&conn->remote_addr, &evt_buf[3], 6);

    printf("[HCI] Connection established!\n");
    printf("      Handle    : 0x%04X\n", conn->handle);
    printf("      Link Type : %s\n",
           conn->link_type == 0x01 ? "ACL" : "SCO");
}

/* Send HCI_Disconnect using the stored connection handle */
int hci_send_disconnect(int dev_fd, uint16_t conn_handle, uint8_t reason)
{
    /*
     * HCI_Disconnect command (OGF=0x01, OCF=0x0006)
     *   Parameter 1: Connection_Handle  (2 bytes, 12-bit value)
     *   Parameter 2: Reason             (1 byte)
     */
    struct hci_request rq;
    disconnect_cp     cp;
    evt_disconn_complete rp;

    memset(&cp, 0, sizeof(cp));
    cp.handle = htobs(conn_handle);   /* host to BT short (little-endian) */
    cp.reason = reason;               /* 0x13 = Remote User Terminated    */

    memset(&rq, 0, sizeof(rq));
    rq.ogf    = OGF_LINK_CTL;
    rq.ocf    = OCF_DISCONNECT;
    rq.cparam = &cp;
    rq.clen   = DISCONNECT_CP_SIZE;
    rq.rparam = &rp;
    rq.rlen   = EVT_DISCONN_COMPLETE_SIZE;

    if (hci_send_req(dev_fd, &rq, 5000) < 0) {
        perror("hci_send_req (disconnect)");
        return -1;
    }

    printf("[HCI] Disconnect sent for handle 0x%04X\n", conn_handle);
    return 0;
}

int main(void)
{
    int          dev_id  = hci_get_route(NULL);
    int          dev_fd  = hci_open_dev(dev_id);
    hci_connection_t conn;

    if (dev_fd < 0) {
        perror("hci_open_dev");
        return 1;
    }

    printf("[HCI] Device fd=%d opened\n", dev_fd);

    /*
     * In a real program you would:
     *  1. Send HCI_Create_Connection
     *  2. Wait for Connection_Complete_Event in an event loop
     *  3. Call on_connection_complete() to store the handle
     *  4. Use conn.handle for all further operations
     */

    /* Simulating a received Connection_Complete_Event buffer */
    uint8_t mock_evt[] = {
        0x00,               /* Status = Success          */
        0x40, 0x00,         /* Connection_Handle = 0x0040 (little-endian) */
        0xFF,0xEE,0xDD,
        0xCC,0xBB,0xAA,     /* BD_ADDR = AA:BB:CC:DD:EE:FF (reversed)    */
        0x01,               /* Link_Type = ACL           */
        0x00                /* Encryption = disabled     */
    };

    on_connection_complete(mock_evt, &conn);

    /* Now use the handle to disconnect */
    hci_send_disconnect(dev_fd, conn.handle, 0x13);

    hci_close_dev(dev_fd);
    return 0;
}
Important: The Connection Handle is only 12 bits wide (bits 11:0 of the 16-bit field). The upper 4 bits are used for Packet Boundary Flag and Broadcast Flag in ACL data packets. Always mask with 0x0FFF when extracting the handle from a raw HCI buffer.

3.5.6 — HCI Transport Layer

The 4 HCI Transport Layers

The HCI interface does not dictate a single physical connection. The Bluetooth specification defines four standard transport layers so that Host and Controller can be connected in different hardware configurations.

# Transport Layer Common Use Case Type
1 UART (H4) Smartphones, Tablets, SBCs (same PCB) Most Common
2 USB External BT USB dongles on PCs/Laptops Common
3 Secure Digital (SD) SD card form-factor BT modules Rare
4 Three-Wire UART (H5) Reliable UART with ACK/NACK (longer cables) Specialized

UART Transport Layer (H4) — Deep Dive

The UART Transport Layer (also called H4) is by far the most widely used. It is used when the Host CPU and the Bluetooth Controller sit on the same PCB — for example in a Raspberry Pi, an Android smartphone, or a custom embedded board.

Because the two chips are physically close to each other, the UART line is assumed to be error-free. There is no built-in retransmission mechanism — that is why a separate Three-Wire UART (H5) transport was defined for noisy or longer connections.

Error Recovery: If synchronization is lost on the UART line, the Controller sends a Hardware_Error_Event to the Host. The Host must then terminate all pending Bluetooth activity and send an HCI_Reset command to the Controller to restore communication.

3.5.6.1 — Packet Indicators on the UART Bus

Every HCI packet sent over UART is prefixed with a 1-byte Packet Indicator. This is necessary because Commands, Events, and Data packets all share the same UART wire — without an indicator, the receiver would not know what type of packet is arriving.

Packet Indicator HCI Packet Type Direction
0x01 HCI Command Packet Host → Controller
0x02 HCI ACL Data Packet Host ↔ Controller (bidirectional)
0x03 HCI Synchronous (SCO/eSCO) Packet Host ↔ Controller (voice data)
0x04 HCI Event Packet Controller → Host

                    HCI UART TRANSPORT LAYER
    ═══════════════════════════════════════════════════════════

         HOST                              CONTROLLER
    ┌─────────────────┐               ┌─────────────────────┐
    │                 │               │                     │
    │                 │──── 0x01 ────►│  HCI Command Pkt    │
    │                 │               │                     │
    │                 │◄─── 0x04 ────│  HCI Event Pkt      │
    │                 │               │                     │
    │                 │──── 0x02 ────►│  HCI ACL Data Pkt   │
    │                 │◄─── 0x02 ────│  HCI ACL Data Pkt   │
    │                 │               │                     │
    │                 │──── 0x03 ────►│  HCI Sync Data Pkt  │
    │                 │◄─── 0x03 ────│  HCI Sync Data Pkt  │
    │                 │               │                     │
    └─────────────────┘               └─────────────────────┘
           │                                    │
    TX ────┤ UART RX/TX Lines ├─────────────────┤ RX
    RX ────┘                                    └────
Figure 3.19 — HCI UART Packet directions and indicators

Special Case: Smartphones and Voice Data

In many smartphones, HCI Synchronous Data packets (SCO/eSCO) carrying voice are not sent over the UART transport at all. Instead, the Application Processor or Modem has a direct PCM / I²S interface to the Bluetooth chip.

This is more efficient for real-time audio — the voice stream bypasses the HCI UART path entirely, reducing latency and CPU overhead.

    TYPICAL HCI UART CONNECTIONS IN A SMARTPHONE
    ═══════════════════════════════════════════════

    ┌───────────────────────┐         ┌────────────────────────┐
    │  Application          │         │                        │
    │  Processor            │         │   Bluetooth Chip       │
    │                       │         │                        │
    │  ┌─────────────────┐  │         │  ┌──────────────────┐  │
    │  │ Bluetooth Host  │  │◄──UART─►│  │ HCI Transport    │  │
    │  │ Stack (BlueZ)   │  │         │  │ (Cmds+Events+ACL)│  │
    │  └─────────────────┘  │         │  └──────────────────┘  │
    │                       │         │                        │
    │  ┌─────────────────┐  │         │  ┌──────────────────┐  │
    │  │ Cellular Modem  │  │◄─PCM/──►│  │  PCM / I2S       │  │
    │  │ (Voice codec)   │  │  I2S    │  │  Voice Interface │  │
    │  └─────────────────┘  │         │  └──────────────────┘  │
    └───────────────────────┘         └────────────────────────┘

     HCI UART  → Commands, Events, ACL Data
     PCM/I2S   → Voice (SCO/eSCO) packets directly
Figure 3.20 — Typical HCI UART connections in a smartphone

3.5.6.1 — Decoding HCI Packets

Understanding how to manually decode raw HCI bytes is a core skill for Bluetooth debugging. You will use this every time you run btmon, read a Wireshark capture, or parse a UART logic analyser trace.

Let’s walk through the most common exchange — the HCI_Reset command and its Command Complete Event.

Step-by-Step: Decoding HCI_Reset on UART
  ┌──────────────────────────────────────────────────────────────────┐
  │  BYTES ON THE UART WIRE (Host → Controller)                      │
  │                                                                  │
  │   01   03  0C   00                                               │
  │   ──   ───────  ──                                               │
  │   │       │      └── Parameter Total Length = 0 (no params)     │
  │   │       └───────── Opcode = 0x0C03                            │
  │   │                   OGF = 0x03 (HCI Control & Baseband)       │
  │   │                   OCF = 0x0003 (Reset)                      │
  │   └───────────────── Packet Indicator = 0x01 (HCI Command)      │
  └──────────────────────────────────────────────────────────────────┘

  Opcode encoding:
  ┌──────────────────────────────────────────────────────────────────┐
  │  Bits [15:10]  = OGF  (Opcode Group Field)   = 0x03             │
  │  Bits [ 9: 0]  = OCF  (Opcode Command Field) = 0x003            │
  │                                                                  │
  │  Raw value = (OGF << 10) | OCF                                   │
  │            = (0x03 << 10) | 0x003                               │
  │            = 0x0C03  →  stored little-endian as: 03 0C           │
  └──────────────────────────────────────────────────────────────────┘

  ┌──────────────────────────────────────────────────────────────────┐
  │  BYTES ON THE UART WIRE (Controller → Host)                      │
  │                                                                  │
  │   04   0E   04   02   03  0C   00                                │
  │   ──   ──   ──   ──   ───────  ──                                │
  │   │    │    │    │       │      └── Return Parameter(s)          │
  │   │    │    │    │       └───────── Command_Opcode = 0x0C03      │
  │   │    │    │    └───────────────── Num_HCI_Command_Packets = 2  │
  │   │    │    └────────────────────── Param Total Length = 4 bytes │
  │   │    └─────────────────────────── Event Code = 0x0E            │
  │   │                                 (Command Complete Event)     │
  │   └──────────────────────────────── Packet Indicator = 0x04      │
  │                                     (HCI Event Packet)           │
  └──────────────────────────────────────────────────────────────────┘
Figure 3.21 — Annotated HCI_Reset command and Command_Complete_Event bytes

Field-by-Field Breakdown
Byte(s) Hex Value Field Name Meaning
0 0x01 Packet Indicator This is an HCI Command packet
1–2 0x03 0x0C Opcode (little-endian) OGF=0x03, OCF=0x003 → HCI_Reset
3 0x00 Parameter Total Length No parameters follow
↓ Controller Response (Event)
0 0x04 Packet Indicator This is an HCI Event packet
1 0x0E Event Code Command Complete Event
2 0x04 Param Total Length 4 bytes of parameters follow
3 0x02 Num_HCI_Command_Packets Host may now send 2 more commands
4–5 0x03 0x0C Command_Opcode Echoes back 0x0C03 (HCI_Reset)
6 0x00 Return_Parameter Status = 0x00 (Success)

Bluetooth Programming in C — Parsing HCI UART Bytes
📄 hci_uart_decode.c
#include <stdio.h>
#include <stdint.h>
#include <string.h>

/* -------------------------------------------------------
 * Packet Indicators (H4 UART)
 * ------------------------------------------------------- */
#define HCI_COMMAND_PKT   0x01
#define HCI_ACLDATA_PKT   0x02
#define HCI_SCODATA_PKT   0x03
#define HCI_EVENT_PKT     0x04

/* Event codes */
#define EVT_CMD_COMPLETE  0x0E
#define EVT_CMD_STATUS    0x0F

/* OGF values */
#define OGF_LINK_CTL      0x01
#define OGF_HOST_CTL      0x03   /* HCI Control & Baseband */
#define OGF_INFO_PARAM    0x04

/* Opcode helper: pack OGF and OCF into 16-bit opcode */
#define HCI_OPCODE(ogf, ocf)  (((ogf) << 10) | (ocf))

/* Common opcodes */
#define HCI_RESET_OPCODE    HCI_OPCODE(OGF_HOST_CTL, 0x0003)  /* = 0x0C03 */
#define HCI_READ_BD_ADDR    HCI_OPCODE(OGF_INFO_PARAM, 0x0009) /* = 0x1009 */

/* -------------------------------------------------------
 * Build an HCI_Reset command into a buffer.
 * Returns number of bytes written.
 * ------------------------------------------------------- */
int build_hci_reset(uint8_t *buf)
{
    /*
     * HCI Command packet layout:
     *   [0]    Packet Indicator  (1 byte)
     *   [1-2]  Opcode            (2 bytes, little-endian)
     *   [3]    Parameter Length  (1 byte)
     *   [4..N] Parameters        (0 bytes for HCI_Reset)
     */
    buf[0] = HCI_COMMAND_PKT;
    buf[1] = HCI_RESET_OPCODE & 0xFF;         /* low byte  */
    buf[2] = (HCI_RESET_OPCODE >> 8) & 0xFF; /* high byte */
    buf[3] = 0x00;                             /* no params */
    return 4;
}

/* -------------------------------------------------------
 * Parse a raw UART byte stream and print decoded fields.
 * ------------------------------------------------------- */
void decode_hci_packet(const uint8_t *buf, int len)
{
    if (len < 1) {
        printf("[DECODE] Empty buffer\n");
        return;
    }

    uint8_t pkt_indicator = buf[0];

    printf("[DECODE] ─────────────────────────────────────\n");

    switch (pkt_indicator) {

    case HCI_COMMAND_PKT: {
        printf("[DECODE] Packet Type   : HCI Command (0x01)\n");
        if (len < 4) { printf("[DECODE] Truncated!\n"); return; }

        uint16_t opcode = (uint16_t)(buf[1] | (buf[2] << 8));
        uint8_t  ogf    = (opcode >> 10) & 0x3F;
        uint16_t ocf    = opcode & 0x03FF;
        uint8_t  plen   = buf[3];

        printf("[DECODE] Opcode        : 0x%04X  (OGF=0x%02X, OCF=0x%03X)\n",
               opcode, ogf, ocf);
        printf("[DECODE] Param Length  : %d bytes\n", plen);

        if (opcode == HCI_RESET_OPCODE)
            printf("[DECODE] Command Name  : HCI_Reset\n");
        break;
    }

    case HCI_EVENT_PKT: {
        printf("[DECODE] Packet Type   : HCI Event (0x04)\n");
        if (len < 3) { printf("[DECODE] Truncated!\n"); return; }

        uint8_t  event_code = buf[1];
        uint8_t  plen       = buf[2];

        printf("[DECODE] Event Code    : 0x%02X\n", event_code);
        printf("[DECODE] Param Length  : %d bytes\n", plen);

        if (event_code == EVT_CMD_COMPLETE && len >= 7) {
            uint8_t  num_pkts = buf[3];
            uint16_t cmd_op   = (uint16_t)(buf[4] | (buf[5] << 8));
            uint8_t  status   = buf[6];

            printf("[DECODE] Event Name    : Command_Complete\n");
            printf("[DECODE] Num_HCI_Pkts  : %d (host may send %d more cmds)\n",
                   num_pkts, num_pkts);
            printf("[DECODE] Command_Op    : 0x%04X\n", cmd_op);
            printf("[DECODE] Return Status : 0x%02X (%s)\n",
                   status, status == 0 ? "Success" : "Error");
        }
        break;
    }

    case HCI_ACLDATA_PKT: {
        printf("[DECODE] Packet Type   : HCI ACL Data (0x02)\n");
        if (len < 5) { printf("[DECODE] Truncated!\n"); return; }

        uint16_t handle_flags = (uint16_t)(buf[1] | (buf[2] << 8));
        uint16_t conn_handle  = handle_flags & 0x0FFF;
        uint8_t  pb_flag      = (handle_flags >> 12) & 0x03;
        uint8_t  bc_flag      = (handle_flags >> 14) & 0x03;
        uint16_t data_len     = (uint16_t)(buf[3] | (buf[4] << 8));

        printf("[DECODE] Conn Handle   : 0x%04X\n", conn_handle);
        printf("[DECODE] PB Flag       : %d  (0=1st non-frag, 1=cont, 2=1st frag)\n",
               pb_flag);
        printf("[DECODE] BC Flag       : %d  (0=point-to-point)\n", bc_flag);
        printf("[DECODE] Data Length   : %d bytes\n", data_len);
        break;
    }

    case HCI_SCODATA_PKT:
        printf("[DECODE] Packet Type   : HCI SCO/Voice Data (0x03)\n");
        break;

    default:
        printf("[DECODE] Unknown Packet Indicator: 0x%02X\n", pkt_indicator);
        break;
    }
    printf("[DECODE] ─────────────────────────────────────\n\n");
}

/* -------------------------------------------------------
 * Main — demonstrate building and decoding HCI packets
 * ------------------------------------------------------- */
int main(void)
{
    uint8_t tx_buf[16];
    int     tx_len;

    /* 1. Build HCI_Reset command */
    printf("=== Building HCI_Reset Command ===\n");
    tx_len = build_hci_reset(tx_buf);
    printf("Raw bytes: ");
    for (int i = 0; i < tx_len; i++) printf("%02X ", tx_buf[i]);
    printf("\n\n");

    /* 2. Decode the command bytes */
    printf("=== Decoding HCI_Reset Command ===\n");
    decode_hci_packet(tx_buf, tx_len);

    /* 3. Simulate receiving Command_Complete_Event */
    printf("=== Decoding Command_Complete_Event ===\n");
    uint8_t evt_buf[] = { 0x04, 0x0E, 0x04, 0x02, 0x03, 0x0C, 0x00 };
    decode_hci_packet(evt_buf, sizeof(evt_buf));

    /* 4. Simulate receiving an ACL Data packet on handle 0x0040 */
    printf("=== Decoding ACL Data Packet ===\n");
    /*
     * ACL Header:
     *   [0]    Packet Indicator = 0x02
     *   [1-2]  Handle + Flags   = 0x40 | (PB=0x02 << 12) = 0x2040
     *                             little-endian: 40 20
     *   [3-4]  Data Length      = 0x0005 → LE: 05 00
     *   [5-9]  Payload          = 5 bytes of L2CAP data
     */
    uint8_t acl_buf[] = { 0x02, 0x40, 0x20, 0x05, 0x00,
                           0x01, 0x00, 0x04, 0x00, 0x00 };
    decode_hci_packet(acl_buf, sizeof(acl_buf));

    return 0;
}

Compile and Run
💻 Terminal
# Compile (BlueZ development headers required for connection handle example)
gcc -o hci_uart_decode hci_uart_decode.c
./hci_uart_decode

# Expected output:
# === Building HCI_Reset Command ===
# Raw bytes: 01 03 0C 00
#
# === Decoding HCI_Reset Command ===
# [DECODE] Packet Type   : HCI Command (0x01)
# [DECODE] Opcode        : 0x0C03  (OGF=0x03, OCF=0x003)
# [DECODE] Param Length  : 0 bytes
# [DECODE] Command Name  : HCI_Reset
#
# === Decoding Command_Complete_Event ===
# [DECODE] Packet Type   : HCI Event (0x04)
# [DECODE] Event Code    : 0x0E
# [DECODE] Param Length  : 4 bytes
# [DECODE] Event Name    : Command_Complete
# [DECODE] Num_HCI_Pkts  : 2
# [DECODE] Command_Op    : 0x0C03
# [DECODE] Return Status : 0x00 (Success)
#
# For the connection handle example (requires BlueZ headers):
gcc -o hci_conn hci_connection_handle.c -lbluetooth

Quick Reference Summary

  HCI CONCEPTS — QUICK REFERENCE
  ════════════════════════════════════════════════════════════════

  Connection Handle
  ─────────────────
  • Assigned by Controller in Connection_Complete_Event
  • 12-bit value  (bits 11:0 of a 16-bit field)
  • Used for: ACL send, Disconnect, RSSI query, Encryption setup
  • Mask to extract: handle = raw_value & 0x0FFF

  HCI Transport Layers
  ─────────────────────
  • UART  (H4) — Same PCB, no error correction, most common
  • USB        — External dongles
  • SD         — SD card modules
  • UART  (H5) — Three-wire UART with reliability (longer links)

  UART Packet Indicators
  ───────────────────────
  • 0x01 → HCI Command       (Host → Controller)
  • 0x02 → HCI ACL Data      (bidirectional)
  • 0x03 → HCI SCO/eSCO Data (voice, bidirectional)
  • 0x04 → HCI Event         (Controller → Host)

  HCI Command Opcode Structure
  ─────────────────────────────
  • 16-bit value, little-endian on wire
  • Bits [15:10] = OGF   (Opcode Group Field)
  • Bits [ 9: 0] = OCF   (Opcode Command Field)
  • HCI_OPCODE(ogf, ocf) = (ogf << 10) | ocf

  Common Opcodes
  ──────────────
  • 0x0C03  HCI_Reset
  • 0x0406  HCI_Disconnect
  • 0x0409  HCI_Read_RSSI
  • 0x1009  HCI_Read_BD_ADDR
  • 0x2006  LE_Set_Advertising_Parameters
  • 0x200B  LE_Set_Scan_Parameters

Continue Learning Bluetooth

Explore the complete HCI series, BLE protocol stack, and BlueZ internals at EmbeddedPathashala — free for all embedded developers. Hope you have learnt about HCI Connection Handle.

Visit EmbeddedPathashala Bluetooth Course

Leave a Reply

Your email address will not be published. Required fields are marked *