How to initiate BLE pairing on BlueZ - security

I want to initiate pairing on Bluez with a Bluetooth Low Energy device.
While there are some posts on how to trigger the SMP procedures using GATT, there is not much available if you do not want to use GATT.
My use case is that I want to use an encrypted link for bluetooth-6lowpan which exchanges data over L2CAP credit based mode and not ATT/GATT.
Further, I would like to use the OOB mode for SMP pairing.
Pointers on how I could trigger SMP pairing either using command line or writing a C program is appreciated.
Thank you!

I don't think it's possible to perform BLE pairing without the use of GATT commands (from the command line only). The reason for this is that security in LE is GATT-action-based. In other words, the characteristic/service permissions dictate whether you need to pair with the device or not (i.e. to read the heart rate characteristic, the device might dictate that you need to be paired first). For this, the operation would be something like:
gatttool --sec-level=high --device=00:11:22:33:44:55:66 --char-read --uuid=0x2A37
This command will establish pairing first before reading the characteristic.
As for how to perform this using a C program, You can download the BlueZ source code and have a look at what passing this "sec-level" option does. I've quickly browsed through the code and found this in utils.c:-
chan = bt_io_connect(connect_cb, NULL, NULL, &tmp_err,
BT_IO_OPT_SOURCE_BDADDR, &sba,
BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
BT_IO_OPT_DEST_BDADDR, &dba,
BT_IO_OPT_DEST_TYPE, dest_type,
BT_IO_OPT_CID, ATT_CID,
BT_IO_OPT_SEC_LEVEL, sec,
BT_IO_OPT_INVALID);
where sec is set with sec = BT_IO_SEC_HIGH;
I hope this helps.

Related

Sending/Recieving HID reports in Linux?

I'm trying to communicate to a custom piece of hardware from a (userspace) C++ program. The device is an HID device, but not a mouse/keyboard.
On Windows, I can use HidD_SetOutputReport to send a report, and then HidD_GetInputReport to receive the reply. (There is more than one report being generated, but those calls let me specify which one I want.)
I'm not doing anything fancy, so it's nice and straightforward.
I am having trouble figuring out what the simple Linux alternative to those calls is.
If someone could point me towards documentation or a code example that illustrates equivalent operations on Linux, I would be very grateful.
Thank you.
If your device is a HID device then for sending the HID report you need to write to the corresponding /dev/hid* device. This will be HidD_SetOutputReport alternate.
Most of the devices now using EP0 for backward communication, so for getting the response you need to read from corresponding /dev/hid* device. This will beHidD_GetInputReport alternate.
If your hardware are not using the EP0 for communication then you can find the information from your Endpoint descriptor, in which it will be defined how to get the response back.

Can the the device receive commands without previous negotiation (sending any data)?

I'm dealing with the following challenge. In my system, there are two devices. Tags and anchors. Tags have BLE module with the transmit power 0dBm and not Long Range feature (BLE 4.0). Anchors have BLE module with transmit power over 8dBm and Long range feature (BLE 5.0).
I want tags to only receive some commands. Bi-directional communication is not necessary. This way, I can utilize the transmit power of anchor (8dBm) and thus quite bigger range, if tag with 0dBm is only receiving.
I read something about Observer/Broadcaster principle, where connecting is not necessary. But somehow devices have to agree on what frequencies should they hop on, the step and so on.
I'm asking, is it possible for device to only receive commands without previous negotiation with the sender?
Thank you very much for help. I'm beginning with BLE standard and there is a lot to learn.
Yes, it is possible to send data via adverts/scanning only. This way, there's no connection that needs to be established, and therefore no connection parameter negotiation takes place. As for the frequency hopping agreement - this happens via the baseband (in other words you will not deal with this in the software yourself) and is generally not applicable for advertising/scanning (these happen on 3 frequency channels only and therefore it is likely that the observer will catch what the broadcaster is broadcasting).
However, keep in mind that because you are broadcasting/advertising the data as opposed to directly sending it, that data can be received by any observing/scanning BLE devices which is not desired for safety/security/privacy purposes.
For more information on BLE communication, I recommend the links below:-
Getting Started with Bluetooth Low Energy
Is it Possible to Send Data with BLE Broadcast Mode

BlueZ remote device presence

