libbluetooth 0.1.0

Raw FFI bindings for Unix' libbluetooth.
Documentation
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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
use std::os::raw::{c_char, c_int, c_long, c_uint, c_ushort, c_void};

use crate::bluetooth::bdaddr_t;
use crate::hci::{
    hci_dev_info, hci_filter, inquiry_info, HCI_FLT_EVENT_BITS, HCI_FLT_TYPE_BITS, HCI_VENDOR_PKT,
};

STRUCT! {struct hci_request {
    ogf: c_ushort,
    ocf: c_ushort,
    event: c_int,
    cparam: *mut c_void,
    clen: c_int,
    rparam: * mut c_void,
    rlen: c_int,
}}

STRUCT! {struct hci_version {
    manufacturer: c_ushort,
    hci_ver: c_char,
    hci_rev: c_ushort,
    lmp_ver: c_char,
    lmp_subver: c_ushort,
}}

#[link(name = "bluetooth")]
extern "C" {
    pub fn hci_open_dev(dev_id: c_int) -> c_int;
    pub fn hci_close_dev(dd: c_int) -> c_int;
    pub fn hci_send_cmd(
        dd: c_int,
        ogf: c_ushort,
        ocf: c_ushort,
        plen: c_char,
        param: *mut c_void,
    ) -> c_int;
    pub fn hci_send_req(dd: c_int, req: *mut hci_request, timeout: c_int) -> c_int;
    pub fn hci_create_connection(
        dd: c_int,
        bdaddr: *const bdaddr_t,
        ptype: c_ushort,
        clkoffset: c_ushort,
        rswitch: c_char,
        handle: *mut c_ushort,
        to: c_int,
    ) -> c_int;
    pub fn hci_disconnect(dd: c_int, handle: c_ushort, reason: c_char, to: c_int) -> c_int;
    pub fn hci_inquiry(
        dev_id: c_int,
        len: c_int,
        num_rsp: c_int,
        lap: *const c_char,
        ii: *mut *mut inquiry_info,
        flags: c_long,
    ) -> c_int;
    pub fn hci_devinfo(dev_id: c_int, di: *mut hci_dev_info) -> c_int;
    pub fn hci_devba(dev_id: c_int, bdaddr: *mut bdaddr_t) -> c_int;
    pub fn hci_devid(str_: *const c_char) -> c_int;
    pub fn hci_read_local_name(dd: c_int, len: c_int, name: *mut c_char, to: c_int) -> c_int;
    pub fn hci_write_local_name(dd: c_int, name: *const c_char, to: c_int) -> c_int;
    pub fn hci_read_remote_name(
        dd: c_int,
        bdaddr: *const bdaddr_t,
        len: c_int,
        name: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_remote_name_with_clock_offset(
        dd: c_int,
        bdaddr: *const bdaddr_t,
        pscan_rep_mode: c_char,
        clkoffset: c_ushort,
        len: c_int,
        name: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_remote_name_cancel(dd: c_int, bdaddr: *const bdaddr_t, to: c_int) -> c_int;
    pub fn hci_read_remote_version(
        dd: c_int,
        handle: c_ushort,
        ver: *mut hci_version,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_remote_features(
        dd: c_int,
        handle: c_ushort,
        features: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_remote_ext_features(
        dd: c_int,
        handle: c_ushort,
        page: c_char,
        max_page: *mut c_char,
        features: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_clock_offset(
        dd: c_int,
        handle: c_ushort,
        clkoffset: *mut c_ushort,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_local_version(dd: c_int, ver: *mut hci_version, to: c_int) -> c_int;
    pub fn hci_read_local_commands(dd: c_int, commands: *mut c_char, to: c_int) -> c_int;
    pub fn hci_read_local_features(dd: c_int, features: *mut c_char, to: c_int) -> c_int;
    pub fn hci_read_local_ext_features(
        dd: c_int,
        page: c_char,
        max_page: *mut c_char,
        features: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_bd_addr(dd: c_int, bdaddr: *mut bdaddr_t, to: c_int) -> c_int;
    pub fn hci_read_class_of_dev(dd: c_int, cls: *mut c_char, to: c_int) -> c_int;
    pub fn hci_write_class_of_dev(dd: c_int, cls: c_uint, to: c_int) -> c_int;
    pub fn hci_read_voice_setting(dd: c_int, vs: *mut c_ushort, to: c_int) -> c_int;
    pub fn hci_write_voice_setting(dd: c_int, vs: c_ushort, to: c_int) -> c_int;
    pub fn hci_read_current_iac_lap(
        dd: c_int,
        num_iac: *mut c_char,
        lap: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_write_current_iac_lap(
        dd: c_int,
        num_iac: c_char,
        lap: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_stored_link_key(
        dd: c_int,
        bdaddr: *mut bdaddr_t,
        all: c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_write_stored_link_key(
        dd: c_int,
        bdaddr: *mut bdaddr_t,
        key: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_delete_stored_link_key(
        dd: c_int,
        bdaddr: *mut bdaddr_t,
        all: c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_authenticate_link(dd: c_int, handle: c_ushort, to: c_int) -> c_int;
    pub fn hci_encrypt_link(dd: c_int, handle: c_ushort, encrypt: c_char, to: c_int) -> c_int;
    pub fn hci_change_link_key(dd: c_int, handle: c_ushort, to: c_int) -> c_int;
    pub fn hci_switch_role(dd: c_int, bdaddr: *mut bdaddr_t, role: c_char, to: c_int) -> c_int;
    pub fn hci_park_mode(
        dd: c_int,
        handle: c_ushort,
        max_interval: c_ushort,
        min_interval: c_ushort,
        to: c_int,
    ) -> c_int;
    pub fn hci_exit_park_mode(dd: c_int, handle: c_ushort, to: c_int) -> c_int;
    pub fn hci_read_inquiry_scan_type(dd: c_int, type_: *mut c_char, to: c_int) -> c_int;
    pub fn hci_write_inquiry_scan_type(dd: c_int, type_: c_char, to: c_int) -> c_int;
    pub fn hci_read_inquiry_mode(dd: c_int, mode: *mut c_char, to: c_int) -> c_int;
    pub fn hci_write_inquiry_mode(dd: c_int, mode: c_char, to: c_int) -> c_int;
    pub fn hci_read_afh_mode(dd: c_int, mode: *mut c_char, to: c_int) -> c_int;
    pub fn hci_write_afh_mode(dd: c_int, mode: c_char, to: c_int) -> c_int;
    pub fn hci_read_ext_inquiry_response(
        dd: c_int,
        fec: *mut c_char,
        data: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_write_ext_inquiry_response(
        dd: c_int,
        fec: c_char,
        data: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_simple_pairing_mode(dd: c_int, mode: *mut c_char, to: c_int) -> c_int;
    pub fn hci_write_simple_pairing_mode(dd: c_int, mode: c_char, to: c_int) -> c_int;
    pub fn hci_read_local_oob_data(
        dd: c_int,
        hash: *mut c_char,
        randomizer: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_inq_response_tx_power_level(dd: c_int, level: *mut c_char, to: c_int) -> c_int;
    pub fn hci_read_inquiry_transmit_power_level(dd: c_int, level: *mut c_char, to: c_int)
        -> c_int;
    pub fn hci_write_inquiry_transmit_power_level(dd: c_int, level: c_char, to: c_int) -> c_int;
    pub fn hci_read_transmit_power_level(
        dd: c_int,
        handle: c_ushort,
        type_: c_char,
        level: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_link_policy(
        dd: c_int,
        handle: c_ushort,
        policy: *mut c_ushort,
        to: c_int,
    ) -> c_int;
    pub fn hci_write_link_policy(dd: c_int, handle: c_ushort, policy: c_ushort, to: c_int)
        -> c_int;
    pub fn hci_read_link_supervision_timeout(
        dd: c_int,
        handle: c_ushort,
        timeout: *mut c_ushort,
        to: c_int,
    ) -> c_int;
    pub fn hci_write_link_supervision_timeout(
        dd: c_int,
        handle: c_ushort,
        timeout: c_ushort,
        to: c_int,
    ) -> c_int;
    pub fn hci_set_afh_classification(dd: c_int, map: *mut c_char, to: c_int) -> c_int;
    pub fn hci_read_link_quality(
        dd: c_int,
        handle: c_ushort,
        link_quality: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_rssi(dd: c_int, handle: c_ushort, rssi: *mut c_char, to: c_int) -> c_int;
    pub fn hci_read_afh_map(
        dd: c_int,
        handle: c_ushort,
        mode: *mut c_char,
        map: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_read_clock(
        dd: c_int,
        handle: c_ushort,
        which: c_char,
        clock: *mut c_uint,
        accuracy: *mut c_ushort,
        to: c_int,
    ) -> c_int;
    pub fn hci_le_set_scan_enable(
        dev_id: c_int,
        enable: c_char,
        filter_dup: c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_le_set_scan_parameters(
        dev_id: c_int,
        type_: c_char,
        interval: c_ushort,
        window: c_ushort,
        own_type: c_char,
        filter: c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_le_set_advertise_enable(dev_id: c_int, enable: c_char, to: c_int) -> c_int;
    pub fn hci_le_create_conn(
        dd: c_int,
        interval: c_ushort,
        window: c_ushort,
        initiator_filter: c_char,
        peer_bdaddr_type: c_char,
        peer_bdaddr: bdaddr_t,
        own_bdaddr_type: c_char,
        min_interval: c_ushort,
        max_interval: c_ushort,
        latency: c_ushort,
        supervision_timeout: c_ushort,
        min_ce_length: c_ushort,
        max_ce_length: c_ushort,
        handle: *mut c_ushort,
        to: c_int,
    ) -> c_int;
    pub fn hci_le_conn_update(
        dd: c_int,
        handle: c_ushort,
        min_interval: c_ushort,
        max_interval: c_ushort,
        latency: c_ushort,
        supervision_timeout: c_ushort,
        to: c_int,
    ) -> c_int;
    pub fn hci_le_add_white_list(
        dd: c_int,
        bdaddr: *const bdaddr_t,
        type_: c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_le_rm_white_list(
        dd: c_int,
        bdaddr: *const bdaddr_t,
        type_: c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_le_read_white_list_size(dd: c_int, size: *mut c_char, to: c_int) -> c_int;
    pub fn hci_le_clear_white_list(dd: c_int, to: c_int) -> c_int;
    pub fn hci_le_add_resolving_list(
        dd: c_int,
        bdaddr: *const bdaddr_t,
        type_: c_char,
        peer_irk: *mut c_char,
        local_irk: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_le_rm_resolving_list(
        dd: c_int,
        bdaddr: *const bdaddr_t,
        type_: c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_le_clear_resolving_list(dd: c_int, to: c_int) -> c_int;
    pub fn hci_le_read_resolving_list_size(dd: c_int, size: *mut c_char, to: c_int) -> c_int;
    pub fn hci_le_set_address_resolution_enable(dev_id: c_int, enable: c_char, to: c_int) -> c_int;
    pub fn hci_le_read_remote_features(
        dd: c_int,
        handle: c_ushort,
        features: *mut c_char,
        to: c_int,
    ) -> c_int;
    pub fn hci_for_each_dev(
        flag: c_int,
        func: extern "C" fn(dd: c_int, dev_id: c_int, arg: c_long) -> c_int,
        arg: c_long,
    ) -> c_int;
    pub fn hci_get_route(bdaddr: *mut bdaddr_t) -> c_int;
    pub fn hci_bustostr(bus: c_int) -> *mut c_char;
    pub fn hci_typetostr(type_: c_int) -> *mut c_char;
    pub fn hci_dtypetostr(type_: c_int) -> *mut c_char;
    pub fn hci_dflagstostr(flags: c_uint) -> *mut c_char;
    pub fn hci_ptypetostr(ptype: c_uint) -> c_int;
    pub fn hci_strtoptype(str_: *mut c_char, val: *mut c_uint) -> c_int;
    pub fn hci_scoptypetostr(ptype: c_uint) -> *mut c_char;
    pub fn hci_strtoscoptype(str_: *mut c_char, val: *mut c_uint) -> c_int;
    pub fn hci_lptostr(ptype: c_uint) -> *mut c_char;
    pub fn hci_strtolp(str_: *mut c_char, val: *mut c_uint) -> c_int;
    pub fn hci_lmtostr(ptype: c_uint) -> *mut c_char;
    pub fn hci_strtolm(str_: *mut c_char, val: *mut c_uint) -> c_int;
    pub fn hci_cmdtostr(cmd: c_uint) -> *mut c_char;
    pub fn hci_commandstostr(commands: *mut c_char, pref: *mut c_char, width: c_int)
        -> *mut c_char;
    pub fn hci_vertostr(ver: c_uint) -> *mut c_char;
    pub fn hci_strtover(str_: *mut c_char, ver: *mut c_uint) -> c_int;
    pub fn lmp_vertostr(ver: c_uint) -> *mut c_char;
    pub fn lmp_strtover(str_: *mut c_char, ver: *mut c_uint) -> c_int;
    pub fn pal_vertostr(ver: c_uint) -> *mut c_char;
    pub fn pal_strtover(str_: *mut c_char, ver: *mut c_uint) -> c_int;
    pub fn lmp_featurestostr(features: *mut c_char, pref: *mut c_char, width: c_int)
        -> *mut c_char;
}
#[inline]
pub fn hci_set_bit(nr: c_int, addr: *mut c_uint) {
    let bitset = unsafe { addr.offset((nr >> 5) as isize).as_mut() }.unwrap();
    *bitset |= 1 << (nr & 31);
}
#[inline]
pub fn hci_clear_bit(nr: c_int, addr: *mut c_uint) {
    let bitset = unsafe { addr.offset((nr >> 5) as isize).as_mut() }.unwrap();
    *bitset &= !(1 << (nr & 31));
}
#[inline]
pub fn hci_test_bit(nr: c_int, addr: *mut c_uint) -> c_uint {
    let bitset = unsafe { addr.offset((nr >> 5) as isize).as_ref() }.unwrap();
    *bitset & (1 << (nr & 31))
}
// HCI filter tools
#[inline]
#[cfg(feature = "impl-default")]
pub fn hci_filter_clear(f: &mut hci_filter) {
    *f = Default::default();
}
#[inline]
pub fn hci_filter_set_ptype(t: c_int, f: &mut hci_filter) {
    let nr = if t == HCI_VENDOR_PKT {
        0
    } else {
        t & HCI_FLT_TYPE_BITS
    };
    hci_set_bit(nr, &mut f.type_mask as *mut c_uint);
}
#[inline]
pub fn hci_filter_clear_ptype(t: c_int, f: &mut hci_filter) {
    let nr = if t == HCI_VENDOR_PKT {
        0
    } else {
        t & HCI_FLT_TYPE_BITS
    };
    hci_clear_bit(nr, &mut f.type_mask as *mut c_uint);
}
#[inline]
pub fn hci_filter_test_ptype(t: c_int, f: &mut hci_filter) -> c_uint {
    let nr = if t == HCI_VENDOR_PKT {
        0
    } else {
        t & HCI_FLT_TYPE_BITS
    };
    hci_test_bit(nr, &mut f.type_mask as *mut c_uint)
}
#[inline]
pub fn hci_filter_all_ptypes(f: &mut hci_filter) {
    f.type_mask = c_uint::max_value();
}
#[inline]
pub fn hci_filter_set_event(e: c_int, f: &mut hci_filter) {
    hci_set_bit(e & HCI_FLT_EVENT_BITS, &mut f.event_mask[0] as *mut c_uint);
}
#[inline]
pub fn hci_filter_clear_event(e: c_int, f: &mut hci_filter) {
    hci_clear_bit(e & HCI_FLT_EVENT_BITS, &mut f.event_mask[0] as *mut c_uint);
}
#[inline]
pub fn hci_filter_test_event(e: c_int, f: &mut hci_filter) -> c_uint {
    hci_test_bit(e & HCI_FLT_EVENT_BITS, &mut f.event_mask[0] as *mut c_uint)
}
#[inline]
pub fn hci_filter_all_events(f: &mut hci_filter) {
    for mask in &mut f.event_mask {
        *mask = c_uint::max_value();
    }
}
#[inline]
pub fn hci_filter_set_opcode(opcode: c_ushort, f: &mut hci_filter) {
    f.opcode = opcode;
}
#[inline]
pub fn hci_filter_clear_opcode(f: &mut hci_filter) {
    f.opcode = 0;
}
#[inline]
pub fn hci_filter_test_opcode(opcode: c_ushort, f: &mut hci_filter) -> bool {
    f.opcode == opcode
}