Skip to content

Commit

Permalink
receive 32 bytes of BLE advertising packets on channel 38
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeryan committed Dec 5, 2018
1 parent 3d68f0c commit f844b6c
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -5,6 +5,7 @@ TARGET = uberducky

# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
ble.c \
hid.c \
script.c \
usb.c \
Expand Down
109 changes: 109 additions & 0 deletions ble.c
@@ -0,0 +1,109 @@
/*
* Copyright 2019 Mike Ryan
*
* This file is part of Uberducky and is released under the terms of the
* GPL version 2. Refer to COPYING for more information.
*/

#include "ble.h"

#include "ubertooth.h"

// advertising channel 38
uint16_t rf_channel = 2426;

// initialize RF and strobe FSON
static void cc2400_init_rf(void) {
u16 grmdm, mdmctrl;
uint32_t sync = rbit(0x8e89bed6);

mdmctrl = 0x0040; // 250 kHz frequency deviation
grmdm = 0x4CE1; // un-buffered mode, packet w/ sync word detection
// 0 10 01 1 001 11 0 00 0 1
// | | | | | +--------> CRC off
// | | | | +-----------> sync word: 32 MSB bits of SYNC_WORD
// | | | +---------------> 1 preamble byte of 01010101
// | | +-----------------> packet mode
// | +--------------------> buffered mode
// +-----------------------> sync error bits: 2

cc2400_set(MANAND, 0x7ffe);
cc2400_set(LMTST, 0x2b22);

cc2400_set(MDMTST0, 0x124b);
// 1 2 4b
// 00 0 1 0 0 10 01001011
// | | | | | +---------> AFC_DELTA = ??
// | | | | +------------> AFC settling = 4 pairs (8 bit preamble)
// | | | +--------------> no AFC adjust on packet
// | | +----------------> do not invert data
// | +------------------> TX IF freq 1 0Hz
// +--------------------> PRNG off
//
// ref: CC2400 datasheet page 67
// AFC settling explained page 41/42

cc2400_set(GRMDM, grmdm);

cc2400_set(SYNCL, sync & 0xffff);
cc2400_set(SYNCH, (sync >> 16) & 0xffff);

cc2400_set(FSDIV, rf_channel - 1); // 1 MHz IF
cc2400_set(MDMCTRL, mdmctrl);

// XOSC16M should always be stable, but leave this test anyway
while (!(cc2400_status() & XOSC16M_STABLE));

// wait for FS_LOCK
cc2400_strobe(SFSON);
while (!(cc2400_status() & FS_LOCK)) ;
}

// dewhiten and reverse the bit order of a packet in place
static void ble_dewhiten(uint8_t *pkt, unsigned len) {
unsigned i;
uint32_t *pkt_out = (void *)pkt;

uint32_t dewhiten[] = {
0x2044c5d6, 0x8fe1de59, 0x42afa51b, 0x60cd4e7b, 0x902262eb, 0xc7f0ef2c,
0xa157d28d, 0xb066a73d, 0x48113175, 0xe3f87796, 0xd0abe946, 0xd833539e,
};

for (i = 0; i < len; i+= 4) {
uint32_t v = pkt[i+0] << 24
| pkt[i+1] << 16
| pkt[i+2] << 8
| pkt[i+3] << 0;
pkt_out[i/4] = rbit(v) ^ dewhiten[i/4];
}
}

void ble_init(void) {
cc2400_strobe(SRFOFF);
while (cc2400_status() & FS_LOCK) ;

cc2400_init_rf();
cc2400_strobe(SRX);
}

int ble_get_packet(uint8_t *pkt) {
unsigned i;

// when the FIFO is full the radio state returns to FS_ON
if ((cc2400_get(FSMSTATE) & 0x1f) != STATE_STROBE_FS_ON)
return 0;

// load all bytes into buffer
for (i = 0; i < BLE_PACKET_SIZE; ++i)
pkt[i] = cc2400_get8(FIFOREG);

// dewhiten
ble_dewhiten(pkt, BLE_PACKET_SIZE);

// restart RF
while (!(cc2400_status() & FS_LOCK)) ;
cc2400_strobe(SRX);
while ((cc2400_get(FSMSTATE) & 0x1f) != STATE_STROBE_RX) ;

return 1;
}
11 changes: 11 additions & 0 deletions ble.h
@@ -0,0 +1,11 @@
#ifndef __BLE_H__
#define __BLE_H__

#include <stdint.h>

#define BLE_PACKET_SIZE 32

void ble_init(void);
int ble_get_packet(uint8_t *pkt);

#endif /* __BLE_H__ */
19 changes: 19 additions & 0 deletions uberducky.c
Expand Up @@ -6,6 +6,8 @@
*/

#include "hid.h"
#include "ble.h"

#include "type.h"
#include "ubertooth.h"
#include "usbapi.h"
Expand Down Expand Up @@ -211,12 +213,20 @@ void TIMER0_IRQHandler(void) {
}
}
}

// LEDs
if (T0IR & TIR_MR1_Interrupt) {
T0IR = TIR_MR1_Interrupt;
RXLED_CLR;
}
}

// from usb.c
void usb_init(void);

int main() {
uint8_t ble_packet[BLE_PACKET_SIZE];

ubertooth_init();

timer0_start();
Expand All @@ -225,10 +235,19 @@ int main() {
timer0_set_match(NOW + 2000);

usb_init();
ble_init();

// call USB interrupt handler continuously
while (1) {
USBHwISR();

// fetch BLE packets
if (ble_get_packet(ble_packet)) {
// blink LED - TODO something more interesting
RXLED_SET;
T0MR1 = NOW + 10;
T0MCR |= TMCR_MR1I;
}
}

return 0;
Expand Down

0 comments on commit f844b6c

Please sign in to comment.