Using BlueZ, which
is the official Linux Bluetooth stack
I'd like to know which of the below two methods are better suited for detecting a device's presence in the nearby.
To be more exact, I want to periodically scan for a Bluetooth device (not BLE => no advertisement packets are sent).
I found two ways of detecting it:
1.) Using l2ping
# l2ping BTMAC
2.) Using hcitool
# hcitool name BTMAC
Both approaches working.
I'd like to know, which approach would drain more battery of the scanned device?
Looking at solution #1 (l2ping's source):
It uses a standard socket connect call to connect to the remote device, then uses the send command to send data to it:
send(sk, send_buf, L2CAP_CMD_HDR_SIZE + size, 0)
Now, L2CAP_CMD_HDR_SIZE is 4, and default size is 44, so altogether 48 bytes are sent, and received back with L2CAP_ECHO_REQ.
For hcitool I just have found the entrypoint:
int hci_read_remote_name(int dd, const bdaddr_t *bdaddr, int len, char *name, int to);
My questions:
which of these approaches are better (less power-consuming) for the remote device? If there is any difference at all.
shall I reduce the l2ping's size? What shall be the minimum?
is my assumption correct that hci_read_remote_name also connects to the remote device and sends some kind of request to it for getting back its name?
To answer your questions:-
which of these approaches are better (less power-consuming) for the remote device? If there is any difference at all.
l2ping BTMAC is the more suitable command purely because this is what it is meant to do. While "hcitool name BTMAC" is used to get the remote device's name, "l2ping" is used to detect its presence which is what you want to achieve. The difference in power consumption is really minimal, but if there is any then l2ping should be less power consuming.
shall I reduce the l2ping's size? What shall be the minimum?
If changing the l2ping size requires modifying the source code then I recommend leaving it the same. By leaving it the same you are using the same command that has been used countless times and the same command that was used to qualify the BlueZ stack. This way there's less chance for error and any change would not result in noticeable performance or power improvements.
is my assumption correct that hci_read_remote_name also connects to the remote device and sends some kind of request to it for getting back its name?
Yes your assumption is correct. According the Bluetooth Specification v5.2, Vol 4, Part E, Section 7.1.19 Remote Name Request Command:
If no connection exists between the local device and the device
corresponding to the BD_ADDR, a temporary Link Layer connection will
be established to obtain the LMP features and name of the remote
device.
I hope this helps.

BLED112 advertise GATT services list

