1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
//! System native types and constants.
#![allow(dead_code)]

use libc::{c_int, c_ushort, sa_family_t};
use nix::{request_code_write, sys::ioctl::ioctl_num_type};
use std::mem::size_of;

pub const SOL_L2CAP: i32 = 6;
pub const SOL_RFCOMM: i32 = 18;

/// Bluetooth security.
#[repr(C)]
#[derive(Clone)]
pub struct bt_security {
    /// Level.
    pub level: u8,
    /// Key size.
    pub key_size: u8,
}

pub const BT_SECURITY: i32 = 4;
pub const BT_SECURITY_SDP: i32 = 0;
pub const BT_SECURITY_LOW: i32 = 1;
pub const BT_SECURITY_MEDIUM: i32 = 2;
pub const BT_SECURITY_HIGH: i32 = 3;
pub const BT_SECURITY_FIPS: i32 = 4;

#[repr(C)]
#[derive(Clone)]
pub struct bt_power {
    pub force_active: u8,
}

pub const BT_POWER: i32 = 9;
pub const BT_POWER_FORCE_ACTIVE_OFF: i32 = 0;
pub const BT_POWER_FORCE_ACTIVE_ON: i32 = 1;

pub const BT_SNDMTU: i32 = 12;
pub const BT_RCVMTU: i32 = 13;
pub const BT_PHY: i32 = 14;
pub const BT_MODE: i32 = 15;

/// BR1M1SLOT PHY.
pub const BR1M1SLOT: i32 = 1 << 0;
/// BR1M3SLOT PHY.
pub const BR1M3SLOT: i32 = 1 << 1;
/// BR1M5SLOT PHY.
pub const BR1M5SLOT: i32 = 1 << 2;
/// EDR2M1SLOT PHY.
pub const EDR2M1SLOT: i32 = 1 << 3;
/// EDR2M3SLOT PHY.
pub const EDR2M3SLOT: i32 = 1 << 4;
/// EDR2M5SLOT PHY.
pub const EDR2M5SLOT: i32 = 1 << 5;
/// EDR3M1SLOT PHY.
pub const EDR3M1SLOT: i32 = 1 << 6;
/// EDR3M3SLOT PHY.
pub const EDR3M3SLOT: i32 = 1 << 7;
/// EDR3M5SLOT PHY.
pub const EDR3M5SLOT: i32 = 1 << 8;
/// LE1MTX PHY.
pub const LE1MTX: i32 = 1 << 9;
/// LE1MRX PHY.
pub const LE1MRX: i32 = 1 << 10;
/// LE2MTX PHY.
pub const LE2MTX: i32 = 1 << 11;
/// LE2MRX PHY.
pub const LE2MRX: i32 = 1 << 12;
/// LECODEDTX PHY.
pub const LECODEDTX: i32 = 1 << 13;
/// LECODEDRX PHY.
pub const LECODEDRX: i32 = 1 << 14;

pub const BTPROTO_L2CAP: i32 = 0;
pub const BTPROTO_RFCOMM: i32 = 3;

/// Bluetooth address.
#[repr(packed)]
#[repr(C)]
#[derive(Clone, Default)]
pub struct bdaddr_t {
    pub b: [u8; 6],
}

pub const BDADDR_BREDR: u8 = 0x00;
pub const BDADDR_LE_PUBLIC: u8 = 0x01;
pub const BDADDR_LE_RANDOM: u8 = 0x02;

/// L2CAP socket address.
#[repr(C)]
#[derive(Clone)]
pub struct sockaddr_l2 {
    pub l2_family: sa_family_t,
    pub l2_psm: c_ushort,
    pub l2_bdaddr: bdaddr_t,
    pub l2_cid: c_ushort,
    pub l2_bdaddr_type: u8,
}

pub const L2CAP_OPTIONS: i32 = 0x01;
pub const L2CAP_CONNINFO: i32 = 0x02;
pub const L2CAP_LM: i32 = 0x03;

/// Master.
pub const L2CAP_LM_MASTER: i32 = 0x0001;
/// Auth.
pub const L2CAP_LM_AUTH: i32 = 0x0002;
/// Encrypt.
pub const L2CAP_LM_ENCRYPT: i32 = 0x0004;
/// Trusted.
pub const L2CAP_LM_TRUSTED: i32 = 0x0008;
/// Reliable.
pub const L2CAP_LM_RELIABLE: i32 = 0x0010;
/// Secure.
pub const L2CAP_LM_SECURE: i32 = 0x0020;
/// FIPS.
pub const L2CAP_LM_FIPS: i32 = 0x0040;

/// Raw socket options for classic Bluetooth (BR/EDR) L2CAP sockets.
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub struct l2cap_options {
    /// Outgoing MTU.
    pub omtu: u16,
    /// Incoming MTU.
    pub imtu: u16,
    /// Flush to?
    pub flush_to: u16,
    /// Mode.
    pub mode: u8,
    /// FCS option.
    pub fcs: u8,
    /// Max transmission.
    pub max_tx: u8,
    /// Transmission window.
    pub txwin_size: u16,
}

impl Default for l2cap_options {
    fn default() -> Self {
        Self { omtu: 0, imtu: 672, flush_to: 65535, mode: 0, fcs: 0x01, max_tx: 3, txwin_size: 63 }
    }
}

/// L2CAP socket connection information.
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub struct l2cap_conninfo {
    /// Host controller interface (HCI) handle for the connection.
    pub hci_handle: u16,
    /// Device class.
    pub dev_class: [u8; 3],
}

/// RFCOMM socket address.
#[repr(C)]
#[derive(Clone)]
pub struct sockaddr_rc {
    pub rc_family: sa_family_t,
    pub rc_bdaddr: bdaddr_t,
    pub rc_channel: u8,
}

pub const RFCOMM_CONNINFO: i32 = 0x02;
pub const RFCOMM_LM: i32 = 0x03;

pub const RFCOMM_LM_MASTER: u32 = 0x0001;

/// RFCOMM socket connection information.
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub struct rfcomm_conninfo {
    /// Host controller interface (HCI) handle for the connection.
    pub hci_handle: u16,
    /// Device class.
    pub dev_class: [u8; 3],
}

pub const RFCOMM_REUSE_DLC: u32 = 1 << 0;
pub const RFCOMM_RELEASE_ONHUP: u32 = 1 << 1;

pub const RFCOMMCREATEDEV: ioctl_num_type = request_code_write!('R', 200, size_of::<c_int>());
pub const RFCOMMRELEASEDEV: ioctl_num_type = request_code_write!('R', 201, size_of::<c_int>());

/// RFCOMM TTY device request.
#[repr(C)]
#[derive(Clone, Default)]
pub struct rfcomm_dev_req {
    pub dev_id: i16,
    pub flags: u32,
    pub src: bdaddr_t,
    pub dst: bdaddr_t,
    pub channel: u8,
}