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

feat: Refactor and implement input report for ble #33

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions lib/rktk-drivers-nrf/src/softdevice/ble/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,3 @@ pub const HARDWARE_REVISION: Uuid = Uuid::new_16(0x2a27);
pub const SOFTWARE_REVISION: Uuid = Uuid::new_16(0x2a28);
pub const MANUFACTURER_NAME: Uuid = Uuid::new_16(0x2a29);
pub const PNP_ID: Uuid = Uuid::new_16(0x2a50);

pub const HID_INFO: Uuid = Uuid::new_16(0x2a4a);
pub const REPORT_MAP: Uuid = Uuid::new_16(0x2a4b);
pub const HID_CONTROL_POINT: Uuid = Uuid::new_16(0x2a4c);
pub const HID_REPORT: Uuid = Uuid::new_16(0x2a4d);
pub const PROTOCOL_MODE: Uuid = Uuid::new_16(0x2a4e);
pub const HID_REPORT_REF: Uuid = Uuid::new_16(0x2908);
16 changes: 11 additions & 5 deletions lib/rktk-drivers-nrf/src/softdevice/ble/server.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use nrf_softdevice::{
ble::{
gatt_server::{self, RegisterError, WriteOp},
gatt_server::{self, RegisterError, Service as _, WriteOp},
Connection,
},
Softdevice,
Expand All @@ -9,7 +9,7 @@ use nrf_softdevice::{
use super::services::{
battery::BatteryService,
device_information::{DeviceInformation, DeviceInformationService, PnPID, VidSource},
hid::HidService,
hid::{HidService, HidServiceEvent},
};

pub struct Server {
Expand Down Expand Up @@ -47,18 +47,24 @@ impl Server {
}
}

pub enum ServerEvent {
Hid(HidServiceEvent),
}

impl gatt_server::Server for Server {
type Event = ();
type Event = ServerEvent;

fn on_write(
&self,
conn: &Connection,
_conn: &Connection,
handle: u16,
_op: WriteOp,
_offset: usize,
data: &[u8],
) -> Option<Self::Event> {
self.hid.on_write(conn, handle, data);
if let Some(e) = self.hid.on_write(handle, data) {
return Some(Self::Event::Hid(e));
};
self.bas.on_write(handle, data);
None
}
Expand Down
240 changes: 89 additions & 151 deletions lib/rktk-drivers-nrf/src/softdevice/ble/services/hid.rs
Original file line number Diff line number Diff line change
@@ -1,155 +1,93 @@
use descriptor::{BleCompositeReportType, BleKeyboardReport};
use nrf_softdevice::{
ble::{
gatt_server::{
self,
builder::ServiceBuilder,
characteristic::{Attribute, Metadata, Properties},
NotifyValueError, RegisterError,
},
Connection, SecurityMode, Uuid,
},
Softdevice,
};
use descriptor::{BleHidReport, BleHidReportKind};
use nrf_softdevice::ble::{gatt_server::NotifyValueError, Connection};
use ssmarshal::serialize;
use usbd_hid::descriptor::SerializedDescriptor as _;

use crate::softdevice::ble::HidReport;

use super::super::constant::*;

mod descriptor;

#[allow(dead_code)]
pub const HID_INFO: [u8; 4] = [
0x11u8, 0x1u8, // HID version: 1.1
0x00u8, // Country Code
0x01u8, // Remote wake + Normally Connectable
];

#[nrf_softdevice::gatt_service(uuid = "1812")]
pub struct HidService {
hid_info: u16,
report_map: u16,
hid_control: u16,
protocol_mode: u16,
input_keyboard: u16,
input_keyboard_cccd: u16,
input_keyboard_descriptor: u16,
output_keyboard: u16,
output_keyboard_descriptor: u16,
input_media_keys: u16,
input_media_keys_cccd: u16,
input_media_keys_descriptor: u16,
input_mouse: u16,
input_mouse_cccd: u16,
input_mouse_descriptor: u16,
#[characteristic(uuid = "2A4A", security = "justworks", read, value = "HID_INFO")]
pub hid_info: u8,

#[characteristic(
uuid = "2A4B", // REPORT_MAP
security = "justworks",
read,
value = "BleHidReport::desc()"
)]
pub report_map: u8,

#[characteristic(
uuid = "2A4C", // CONTROL_POINT
security = "justworks",
write_without_response,
value = "[0u8]"
)]
pub control_point: u8,