I am trying to make a BLED112 behave like an iBEacon and also advertise few more GATT services. While advertising user data for iBeacon as in Bluegiga examples works fine, I do not know how to also advertise the list of available GATT services. Any ideas are highly appreciated!
Take a look at my website for some potential help regarding using the BLED112 and Bluegiga tools: http://www.sureshjoshi.com/tag/bluegiga/
Otherwise, you shouldn't really be explicitly advertising anything. If you've set up your gatt.xml correctly, the GATT characteristics are advertised inherently (it's a BLE thing, not an explicit thing).
Are you sure you're setting them up correctly? Take a look at my BLE113 examples, specifically dealing with gatt.xml and see if there is anything helpful there: https://github.com/sureshjoshi/ble113-firmware-examples
One approach would be to use the Bluegiga dual-mode advertising as a guide and instead of the Physical Web Beacon, advertise your GATT service there. Assuming you have a 128 bit service UUID of 112233-4455-6677-8899-00AABBCCDDEEFF your advertising data would look like this:
procedure gatt_service_advertisement()
# Beacon mode
beaconMode = 1
#Stop advertisement
call gap_set_mode(0,0)
# Length
service_adv(0:1) = $11
# Incomplete list of 128 bit UUIDs (use $07 if the list is complete)
service_adv(1:1) = $06
# GATT Service UUID - should be little endian I think
service_adv(2:1) = $FF
service_adv(3:1) = $EE
...
service_adv(16:1) = $11
service_adv(17:1) = $00
# Set advertisement interval to 100ms.
# Use all three advertisement channels
call gap_set_adv_parameters(160, 160, 7)
# Set advertisement data
call gap_set_adv_data(0, 18, service_adv(0:18))
#set to advertising mode - with user data
call gap_set_mode(4, gap_undirected_connectable)
end
You can use that procedure to alternate advertisements between iBeacon and your GATT service by calling it in a repeating timer like in the linked dual-mode example.
Another approach would be to advertise the GATT service in the scan response, but without knowing more about your particular use case, it's hard to say if that's an option for you.

Bi-directional sniffing/snooping on an ALSA MIDI SysEx exchange

Does anyone know of a good way to get a bi-directional dump of MIDI SysEx data on Linux? (between a Yamaha PSR-E413 MIDI keyboard and a copy of the Yamaha MusicSoft Downloader running in Wine)
I'd like to reverse-engineer the protocol used to copy MIDI files to and from my keyboard's internal memory and, to do that, I need to do some recording of valid exchanges between the two.
The utility does work in Wine (with a little nudging) but I don't want to have to rely on a cheap, un-scriptable app in Wine when I could be using a FUSE filesystem.
Here's the current state of things:
My keyboard connects to my PC via a built-in USB-MIDI bridge. USB dumpers/snoopers are a possibility, but I'd prefer to avoid them if possible. I don't want to have to decode yet another layer of protocol encoding before I even get started.
I run only Linux. However, if there really is no other option than a Windows-based dumper/snooper, I can try getting the USB 1.1 pass-through working on my WinXP VirtualBox VM.
I run bare ALSA for my audio system with dmix for waveform audio mixing.
If a sound server is necessary, I'm willing to experiment with JACK.
No PulseAudio please. It took long enough to excise it from my system.
If the process involves ALSA MIDI routing:
a virtual pass-through device I can select from inside the Downloader is preferred because it often only appears in an ALSA patch bay GUI like patchage an instant before it starts communicating with the keyboard.
Neither KMIDIMon nor GMIDIMonitor support snooping bi-directionally as far as I can tell.
virmidi isn't relevant and I haven't managed to get snd-seq-dummy working.
I I suppose I could patch ALSA to get dumps if I really must, but it's really an option of last resort.
The vast majority of my programming experience is in Python, PHP, Javascript, and shell script.
I have almost no experience programming in C.
I've never even seen a glimpse of kernel-mode code.
I'd prefer to keep my system stable and my uptime high.
This question has been unanswered for some time and while I do not have an exact answer to your problem I maybe have something that can push you in the right direction (or maybe others with similar problems).
I had a similar albeit less complex problem when I wanted to sniff the data used to set and read presets on an Akai LPK25 MIDI keyboard. Similar to your setup the software to setup the keyboard can run in Wine but I also had no luck in finding a sniffer setup for Linux.
For the lack of an existing solution I rolled my own using ALSA MIDI routing over virmidi ports. I understand why you see them as useless because without additional software they cannot help at sniffing MIDI traffic.
My solution was programming a MIDI relay/bridge in Java where I read input from a virmidi port, display the data and send it further to the keyboard. The answer from the keyboard (if any) is also read, displayed and finally transmitted back to the virmidi port. The application in Wine can be setup to use the virmidi port for communication and in theory this process is completely transparent (except for potential latency issues). The application is written in a generic way and not hardcoded to my problem.
I was only dealing with SysEx messages of about 20 bytes length so I am not sure how well the software works for sniffing the transfer of large amounts of data. But maybe you can modify it / write your own program following the example.
Sources available here: https://github.com/hiben/MIDISpy
(Java 1.6, ant build file included, source is under BSD license)
I like using aseqdump for that.
http://www.linuxcommand.org/man_pages/aseqdump1.html
You could use virtual midi devices for this purpose. So you have to load snd_seq_dummy so that it creates at least two ports:
$ sudo modprobe -r snd_seq_dummy
$ sudo modprobe snd_seq_dummy ports=1 duplex=1
Then you should have a device named Midi through:
$ aconnect -i -o -l
client 0: 'System' [type=kernel]
0 'Timer '
1 'Announce '
client 14: 'Midi Through' [type=kernel]
0 'Midi Through Port-0:A'
1 'Midi Through Port-0:B'
client 131: 'VMPK Input' [type=user,pid=50369]
0 'in '
client 132: 'VMPK Output' [type=user,pid=50369]
0 'out '
I will take the port and device numbers form this example. You have to inspect them yourself according to your setup.
Now you plug your favourate MIDI Device to the Midi Through ports:
$ aconnect 132:0 14:0
$ aconnect 14:0 131:0
At this time you have a connection where you can spy on both devices at the same time. You could use aseqdump to spy the MIDI conversation. There are different possibilities. I suggest to spy the connection between the loopback devices and the real device. This allows you for rawmidi connections to the loopback devices.
$ aseqdump -p 14:0,132:0 | tee dump.log
Now everything is set up for use. You just have to be careful about port names in your MIDI application. It should read MIDI data from Midi Through Port-0:B and write data to Midi Through Port-0:B.
Some additional hint: You could use the graphical frontend patchage for connecting and inspecting the MIDI connections via drag and drop. If you do this you will see that every Midi Through port occurs twice once as input and once as output. Both have to be connected in order to make this setup work.
If you want to use GMidiMonitor or some other application you spy on both streams intermixed (without showing the direction) using aconnect suppose 129:0 is the Midi Monitor port :
$ aconnect 14:0 129:0
$ aconnect 132:0 129:0
If you want to have exact direction information you could add another GMidiMonitor instance that you connect only to one of the ports. The missing messages come from the other port.
What about using gmidimonitor? See http://home.gna.org/gmidimonitor/

Resources