Skip to content

Instantly share code, notes, and snippets.

@mschulz
Last active December 15, 2015 11:09

Revisions

  1. Mark Schulz revised this gist Mar 27, 2013. 1 changed file with 18 additions and 9 deletions.
    27 changes: 18 additions & 9 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -30,13 +30,22 @@ NRF24 nrf24;

    unsigned long swaplong(unsigned long src)
    {
    unsigned long tmp;
    typedef union {
    unsigned long l_word;
    unsigned char l_byte[sizeof(long)];
    } __attribute__((__packed__)) swapper;
    swapper tmp;
    unsigned char ooo;

    //Serial.println(src, HEX);
    tmp = (src >> 24) | (src << 24) | ((src >> 8) & 0x0000ff00) | ((src << 8) & 0x00ff0000);
    //Serial.println(tmp, HEX);
    return tmp;
    //return (src >> 24) | (src << 24) | ((src >> 8) & 0x0000ff00) | ((src << 8) & 0x00ff0000);
    tmp.l_word = src;
    ooo = tmp.l_byte[0];
    tmp.l_byte[0] = tmp.l_byte[3];
    tmp.l_byte[3] = ooo;

    ooo = tmp.l_byte[2];
    tmp.l_byte[2] = tmp.l_byte[1];
    tmp.l_byte[1] = ooo;
    return tmp.l_word;
    }

    unsigned long TEA_KEY[] = { 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF };
    @@ -61,19 +70,19 @@ void xxtea_decode(unsigned long v[], unsigned long len)

    z = v[1];
    tmp = v[2];
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[(2) ^ e] ^ z)));
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[2 ^ e] ^ z)));
    y = tmp - mx;
    v[2] = y;

    z = v[0];
    tmp = v[1];
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[(1) ^ e] ^ z)));
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[1 ^ e] ^ z)));
    y = tmp - mx;
    v[1] = y;

    z = v[3];
    tmp = v[0];
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[(0) ^ e] ^ z)));
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[0 ^ e] ^ z)));
    y = tmp - mx;
    v[0] = y;
    }
  2. Mark Schulz created this gist Mar 27, 2013.
    189 changes: 189 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,189 @@
    // Sniff the Openbeacon messages with the NRF24 class.
    // Feed the messages to the USB port for upstream processing,
    // hopefully using a Raspberry Pi. :-) This is much simpler than
    // using the Netduino as a base platform, running FreeRTOS. The real hassle
    // is to determine just how much processing to do on the Arduino, and how
    // much to leave for the upstream processor.
    //
    // Wire the Sparkfun nRF24L01+ breakout board with a Uno as follows (Arduino pin => Nordic pin)
    // GND == GND
    // 3.3V == Vcc
    // 11 == MOSI
    // 12 == MISO
    // 13 == SCK
    // 10 == CSN
    // 8 == CE
    // IRQ is left disconnected

    #include <NRF24.h>
    #include <SPI.h>

    #define XXTEA_BLOCK_COUNT 4

    typedef union {
    unsigned long data[XXTEA_BLOCK_COUNT];
    unsigned char datab[XXTEA_BLOCK_COUNT * 4];
    } __attribute__((__packed__)) TBeaconEnvelope;

    // Singleton instance of the radio
    NRF24 nrf24;

    unsigned long swaplong(unsigned long src)
    {
    unsigned long tmp;

    //Serial.println(src, HEX);
    tmp = (src >> 24) | (src << 24) | ((src >> 8) & 0x0000ff00) | ((src << 8) & 0x00ff0000);
    //Serial.println(tmp, HEX);
    return tmp;
    //return (src >> 24) | (src << 24) | ((src >> 8) & 0x0000ff00) | ((src << 8) & 0x00ff0000);
    }

    unsigned long TEA_KEY[] = { 0x00112233, 0x44556677, 0x8899AABB, 0xCCDDEEFF };
    #define TEA_ROUNDS_COUNT (6 + 52/4)
    #define DELTA 0x9e3779b9L

    void xxtea_decode(unsigned long v[], unsigned long len)
    {
    unsigned long z, y, sum, tmp, mx;
    unsigned char e;
    int q;

    y = v[0];
    for (sum = DELTA * TEA_ROUNDS_COUNT; sum != 0; sum -= DELTA) {
    e = sum >> 2 & 3;

    z = v[2];
    tmp = v[3];
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[3 ^ e] ^ z)));
    y = tmp - mx;
    v[3] = y;

    z = v[1];
    tmp = v[2];
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[(2) ^ e] ^ z)));
    y = tmp - mx;
    v[2] = y;

    z = v[0];
    tmp = v[1];
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[(1) ^ e] ^ z)));
    y = tmp - mx;
    v[1] = y;

    z = v[3];
    tmp = v[0];
    mx = ((((z >> 5) ^(y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((sum ^ y) + (TEA_KEY[(0) ^ e] ^ z)));
    y = tmp - mx;
    v[0] = y;
    }
    }

    void printMessage(unsigned char *buf, unsigned char len)
    {
    unsigned char i;

    Serial.print("M");
    for (i = 0; i < len; i++) {
    if (buf[i] < 0x10)
    Serial.print("0");
    Serial.print(buf[i], HEX);
    }
    Serial.println();

    //Serial.write(buf, len);
    }

    unsigned short
    crc16 (const unsigned char *buffer, int size)
    {
    unsigned short crc = 0xFFFF;

    if (buffer && size)
    while (size--) {
    crc = (crc >> 8) | (crc << 8);
    crc ^= *buffer++;
    crc ^= ((unsigned char) crc) >> 4;
    crc ^= crc << 12;
    crc ^= (crc & 0xFF) << 5;
    }
    return crc;
    }

    void setup()
    {
    unsigned char SMAC[] = {0x01, 0x02, 0x03, 0x02, 0x01};
    unsigned char TMAC[] = {'O', 'C', 'A', 'E', 'B'};

    Serial.begin(115200);

    nrf24.init();

    nrf24.spiWriteRegister(NRF24_REG_00_CONFIG, 0x00); // Stop nRF
    nrf24.spiWriteRegister(NRF24_REG_01_EN_AA, 0x00); //Disable Shockburst
    nrf24.spiWriteRegister(NRF24_REG_02_EN_RXADDR, NRF24_ERX_P0); //Set Rx Pipe 0
    nrf24.spiWriteRegister(NRF24_REG_03_SETUP_AW, NRF24_AW_5_BYTES); // Setup AW for 5 bytes

    if (!nrf24.setChannel(81))
    Serial.println("setChannel failed");

    if (!nrf24.setRF(NRF24::NRF24DataRate2Mbps, NRF24::NRF24TransmitPowerm18dBm))
    Serial.println("setRF failed");

    nrf24.spiWriteRegister(NRF24_REG_07_STATUS, NRF24_RX_DR|NRF24_TX_DS|NRF24_MAX_RT|0x08); // Clear status regsiter

    nrf24.spiBurstWriteRegister(NRF24_REG_0A_RX_ADDR_P0, SMAC, 5);

    nrf24.spiBurstWriteRegister(NRF24_REG_10_TX_ADDR, TMAC, 5);

    if (!nrf24.setPayloadSize(16))
    Serial.println("setPayloadSize failed");

    nrf24.spiWriteRegister(NRF24_REG_00_CONFIG, NRF24_MASK_RX_DR|NRF24_MASK_TX_DS|NRF24_MASK_MAX_RT|NRF24_EN_CRC|NRF24_PWR_UP|NRF24_PRIM_RX);
    }

    void loop()
    {
    unsigned char len;
    unsigned int i;
    TBeaconEnvelope g_Beacon;
    unsigned short crc;

    nrf24.powerUpRx();
    if (nrf24.spiReadRegister(NRF24_REG_07_STATUS) & NRF24_RX_DR) {
    if (nrf24.recv(g_Beacon.datab, &len)) {

    // Only accept 16 byte messages, for now
    if (len != 16) {
    Serial.print("B ytes in message not equal to 16");
    return;
    }

    /*
    * Decode the packet, then check the packet is not corrupted.
    */
    for (i = 0; i < len/4; i++)
    g_Beacon.data[i] = swaplong(g_Beacon.data[i]);
    xxtea_decode(g_Beacon.data, len/4);
    for (i = 0; i < len/4; i++)
    g_Beacon.data[i] = swaplong(g_Beacon.data[i]);

    /*
    *Pass up meesage to the upline processor via the serial connection (USB);
    *
    * Each line starts with a Tag characyer and a space and then any text you want.
    *
    * M<sp><16 bytes of messages as 16 pairs of hex characters
    *C<sp> <nothing, but here the details of the CRC failure>
    */

    crc = crc16(g_Beacon.datab, len);
    if (crc != 0) {
    Serial.print("CRC Error: 0x");
    Serial.println(crc, HEX);
    } else {
    printMessage(g_Beacon.datab, len);
    }
    }
    }
    }