#[characteristic(
uuid = "2A4E", // PROTOCOL_MODE
security = "justworks",
read,
write_without_response,
value = "[1u8]"
)]
pub protocl_mode: u8,

#[characteristic(
uuid = "2A4D", // HID_REPORT
security = "justworks",
read,
notify,
value = "[0u8, 1u8]",
// HID_REPORT_REF, Keyboard, input
descriptor(uuid = "2908", security = "justworks", value = "[BleHidReportKind::Keyboard as u8, 1u8]")
)]
pub keyboard_input_report: [u8; 8],

#[characteristic(
uuid = "2A4D", // HID_REPORT
security = "justworks",
read,
write,
write_without_response,
value = "[0u8, 1u8]",
// HID_REPORT_REF, Keyboard, output
descriptor(uuid = "2908", security = "justworks", value = "[BleHidReportKind::Keyboard as u8, 2u8]"),
)]
pub keyboard_output_report: u8,

#[characteristic(
uuid = "2A4D", // HID_REPORT
security = "justworks",
read,
notify,
value = "[0u8; 5]",
descriptor(uuid = "2908", security = "justworks", value = "[BleHidReportKind::Mouse as u8, 1u8]"), // HID_REPORT_REF
)]
pub mouse_input_report: [u8; 5],

#[characteristic(
uuid = "2A4D", // HID_REPORT
security = "justworks",
read,
notify,
value = "[0u8; 2]",
descriptor(uuid = "2908", security = "justworks", value = "[BleHidReportKind::Media as u8, 1u8]"), // HID_REPORT_REF
)]
pub media_input_report: [u8; 2],
}

