Skip to content

Commit

Permalink
Implement creation of ble payload in userland
Browse files Browse the repository at this point in the history
 - adapt run parameters for tockloader
  • Loading branch information
torfmaster committed Jul 6, 2018
1 parent 812297d commit 090398c
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 111 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -2,6 +2,8 @@
# libtock-rs
Rust userland library for Tock (WIP)

Tested with tock a3b36d5872315ff05ef5ad34ed9453b0789218ce.

## Getting Started

This project is nascent and still under heavy development, but first steps:
Expand Down
35 changes: 20 additions & 15 deletions examples/ble_scanning.rs
@@ -1,14 +1,14 @@
#![no_std]
#![feature(alloc)]

#[allow(unused)]
#[macro_use]
extern crate alloc;
extern crate corepack;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate tock;

use alloc::Vec;
use tock::ble_parser;
use tock::led;
use tock::simple_ble::BleCallback;
Expand All @@ -25,21 +25,26 @@ struct LedCommand {
#[allow(unreachable_code)]
fn main() {
let mut shared_buffer = BleDriver::create_scan_buffer();
let mut my_buffer = BleDriver::create_scan_buffer();
let shared_memory = BleDriver::share_memory(&mut shared_buffer).unwrap();
let mut _my_buffer = BleDriver::create_scan_buffer();
let _shared_memory = BleDriver::share_memory(&mut shared_buffer).unwrap();

let mut callback = BleCallback::new(|_: usize, _: usize| {
shared_memory.read_bytes(&mut my_buffer);
match ble_parser::find(&my_buffer, tock::simple_ble::gap_data::SERVICE_DATA as u8) {
Some(payload) => {
let payload: Vec<u8> = payload.into_iter().map(|x| *x).collect::<Vec<u8>>();
let msg: LedCommand = corepack::from_bytes(payload.as_slice()).unwrap();
let msg_led = led::get(msg.nr as isize);
match msg_led {
Some(msg_led) => match msg.st {
true => msg_led.on(),
false => msg_led.off(),
},
_shared_memory.read_bytes(&mut _my_buffer);
match ble_parser::find(&_my_buffer, tock::simple_ble::gap_data::SERVICE_DATA as u8)
.and_then(|x| ble_parser::extract_for_service([91, 79], x))
{
Some(_payload) => {
let msg: Result<LedCommand, _> = corepack::from_bytes(&_payload);
match msg {
Ok(msg) => {
let led = led::get(msg.nr as isize);
match led {
Some(led) => {
led.set_state(msg.st);
}
None => (),
}
}
_ => (),
}
}
Expand Down
21 changes: 16 additions & 5 deletions examples/simple_ble.rs
Expand Up @@ -9,6 +9,8 @@ extern crate serde_derive;
extern crate tock;

use alloc::String;
use tock::ble_composer;
use tock::ble_composer::BlePayload;
use tock::led;
use tock::simple_ble::BleAdvertisingDriver;
use tock::timer;
Expand All @@ -25,14 +27,23 @@ fn main() {
let led = led::get(0).unwrap();

let name = String::from("Tock!");
let mut uuid: [u8; 2] = [0x18, 0x00];
let uuid: [u8; 2] = [0x00, 0x18];

let mut payload = corepack::to_bytes(LedCommand { nr: 2, st: true }).unwrap();
let payload = corepack::to_bytes(LedCommand { nr: 2, st: true }).unwrap();

let mut buffer = BleAdvertisingDriver::create_advertising_buffer();
let handle =
BleAdvertisingDriver::initialize(100, name, &mut uuid, true, &mut payload, &mut buffer)
.unwrap();
let mut gap_payload = BlePayload::new();
gap_payload.add_flag(ble_composer::flags::LE_GENERAL_DISCOVERABLE);

gap_payload.add(ble_composer::gap_types::UUID, &uuid);

gap_payload.add(
ble_composer::gap_types::COMPLETE_LOCAL_NAME,
name.as_bytes(),
);
gap_payload.add_service_payload([91, 79], &payload);

let handle = BleAdvertisingDriver::initialize(100, &gap_payload, &mut buffer).unwrap();

loop {
led.on();
Expand Down
6 changes: 3 additions & 3 deletions run_example.sh
Expand Up @@ -21,9 +21,9 @@ then
then
echo "do not delete apps from board."
else
tockloader uninstall --jtag --arch cortex-m4 --board nrf52-dk --jtag-device nrf52 --app-address 0x20000 || true
tockloader uninstall --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 || true
fi
else
tockloader uninstall --jtag --arch cortex-m4 --board nrf52-dk --jtag-device nrf52 --app-address 0x20000 || true
tockloader uninstall --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 || true
fi
tockloader install --jtag --arch cortex-m4 --board nrf52-dk --jtag-device nrf52 --app-address 0x20000 "$tab_file_name"
tockloader install --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 "$tab_file_name"
2 changes: 1 addition & 1 deletion run_hardware_test.sh
Expand Up @@ -4,7 +4,7 @@

set -eux

yes 0|tockloader uninstall --jtag --arch cortex-m4 --board nrf52-dk --jtag-device nrf52 --app-address 0x20000 || true
yes 0|tockloader uninstall --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 || true

./run_example.sh hardware_test_server --dont-clear-apps
./run_example.sh hardware_test --dont-clear-apps
2 changes: 1 addition & 1 deletion run_ipc_example.sh
Expand Up @@ -4,7 +4,7 @@

set -eux

yes 0|tockloader uninstall --jtag --arch cortex-m4 --board nrf52-dk --jtag-device nrf52 --app-address 0x20000 || true
yes 0|tockloader uninstall --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 --app-address 0x20000 || true

./run_example.sh ipcclient --dont-clear-apps
./run_example.sh ipcserver --dont-clear-apps
64 changes: 64 additions & 0 deletions src/ble_composer.rs
@@ -0,0 +1,64 @@
use alloc::*;

pub mod gap_types {
pub static COMPLETE_LOCAL_NAME: u8 = 0x09;
pub static SERVICE_DATA: u8 = 0x16;
pub static UUID: u8 = 0x02;
pub static FLAGS: u8 = 0x01;
}

pub mod flags {
pub static LE_GENERAL_DISCOVERABLE: u8 = 0x01;
}

pub struct BlePayload {
pub bytes: Vec<u8>,
}

impl BlePayload {
pub fn add(&mut self, kind: u8, content: &[u8]) {
self.bytes.push((content.len() + 1) as u8);
self.bytes.push(kind);
for e in content {
self.bytes.push(*e);
}
}

pub fn add_flag(&mut self, flag: u8) {
self.bytes.push(2);
self.bytes.push(gap_types::FLAGS);
self.bytes.push(flag);
}

pub fn new() -> Self {
BlePayload { bytes: Vec::new() }
}

pub fn add_service_payload(&mut self, uuid: [u8; 2], content: &[u8]) {
self.bytes.push((content.len() + 3) as u8);
self.bytes.push(gap_types::SERVICE_DATA);
self.bytes.push(uuid[0]);
self.bytes.push(uuid[1]);
for e in content {
self.bytes.push(*e);
}
}
}

#[cfg(test)]
mod test {
use ble_composer::*;
#[test]
pub fn test_add() {
let mut pld = BlePayload::new();
pld.add(1, &[2]);
assert_eq!(pld.bytes, vec![2, 1, 2])
}

#[test]
pub fn test_add_service_payload() {
let mut pld = BlePayload::new();
pld.add_service_payload([1, 2], &[2]);
assert_eq!(pld.bytes, &[4, 0x16, 1, 2, 2])
}
}
56 changes: 42 additions & 14 deletions src/ble_parser.rs
@@ -1,14 +1,16 @@
use alloc::*;

pub fn find(buffer: &[u8], kind: u8) -> Option<Vec<&u8>> {
let mut iter = buffer[8..].iter();
pub fn find(buffer: &[u8], kind: u8) -> Option<&[u8]> {
let mut iter = buffer[8..].iter().enumerate();
let buffer_len = buffer.len();

loop {
match iter.next() {
Some(&len) => {
let data_type = iter.next();
if data_type == Some(&kind) {
return Some(iter.take(len as usize - 1).collect::<Vec<&u8>>());
Some((_, &len)) => match iter.next() {
Some((i, potentialkind)) => if potentialkind == &kind {
if (8 + i) + len as usize > buffer_len {
return None;
} else {
return Some(&buffer[9 + i..8 + i + len as usize]);
}
} else {
if len > 0 {
for _ in 0..len - 1 {
Expand All @@ -17,12 +19,26 @@ pub fn find(buffer: &[u8], kind: u8) -> Option<Vec<&u8>> {
} else {
return None;
}
}
}
},
_ => return None,
},
None => return None,
}
}
}

pub fn extract_for_service(service: [u8; 2], data: &[u8]) -> Option<&[u8]> {
if data.len() > 1 {
if service[0] == data[0] && service[1] == data[1] {
Some(&data[2..])
} else {
None
}
} else {
None
}
}

#[cfg(test)]
mod test {
use ble_parser::*;
Expand All @@ -39,10 +55,10 @@ mod test {
];
slice.clone_from_slice(data);
}
assert_eq!(find(&buf, 0x02), Some(vec![&0x01]));
assert_eq!(find(&buf, 0x01), Some(vec![&0x03]));
assert_eq!(find(&buf, 0x16), Some(vec![&0x01, &0x02]));
assert_eq!(find(&buf, 0xFF), Some(vec![&0x01, &0x02, &0x03]));
assert_eq!(find(&buf, 0x02), Some(&[0x01][0..1]));
assert_eq!(find(&buf, 0x01), Some(&[0x03][0..1]));
assert_eq!(find(&buf, 0x16), Some(&[0x01, 0x02][0..2]));
assert_eq!(find(&buf, 0xFF), Some(&[0x01, 0x02, 0x03][0..3]));
}

#[test]
Expand All @@ -54,4 +70,16 @@ mod test {
slice.clone_from_slice(data);
}
}

#[test]
pub fn ignores_illegal_lengths_in_packets() {
let mut buf = [0; 11];
{
let slice = &mut buf[8..10];
let data = &[0x04, 0x02];
slice.clone_from_slice(data);
}
assert_eq!(find(&buf, 0xF2), None);
}

}
1 change: 1 addition & 0 deletions src/lib.rs
Expand Up @@ -5,6 +5,7 @@ extern crate alloc;

mod callback;

pub mod ble_composer;
pub mod ble_parser;
pub mod buttons;
pub mod console;
Expand Down

0 comments on commit 090398c

Please sign in to comment.