xref: /btstack/src/hci.h (revision 80d52d6be7321bc40d8ef8c4ea2a1afbfbed435b)
11f504dbdSmatthias.ringwald /*
21f504dbdSmatthias.ringwald  *  hci.h
31f504dbdSmatthias.ringwald  *
41f504dbdSmatthias.ringwald  *  Created by Matthias Ringwald on 4/29/09.
51f504dbdSmatthias.ringwald  *
61f504dbdSmatthias.ringwald  */
71f504dbdSmatthias.ringwald 
81f504dbdSmatthias.ringwald #pragma once
91f504dbdSmatthias.ringwald 
1023053b9eSmatthias.ringwald #include <btstack/hci_cmds.h>
1123053b9eSmatthias.ringwald #include <btstack/utils.h>
12ba681a6cSmatthias.ringwald #include "hci_transport.h"
13ba681a6cSmatthias.ringwald #include "bt_control.h"
14ba681a6cSmatthias.ringwald 
1593b8dc03Smatthias.ringwald #include <stdint.h>
1602ea9861Smatthias.ringwald #include <stdlib.h>
171cd208adSmatthias.ringwald #include <stdarg.h>
1893b8dc03Smatthias.ringwald 
19*80d52d6bSmatthias.ringwald // packet header lenghts
20*80d52d6bSmatthias.ringwald #define HCI_CMD_DATA_PKT_HDR	  0x03
21*80d52d6bSmatthias.ringwald #define HCI_ACL_DATA_PKT_HDR	  0x04
22*80d52d6bSmatthias.ringwald #define HCI_SCO_DATA_PKT_HDR	  0x03
23*80d52d6bSmatthias.ringwald #define HCI_EVENT_PKT_HDR         0x02
24*80d52d6bSmatthias.ringwald 
25*80d52d6bSmatthias.ringwald 
26*80d52d6bSmatthias.ringwald // cmds for BTstack
27*80d52d6bSmatthias.ringwald // get state: @returns HCI_STATE
28*80d52d6bSmatthias.ringwald #define BTSTACK_GET_STATE                                  0x01
29*80d52d6bSmatthias.ringwald 
30*80d52d6bSmatthias.ringwald // set power mode: @param HCI_POWER_MODE
31*80d52d6bSmatthias.ringwald #define BTSTACK_SET_POWER_MODE                             0x02
32*80d52d6bSmatthias.ringwald 
33*80d52d6bSmatthias.ringwald // set capture mode: @param on
34*80d52d6bSmatthias.ringwald #define BTSTACK_SET_ACL_CAPTURE_MODE                       0x03
35*80d52d6bSmatthias.ringwald 
36*80d52d6bSmatthias.ringwald // create l2cap channel: @param bd_addr(48), psm (16)
37*80d52d6bSmatthias.ringwald #define L2CAP_CREATE_CHANNEL                               0x20
38*80d52d6bSmatthias.ringwald 
39*80d52d6bSmatthias.ringwald // disconnect l2cap disconnect, @param channel(16), reason(8)
40*80d52d6bSmatthias.ringwald #define L2CAP_DISCONNECT                                   0x21
41*80d52d6bSmatthias.ringwald 
42*80d52d6bSmatthias.ringwald //
43*80d52d6bSmatthias.ringwald #define IS_COMMAND(packet, command) (READ_BT_16(packet,0) == command.opcode)
44*80d52d6bSmatthias.ringwald 
4506b35ec0Smatthias.ringwald /**
4606b35ec0Smatthias.ringwald  * Connection State
4706b35ec0Smatthias.ringwald  */
48c01e9cbdSmatthias.ringwald typedef enum {
49c01e9cbdSmatthias.ringwald     SEND_NEGATIVE_LINK_KEY_REQUEST = 1 << 0,
50c01e9cbdSmatthias.ringwald     SEND_PIN_CODE_RESPONSE = 1 << 1
51c01e9cbdSmatthias.ringwald } hci_connection_flags_t;
52c01e9cbdSmatthias.ringwald 
53c8e4258aSmatthias.ringwald typedef enum {
54c8e4258aSmatthias.ringwald     SENT_CREATE_CONNECTION = 1,
55c8e4258aSmatthias.ringwald     RECEIVED_CONNECTION_REQUEST,
56c8e4258aSmatthias.ringwald     ACCEPTED_CONNECTION_REQUEST,
57c8e4258aSmatthias.ringwald     REJECTED_CONNECTION_REQUEST,
58c8e4258aSmatthias.ringwald     OPEN,
59c8e4258aSmatthias.ringwald     SENT_DISCONNECT
60c8e4258aSmatthias.ringwald } CONNECTION_STATE;
61c8e4258aSmatthias.ringwald 
6243bfb1bdSmatthias.ringwald typedef enum {
6343bfb1bdSmatthias.ringwald     BLUETOOTH_OFF = 1,
6443bfb1bdSmatthias.ringwald     BLUETOOTH_ON,
6543bfb1bdSmatthias.ringwald     BLUETOOTH_ACTIVE
6643bfb1bdSmatthias.ringwald } BLUETOOTH_STATE;
6743bfb1bdSmatthias.ringwald 
68c8e4258aSmatthias.ringwald typedef struct {
6906b35ec0Smatthias.ringwald     // linked list - assert: first field
7006b35ec0Smatthias.ringwald     linked_item_t    item;
71c01e9cbdSmatthias.ringwald 
72c01e9cbdSmatthias.ringwald     // remote side
7316833f0aSmatthias.ringwald     bd_addr_t address;
7406b35ec0Smatthias.ringwald 
7506b35ec0Smatthias.ringwald     // module handle
7616833f0aSmatthias.ringwald     hci_con_handle_t con_handle;
77c01e9cbdSmatthias.ringwald 
78c8e4258aSmatthias.ringwald     // state
79c8e4258aSmatthias.ringwald     CONNECTION_STATE state;
80c8e4258aSmatthias.ringwald 
8106b35ec0Smatthias.ringwald     // errands
82c01e9cbdSmatthias.ringwald     hci_connection_flags_t flags;
83c8e4258aSmatthias.ringwald 
84ee091cf1Smatthias.ringwald     // timer
85ee091cf1Smatthias.ringwald     timer_t timeout;
86ee091cf1Smatthias.ringwald     struct timeval timestamp;
87ee091cf1Smatthias.ringwald 
8816833f0aSmatthias.ringwald } hci_connection_t;
8916833f0aSmatthias.ringwald 
9006b35ec0Smatthias.ringwald /**
9106b35ec0Smatthias.ringwald  * main data structure
9206b35ec0Smatthias.ringwald  */
9316833f0aSmatthias.ringwald typedef struct {
9406b35ec0Smatthias.ringwald     // transport component with configuration
9516833f0aSmatthias.ringwald     hci_transport_t  * hci_transport;
9611e23e5fSmatthias.ringwald     void             * config;
9711e23e5fSmatthias.ringwald 
9806b35ec0Smatthias.ringwald     // hardware power controller
9906b35ec0Smatthias.ringwald     bt_control_t     * control;
10006b35ec0Smatthias.ringwald 
10106b35ec0Smatthias.ringwald     // list of existing baseband connections
102fe1ed1b8Smatthias.ringwald     linked_list_t     connections;
10316833f0aSmatthias.ringwald 
10406b35ec0Smatthias.ringwald     // single buffer for HCI Command assembly
10506b35ec0Smatthias.ringwald     uint8_t          * hci_cmd_buffer;
10606b35ec0Smatthias.ringwald 
10716833f0aSmatthias.ringwald     /* host to controller flow control */
10816833f0aSmatthias.ringwald     uint8_t  num_cmd_packets;
10916833f0aSmatthias.ringwald     uint8_t  num_acl_packets;
11016833f0aSmatthias.ringwald 
11116833f0aSmatthias.ringwald     /* callback to L2CAP layer */
1121cd208adSmatthias.ringwald     void (*event_packet_handler)(uint8_t *packet, uint16_t size);
1131cd208adSmatthias.ringwald     void (*acl_packet_handler)  (uint8_t *packet, uint16_t size);
11416833f0aSmatthias.ringwald 
1153429f56bSmatthias.ringwald     /* hci state machine */
1163429f56bSmatthias.ringwald     HCI_STATE state;
1173429f56bSmatthias.ringwald     uint8_t   substate;
1183429f56bSmatthias.ringwald     uint8_t   cmds_ready;
1193429f56bSmatthias.ringwald 
12016833f0aSmatthias.ringwald } hci_stack_t;
12116833f0aSmatthias.ringwald 
122475c8125Smatthias.ringwald // set up HCI
12311e23e5fSmatthias.ringwald void hci_init(hci_transport_t *transport, void *config, bt_control_t *control);
124475c8125Smatthias.ringwald 
1251cd208adSmatthias.ringwald void hci_register_event_packet_handler(void (*handler)(uint8_t *packet, uint16_t size));
12616833f0aSmatthias.ringwald 
1271cd208adSmatthias.ringwald void hci_register_acl_packet_handler  (void (*handler)(uint8_t *packet, uint16_t size));
12816833f0aSmatthias.ringwald 
129475c8125Smatthias.ringwald // power control
130475c8125Smatthias.ringwald int hci_power_control(HCI_POWER_MODE mode);
131475c8125Smatthias.ringwald 
1323429f56bSmatthias.ringwald /**
133c8e4258aSmatthias.ringwald  * run the hci control loop once
1343429f56bSmatthias.ringwald  */
13506b35ec0Smatthias.ringwald void hci_run();
1361f504dbdSmatthias.ringwald 
1371cd208adSmatthias.ringwald // create and send hci command packets based on a template and a list of parameters
13802ea9861Smatthias.ringwald int hci_send_cmd(hci_cmd_t *cmd, ...);
139d8905019Smatthias.ringwald 
140d8905019Smatthias.ringwald // send complete CMD packet
14149857181Smatthias.ringwald int hci_send_cmd_packet(uint8_t *packet, int size);
142554588a5Smatthias.ringwald 
14343625864Smatthias.ringwald // send ACL packet
14443625864Smatthias.ringwald int hci_send_acl_packet(uint8_t *packet, int size);
14506b35ec0Smatthias.ringwald 
14606b35ec0Smatthias.ringwald //
1471e6aba47Smatthias.ringwald void hci_emit_state();
148c8e4258aSmatthias.ringwald void hci_emit_connection_complete(hci_connection_t *conn);
149ee091cf1Smatthias.ringwald void hci_emit_l2cap_check_timeout(hci_connection_t *conn);
15043bfb1bdSmatthias.ringwald void hci_emit_nr_connections_changed();
151038bc64cSmatthias.ringwald void hci_emit_hci_open_failed();
152