impl HidService {
pub fn new(sd: &mut Softdevice) -> Result<Self, RegisterError> {
let mut service_builder = ServiceBuilder::new(sd, Uuid::new_16(0x1812))?;

let hid_info = service_builder.add_characteristic(
HID_INFO,
Attribute::new([
0x11u8, 0x1u8, // HID version: 1.1
0x00u8, // Country Code
0x01u8, // Remote wake + Normally Connectable
])
.security(SecurityMode::JustWorks),
Metadata::new(Properties::new().read()),
)?;
let hid_info_handle = hid_info.build();

let report_map = service_builder.add_characteristic(
REPORT_MAP,
Attribute::new(BleKeyboardReport::desc()).security(SecurityMode::JustWorks),
Metadata::new(Properties::new().read()),
)?;
let report_map_handle = report_map.build();

let hid_control = service_builder.add_characteristic(
HID_CONTROL_POINT,
Attribute::new([0u8]).security(SecurityMode::JustWorks),
Metadata::new(Properties::new().write_without_response()),
)?;
let hid_control_handle = hid_control.build();

let protocol_mode = service_builder.add_characteristic(
PROTOCOL_MODE,
Attribute::new([1u8]).security(SecurityMode::JustWorks),
Metadata::new(Properties::new().read().write_without_response()),
)?;
let protocol_mode_handle = protocol_mode.build();

let mut input_keyboard = service_builder.add_characteristic(
HID_REPORT,
Attribute::new([0u8; 8]).security(SecurityMode::JustWorks),
Metadata::new(Properties::new().read().notify()),
)?;
let input_keyboard_desc = input_keyboard.add_descriptor(
Uuid::new_16(0x2908),
Attribute::new([
BleCompositeReportType::Keyboard as u8,
1u8, // in/out
])
.security(SecurityMode::JustWorks),
)?;
let input_keyboard_handle = input_keyboard.build();

let mut output_keyboard = service_builder.add_characteristic(
HID_REPORT,
Attribute::new([0u8; 8]).security(SecurityMode::JustWorks),
Metadata::new(Properties::new().read().write().write_without_response()),
)?;
let output_keyboard_desc = output_keyboard.add_descriptor(
HID_REPORT_REF,
Attribute::new([BleCompositeReportType::Keyboard as u8, 2u8])
.security(SecurityMode::JustWorks),
)?;
let output_keyboard_handle = output_keyboard.build();

let mut input_media_keys = service_builder.add_characteristic(
HID_REPORT,
Attribute::new([0u8; 2]).security(SecurityMode::JustWorks),
Metadata::new(Properties::new().read().notify()),
)?;
let input_media_keys_desc = input_media_keys.add_descriptor(
HID_REPORT_REF,
Attribute::new([BleCompositeReportType::Media as u8, 1u8])
.security(SecurityMode::JustWorks),
)?;
let input_media_keys_handle = input_media_keys.build();

let mut input_mouse = service_builder.add_characteristic(
HID_REPORT,
Attribute::new([0u8; 5]).security(SecurityMode::JustWorks),
Metadata::new(Properties::new().read().write().notify()),
)?;
let input_mouse_desc = input_mouse.add_descriptor(
HID_REPORT_REF,
Attribute::new([BleCompositeReportType::Mouse as u8, 1u8])
.security(SecurityMode::JustWorks),
)?;
let input_mouse_handle = input_mouse.build();

let _service_handle = service_builder.build();

Ok(HidService {
hid_info: hid_info_handle.value_handle,
report_map: report_map_handle.value_handle,
hid_control: hid_control_handle.value_handle,
protocol_mode: protocol_mode_handle.value_handle,
input_keyboard: input_keyboard_handle.value_handle,
input_keyboard_cccd: input_keyboard_handle.cccd_handle,
input_keyboard_descriptor: input_keyboard_desc.handle(),
output_keyboard: output_keyboard_handle.value_handle,
output_keyboard_descriptor: output_keyboard_desc.handle(),
input_media_keys: input_media_keys_handle.value_handle,
input_media_keys_cccd: input_media_keys_handle.cccd_handle,
input_media_keys_descriptor: input_media_keys_desc.handle(),
input_mouse: input_mouse_handle.value_handle,
input_mouse_cccd: input_mouse_handle.cccd_handle,
input_mouse_descriptor: input_mouse_desc.handle(),
})
}

pub fn on_write(&self, _conn: &Connection, _handle: u16, _data: &[u8]) {}

pub fn send_report(
&self,
conn: &Connection,
Expand All @@ -158,20 +96,20 @@ impl HidService {
match report {
HidReport::Keyboard(r) => {
let mut buf = [0u8; 8];
if let Ok(n) = serialize(&mut buf, &r) {
gatt_server::notify_value(conn, self.input_keyboard, &buf[0..n])?;
if let Ok(_n) = serialize(&mut buf, &r) {
self.keyboard_input_report_notify(conn, &buf)?;
}
}
HidReport::MediaKeyboard(r) => {
let mut buf = [0u8; 8];
if let Ok(n) = serialize(&mut buf, &r) {
gatt_server::notify_value(conn, self.input_media_keys, &buf[0..n])?;
HidReport::Mouse(r) => {
let mut buf = [0u8; 5];
if let Ok(_n) = serialize(&mut buf, &r) {
self.mouse_input_report_notify(conn, &buf)?;
}
}
HidReport::Mouse(r) => {
let mut buf = [0u8; 8];
if let Ok(n) = serialize(&mut buf, &r) {
gatt_server::notify_value(conn, self.input_mouse, &buf[0..n])?;
HidReport::MediaKeyboard(r) => {
let mut buf = [0u8; 2];
if let Ok(_n) = serialize(&mut buf, &r) {
self.media_input_report_notify(conn, &buf)?;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use usbd_hid::descriptor::generator_prelude::*;
},
)]
#[allow(dead_code)]
pub struct BleKeyboardReport {
pub struct BleHidReport {
pub modifier: u8,
pub reserved: u8,
pub leds: u8,
Expand All @@ -76,7 +76,7 @@ pub struct BleKeyboardReport {

#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) enum BleCompositeReportType {
pub(crate) enum BleHidReportKind {
Keyboard = 0x01,
Mouse = 0x02,
Media = 0x03,
Expand Down
Loading