Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

microbit-dal: Minimalist Keyboard HID Service #249

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

Conversation

jamesadevine
Copy link
Contributor

This commit introduces a lightweight Keyboard HID service that has very simple send operations to the host.

Inspired by the initial pull request of @matthewelse and the sterling work by @jpbrucker .

Points to note:

  • as of this morning only tested on my Mac using Just Works pairing, however I would consider this the most difficult scenario based on previous Apple experience.
  • It is super RAM efficient, and as a result may not function entirely how a Keyboard HID should, critiques are of course welcome.
  • Advertising data is modified in this service, I have yet to determine if this is necessary or not (thoughts @bluetooth-mdw ?)
  • The device information service has been modified, and now contains a more RAM efficient version. However, now the device information service will always display the PnPID required as per the HID Bluetooth spec. This shouldn't be harmful to the existing operation of the micro:bit.
  • In this service an additional BatteryService is instantiated, as per the HID Bluetooth spec.

This commit introduces a lightweight HID service that
has very simple send operations to the host.

This HID service has only been tested using Just works pairing,
and should be considered an initial implementation, pending review.
@ghost
Copy link

ghost commented Dec 6, 2016

@jamesadevine The spec recommends certain AD fields be included in advertising from a device that implements the HID over GATT Profile.

image

@jamesadevine
Copy link
Contributor Author

@bluetooth-mdw I was more concerned with the new Device Information service.

Is it bad to advertise the PnpID all the time regardless of whether you are a HID?

@ghost
Copy link

ghost commented Dec 6, 2016

OK. No, I wouldn't say it's bad, just unnecessary. Per our discussion the other day, Characteristics can be optional and that one is defined as such should you could exploit this and only add the characteristic when the HID Service is included.

* Added a special send for characters outside the ascii keyset
* redesigned the interface, to include locks, and fiber blocking
  on all calls.
* at 1:30am, I reimplemented fiber_sleep, I've undone that... ;)
@jaustin
Copy link
Contributor

jaustin commented Dec 8, 2016

Some comments from me and Thomas (@Lord-Nazdar)

inc/bluetooth/MicrobitKeyboardService.h --> MicroBitKeyboardService.h

Because it isn't bondable by default, it's weird to connect from a Mac, etc.

Perhaps instead when pairing_mode (config.json version of the name) is 0 then we should be bondable in the default uBit instance of BLEManager

…rvice.h

My fs is case-insensitive, so I didn't realise the file was incorrectly named.

Used git mv to rename the file.
@jamesadevine
Copy link
Contributor Author

@jaustin 47d6912 (for the rename)

@jaustin
Copy link
Contributor

jaustin commented Jul 24, 2017

Now that there are nice game controller addons out like https://sciencescope.uk/product/microbit-gvs-controller-kit/ it feels like time to re-asses this.

@jamesadevine was there a reason other than time it didn't make it in? @Lord-Nazdar are you interested in picking it up and running with it?

@jamesadevine
Copy link
Contributor Author

It was a number of things:

  • Time
  • No great method for diagnosing issues.
  • Had a limited number of test devices, only one could actually see the micro:bit

