ftonello / bluez

Clone of mainline BlueZ to implement MIDI over BLE protocol
GNU General Public License v2.0
32 stars 15 forks source link

BLE Midi Peripheral #2

Open cookj273 opened 7 years ago

cookj273 commented 7 years ago

Hello! First of all thank you for all your great work! I have this up and running on an embedded ARM system and am able to connect to and send MIDI to BLE MIDI devices. However, the midi device is only created when i connect to something that is a BLE midi device.

My device has the ability of creating midi data, so I have the need to make my system a BLE midi device and be able to connect to it from and iOS app or similar and stream the created midi data. I saw on your blog that the peripheral role is something that still needs completed. Do you have any advice for me of how to go about getting this to work? It seems like all the functionality is done in that i can send the MIDI data out no problem, but what is missing is the ability to essentially advertise as a BLE Midi device and allow the connection to be instantiated from something such as an iOS app.

cookj273 commented 7 years ago

I was playing around with some things today and was able to get this to work. I was just trying things and obviously i need to clean stuff up but the following sequence of events allowed me to connect in iOS and then play midi in an app from my device running your BlueZ:

~ # hciconfig hci0 up
~ # hciconfig hci0 noleadv
~ # hcitool -i hci0 cmd 0x08 0x0008 10 02 01 1a 0c ff 18 01 48 45 4c 4c 4f 57 4f 52 4c 44

^--Just some simple hello world advertise data for now

~ # hciconfig hci0 leadv 0
~ # dbus-daemon --system
~ # /usr/libexec/bluetooth/bluetoothd -d &
~ # bluetoothctl
[bluetooth]# power on
[bluetooth]# agent on
[bluetooth]# default-agent
[bluetooth]# discoverable on
[bluetooth]# pairable on
*I then connected from the IPad and was asked to enter a passcode, I entered it and connection was made
[60-BC-27-35-95-B0]# exit
~ # aplaymidi -l
Port Client name Port name
14:0 Midi Through Midi Through Port-0
20:0 f_midi f_midi
128:0 60:BC:27:35:95:B0 60:BC:27:35:95:B0 Bluetooth
~ # aplaymidi --port=128:0 04801253.MID

And after that the midi file was streaming to my IPad!!! I think i still need to setup the service stuff correctly though because i cannot find my device in my actual App (I am using SuperScore to test with). What i had to do was bring up LightBlue on iOS to connect to my device and then i could play the Midi from it in SuperScore. But anyways it is very reassuring that it is working this easily.

I will work to get the rest working. Thank you again for all your hard work! Saved me lots of time!

ftonello commented 7 years ago

This is great stuff. I never tested this BlueZ plugin as a GATT server (peripheral). Interesting that it works.

Like you mentined, to write a proper peripheral plugin is not that complicated, since most of the functionality is done, it is just a matter of advertise the GATT server and write properly the ATT table. BlueZ provides APIs for that, so it should be ok.

I will go with this approach, first.

cookj273 commented 7 years ago

Awesome! This is my first foray into bluetooth, i haven't really worked with it much before. It was just a desire to add it into a device we have to prevent having to plug in a USB or MIDI cable to stream it. I will keep researching and playing around to get a better understanding but yeah seems like it won't be too bad : )

oxesoft commented 7 years ago

As user, I want to plug my USB MIDI controller in the USB port and then expose the specific ALSA MIDI device (listed in "amidi -l") as a BLE-MIDI service (using its device name). I'm interested in implement this, but first I need do understand how it would be used. It would be done automatically? if not, which would be the command line to interact with this? I'm new in BlueZ world, but I've made a MIDI to BLE-MIDI device using Arduino.

cookj273 commented 7 years ago

I have a server that works. I need to clean some things up first, so maybe tomorrow I will get it cleaned up a little and then fork this repo and commit the changes there. Of course it will need some good testing and stuff too, but it is working pretty good for me right now. I basically merged Felipe's midi profile code with the btgatt-server, so that when you build with enable-midi now you get a btmidi-server executable. You simply run this program and it creates the ALSA midi devices and exposes them over BLE. You can then connect from an I-Pad or whatever and use the MIDI devices like normal. So in Daniels case you could use aconnect to connect the USB Midi device to the BLE Midi ports.

Like i said this is my first time really messing with Bluez, so not sure if the way I added this code in is correct, so sorry if anything is amiss...

ftonello commented 7 years ago

Great stuff. I have been working on some connection reliabilities improvements so far, so I haven't tried the peripheral mode yet. But It will be great to have others working on this too. Ideally I want to add it too bluetoothd as a plugin, similar to what is upstream already. If the latency is not good, than we can try doing a dedicated daemon.

oxesoft commented 7 years ago

Great, @cookj273 I'll test as soon as you push the code.

oxesoft commented 7 years ago

It is being a pain to get any of the BlueZ MGMT based tools working correctly as a peripheral. I need help with this. I want to SEE the sequence of commands that advertises a peripheral with a service. That simple. The most interesting example is the peripheral/btsensor but it is shown on LightBlue as "No services".

cookj273 commented 7 years ago

Another question/thought here:

You discuss the need to set the ConnectionParameters stuff to in the central setup in case where the peripheral does not handle it. So will it be necessary to signal these parameters correctly when we are the peripheral? I have found this patch that seems to add this functionality into hcitool: https://gist.github.com/SandyChapman/4a64c9ea22cd27d935e3

I have tried placing the code into our midigatt-server as a test and it seems to send correctly according to hcidump. I am not sure how to investigate if the parameters are then set correctly but it did seem to positively affect my playback... I will need to research some into this when i have time.

oxesoft commented 7 years ago

Guys, now I have a fully working code, just as the original one, but using the updated API (no hci stuff) to make the advertisement and including the connection parameters. @cookj273 please test.

cookj273 commented 7 years ago

That's awesome! : ) I will test it this week and let you know of any issues I encounter!

audetto commented 5 years ago

Have you guys managed to connect to btmidi-server.c from an Android device?

It can scan it, but it never gets to the point of the initial read of the MIDI Characteristics. Tried with various Android 7 devices.

On the other hand, apps which can browse the GATT server interact correctly with this code.