Skip to content

Commit

Permalink
Adds HAL Get Anchor Period command
Browse files Browse the repository at this point in the history
  • Loading branch information
danielgallagher0 committed Aug 19, 2018
1 parent 4fb8078 commit 0b43e98
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/command/hal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ pub trait Commands {
/// The controller will generate a [command
/// complete](::event::command::ReturnParameters::HalGetLinkStatus) event.
fn get_link_status(&mut self) -> nb::Result<(), Self::Error>;

/// This command is intended to retrieve information about the current Anchor Interval and
/// allocable timing slots.
///
/// # Errors
///
/// Only underlying communication errors are reported.
///
/// # Generated events
///
/// The controller will generate a [command
/// complete](::event::command::ReturnParameters::HalGetAnchorPeriod) event.
fn get_anchor_period(&mut self) -> nb::Result<(), Self::Error>;
}

impl<'spi, 'dbuf, SPI, OutputPin1, OutputPin2, InputPin, E> Commands
Expand Down Expand Up @@ -219,6 +232,10 @@ where
fn get_link_status(&mut self) -> nb::Result<(), Self::Error> {
self.write_command(::opcode::HAL_GET_LINK_STATUS, &[])
}

fn get_anchor_period(&mut self) -> nb::Result<(), Self::Error> {
self.write_command(::opcode::HAL_GET_ANCHOR_PERIOD, &[])
}
}

/// Potential errors from parameter validation.
Expand Down
33 changes: 33 additions & 0 deletions src/event/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ extern crate bluetooth_hci as hci;
use byteorder::{ByteOrder, LittleEndian};
use core::convert::{TryFrom, TryInto};
use core::fmt::{Debug, Formatter, Result as FmtResult};
use core::time::Duration;

/// Vendor-specific commands that may generate the [Command
/// Complete](hci::event::command::ReturnParameters::Vendor) event. If the commands have defined
Expand Down Expand Up @@ -46,6 +47,10 @@ pub enum ReturnParameters {
/// Status returned by the [HAL Get Link Status](::hal::Commands::get_link_status) command.
HalGetLinkStatus(HalLinkStatus),

/// Parameters returned by the [HAL Get Anchor Period](::hal::Commands::get_anchor_period)
/// command.
HalGetAnchorPeriod(HalAnchorPeriod),

/// Status returned by the [GAP Set Non-Discoverable](::gap::Commands::set_nondiscoverable)
/// command.
GapSetNonDiscoverable(hci::Status),
Expand Down Expand Up @@ -259,6 +264,9 @@ impl hci::event::VendorReturnParameters for ReturnParameters {
::opcode::HAL_GET_LINK_STATUS => Ok(ReturnParameters::HalGetLinkStatus(
to_hal_link_status(&bytes[3..])?,
)),
::opcode::HAL_GET_ANCHOR_PERIOD => Ok(ReturnParameters::HalGetAnchorPeriod(
to_hal_anchor_period(&bytes[3..])?,
)),
::opcode::GAP_SET_NONDISCOVERABLE => Ok(ReturnParameters::GapSetNonDiscoverable(
to_status(&bytes[3..])?,
)),
Expand Down Expand Up @@ -678,6 +686,31 @@ fn to_hal_link_status(
Ok(status)
}

/// Parameters returned by the [HAL Get Anchor Period](::hal::Commands::get_anchor_period) command.
#[derive(Clone, Debug)]
pub struct HalAnchorPeriod {
/// Did the command fail, and if so, how?
pub status: hci::Status,

/// Duration between the beginnings of sniff anchor points.
pub anchor_interval: Duration,

/// Maximum available size that can be allocated to a new connection slot.
pub max_slot: Duration,
}

fn to_hal_anchor_period(
bytes: &[u8],
) -> Result<HalAnchorPeriod, hci::event::Error<super::BlueNRGError>> {
require_len!(bytes, 9);

Ok(HalAnchorPeriod {
status: to_status(bytes)?,
anchor_interval: Duration::from_micros(625 * LittleEndian::read_u32(&bytes[1..5]) as u64),
max_slot: Duration::from_micros(625 * LittleEndian::read_u32(&bytes[5..9]) as u64),
})
}

/// Parameters returned by the [GAP Init](::gap::Commands::init) command.
#[derive(Copy, Clone, Debug)]
pub struct GapInit {
Expand Down
4 changes: 4 additions & 0 deletions src/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ opcodes! {
pub const HAL_START_TONE = 0x15;
pub const HAL_STOP_TONE = 0x16;
pub const HAL_GET_LINK_STATUS = 0x17;

// The documentation says the OCF is 0xF8 (0b1111_1000), but that does not fit the OCF
// length (7 bits). The C source code has 0x19, which is valid.
pub const HAL_GET_ANCHOR_PERIOD = 0x19;
}
Gap = 0x1;
{
Expand Down
25 changes: 25 additions & 0 deletions tests/command_complete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use bluenrg::event::command::*;
use bluenrg::event::*;
use hci::event::command::ReturnParameters as HciParams;
use hci::event::{Error as HciError, Event as HciEvent, Packet};
use std::time::Duration;

type Event = HciEvent<BlueNRGEvent>;

Expand Down Expand Up @@ -297,6 +298,30 @@ fn hal_get_firmware_revision() {
}
}

#[test]
fn hal_get_anchor_period() {
let buffer = [
0x0E, 12, 8, 0x19, 0xFC, 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
];
match Event::new(Packet(&buffer)) {
Ok(HciEvent::CommandComplete(event)) => {
assert_eq!(event.num_hci_command_packets, 8);
match event.return_params {
HciParams::Vendor(BNRGParams::HalGetAnchorPeriod(params)) => {
assert_eq!(params.status, hci::Status::Success);
assert_eq!(
params.anchor_interval,
Duration::from_micros(625 * 0x04030201)
);
assert_eq!(params.max_slot, Duration::from_micros(625 * 0x08070605));
}
other => panic!("Wrong return parameters: {:?}", other),
}
}
other => panic!("Did not get command complete event: {:?}", other),
}
}

#[test]
fn gap_init() {
let buffer = [
Expand Down
10 changes: 10 additions & 0 deletions tests/hal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,13 @@ fn get_link_status() {
assert!(fixture.wrote_header());
assert!(fixture.wrote(&[1, 0x17, 0xFC, 0]));
}

#[test]
fn get_anchor_period() {
let mut fixture = Fixture::new();
fixture
.act(|controller| controller.get_anchor_period())
.unwrap();
assert!(fixture.wrote_header());
assert!(fixture.wrote(&[1, 0x19, 0xFC, 0]));
}

0 comments on commit 0b43e98

Please sign in to comment.