From 3b97f99facfbba2f060230b53507ddc4fdb5c5a9 Mon Sep 17 00:00:00 2001 From: dberenguer Date: Fri, 19 Jun 2015 11:03:32 +0200 Subject: [PATCH] First upload to the new independent repository --- README.txt | 19 ++++ commonregs.h | 226 +++++++++++++++++++++++++++++++++++++++++ config.h | 44 ++++++++ datatypes.h | 40 ++++++++ library.properties | 9 ++ nvolat.h | 53 ++++++++++ register.cpp | 113 +++++++++++++++++++++ register.h | 176 ++++++++++++++++++++++++++++++++ repeater.cpp | 151 ++++++++++++++++++++++++++++ repeater.h | 114 +++++++++++++++++++++ swap.cpp | 245 +++++++++++++++++++++++++++++++++++++++++++++ swap.h | 242 ++++++++++++++++++++++++++++++++++++++++++++ swcommand.cpp | 54 ++++++++++ swcommand.h | 48 +++++++++ swpacket.cpp | 235 +++++++++++++++++++++++++++++++++++++++++++ swpacket.h | 201 +++++++++++++++++++++++++++++++++++++ swquery.cpp | 52 ++++++++++ swquery.h | 44 ++++++++ swstatus.cpp | 52 ++++++++++ swstatus.h | 46 +++++++++ swvalue.h | 105 +++++++++++++++++++ 21 files changed, 2269 insertions(+) create mode 100755 README.txt create mode 100755 commonregs.h create mode 100755 config.h create mode 100755 datatypes.h create mode 100755 library.properties create mode 100755 nvolat.h create mode 100755 register.cpp create mode 100755 register.h create mode 100755 repeater.cpp create mode 100755 repeater.h create mode 100755 swap.cpp create mode 100755 swap.h create mode 100755 swcommand.cpp create mode 100755 swcommand.h create mode 100755 swpacket.cpp create mode 100755 swpacket.h create mode 100755 swquery.cpp create mode 100755 swquery.h create mode 100755 swstatus.cpp create mode 100755 swstatus.h create mode 100755 swvalue.h diff --git a/README.txt b/README.txt new file mode 100755 index 0000000..27a9e9c --- /dev/null +++ b/README.txt @@ -0,0 +1,19 @@ +This library for Arduino IDE 1.6 implements SWAP on top of any existing +ISM radio as far as the necessary hardware cores exist. Take a look at +our repository containing the cores to see how to port your radio for SWAP. + +https://github.com/panStamp/panstamp/wiki + +SWAP stands for Simple Wireless Abstract Protocol and is designed to turn +simple wireless nodes into powerful interoperable devices programmable +the Arduino IDE: + +https://github.com/panStamp/panstamp/wiki/Simple%20Wireless%20Abstract%20Protocol + +panStamp is fully supporting SWAP, which has proven to be a serious +alternative to other oversized and overkilled protocols like Zigbee. +SWAP usually requires less than 8 KB of flash space and less than 1 KB of RAM. + +SWAP is not a true MESH technology. However, it is able to implement a good +amount of very different topologies, including star, point-to-point and +mixed coordinated-autonomous cells. diff --git a/commonregs.h b/commonregs.h new file mode 100755 index 0000000..92cebef --- /dev/null +++ b/commonregs.h @@ -0,0 +1,226 @@ +/** + * Copyright (c) 2014 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 07/06/2011 + */ + +#ifndef _COMMONREGS_H +#define _COMMONREGS_H + +#include "swstatus.h" +#include "nvolat.h" +#include "register.h" +#include "register.h" +#include "swap.h" + +const void setSysState(uint8_t id, uint8_t *state); +const void setFreqChannel(uint8_t id, uint8_t *channel); +const void setDevAddress(uint8_t id, uint8_t *addr); +const void setNetworkId(uint8_t rId, uint8_t *nId); +const void setTxInterval(uint8_t id, uint8_t *interval); + +#define DECLARE_COMMON_CALLBACKS() + +/** + * Macros for the definition of common register indexes + */ +#define DEFINE_COMMON_REGINDEX_START() \ +enum CUSTOM_REGINDEX \ +{ \ + REGI_PRODUCTCODE = 0, \ + REGI_HWVERSION, \ + REGI_FWVERSION, \ + REGI_SYSSTATE, \ + REGI_FREQCHANNEL, \ + REGI_SECUOPTION, \ + REGI_PASSWORD, \ + REGI_SECUNONCE, \ + REGI_NETWORKID, \ + REGI_DEVADDRESS, \ + REGI_TXINTERVAL, + +#define DEFINE_COMMON_REGINDEX_END() }; + +#define DEFINE_REGINDEX_START() DEFINE_COMMON_REGINDEX_START() +#define DEFINE_REGINDEX_END() DEFINE_COMMON_REGINDEX_END() + +/** + * Macro for the definition of registers common to all SWAP devices + */ +#define DEFINE_COMMON_REGISTERS() \ +/* Product code */ \ +static uint8_t dtProductCode[8] = {(uint8_t)(SWAP_MANUFACT_ID >> 24), (uint8_t)(SWAP_MANUFACT_ID >> 16) , (uint8_t)(SWAP_MANUFACT_ID >> 8), (uint8_t)(SWAP_MANUFACT_ID), \ + (uint8_t)(SWAP_PRODUCT_ID >> 24), (uint8_t)(SWAP_PRODUCT_ID >> 16) , (uint8_t)(SWAP_PRODUCT_ID >> 8), (uint8_t)(SWAP_PRODUCT_ID)}; \ +REGISTER regProductCode(dtProductCode, sizeof(dtProductCode), NULL, NULL); \ +/* Hardware version */ \ +static uint8_t dtHwVersion[4] = {(uint8_t)(HARDWARE_VERSION >> 24), (uint8_t)(HARDWARE_VERSION >> 16) , (uint8_t)(HARDWARE_VERSION >> 8), (uint8_t)(HARDWARE_VERSION)}; \ +REGISTER regHwVersion(dtHwVersion, sizeof(dtHwVersion), NULL, NULL); \ +/* Firmware version */ \ +static uint8_t dtFwVersion[4] = {(uint8_t)(FIRMWARE_VERSION >> 24), (uint8_t)(FIRMWARE_VERSION >> 16) , (uint8_t)(FIRMWARE_VERSION >> 8), (uint8_t)(FIRMWARE_VERSION)}; \ +REGISTER regFwVersion(dtFwVersion, sizeof(dtFwVersion), NULL, NULL); \ +/* System state */ \ +REGISTER regSysState(&swap.systemState, sizeof(swap.systemState), NULL, &setSysState); \ +/* Frequency channel */ \ +REGISTER regFreqChannel(&panstamp.radio.channel, sizeof(panstamp.radio.channel), NULL, &setFreqChannel, SWDTYPE_INTEGER, NVOLAT_FREQ_CHANNEL); \ +/* Security option */ \ +REGISTER regSecuOption(&swap.security, sizeof(swap.security), NULL, NULL); \ +/* Security password (not implemented yet) */ \ +static uint8_t dtPassword[1]; \ +REGISTER regPassword(dtPassword, sizeof(dtPassword), NULL, NULL); \ +/* Security nonce */ \ +REGISTER regSecuNonce(&swap.nonce, sizeof(swap.nonce), NULL, NULL); \ +/* Network Id */ \ +REGISTER regNetworkId(panstamp.radio.syncWord, sizeof(panstamp.radio.syncWord), NULL, &setNetworkId, SWDTYPE_OTHER, NVOLAT_SYNC_WORD); \ +/* Device address */ \ +REGISTER regDevAddress((uint8_t*)&swap.devAddress, sizeof(swap.devAddress), NULL, &setDevAddress, SWDTYPE_INTEGER, NVOLAT_DEVICE_ADDRESS); \ +/* Periodic Tx interval */ \ +REGISTER regTxInterval((uint8_t*)&swap.txInterval, sizeof(swap.txInterval), NULL, &setTxInterval, SWDTYPE_INTEGER, NVOLAT_TX_INTERVAL); + +/** + * Macros for the declaration of global table of registers + */ +#define DECLARE_REGISTERS_START() \ +REGISTER *regTable[] = { \ + ®ProductCode, \ + ®HwVersion, \ + ®FwVersion, \ + ®SysState, \ + ®FreqChannel, \ + ®SecuOption, \ + ®Password, \ + ®SecuNonce, \ + ®NetworkId, \ + ®DevAddress, \ + ®TxInterval, + +#define DECLARE_REGISTERS_END() \ +}; \ +/* Size of regTable */ \ +uint8_t regTableSize = sizeof(regTable)/sizeof(*regTable); + +/** + * Macro for the definition of getter/setter functions related to all common registers + */ +#define DEFINE_COMMON_CALLBACKS() \ +/** \ + * setSysState \ + * \ + * Set system state \ + * \ + * 'id' Register ID \ + * 'state' New system state \ + */ \ +const void setSysState(uint8_t id, uint8_t *state) \ +{ \ + swap.systemState = state[0]; \ + switch(state[0]) \ + { \ + case SYSTATE_RESTART: \ + /* Send status message before restarting the mote */ \ + swap.getRegister(REGI_SYSSTATE)->sendSwapStatus(); \ + panstamp.reset(); \ + break; \ + case SYSTATE_UPGRADE: \ + panstamp.goToWirelessBoot(); \ + break; \ + default: \ + break; \ + } \ +} \ + \ +/** \ + * setFreqChannel \ + * \ + * Set frequency channel \ + * \ + * 'id' Register ID \ + * 'channel' New channel \ + */ \ +const void setFreqChannel(uint8_t id, uint8_t *channel) \ +{ \ + if (channel[0] != regFreqChannel.value[0]) \ + { \ + /* Send status message before entering the new \ + frequency channel */ \ + SWSTATUS packet = SWSTATUS(regFreqChannel.id, channel, regFreqChannel.length); \ + packet.send(); \ + /* Update register value */ \ + panstamp.radio.setChannel(channel[0]); \ + /* Restart device */ \ + panstamp.reset(); \ + } \ +} \ + \ + \ +/** \ + * setDevAddress \ + * \ + * Set device address \ + * \ + * 'id' Register ID \ + * 'addr' New device address \ + */ \ +const void setDevAddress(uint8_t id, uint8_t *addr) \ +{ \ + /* Send status before setting the new address */ \ + SWSTATUS packet = SWSTATUS(regDevAddress.id, addr, regDevAddress.length); \ + packet.send(); \ + /* Set new SWAP address. BE to LE conversion */ \ + regDevAddress.setValueFromBeBuffer(addr); \ + /* Update register value */ \ + panstamp.radio.setDevAddress(addr[regDevAddress.length-1]); \ +} \ + \ +/** \ + * setNetworkId \ + * \ + * Set network id \ + * \ + * 'rId' Register ID \ + * 'nId' New network id \ + */ \ +const void setNetworkId(uint8_t rId, uint8_t *nId) \ +{ \ + if ((nId[0] != regNetworkId.value[0]) || \ + (nId[1] != regNetworkId.value[1])) \ + { \ + /* Send status before taking the new network ID */ \ + SWSTATUS packet = SWSTATUS(regNetworkId.id, nId, regNetworkId.length); \ + packet.send(); \ + /* Update register value */ \ + panstamp.radio.setSyncWord(nId); \ + } \ +} \ +/** \ + * setTxInterval \ + * \ + * Set periodic Tx interval \ + * \ + * 'id' Register ID \ + * 'interval' New interval (in seconds) \ + */ \ +const void setTxInterval(uint8_t id, uint8_t *interval) \ +{ \ + /* Set new Tx interval. BE to LE conversion */ \ + regTxInterval.setValueFromBeBuffer(interval); \ +} +#endif + diff --git a/config.h b/config.h new file mode 100755 index 0000000..1a8c555 --- /dev/null +++ b/config.h @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/02/2012 + */ + +#ifndef _CONFIG_H +#define _CONFIG_H + +/** + * Repeater options + */ +// Amount of transactions to be saved for evaluation before repeating a packet +// Maximum depth = 255 +#define REPEATER_TABLE_DEPTH 20 +// Expiration time (in ms) for any transaction +#define REPEATER_EXPIRATION_TIME 2000 + +/** + * Addressing schema + */ +// Extended addresses (2 bytes) +//#define SWAP_EXTENDED_ADDRESS 1 + +#endif + diff --git a/datatypes.h b/datatypes.h new file mode 100755 index 0000000..43d6104 --- /dev/null +++ b/datatypes.h @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/27/2013 + */ + +#ifndef _DATATYPES_H +#define _DATATYPES_H + +#include +#include "config.h" + +/** + * SWDTYPE : Type of data contained in SWAP register + */ +typedef enum SWDTYPE/* : unsigned char*/ +{ + SWDTYPE_INTEGER = 0, // Register containing a single 1-to-4 byte integer + SWDTYPE_OTHER // Other type of register contents +} SWDTYPE; +#endif + diff --git a/library.properties b/library.properties new file mode 100755 index 0000000..c8ee350 --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=SWAP +version=1.0.0 +author=panStamp +maintainer=panStamp +sentence=Simple Wireless Abstract Protocol (SWAP) library for ISM radios +paragraph=Simple Wireless Abstract Protocol (SWAP) library for ISM radios +category=Communication +url=https://github.com/panStamp/swap.git +architectures=* diff --git a/nvolat.h b/nvolat.h new file mode 100755 index 0000000..3c52ca5 --- /dev/null +++ b/nvolat.h @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2014 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 07/04/2014 + */ + +#ifndef _NVOLAT_H +#define _NVOLAT_H + +#include "config.h" + +/** + * EEPROM/Infomem addresses + */ +#define NVOLAT_FREQ_CHANNEL 0x00 // 1-byte register +#define NVOLAT_NOT_USED 0x01 // 1-byte register +#define NVOLAT_SYNC_WORD 0x02 // 2-byte register +#define NVOLAT_DEVICE_ADDR 0x04 // 1 or 2 byte register +#define NVOLAT_TX_INTERVAL 0x06 // 2-byte register +#define NVOLAT_SIGNATURE 0x08 // 2-byte register +#define NVOLAT_CARRIER_FREQ 0x0A // 3-byte register +#define NVOLAT_FIRST_CUSTOM 0x20 + +// Signature +#define NVOLAT_SIGNATURE_HIGH 0xAB +#define NVOLAT_SIGNATURE_LOW 0xCD + +// Extended address +#ifdef SWAP_EXTENDED_ADDRESS +#define NVOLAT_DEVICE_ADDRESS NVOLAT_DEVICE_ADDR +#else +#define NVOLAT_DEVICE_ADDRESS NVOLAT_DEVICE_ADDR + 1 +#endif + +#endif diff --git a/register.cpp b/register.cpp new file mode 100755 index 0000000..a8e26d7 --- /dev/null +++ b/register.cpp @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#include "register.h" +#include "swstatus.h" + +unsigned char regIndex = 0; + + +/** + * init + * + * Initialize register + */ +void REGISTER::init(void) +{ + // Does the value need to be read from EEPROM? + if (eepromAddress >= 0) + { + STORAGE nvMem; + + // Read from info memory + nvMem.read(value, eepromBank, eepromAddress, length); + } +} + +/** + * getData + * + * Update and get register value + */ +void REGISTER::getData(void) +{ + // Update register value + if (updateValue != NULL) + updateValue(id); + + // Send SWAP status message about the new value + sendSwapStatus(); +} + +/** + * setData + * + * Set register value + * + * @param data New register value + */ +void REGISTER::setData(unsigned char *data) +{ + // Update register value + if (setValue != NULL) + setValue(id, data); + + // Send SWAP status message + sendSwapStatus(); + + // Does the value need to be saved in info memory (flash)? + if (eepromAddress >= 0) + { + STORAGE nvMem; + // Write info memory + nvMem.write(value, eepromBank, eepromAddress, length); + } +} + +/** + * sendSwapStatus + * + * Send SWAP status message + */ +void REGISTER::sendSwapStatus(void) +{ + SWSTATUS packet = SWSTATUS(id, value, length, type); + packet.send(); +} + +/** + * setValueFromBeBuffer + * + * Set curent value from a Big Endian buffer passed as argument + * + * @param beBuffer Big Endian buffer + */ +void REGISTER::setValueFromBeBuffer(unsigned char* beBuffer) +{ + unsigned char i; + + for(i=0 ; i + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#ifndef _REGISTER_H +#define _REGISTER_H + +#include "storage.h" +#include "datatypes.h" + +extern uint8_t regIndex; + +/** + * Class: REGISTER + * + * Description: + * Register class + */ +class REGISTER +{ + private: + /** + * Pointer to the register "updater" function + * + * @param rId Register ID + */ + const void (*updateValue)(uint8_t rId); + + /** + * Pointer to the register "setter" function + * + * @param rId Register ID + * @param v New register value + */ + const void (*setValue)(uint8_t rId, uint8_t *v); + + public: + /** + * Register id + */ + const uint8_t id; + + /** + * Register value + */ + uint8_t *value; + + /** + * Data length + */ + const uint8_t length; + + /** + * Data type + */ + const SWDTYPE type; + + /** + * Adddress in EEPROM. Set to -1 if no storage in EEPROM has to be done + */ + const int eepromAddress; + + /** + * Bank address in EEPROM or flash + */ + const uint16_t eepromBank; + + /** + * REGISTER + * + * Constructor + * + * @param val Pointer to the register value + * @param len Length of the register value + * @param getValH Pointer to the getter function + * @param setValH Pointer to the setter function + * @param typ Type of SWAP data (SWDTYPE) + * @param eepromAddr address in EEPROM. Set to -1 if the register value has not to + * be saved in EEPROM + * @param bank sector in eeprom or flash + */ + REGISTER(uint8_t *val, const uint8_t len, const void (*updateValH)(uint8_t rId), const void (*setValH)(uint8_t rId, uint8_t *v), const SWDTYPE typ=SWDTYPE_OTHER, const int eepromAddr=-1, const uint16_t bank=DEFAULT_NVOLAT_SECTION): id(regIndex++), value(val), length(len), updateValue(updateValH), setValue(setValH), type(typ), eepromAddress(eepromAddr), eepromBank(bank) {}; + + /** + * init + * + * Initialize register + */ + void init(void); + + /** + * getData + * + * Update and get register value + * + */ + void getData(); + + /** + * setData + * + * Set register value + * + * @param data New register value + */ + void setData(uint8_t *data); + + /** + * sendSwapStatus + * + * Send SWAP status message + */ + void sendSwapStatus(void); + + /** + * setValueFromBeBuffer + * + * Set curent value from a Big Endian buffer passed as argument + * + * @param beBuffer Big Endian buffer + */ + void setValueFromBeBuffer(uint8_t* beBuffer); + + /** + * setRegValue + * + * Set register value from different data formats + * Use this method to simplify LE to BE conversion + * + * @param val New register value + * @param size length of the value + * @param offset starting point for the new partial value + */ + /* + template void setRegValue(T val, uint8_t size=0 , uint8_t offset=0) + { + int i, len; + + size > 0 ? len = size : len = length; + + for(i=len+offset-1 ; i>=offset ; i--) + { + value[i] = val & 0xFF; + val >>= 8; + } + } + */ +}; + +/** + * Array of registers + */ +extern REGISTER* regTable[]; + +#endif + diff --git a/repeater.cpp b/repeater.cpp new file mode 100755 index 0000000..768873d --- /dev/null +++ b/repeater.cpp @@ -0,0 +1,151 @@ +/** + * Copyright (c) 2014 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#include "repeater.h" +#include "panstamp.h" +//#include "Arduino.h" +#include "swap.h" + +/** + * init + * + * Initialize repeater + * + * @param maxHop maximum hop count + */ +void REPEATER::init(uint8_t maxHop) +{ + maxHopCount = maxHop; + start(); +} + +/** + * Class constructor + */ +REPEATER::REPEATER(void) +{ +} + +/** + * packetHandler + * + * Handle incoming packet. Repeat if necessary + * + * @param packet Pointer to the SWAP packet received + */ +void REPEATER::packetHandler(SWPACKET *packet) +{ + bool repeatPacket = true; + uint32_t currentTime; + + if (enabled) + { + // Don't repeat packets addressed to our device + if (packet->destAddr != swap.devAddress) + { + // Don't repeat beyond the maximum hop count + if (packet->hop < maxHopCount) + { + uint8_t i; + + // Check received packet against the latest transactions + for(i=0 ; iregAddr) + { + // Same SWAP function? + if (transactions[i].function == packet->function) + { + // Same cyclic nonce? + if (transactions[i].nonce == packet->nonce) + { + currentTime = millis(); + // Time stamp not expired? + if ((currentTime - transactions[i].timeStamp) < REPEATER_EXPIRATION_TIME) + { + repeatPacket = false; //Don't repeat packet + break; + } + } + } + } + } + + // Repeat packet? + if (repeatPacket) + { + packet->srcAddr = swap.devAddress; // Modify source address + packet->hop++; // Increment hop counter + delay(SWAP_TX_DELAY); // Delay before sending + if (packet->send()) // Repeat packet + saveTransaction(packet); // Save transaction + } + } + } + } +} + +/** + * saveTransaction + * + * Save transaction in array + * + * @param packet SWAP packet being repeated + */ +void REPEATER::saveTransaction(SWPACKET *packet) +{ + static uint8_t transactionIndex = 0; + + // Save current transaction in first position + transactions[transactionIndex].timeStamp = millis(); // Current time stamp + transactions[transactionIndex].function = packet->function; // SWAP function + transactions[transactionIndex].srcAddr = packet->srcAddr; // Source address + transactions[transactionIndex].nonce = packet->nonce; // Cyclic nonce + transactions[transactionIndex].regAddr = packet->regAddr; // Register address + + transactionIndex = (transactionIndex + 1) % REPEATER_TABLE_DEPTH; +} + +/** + * start + * + * Start repeater + */ +void REPEATER::start(void) +{ + enabled = true; +} + +/** + * stop + * + * Stop repeater + */ +void REPEATER::stop(void) +{ + enabled = false; +} + + diff --git a/repeater.h b/repeater.h new file mode 100755 index 0000000..c589e62 --- /dev/null +++ b/repeater.h @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#ifndef _REPEATER_H +#define _REPEATER_H + +#include "swpacket.h" +#include "config.h" + +/** + * Transaction + */ +typedef struct +{ + unsigned long timeStamp; // Transmission time stamp (ms) + unsigned char function; // SWAP function + unsigned char srcAddr; // Source address + unsigned char nonce; // Cyclic nonce + unsigned char regAddr; // Register address +} Transaction; + + +/** + * Cñass declaration + */ +class REPEATER +{ + private: + /** + * Maximum hop + */ + uint8_t maxHopCount; + + /** + * Array of latest transactions + */ + Transaction transactions[REPEATER_TABLE_DEPTH]; + + /** + * saveTransaction + * + * Save transaction in array + * + * @param packet SWAP packet being repeated + */ + void saveTransaction(SWPACKET *packet); + + public: + /** + * Enable flag + */ + bool enabled; + + /** + * init + * + * Initialize repeater + * + * @param maxHop maximum hop count + */ + void init(uint8_t maxHop); + + /** + * packetHandler + * + * Handle incoming packet. Repeat if necessary + * + * @param packet Pointer to the SWAP packet received + */ + void packetHandler(SWPACKET *packet); + + /** + * Class constructor + */ + REPEATER(void); + + /** + * start + * + * Start repeater + */ + void start(void); + + /** + * stop + * + * Stop repeater + */ + void stop(void); +}; + +#endif + diff --git a/swap.cpp b/swap.cpp new file mode 100755 index 0000000..aa1a3e9 --- /dev/null +++ b/swap.cpp @@ -0,0 +1,245 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#include "panstamp.h" +#include "swap.h" +#include "swpacket.h" +#include "commonregs.h" + + +DEFINE_COMMON_REGINDEX_START() +DEFINE_COMMON_REGINDEX_END() + +/** + * pacKetReceived + * + * CCPACKET received + * + * @param packet CCPACKET received + */ +void pacKetReceived(CCPACKET *packet) +{ + if (packet->length <= SWAP_DATA_HEAD_LEN) + return; + + SWPACKET swPacket = SWPACKET(packet); + REGISTER *reg; + bool eval = true; + + + #ifdef SWAP_EXTENDED_ADDRESS + if (swPacket.addrType == SWAPADDR_EXTENDED) + #else + if (swPacket.addrType == SWAPADDR_SIMPLE) + #endif + { + // Repeater enabled? + if (swap.repeater != NULL) + swap.repeater->packetHandler(&swPacket); + + // Smart encryption locally enabled? + if (swap.security & 0x02) + { + // OK, then incoming packets must be encrypted too + if (!(swPacket.security & 0x02)) + eval = false; + } + } + else + eval = false; + + if (eval) + { + // Function + switch(swPacket.function) + { + case SWAPFUNCT_CMD: + // Command not addressed to us? + if (swPacket.destAddr != swap.devAddress) + break; + // Current version does not support data recording mode + // so destination address and register address must be the same + if (swPacket.destAddr != swPacket.regAddr) + break; + // Valid register? + if ((reg = swap.getRegister(swPacket.regId)) == NULL) + break; + // Anti-playback security enabled? + if (swap.security & 0x01) + { + // Check received nonce + if (swap.nonce != swPacket.nonce) + { + // Nonce missmatch. Transmit correct nonce. + reg = swap.getRegister(REGI_SECUNONCE); + reg->sendSwapStatus(); + break; + } + } + // Filter incorrect data lengths + if (swPacket.value.length == reg->length) + reg->setData(swPacket.value.data); + else + reg->sendSwapStatus(); + break; + case SWAPFUNCT_QRY: + // Only Product Code can be broadcasted + if (swPacket.destAddr == SWAP_BCAST_ADDR) + { + if (swPacket.regId != REGI_PRODUCTCODE) + break; + } + // Query not addressed to us? + else if (swPacket.destAddr != swap.devAddress) + break; + // Current version does not support data recording mode + // so destination address and register address must be the same + if (swPacket.destAddr != swPacket.regAddr) + break; + // Valid register? + if ((reg = swap.getRegister(swPacket.regId)) == NULL) + break; + reg->getData(); + break; + case SWAPFUNCT_STA: + // User callback function declared? + if (swap.statusReceived != NULL) + swap.statusReceived(&swPacket); + break; + default: + break; + } + } +} + +/** + * SWAP + * + * Class constructor + */ +SWAP::SWAP(void) +{ + statusReceived = NULL; + repeater = NULL; + encryptPwd = NULL; + security = 0; +} + +/** + * init + * + * Initialize SWAP registers and stack + */ +void SWAP::init(void) +{ + uint8_t i; + STORAGE nvMem; + + // Read signature from info/eeprom memory + uint8_t signature[2]; + nvMem.read(signature, DEFAULT_NVOLAT_SECTION, NVOLAT_SIGNATURE, sizeof(signature)); + + // Correct signature in non-volatile memory? + if ((signature[0] != NVOLAT_SIGNATURE_HIGH) || (signature[1] != NVOLAT_SIGNATURE_LOW)) + nvolatToFactoryDefaults(); // Copy default settings in non-volatile memory + + // Intialize registers + for(i=0 ; iinit(); + + // Config radio settings + panstamp.radio.devAddress = devAddress & 0xFF; + panstamp.radio.setCCregs(); + + // Attach RF ISR + panstamp.attachInterrupt(pacKetReceived); +} + +/** + * enableRepeater + * + * Enable repeater mode + * + * @param maxHop Maximum repeater count. Zero if omitted + */ +void SWAP::enableRepeater(unsigned char maxHop) +{ + if (repeater == NULL) + { + static REPEATER repe; + repeater = &repe; + repeater->init(maxHop); + } + + if (maxHop == 0) + repeater->stop(); +} + +/** + * goToSleep + * + * put the MCU in sleep mode during txInterval seconds + */ +void SWAP::goToSleep(void) +{ + systemState = SYSTATE_RXOFF; + panstamp.sleepSec(txInterval); + systemState = SYSTATE_RXON; +} + +/** + * nvolatToFactoryDefaults + * + * Write default config values in non-volatile memory + */ +void SWAP::nvolatToFactoryDefaults(void) +{ + STORAGE nvMem; + + // Signature + uint8_t signature[] = {NVOLAT_SIGNATURE_HIGH, NVOLAT_SIGNATURE_LOW}; + nvMem.write(signature, DEFAULT_NVOLAT_SECTION, NVOLAT_SIGNATURE, sizeof(signature)); + + // Frequency channel + uint8_t channel[] = {CCDEF_CHANNR}; + nvMem.write(channel, DEFAULT_NVOLAT_SECTION, NVOLAT_FREQ_CHANNEL, sizeof(channel)); + + // Sync word + uint8_t syncW[] = {CCDEF_SYNC1, CCDEF_SYNC0}; + nvMem.write(syncW, DEFAULT_NVOLAT_SECTION, NVOLAT_SYNC_WORD, sizeof(syncW)); + + // SWAP address (pseudo-random number) + uint16_t random = panstamp.GET_RANDOM(); + uint8_t addr[] = {(random >> 8) & 0xFF, random & 0xFF}; + nvMem.write(addr, DEFAULT_NVOLAT_SECTION, NVOLAT_DEVICE_ADDR, sizeof(addr)); + + // TX interval + uint8_t txInt[] = {0xFF, 0}; + nvMem.write(txInt, DEFAULT_NVOLAT_SECTION, NVOLAT_TX_INTERVAL, sizeof(txInt)); +} + +/** + * Pre-instantiate SWAP object + */ +SWAP swap; diff --git a/swap.h b/swap.h new file mode 100755 index 0000000..d788709 --- /dev/null +++ b/swap.h @@ -0,0 +1,242 @@ +/** + * Copyright (c) 2014 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 07/10/2014 + */ + +#ifndef _SWAP_H +#define _SWAP_H + +#include "register.h" +#include "config.h" +#include "repeater.h" + +#ifdef PANSTAMP_NRG +#include "cc430aes.h" +#endif + +/** + * Macros + */ +#define eepromToFactoryDefaults() swap.nvolatToFactoryDefaults() + +#define enableAntiPlayback() security |= 0x01 + +#define swapNetworkId radio.syncWord + +#define setSwapStatusCallBack(ptrFunc) statusReceived = ptrFunc + +/** + * System states + */ +enum SYSTATE +{ + SYSTATE_RESTART = 0, + SYSTATE_RXON, + SYSTATE_RXOFF, + SYSTATE_SYNC, + SYSTATE_LOWBAT, + SYSTATE_UPGRADE +}; + +/** + * Types of SWAP message for attachInterrupt + */ +#define STATUS 0 +#define QUERY 1 +#define COMMAND 2 + +/** + * Array of registers + */ +extern REGISTER* regTable[]; +extern uint8_t regTableSize; + +/** + * Class: SWAP + * + * Description: + * SWAP protocol class + */ +class SWAP +{ + public: + /** + * Pointer to repeater object + */ + REPEATER *repeater; + + /** + * SWAP address + */ + #ifdef SWAP_EXTENDED_ADDRESS + uint16_t devAddress; + #else + uint8_t devAddress; + #endif + + /** + * Security options + */ + uint8_t security; + + /** + * Security cyclic nonce + */ + uint8_t nonce; + + /** + * System state + */ + uint8_t systemState; + + /** + * Interval between periodic transmissions. 0 for asynchronous transmissions + */ + uint16_t txInterval; + + /** + * Smart encryption password + */ + uint8_t *encryptPwd; + + /** + * SWAP status packet received. Callback function + */ + void (*statusReceived)(SWPACKET *status); + + /** + * enableRepeater + * + * Enable repeater mode + * + * @param maxHop Maximum repeater count. Zero if omitted + */ + void enableRepeater(uint8_t maxHop=0); + + /** + * SWAP + * + * Class constructor + */ + SWAP(void); + + /** + * init + * + * Initialize SWAP registers + */ + void init(void); + + /** + * enterSystemState + * + * Enter system state + * + * @param state New system state + */ + void __inline__ enterSystemState(SYSTATE state) + { + // System state register -> id = 3 + regTable[3]->setData((uint8_t *) &state); + } + + /** + * goToSleep + * + * put the MCU in sleep mode during txInterval seconds + */ + void goToSleep(void); + + /** + * nvolatToFactoryDefaults + * + * Write default config values in non-volatile memory + */ + void nvolatToFactoryDefaults(void); + + /** + * attachInterrupt + * + * Declare custom ISR, to be called whenever a SWAP status packet is received + * + * @param type of packet that triggers the user function + * @param funct pointer to the custom function + */ + inline void attachInterrupt(uint8_t type, void (*funct)(SWPACKET*)) + { + if (type == STATUS) + statusReceived = funct; + } + + /** + * getRegister + * + * Return pointer to register with ID = regId + * + * @param regId Register ID + */ + inline REGISTER * getRegister(unsigned char regId) + { + return regTable[regId]; + } + + /** + * setSmartPassword + * + * Set Smart Encryption password + * + * @param password Encryption password. 12-byte length + */ + inline void setSmartPassword(unsigned char* password) + { + // Save password + encryptPwd = password; + // Enable Smart Encryption + security |= 0x02; + } + + /** + * setAesPassword + * + * Set AES-128 Encryption password + * + * @param password Encryption password. It must be 16 byte length + */ + #ifdef PANSTAMP_NRG + inline void setAesPassword(unsigned char* password) + { + // Set AES-128 key + CC430AES::setKey(password); + + // Enable AES Encryption + security |= 0x04; + } + #endif +}; + +/** + * Global SWAP object + */ +extern SWAP swap; + +#endif + diff --git a/swcommand.cpp b/swcommand.cpp new file mode 100755 index 0000000..6c49277 --- /dev/null +++ b/swcommand.cpp @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#include "swcommand.h" +#include "swap.h" + +/** + * SWCOMMAND + * + * Class constructor + * + * @param dAddr Destination address + * @param secNonce Security nonce + * @param rAddr Register address + * @param rId Register id + * @param val Pointer to new value + * @param len Buffer length + */ +SWCOMMAND::SWCOMMAND(unsigned char dAddr, unsigned char secNonce, unsigned char rAddr, unsigned char rId, unsigned char *val, unsigned char len) +{ + destAddr = dAddr; + srcAddr = swap.devAddress; + hop = 0; + security = swap.security & 0x0F; + nonce = secNonce; + function = SWAPFUNCT_CMD; + regAddr = rAddr; + regId = rId; + value.data = val; + value.length = len; + value.type = SWDTYPE_OTHER; +} + diff --git a/swcommand.h b/swcommand.h new file mode 100755 index 0000000..a6e33a5 --- /dev/null +++ b/swcommand.h @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#ifndef _SWCOMMAND_H +#define _SWCOMMAND_H + +#include "swpacket.h" + + +class SWCOMMAND : public SWPACKET +{ + public: + /** + * SWCOMMAND + * + * Class constructor + * + * @param destAddr Destination address + * @param secNonce Security nonce + * @param rAddr Register address + * @param rId Register id + * @param val New value + * @param len Buffer length + */ + SWCOMMAND(unsigned char destAddr, unsigned char secNonce, unsigned char rAddr, unsigned char rId, unsigned char *val, unsigned char len); +}; +#endif diff --git a/swpacket.cpp b/swpacket.cpp new file mode 100755 index 0000000..ce6d9d8 --- /dev/null +++ b/swpacket.cpp @@ -0,0 +1,235 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 03/03/2011 + */ + +#include "swpacket.h" +#include "swap.h" +#include "panstamp.h" + +/** + * SWPACKET + * + * Class constructor + * + * @param packet Pointer to the raw CC1101 packet + */ +SWPACKET::SWPACKET(CCPACKET *packet) +{ + uint8_t i; + + // Save raw data and length + ccPacket.length = packet->length; + for(i=0 ; idata[i]; + + hop = (ccPacket.data[2] >> 4) & 0x0F; + security = ccPacket.data[2] & 0x0F; + + #ifdef PANSTAMP_NRG + // AES-128 encrypted? + if (security & 0x04) + aesCrypto(); // Decrypt + #endif + + nonce = ccPacket.data[3]; + function = ccPacket.data[4] & ~SWAP_EXTENDED_ADDRESS_BIT; + + if (ccPacket.data[4] & SWAP_EXTENDED_ADDRESS_BIT) + { + addrType = SWAPADDR_EXTENDED; + destAddr = ccPacket.data[0]; + destAddr <<= 8; + destAddr |= ccPacket.data[1]; + srcAddr = ccPacket.data[5]; + srcAddr <<= 8; + srcAddr |= ccPacket.data[6]; + regAddr = ccPacket.data[7]; + regAddr <<= 8; + regAddr |= ccPacket.data[8]; + regId = ccPacket.data[9]; + } + else + { + addrType = SWAPADDR_SIMPLE; + destAddr = ccPacket.data[0]; + srcAddr = ccPacket.data[1]; + regAddr = ccPacket.data[5]; + regId = ccPacket.data[6]; + } + + value.data = ccPacket.data + SWAP_DATA_HEAD_LEN + 1; + value.length = ccPacket.length - SWAP_DATA_HEAD_LEN - 1; + + // Smart encryption only available for simple (1-byte) addressing schema + #ifndef SWAP_EXTENDED_ADDRESS + if (addrType == SWAPADDR_SIMPLE) + { + // Smart Encryption - Need to decrypt packet? + if (security & 0x02) + smartDecrypt(); + } + #endif +} + +/** + * SWPACKET + * + * Class constructor + */ +SWPACKET::SWPACKET(void) +{ +} + +/** + * send + * + * Send SWAP packet. Do up to 5 retries if necessary + * + * @return + * True if the transmission succeeds + * False otherwise + */ +bool SWPACKET::send(void) +{ + byte i; + boolean res; + + // LE -> BE conversion for numeric values + if (value.type == SWDTYPE_INTEGER) + { + for(i=0 ; i> 8) & 0xFF; + ccPacket.data[1] = destAddr & 0xFF; + ccPacket.data[4] = function | SWAP_EXTENDED_ADDRESS_BIT; + ccPacket.data[5] = (srcAddr >> 8) & 0xFF; + ccPacket.data[6] = srcAddr & 0xFF; + ccPacket.data[7] = (regAddr >> 8) & 0xFF; + ccPacket.data[8] = regAddr & 0xFF; + ccPacket.data[9] = regId; + #else + addrType = SWAPADDR_SIMPLE; + ccPacket.data[0] = destAddr; + ccPacket.data[1] = srcAddr; + ccPacket.data[4] = function; + ccPacket.data[5] = regAddr; + ccPacket.data[6] = regId; + #endif + + #ifdef PANSTAMP_NRG + // Need to be AES-128 encrypted? + if (security & 0x04) + aesCrypto(); // Encrypt + #endif + + i = SWAP_NB_TX_TRIES; + while(!(res = panstamp.radio.sendData(ccPacket)) && i>1) + { + i--; + delay(SWAP_TX_DELAY); + } + + return res; +} + +/** + * smartEncrypt + * + * Apply Smart Encryption to the SWAP packet passed as argument + * + * @param decrypt if true, Decrypt packet. Encrypt otherwise + */ +#ifndef SWAP_EXTENDED_ADDRESS +void SWPACKET::smartEncrypt(bool decrypt) +{ + byte i, j = 0; + static uint8_t newData[CCPACKET_DATA_LEN]; + + if (decrypt) + nonce ^= swap.encryptPwd[9]; + + function ^= swap.encryptPwd[11] ^ nonce; + srcAddr ^= swap.encryptPwd[10] ^ nonce; + regAddr ^= swap.encryptPwd[8] ^ nonce; + regId ^= swap.encryptPwd[7] ^ nonce; + + for(i=0 ; i 0) + value.data = newData; + + if (!decrypt) + nonce ^= swap.encryptPwd[9]; +} +#endif + +/** + * aesCrypto + * + * Apply AES-128 encryption with CTR cipher to the SWAP packet passed + * as argument + */ +#ifdef PANSTAMP_NRG +void SWPACKET::aesCrypto(void) +{ + uint8_t i; + uint32_t initNonce = 0; + + // Create initial CTR nonce with first four bytes + // None of these fields are encrypted + for(i=0 ; i<4 ; i++) + { + initNonce <<= 8; + initNonce |= ccPacket.data[i]; + } + + CC430AES::ctrCrypto(ccPacket.data + 4, ccPacket.length - 4, initNonce); +} +#endif diff --git a/swpacket.h b/swpacket.h new file mode 100755 index 0000000..26f0bfc --- /dev/null +++ b/swpacket.h @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#ifndef _SWPACKET_H +#define _SWPACKET_H + +#include "ccpacket.h" +#include "datatypes.h" + +/** + * SWAP definitions + */ +#ifdef SWAP_EXTENDED_ADDRESS +#define SWAP_DATA_HEAD_LEN 9 +#else +#define SWAP_DATA_HEAD_LEN 6 +#endif +#define SWAP_REG_VAL_LEN CC1101_DATA_LEN - SWAP_DATA_HEAD_LEN // SWAP data payload - max length +#define SWAP_BCAST_ADDR 0x00 // SWAP broadcast address +#define SWAP_NB_TX_TRIES 3 // Number of transmission retries +#define SWAP_TX_DELAY (panstamp.radio.devAddress & 0xFF) * 2 // Delay before sending +#define SWAP_EXTENDED_ADDRESS_BIT 0x80 + +/** + * SWAP message functions + */ +enum SWAPFUNCT +{ + SWAPFUNCT_STA = 0x00, + SWAPFUNCT_QRY, + SWAPFUNCT_CMD, + SWAPFUNCT_ACK // 0x03 - Reserved for future adoption by SWAP +}; + +/** + * Adressing schema + */ +enum SWAPADDR_SCHEMA +{ + SWAPADDR_SIMPLE = 0, + SWAPADDR_EXTENDED +}; + +/** + * Macros + */ +#ifndef SWAP_EXTENDED_ADDRESS +#define smartDecrypt() smartEncrypt(true) +#endif + +/** + * SWDATA : SWAP data structure + */ +struct SWDATA +{ + /** + * Data buffer + */ + uint8_t *data; + + /** + * Data length + */ + uint8_t length; + + /** + * Data type + */ + SWDTYPE type; +}; + +class SWPACKET +{ + private: + /** + * Raw packet + */ + CCPACKET ccPacket; + + /** + * smartEncrypt + * + * Apply Smart Encryption to the SWAP packet passed as argument + * + * 'decrypt': if true, Decrypt packet. Encrypt otherwise + */ + #ifndef SWAP_EXTENDED_ADDRESS + void smartEncrypt(bool decrypt=false); + #endif + + /** + * aesCrypto + * + * Apply AES-128 encryption with CTR cipher to the SWAP packet passed + * as argument + */ + //#ifdef PANSTAMP_NRG + void aesCrypto(void); + //#endif + + public: + /** + * Destination address + */ + uint16_t destAddr; + + /** + * Source address + */ + uint16_t srcAddr; + + /** + * Hop counter. Incremented each time the message is repeated + */ + uint8_t hop; + + /** + * Security option byte + */ + uint8_t security; + + /** + * Security cyclic nonce + */ + uint8_t nonce; + + /** + * Function byte + */ + uint8_t function; + + /** + * Type of addressing schema + */ + uint8_t addrType; + + /** + * Register address + */ + uint8_t regAddr; + + /** + * Register id + */ + uint8_t regId; + + /** + * Register value + */ + SWDATA value; + + /** + * SWPACKET + * + * Class constructor + * + * @param packet Pointer to the raw CC1101 packet + */ + SWPACKET(CCPACKET *packet); + + /** + * SWPACKET + * + * Class constructor + */ + SWPACKET(void); + + /** + * send + * + * Send SWAP packet + * + * #return: + * True if the transmission succeeds + * False otherwise + */ + bool send(void); +}; + +#endif diff --git a/swquery.cpp b/swquery.cpp new file mode 100755 index 0000000..fc75234 --- /dev/null +++ b/swquery.cpp @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#include "Arduino.h" +#include "swquery.h" +#include "swap.h" + +/** + * SWQUERY + * + * Class constructor + * + * @param dAddr Destination address + * @param rAddr Register address + * @param rId Register id + */ +SWQUERY::SWQUERY(unsigned char dAddr, unsigned char rAddr, unsigned char rId) +{ + destAddr = dAddr; + srcAddr = swap.devAddress; + hop = 0; + security = swap.security & 0x0F; + nonce = 0; + function = SWAPFUNCT_QRY; + regAddr = rAddr; + regId = rId; + value.data = NULL; + value.length = 0; + value.type = SWDTYPE_OTHER; +} + diff --git a/swquery.h b/swquery.h new file mode 100755 index 0000000..3494bf2 --- /dev/null +++ b/swquery.h @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#ifndef _SWQUERY_H +#define _SWQUERY_H + +#include "swpacket.h" + +class SWQUERY : public SWPACKET +{ + public: + /** + * SWQUERY + * + * Class constructor + * + * @param destAddr Destination address + * @param rAddr Register address + * @param rId Register id + */ + SWQUERY(unsigned char destAddr, unsigned char rAddr, unsigned char rId); +}; +#endif diff --git a/swstatus.cpp b/swstatus.cpp new file mode 100755 index 0000000..5186055 --- /dev/null +++ b/swstatus.cpp @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#include "swstatus.h" +#include "swap.h" + +/** + * SWSTATUS + * + * Class constructor + * + * @param rId Register id + * @param val Pointer to new value + * @param len Buffer length + * @param type type of data contained + */ +SWSTATUS::SWSTATUS(unsigned char rId, unsigned char *val, unsigned char len, SWDTYPE type) +{ + destAddr = SWAP_BCAST_ADDR; + srcAddr = swap.devAddress; + hop = 0; + security = swap.security & 0x0F; + nonce = ++swap.nonce; + function = SWAPFUNCT_STA; + regAddr = swap.devAddress; + regId = rId; + value.length = len; + value.data = val; + value.type = type; +} + diff --git a/swstatus.h b/swstatus.h new file mode 100755 index 0000000..f0fba61 --- /dev/null +++ b/swstatus.h @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#ifndef _SWSTATUS_H +#define _SWSTATUS_H + +#include "swpacket.h" + + +class SWSTATUS : public SWPACKET +{ + public: + /** + * SWSTATUS + * + * Class constructor + * + * @param rId Register id + * @param val Pointer to new value + * @param len Buffer length + * @param type type of data contained + */ + SWSTATUS(unsigned char rId, unsigned char *val, unsigned char len, SWDTYPE type = SWDTYPE_OTHER); +}; +#endif diff --git a/swvalue.h b/swvalue.h new file mode 100755 index 0000000..88b24be --- /dev/null +++ b/swvalue.h @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2011 panStamp + * + * This file is part of the panStamp project. + * + * panStamp is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * panStamp is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with panStamp; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * Author: Daniel Berenguer + * Creation date: 06/03/2013 + */ + +#ifndef _SWVALUE_H +#define _SWVALUE_H + +#include "datatypes.h" + +/** + * Class: SWAPVALUE + * + * Description: + * SWAP value class + */ +template< typename T > class SWVALUE +{ + private: + /** + * Byte position in register + */ + uint8_t position; + + /** + * Number of bytes + */ + uint8_t length; + + /** + * value in byte-array format + */ + uint8_t *data; + + public: + /** + * Class constructor + * + * @param pos byte-position in register + * @param size byte-length of the value + */ + SWVALUE(uint8_t pos, uint8_t size) + { + position = pos; + length = size; + data = new uint8_t[size]; + } + + /** + * get + * + * @param val Value in unsigned integer format + */ + void get(T val) + { + int i; + + for(i=length-1 ; i>=0 ; i--) + { + data[i] = val & 0xFF; + val >>= 8; + } + } + +// constructor with user pre-defined size + array (int s) { + size = s; + myarray = new T [size]; + } + + template void setRegValue(T val, uint8_t size=0 , uint8_t offset=0) + { + int i, len; + + size > 0 ? len = size : len = length; + + for(i=len+offset-1 ; i<=offset ; i--) + { + value[i] = val & 0xFF; + val >>= 8; + } + } +}; + +#endif +