It was close, I think it had something to do with security settings (I think it has to be secured by pairing on Windows, but that's not required on Mac OS) and broadcasting as a keyboard at all times, including the pairing process.

It did work on Mac OS, but it wasn't exactly usable, I had to force pairing and connection using the Lightblue App for Mac.

@jaustin
Copy link
Contributor

jaustin commented Oct 27, 2017

@ukBaz this is the PR we were discussing today - would be amazing for game controllers and similar!

@jamesadevine
Copy link
Contributor Author

@jaustin

index 2ea54a3..44e34ac 100644
--- a/inc/core/MicroBitConfig.h
+++ b/inc/core/MicroBitConfig.h
@@ -123,14 +123,14 @@ extern uint32_t __etext;
 // The amount of memory reused depends upon whether or not BLE is enabled using MICROBIT_BLE_ENABLED.
 // Set '1' to enable.
 #ifndef MICROBIT_HEAP_REUSE_SD
-#define MICROBIT_HEAP_REUSE_SD                  1
+#define MICROBIT_HEAP_REUSE_SD                  0
 #endif

 // The amount of memory allocated to Soft Device to hold its BLE GATT table.
 // For standard S110 builds, this should be word aligned and in the range 0x300 - 0x700.
 // Any unused memory will be automatically reclaimed as HEAP memory if both MICROBIT_HEAP_REUSE_SD and MICROBIT_HEAP_ALLOCATOR are enabled.
 #ifndef MICROBIT_SD_GATT_TABLE_SIZE
-#define MICROBIT_SD_GATT_TABLE_SIZE             0x300
+#define MICROBIT_SD_GATT_TABLE_SIZE             0x700
 #endif

 //
@@ -235,14 +235,14 @@ extern uint32_t __etext;
 // SECURITY_MODE_ENCRYPTION_WITH_MITM:      Bonding, encrytion and whitelisting with passkey authentication.
 //
 #ifndef MICROBIT_BLE_SECURITY_LEVEL
-#define MICROBIT_BLE_SECURITY_LEVEL             SECURITY_MODE_ENCRYPTION_WITH_MITM
+#define MICROBIT_BLE_SECURITY_LEVEL             SECURITY_MODE_ENCRYPTION_NO_MITM
 #endif

 // Enable/Disable the use of BLE whitelisting.
 // If enabled, the micro:bit will only respond to connection requests from
 // known, bonded devices.
 #ifndef MICROBIT_BLE_WHITELIST
-#define MICROBIT_BLE_WHITELIST                  1
+#define MICROBIT_BLE_WHITELIST                  0
 #endif

 // Define the period of time for which the BLE stack will advertise (seconds)
@@ -261,7 +261,7 @@ extern uint32_t __etext;
 // Based on trials undertaken by the BBC, the radio is normally set to its lowest power level
 // to best protect children's privacy.
 #ifndef MICROBIT_BLE_DEFAULT_TX_POWER
-#define MICROBIT_BLE_DEFAULT_TX_POWER           0
+#define MICROBIT_BLE_DEFAULT_TX_POWER           7
 #endif

 // Enable/Disable BLE Service: MicroBitDFU
@@ -301,7 +301,7 @@ extern uint32_t __etext;
 // This enables the standard BLE HID keyboard service.
 // Set '1' to enable.
 #ifndef MICROBIT_BLE_KEYBOARD_SERVICE
-#define MICROBIT_BLE_KEYBOARD_SERVICE           0
+#define MICROBIT_BLE_KEYBOARD_SERVICE           1
 #endif

@jamesadevine
Copy link
Contributor Author

This works well on Mac, @finneyj says does not work on Windows.

Would use the send member function rather than putc.
@jaustin
Copy link
Contributor

jaustin commented Feb 21, 2018

I built a working Windows binary using the Nordic SDK, so we can have a bit of a look to see if there's anything missing from your implementation here that Windows needs, @jamesadevine

The hex attached works on Windows 10 on a micro:bit. You first pair, then every time you press 'A' it prints a character.

ble_app_hids_keyboard_gcc_combined_s130_hack.zip

It's based on https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v12.3.0%2Fble_sdk_app_hids_keyboard.html&cp=4_0_5_4_2_2_12 with hacks to make it compile for micro:bit (16k, different pinout).

(this example also prints capson and capsof when the capslock is turned on or off, in case anyone thinks they're losing it!)

@jaustin
Copy link
Contributor

jaustin commented Feb 21, 2018

(Whatever this example does, it also shows up on macOS as a 'real' keyboard as opposed to a generic Bluetooth device in the device selector)

@jaustin
Copy link
Contributor

jaustin commented Feb 21, 2018

It looks like the missing services are the Boot Keyboard Input Report and Boot Keyboard Output Reports... I notice JP never implemented them in his original sample: https://github.com/jpbrucker/BLE_HID/blob/fc151647888329df66ca6985cd240631b965fa4d/BLE_HID/KeyboardService.h#L382

@ghost
Copy link

ghost commented Feb 21, 2018

I gave @jamesadevine some feedback on 13th December 2016 about this. I compared a working HID implementation from Cypress Semiconductor with his and said:

  1. Cypress includes the Scan Parameters service whereas micro:bit does not. The HID over GATT profile spec says “This profile requires the Generic Attribute Profile (GATT), the Battery Service, the Device Information Service, and the Scan Parameters Profile”. However it also says “The HID Device has one or more instances of the HID Service, one or more instances of the Battery Service, a single instance of the Device Information Service, and optionally one instance of the Scan Parameters Service as part of Scan Server role of the Scan Parameters Profile”.
  2. Microbit implementation of HID Information characteristic has no properties
  3. Microbit Device Information service includes different characteristics to the Cypress implementation. Only PnP ID is mandatory in this profile however so assume the difference is not significant.
  4. Cypress HID service includes Boot Keyboard Input Report and Boot Keyboard Output Report but micro:bit does not. These are for use when in “Boot Protocol Mode” but reading the Protocol Mode characteristic it seems Report Protoxol Mode is in use.
  5. Reading the micro:bit Protocol Mode causes it to disconnect and the display to flicker!
  6. Cypress includes the Report Map characteristic. micro:bit does not.

I also provided screenshots of nRF Connect connected to the Cypress implementation:

image

image

image

image

image

image

image

@jamesadevine
Copy link
Contributor Author

@bluetooth-mdw I'm not sure how much your analysis still holds true, since I made changes according to your diagnostics. In any case, it's good to have it up here rather than in Skype 😄

Also @jaustin the micro:bit appears as a keyboard to my mac on the latest revision.

@ghost
Copy link

ghost commented Feb 21, 2018

@jamesadevine yep, was just sharing in case it was useful. @jaustin noted the same missing services and I'd noted a few others differences.

@annoo
Copy link

annoo commented Aug 2, 2018

Hi all,

First of all, I wanted to thank you for all the effort and the good work. <3 Otherwise I wanted to bump this thread... (I would if I could help out, but this is just out of my league and a little overwhelming...)

The hex-file by @jaustin is not exactly working on my PC (Win10). It does give me a 'Nordic keyboard', so that's good... but it doesn't seem to 'connect': it does not react as a keyboard... (or typing 'hello, as I assume it would do).

->> The Scratch guys pulled it off though: https://scratch.mit.edu/microbit
But I haven't taken a look at their git. Could it be useful?

Is there someone actively importing this feature into MakeCode? Could this be a lead?

I think a 'bluetooth keyboard' is a logical extension for the Microbit, if possible.
My motivation: an introductory Hackaton I teach at a University College for the first week of class: make your own MIDI(or Open Sound Control)-controller and DJ-away in any Digital Audio Workstation...
Reason Microbit appealed to me was:

  • buttons and leds and accelerometer without any breadboard to start with...
  • Javascript front-end mixed with the blocks (students are enrolled to become front end web developers with serious touch of design and technology)
  • Python and C/C++ to blow them off their socks (Arduino in VS Code with PlatformIO works wonderfully well...)
  • bluetooth capability - so playground for IoT or beacon-stuff

And well, Jonathan, I think I met you 2 years ago on the EU 'Maker Faire' in the EU Parliament in Brussels where you just convinced me of the beauty of Microbit :-) (Wasn't that you?)
So I have been playing with younger children with the board, but now I was figuring out if it could 'bridge' to the more serious stuff...

Let me know?
Chrz,
ann

@orklann
Copy link

orklann commented Aug 22, 2018

I flash this hex (ble_app_hids_keyboard_gcc_combined_s130_hack.zip) to my microbit, it works by first paring with my Mac, and then press A to enter "HELLO" one character by one character, all fine, but all windows minize are slow, very slow, is there any fix?

@ghost
Copy link

ghost commented Aug 22, 2018

Strong recommendation: someone needs to test the HID implementation with the Bluetooth SIG's Profile Tuning Suite, which despite the name is actually a testing tool. It could be it's just not fully compliant with the specification (HID is surprisingly complicated). See https://www.bluetooth.com/develop-with-bluetooth/qualification-listing/qualification-test-tools/profile-tuning-suite

@jamesadevine FYI @finneyj FYI

@orklann
Copy link

orklann commented Aug 24, 2018

@jaustin
Can you share the code which builds into ble_app_hids_keyboard_gcc_combined_s130_hack.zip file?

@pelikhan
Copy link

Would be nice to resurect this eventually...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants