xref: /btstack/src/hci.h (revision 43bfb1bd9ce527929f7260490b797482f1a04ec4)
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 
10ba681a6cSmatthias.ringwald #include "hci_cmds.h"
11ba681a6cSmatthias.ringwald #include "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 
1906b35ec0Smatthias.ringwald /**
2006b35ec0Smatthias.ringwald  * Connection State
2106b35ec0Smatthias.ringwald  */
22c01e9cbdSmatthias.ringwald typedef enum {
23c01e9cbdSmatthias.ringwald     SEND_NEGATIVE_LINK_KEY_REQUEST = 1 << 0,
24c01e9cbdSmatthias.ringwald     SEND_PIN_CODE_RESPONSE = 1 << 1
25c01e9cbdSmatthias.ringwald } hci_connection_flags_t;
26c01e9cbdSmatthias.ringwald 
27c8e4258aSmatthias.ringwald typedef enum {
28c8e4258aSmatthias.ringwald     SENT_CREATE_CONNECTION = 1,
29c8e4258aSmatthias.ringwald     RECEIVED_CONNECTION_REQUEST,
30c8e4258aSmatthias.ringwald     ACCEPTED_CONNECTION_REQUEST,
31c8e4258aSmatthias.ringwald     REJECTED_CONNECTION_REQUEST,
32c8e4258aSmatthias.ringwald     OPEN,
33c8e4258aSmatthias.ringwald     SENT_DISCONNECT
34c8e4258aSmatthias.ringwald } CONNECTION_STATE;
35c8e4258aSmatthias.ringwald 
36*43bfb1bdSmatthias.ringwald typedef enum {
37*43bfb1bdSmatthias.ringwald     BLUETOOTH_OFF = 1,
38*43bfb1bdSmatthias.ringwald     BLUETOOTH_ON,
39*43bfb1bdSmatthias.ringwald     BLUETOOTH_ACTIVE
40*43bfb1bdSmatthias.ringwald } BLUETOOTH_STATE;
41*43bfb1bdSmatthias.ringwald 
42c8e4258aSmatthias.ringwald typedef struct {
4306b35ec0Smatthias.ringwald     // linked list - assert: first field
4406b35ec0Smatthias.ringwald     linked_item_t    item;
45c01e9cbdSmatthias.ringwald 
46c01e9cbdSmatthias.ringwald     // remote side
4716833f0aSmatthias.ringwald     bd_addr_t address;
4806b35ec0Smatthias.ringwald 
4906b35ec0Smatthias.ringwald     // module handle
5016833f0aSmatthias.ringwald     hci_con_handle_t con_handle;
51c01e9cbdSmatthias.ringwald 
52c8e4258aSmatthias.ringwald     // state
53c8e4258aSmatthias.ringwald     CONNECTION_STATE state;
54c8e4258aSmatthias.ringwald 
5506b35ec0Smatthias.ringwald     // errands
56c01e9cbdSmatthias.ringwald     hci_connection_flags_t flags;
57c8e4258aSmatthias.ringwald 
58ee091cf1Smatthias.ringwald     // timer
59ee091cf1Smatthias.ringwald     timer_t timeout;
60ee091cf1Smatthias.ringwald     struct timeval timestamp;
61ee091cf1Smatthias.ringwald 
6216833f0aSmatthias.ringwald } hci_connection_t;
6316833f0aSmatthias.ringwald 
6406b35ec0Smatthias.ringwald /**
6506b35ec0Smatthias.ringwald  * main data structure
6606b35ec0Smatthias.ringwald  */
6716833f0aSmatthias.ringwald typedef struct {
6806b35ec0Smatthias.ringwald     // transport component with configuration
6916833f0aSmatthias.ringwald     hci_transport_t  * hci_transport;
7011e23e5fSmatthias.ringwald     void             * config;
7111e23e5fSmatthias.ringwald 
7206b35ec0Smatthias.ringwald     // hardware power controller
7306b35ec0Smatthias.ringwald     bt_control_t     * control;
7406b35ec0Smatthias.ringwald 
7506b35ec0Smatthias.ringwald     // list of existing baseband connections
76fe1ed1b8Smatthias.ringwald     linked_list_t     connections;
7716833f0aSmatthias.ringwald 
7806b35ec0Smatthias.ringwald     // single buffer for HCI Command assembly
7906b35ec0Smatthias.ringwald     uint8_t          * hci_cmd_buffer;
8006b35ec0Smatthias.ringwald 
8116833f0aSmatthias.ringwald     /* host to controller flow control */
8216833f0aSmatthias.ringwald     uint8_t  num_cmd_packets;
8316833f0aSmatthias.ringwald     uint8_t  num_acl_packets;
8416833f0aSmatthias.ringwald 
8516833f0aSmatthias.ringwald     /* callback to L2CAP layer */
861cd208adSmatthias.ringwald     void (*event_packet_handler)(uint8_t *packet, uint16_t size);
871cd208adSmatthias.ringwald     void (*acl_packet_handler)  (uint8_t *packet, uint16_t size);
8816833f0aSmatthias.ringwald 
893429f56bSmatthias.ringwald     /* hci state machine */
903429f56bSmatthias.ringwald     HCI_STATE state;
913429f56bSmatthias.ringwald     uint8_t   substate;
923429f56bSmatthias.ringwald     uint8_t   cmds_ready;
933429f56bSmatthias.ringwald 
9416833f0aSmatthias.ringwald } hci_stack_t;
9516833f0aSmatthias.ringwald 
96475c8125Smatthias.ringwald // set up HCI
9711e23e5fSmatthias.ringwald void hci_init(hci_transport_t *transport, void *config, bt_control_t *control);
98475c8125Smatthias.ringwald 
991cd208adSmatthias.ringwald void hci_register_event_packet_handler(void (*handler)(uint8_t *packet, uint16_t size));
10016833f0aSmatthias.ringwald 
1011cd208adSmatthias.ringwald void hci_register_acl_packet_handler  (void (*handler)(uint8_t *packet, uint16_t size));
10216833f0aSmatthias.ringwald 
103475c8125Smatthias.ringwald // power control
104475c8125Smatthias.ringwald int hci_power_control(HCI_POWER_MODE mode);
105475c8125Smatthias.ringwald 
1063429f56bSmatthias.ringwald /**
107c8e4258aSmatthias.ringwald  * run the hci control loop once
1083429f56bSmatthias.ringwald  */
10906b35ec0Smatthias.ringwald void hci_run();
1101f504dbdSmatthias.ringwald 
1111cd208adSmatthias.ringwald // create and send hci command packets based on a template and a list of parameters
11202ea9861Smatthias.ringwald int hci_send_cmd(hci_cmd_t *cmd, ...);
113d8905019Smatthias.ringwald 
114d8905019Smatthias.ringwald // send complete CMD packet
11549857181Smatthias.ringwald int hci_send_cmd_packet(uint8_t *packet, int size);
116554588a5Smatthias.ringwald 
11743625864Smatthias.ringwald // send ACL packet
11843625864Smatthias.ringwald int hci_send_acl_packet(uint8_t *packet, int size);
11906b35ec0Smatthias.ringwald 
12006b35ec0Smatthias.ringwald //
1211e6aba47Smatthias.ringwald void hci_emit_state();
122c8e4258aSmatthias.ringwald void hci_emit_connection_complete(hci_connection_t *conn);
123ee091cf1Smatthias.ringwald void hci_emit_l2cap_check_timeout(hci_connection_t *conn);
124*43bfb1bdSmatthias.ringwald void hci_emit_nr_connections_changed();
125