LoRaWAN MAC layer implementation

Dependents:   LoRaWAN-demo-72_tjm LoRaWAN-demo-72_jlc LoRaWAN-demo-elmo frdm_LoRa_Connect_Woodstream_Demo_tjm ... more

LoRAWAN-lib is a port of the GitHub LoRaMac-node LoRaWAN MAC layer implementation.

This library depends on the SX1276Lib or SX1272Lib radio drivers depending on the used mbed component shield.

This library depends also on some cryptographic helper functions as well as helper functions for the timers management. These can be found on the example projects under the system directory.

The example projects are:

  1. LoRaWAN-demo-72
  2. LoRaWAN-demo-76
  3. LoRaWAN-demo-NAMote72

The LoRaWAN specification specifies different ISM bands operating parameters. These are all implemented under the LoRaMac-board.h file.

In order to select which band to use, please change line 24 of board.h file provided on the examples projects as follows:


EU868

board.h

#define USE_BAND_868


US915

board.h

#define USE_BAND_915


US915 - Hybrid

board.h

#define USE_BAND_915_HYBRID


CN780

board.h

#define USE_BAND_780


EU433

board.h

#define USE_BAND_433

Files at this revision

API Documentation at this revision

Comitter:
mluis
Date:
Mon Nov 23 10:09:43 2015 +0000
Parent:
0:91d1a7783bb9
Child:
2:14a5d6ad92d5
Commit message:
Keep LoRaMac only related files in the library.; Updated files according to latest GitHub version

Changed in this revision

LoRaMac-board.h Show annotated file Show diff for this revision Revisions of this file
LoRaMac.cpp Show annotated file Show diff for this revision Revisions of this file
LoRaMac.h Show annotated file Show diff for this revision Revisions of this file
LoRaMacCrypto.cpp Show annotated file Show diff for this revision Revisions of this file
crypto/aes.cpp Show diff for this revision Revisions of this file
crypto/aes.h Show diff for this revision Revisions of this file
crypto/cmac.cpp Show diff for this revision Revisions of this file
crypto/cmac.h Show diff for this revision Revisions of this file
radio/SX1276Lib.lib Show diff for this revision Revisions of this file
system/timer.cpp Show diff for this revision Revisions of this file
system/timer.h Show diff for this revision Revisions of this file
system/utilities.cpp Show diff for this revision Revisions of this file
system/utilities.h Show diff for this revision Revisions of this file
--- a/LoRaMac-board.h	Tue Oct 20 13:21:26 2015 +0000
+++ b/LoRaMac-board.h	Mon Nov 23 10:09:43 2015 +0000
@@ -15,8 +15,6 @@
 #ifndef __LORAMAC_BOARD_H__
 #define __LORAMAC_BOARD_H__
 
-#define USE_BAND_868
-
 /*!
  * Returns individual channel mask
  *
@@ -48,6 +46,16 @@
 #define LORAMAC_DEFAULT_DATARATE                    DR_0
 
 /*!
+ * Minimal Rx1 receive datarate offset
+ */
+#define LORAMAC_MIN_RX1_DR_OFFSET                   0
+
+/*!
+ * Maximal Rx1 receive datarate offset
+ */
+#define LORAMAC_MAX_RX1_DR_OFFSET                   5
+
+/*!
  * Minimal Tx output power that can be used by the node
  */
 #define LORAMAC_MIN_TX_POWER                        TX_POWER_M5_DBM
@@ -129,6 +137,16 @@
 #define LORAMAC_DEFAULT_DATARATE                    DR_0
 
 /*!
+ * Minimal Rx1 receive datarate offset
+ */
+#define LORAMAC_MIN_RX1_DR_OFFSET                   0
+
+/*!
+ * Maximal Rx1 receive datarate offset
+ */
+#define LORAMAC_MAX_RX1_DR_OFFSET                   5
+
+/*!
  * Minimal Tx output power that can be used by the node
  */
 #define LORAMAC_MIN_TX_POWER                        TX_POWER_M5_DBM
@@ -210,6 +228,16 @@
 #define LORAMAC_DEFAULT_DATARATE                    DR_0
 
 /*!
+ * Minimal Rx1 receive datarate offset
+ */
+#define LORAMAC_MIN_RX1_DR_OFFSET                   0
+
+/*!
+ * Maximal Rx1 receive datarate offset
+ */
+#define LORAMAC_MAX_RX1_DR_OFFSET                   5
+
+/*!
  * Minimal Tx output power that can be used by the node
  */
 #define LORAMAC_MIN_TX_POWER                        TX_POWER_02_DBM
@@ -313,6 +341,16 @@
 #define LORAMAC_DEFAULT_DATARATE                    DR_0
 
 /*!
+ * Minimal Rx1 receive datarate offset
+ */
+#define LORAMAC_MIN_RX1_DR_OFFSET                   0
+
+/*!
+ * Maximal Rx1 receive datarate offset
+ */
+#define LORAMAC_MAX_RX1_DR_OFFSET                   3
+
+/*!
  * Minimal Tx output power that can be used by the node
  */
 #define LORAMAC_MIN_TX_POWER                        TX_POWER_10_DBM
--- a/LoRaMac.cpp	Tue Oct 20 13:21:26 2015 +0000
+++ b/LoRaMac.cpp	Mon Nov 23 10:09:43 2015 +0000
@@ -12,10 +12,7 @@
 
 Maintainer: Miguel Luis and Gregory Cristian
 */
-#include "mbed.h"
 #include "board.h"
-#include "utilities.h"
-#include "sx1276-hal.h"
 
 #include "LoRaMacCrypto.h"
 #include "LoRaMac.h"
@@ -23,7 +20,12 @@
 /*!
  * Maximum PHY layer payload size
  */
-#define LORAMAC_PHY_MAXPAYLOAD                      250
+#define LORAMAC_PHY_MAXPAYLOAD                      255
+
+/*!
+ * Maximum MAC commands buffer size
+ */
+#define LORA_MAC_COMMAND_MAX_LENGTH                 15
 
 /*!
  * Device IEEE EUI
@@ -173,7 +175,7 @@
 /*!
  * Buffer containing the MAC layer commands
  */
-static uint8_t MacCommandsBuffer[15];
+static uint8_t MacCommandsBuffer[LORA_MAC_COMMAND_MAX_LENGTH];
 
 #if defined( USE_BAND_433 )
 /*!
@@ -449,7 +451,7 @@
 /*!
  * LoRaMac upper layer event functions
  */
-static LoRaMacEvent_t *LoRaMacEvents;
+static LoRaMacCallbacks_t *LoRaMacCallbacks;
 
 /*!
  * LoRaMac notification event flags
@@ -581,8 +583,7 @@
 /*!
  * Radio events function pointer
  */
-//static RadioEvents_t RadioEvents;
-SX1276MB1xAS Radio( OnRadioTxDone, OnRadioTxTimeout, OnRadioRxDone, OnRadioRxTimeout, OnRadioRxError, NULL, NULL );
+static RadioEvents_t RadioEvents;
 
 /*!
  * \brief Validates if the payload fits into the frame, taking the datarate
@@ -633,7 +634,7 @@
     uint8_t enabledChannels[LORA_MAX_NB_CHANNELS];
     TimerTime_t curTime = TimerGetCurrentTime( );
 
-    memset( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
+    memset1( enabledChannels, 0, LORA_MAX_NB_CHANNELS );
 
     // Update Aggregated duty cycle
     if( AggregatedTimeOff < ( curTime - AggregatedLastTxDoneTime ) )
@@ -741,70 +742,99 @@
  * \param [in] p1  1st parameter ( optional depends on the command )
  * \param [in] p2  2nd parameter ( optional depends on the command )
  *
- * \retval status  Function status [0: OK, 1: Unknown command, 2: Buffer full]
+ * \retval status  Function status [0: OK, 1: Unknown command, 2: Busy]
  */
 static uint8_t AddMacCommand( uint8_t cmd, uint8_t p1, uint8_t p2 )
 {
-    MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+    uint8_t status = 2; // Busy
+
     switch( cmd )
     {
         case MOTE_MAC_LINK_CHECK_REQ:
-            // No payload for this command
+            if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // No payload for this command
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_LINK_ADR_ANS:
-            // Margin
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // Margin
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_DUTY_CYCLE_ANS:
-            // No payload for this answer
+            if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // No payload for this answer
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_RX_PARAM_SETUP_ANS:
-            // Status: Datarate ACK, Channel ACK
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // Status: Datarate ACK, Channel ACK
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_DEV_STATUS_ANS:
-            // 1st byte Battery
-            // 2nd byte Margin
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
+            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 2 ) )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // 1st byte Battery
+                // 2nd byte Margin
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p2;
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_NEW_CHANNEL_ANS:
-            // Status: Datarate range OK, Channel frequency OK
-            MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+            if( MacCommandsBufferIndex < ( LORA_MAC_COMMAND_MAX_LENGTH - 1 ) )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // Status: Datarate range OK, Channel frequency OK
+                MacCommandsBuffer[MacCommandsBufferIndex++] = p1;
+                status = 0; // OK
+            }
             break;
         case MOTE_MAC_RX_TIMING_SETUP_ANS:
-            // No payload for this answer
+            if( MacCommandsBufferIndex < LORA_MAC_COMMAND_MAX_LENGTH )
+            {
+                MacCommandsBuffer[MacCommandsBufferIndex++] = cmd;
+                // No payload for this answer
+                status = 0; // OK
+            }
             break;
         default:
-            return 1;
+            return 1; // Unknown command
     }
-    if( MacCommandsBufferIndex <= 15 )
+    if( status == 0 )
     {
         MacCommandsInNextTx = true;
-        return 0;
     }
-    else
-    {
-        return 2;
-    }
+    return status;
 }
 
 // TODO: Add Documentation
 static void LoRaMacNotify( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info )
 {
-    if( ( LoRaMacEvents != NULL ) && ( LoRaMacEvents->MacEvent != NULL ) )
+    if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->MacEvent != NULL ) )
     {
-        LoRaMacEvents->MacEvent( flags, info );
+        LoRaMacCallbacks->MacEvent( flags, info );
     }
     flags->Value = 0;
 }
 
-typedef uint8_t ( *GetBatteryLevel )( );
-GetBatteryLevel LoRaMacGetBatteryLevel;
-
-void LoRaMacInit( LoRaMacEvent_t *events, uint8_t ( *getBatteryLevel )( ) )
+void LoRaMacInit( LoRaMacCallbacks_t *callbacks )
 {
-    LoRaMacEvents = events;
+    LoRaMacCallbacks = callbacks;
 
     LoRaMacEventFlags.Value = 0;
     
@@ -821,8 +851,6 @@
     LoRaMacEventInfo.NbGateways = 0;
     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
    
-    LoRaMacGetBatteryLevel = getBatteryLevel;
-    
     LoRaMacDeviceClass = CLASS_A;
     
     UpLinkCounter = 1;
@@ -908,9 +936,17 @@
     TimerInit( &RxWindowTimer1, OnRxWindow1TimerEvent );
     TimerInit( &RxWindowTimer2, OnRxWindow2TimerEvent );
     TimerInit( &AckTimeoutTimer, OnAckTimeoutTimerEvent );
+    
+    // Initialize Radio driver
+    RadioEvents.TxDone = OnRadioTxDone;
+    RadioEvents.RxDone = OnRadioRxDone;
+    RadioEvents.RxError = OnRadioRxError;
+    RadioEvents.TxTimeout = OnRadioTxTimeout;
+    RadioEvents.RxTimeout = OnRadioRxTimeout;
+    Radio.Init( &RadioEvents );
 
     // Random seed initialization
-    srand( Radio.Random( ) );
+    srand1( Radio.Random( ) );
 
     // Initialize channel index.
     Channel = LORA_MAX_NB_CHANNELS;
@@ -1035,7 +1071,7 @@
 #if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
     static uint8_t drSwitch = 0;
     
-    if( drSwitch == 0 )
+    if( ( ++drSwitch & 0x01 ) == 0x01 )
     {
         ChannelsDatarate = DR_0;
     }
@@ -1043,7 +1079,6 @@
     {
         ChannelsDatarate = DR_4;
     }
-    drSwitch = ( drSwitch + 1 ) % 2;
 #endif
     return LoRaMacSend( &macHdr, NULL, 0, NULL, 0 );
 }
@@ -1268,9 +1303,9 @@
                         LoRaMacBuffer[pktHeaderLen++] = MacCommandsBuffer[i];
                     }
                 }
-                MacCommandsInNextTx = false;
-                MacCommandsBufferIndex = 0;
             }
+            MacCommandsInNextTx = false;
+            MacCommandsBufferIndex = 0;
             
             if( ( pktHeaderLen + fBufferSize ) > LORAMAC_PHY_MAXPAYLOAD )
             {
@@ -1448,10 +1483,11 @@
                         // Data rate ACK = 0
                         // Channel mask  = 0
                         AddMacCommand( MOTE_MAC_LINK_ADR_ANS, 0, 0 );
+                        macIndex += 3;  // Skip over the remaining bytes of the request
                         break;
                     }
-                    chMask = payload[macIndex++];
-                    chMask |= payload[macIndex++] << 8;
+                    chMask = ( uint16_t )payload[macIndex++];
+                    chMask |= ( uint16_t )payload[macIndex++] << 8;
 
                     nbRep = payload[macIndex++];
                     chMaskCntl = ( nbRep >> 4 ) & 0x07;
@@ -1590,10 +1626,9 @@
                     int8_t drOffset = 0;
                     uint32_t freq = 0;
                 
-                    drOffset = payload[macIndex++];
-                    datarate = drOffset & 0x0F;
-                    drOffset = ( drOffset >> 4 ) & 0x0F;
-                    
+                    drOffset = ( payload[macIndex] >> 4 ) & 0x07;
+                    datarate = payload[macIndex] & 0x0F;
+                    macIndex++;
                     freq = ( uint32_t )payload[macIndex++];
                     freq |= ( uint32_t )payload[macIndex++] << 8;
                     freq |= ( uint32_t )payload[macIndex++] << 16;
@@ -1610,7 +1645,8 @@
                         status &= 0xFD; // Datarate KO
                     }
 
-                    if( ( ( drOffset < 0 ) || ( drOffset > 5 ) ) == true )
+                    if( ( ( drOffset < LORAMAC_MIN_RX1_DR_OFFSET ) ||
+                          ( drOffset > LORAMAC_MAX_RX1_DR_OFFSET ) ) == true )
                     {
                         status &= 0xFB; // Rx1DrOffset range KO
                     }
@@ -1625,7 +1661,14 @@
                 }
                 break;
             case SRV_MAC_DEV_STATUS_REQ:
-                AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, LoRaMacGetBatteryLevel( ), LoRaMacEventInfo.RxSnr );
+                {
+                    uint8_t batteryLevel = BAT_LEVEL_NO_MEASURE;
+                    if( ( LoRaMacCallbacks != NULL ) && ( LoRaMacCallbacks->GetBatteryLevel != NULL ) )
+                    {
+                        batteryLevel = LoRaMacCallbacks->GetBatteryLevel( );
+                    }
+                    AddMacCommand( MOTE_MAC_DEV_STATUS_ANS, batteryLevel, LoRaMacEventInfo.RxSnr );
+                }
                 break;
             case SRV_MAC_NEW_CHANNEL_REQ:
                 {
@@ -1723,6 +1766,12 @@
             TimerSetValue( &RxWindowTimer2, RxWindow2Delay );
             TimerStart( &RxWindowTimer2 );
         }
+        if( ( LoRaMacDeviceClass == CLASS_C ) || ( NodeAckRequested == true ) )
+        {
+            TimerSetValue( &AckTimeoutTimer, RxWindow2Delay + ACK_TIMEOUT +
+                                             randr( -ACK_TIMEOUT_RND, ACK_TIMEOUT_RND ) );
+            TimerStart( &AckTimeoutTimer );
+        }
     }
     else
     {
@@ -1732,6 +1781,7 @@
     
     if( NodeAckRequested == false )
     {
+        LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
         ChannelsNbRepCounter++;
     }
 }
@@ -1746,18 +1796,20 @@
 
     uint8_t pktHeaderLen = 0;
     uint32_t address = 0;
-    uint16_t sequenceCounter = 0;
-    int32_t sequence = 0;
     uint8_t appPayloadStartIndex = 0;
     uint8_t port = 0xFF;
     uint8_t frameLen = 0;
     uint32_t mic = 0;
     uint32_t micRx = 0;
     
+    uint16_t sequenceCounter = 0;
+    uint16_t sequenceCounterPrev = 0;
+    uint16_t sequenceCounterDiff = 0;
+    uint32_t downLinkCounter = 0;
+
     MulticastParams_t *curMulticastParams = NULL;
     uint8_t *nwkSKey = LoRaMacNwkSKey;
     uint8_t *appSKey = LoRaMacAppSKey;
-    uint32_t downLinkCounter = 0;
     
     bool isMicOk = false;
 
@@ -1814,7 +1866,16 @@
                 // DLSettings
                 Rx1DrOffset = ( LoRaMacRxPayload[11] >> 4 ) & 0x07;
                 Rx2Channel.Datarate = LoRaMacRxPayload[11] & 0x0F;
-                
+#if defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+                /*
+                 * WARNING: To be removed once Semtech server implementation
+                 *          is corrected.
+                 */
+                if( Rx2Channel.Datarate == DR_3 )
+                {
+                    Rx2Channel.Datarate = DR_8;
+                }
+#endif
                 // RxDelay
                 ReceiveDelay1 = ( LoRaMacRxPayload[12] & 0x0F );
                 if( ReceiveDelay1 == 0 )
@@ -1847,8 +1908,6 @@
             {
                 LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL;
             }
-
-            LoRaMacEventFlags.Bits.Tx = 1;
             break;
         case FRAME_TYPE_DATA_CONFIRMED_DOWN:
         case FRAME_TYPE_DATA_UNCONFIRMED_DOWN:
@@ -1898,8 +1957,8 @@
                 }
                 fCtrl.Value = payload[pktHeaderLen++];
                 
-                sequenceCounter |= ( uint32_t )payload[pktHeaderLen++];
-                sequenceCounter |= ( uint32_t )payload[pktHeaderLen++] << 8;
+                sequenceCounter = ( uint16_t )payload[pktHeaderLen++];
+                sequenceCounter |= ( uint16_t )payload[pktHeaderLen++] << 8;
 
                 appPayloadStartIndex = 8 + fCtrl.Bits.FOptsLen;
 
@@ -1908,45 +1967,39 @@
                 micRx |= ( (uint32_t)payload[size - LORAMAC_MFR_LEN + 2] << 16 );
                 micRx |= ( (uint32_t)payload[size - LORAMAC_MFR_LEN + 3] << 24 );
 
-                sequence = ( int32_t )sequenceCounter - ( int32_t )( downLinkCounter & 0xFFFF );
-                if( sequence < 0 )
+                sequenceCounterPrev = ( uint16_t )downLinkCounter;
+                sequenceCounterDiff = ( sequenceCounter - sequenceCounterPrev );
+
+                if( sequenceCounterDiff < ( 1 << 15 ) )
                 {
-                    // sequence reset or roll over happened
-                    downLinkCounter = ( downLinkCounter & 0xFFFF0000 ) | ( sequenceCounter + ( uint32_t )0x10000 );
+                    downLinkCounter += sequenceCounterDiff;
                     LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
                     if( micRx == mic )
                     {
                         isMicOk = true;
                     }
-                    else
-                    {
-                        isMicOk = false;
-                        // sequence reset
-                        if( LoRaMacEventFlags.Bits.Multicast == 1 )
-                        {
-                            curMulticastParams->DownLinkCounter = downLinkCounter = sequenceCounter;
-                        }
-                        else
-                        {
-                            DownLinkCounter = downLinkCounter = sequenceCounter;
-                        }
-                        LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
-                    }
                 }
                 else
                 {
-                    downLinkCounter = ( downLinkCounter & 0xFFFF0000 ) | sequenceCounter;
-                    LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounter, &mic );
+                    // check for downlink counter roll-over
+                    uint32_t  downLinkCounterTmp = downLinkCounter + 0x10000 + ( int16_t )sequenceCounterDiff;
+                    LoRaMacComputeMic( payload, size - LORAMAC_MFR_LEN, nwkSKey, address, DOWN_LINK, downLinkCounterTmp, &mic );
+                    if( micRx == mic )
+                    {
+                        isMicOk = true;
+                        downLinkCounter = downLinkCounterTmp;
+                    }
                 }
 
-                if( ( isMicOk == true ) ||
-                    ( micRx == mic ) )
+                if( isMicOk == true )
                 {
                     LoRaMacEventFlags.Bits.Rx = 1;
                     LoRaMacEventInfo.RxSnr = snr;
                     LoRaMacEventInfo.RxRssi = rssi;
                     LoRaMacEventInfo.RxBufferSize = 0;
                     AdrAckCounter = 0;
+
+                    // Update 32 bits downlink counter
                     if( LoRaMacEventFlags.Bits.Multicast == 1 )
                     {
                         curMulticastParams->DownLinkCounter = downLinkCounter;
@@ -2025,27 +2078,29 @@
                         }
                     }
 
-                    LoRaMacEventFlags.Bits.Tx = 1;
                     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
                 }
                 else
                 {
                     LoRaMacEventInfo.TxAckReceived = false;
                     
-                    LoRaMacEventFlags.Bits.Tx = 1;
                     LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL;
                     LoRaMacState &= ~MAC_TX_RUNNING;
+                    if( NodeAckRequested == true )
+                    {
+                        OnAckTimeoutTimerEvent( );
+                    }
                 }
             }
             break;
         case FRAME_TYPE_PROPRIETARY:
             //Intentional falltrough
         default:
-            LoRaMacEventFlags.Bits.Tx = 1;
             LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
             LoRaMacState &= ~MAC_TX_RUNNING;
             break;
     }
+    LoRaMacEventFlags.Bits.Tx = 1;
 }
 
 /*!
@@ -2075,6 +2130,10 @@
     {
         Radio.Sleep( );
     }
+    else
+    {
+        OnRxWindow2TimerEvent( );
+    }
     if( LoRaMacEventFlags.Bits.RxSlot == 1 )
     {
         LoRaMacEventFlags.Bits.Tx = 1;
@@ -2091,6 +2150,10 @@
     {
         Radio.Sleep( );
     }
+    else
+    {
+        OnRxWindow2TimerEvent( );
+    }
     if( LoRaMacEventFlags.Bits.RxSlot == 1 )
     {
         LoRaMacEventFlags.Bits.Tx = 1;
@@ -2108,17 +2171,36 @@
  */
 void LoRaMacRxWindowSetup( uint32_t freq, int8_t datarate, uint32_t bandwidth, uint16_t timeout, bool rxContinuous )
 {
-    if( Radio.GetStatus( ) == IDLE )
+    uint8_t downlinkDatarate = Datarates[datarate];
+    RadioModems_t modem;
+
+    if( Radio.GetStatus( ) == RF_IDLE )
     {
         Radio.SetChannel( freq );
+#if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
         if( datarate == DR_7 )
         {
-            Radio.SetRxConfig( MODEM_FSK, 50e3, Datarates[datarate] * 1e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, rxContinuous );
+            modem = MODEM_FSK;
+            Radio.SetRxConfig( MODEM_FSK, 50e3, downlinkDatarate * 1e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, rxContinuous );
         }
         else
         {
-            Radio.SetRxConfig( MODEM_LORA, bandwidth, Datarates[datarate], 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
+            modem = MODEM_LORA;
+            Radio.SetRxConfig( MODEM_LORA, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
         }
+#elif defined( USE_BAND_915 ) || defined( USE_BAND_915_HYBRID )
+        modem = MODEM_LORA;
+        Radio.SetRxConfig( MODEM_LORA, bandwidth, downlinkDatarate, 1, 0, 8, timeout, false, 0, false, 0, 0, true, rxContinuous );
+#endif
+        if( RepeaterSupport == true )
+        {
+            Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarateRepeater[datarate] );
+        }
+        else
+        {
+            Radio.SetMaxPayloadLength( modem, MaxPayloadOfDatarate[datarate] );
+        }
+
         if( rxContinuous == false )
         {
             Radio.Rx( MaxRxWindow );
@@ -2142,6 +2224,10 @@
     TimerStop( &RxWindowTimer1 );
     LoRaMacEventFlags.Bits.RxSlot = 0;
 
+    if( LoRaMacDeviceClass == CLASS_C )
+    {
+        Radio.Standby( );
+    }
 #if defined( USE_BAND_433 ) || defined( USE_BAND_780 ) || defined( USE_BAND_868 )
     datarate = ChannelsDatarate - Rx1DrOffset;
     if( datarate < 0 )
@@ -2174,7 +2260,6 @@
     {// LoRa 500 kHz
         bandwidth  = 2;
     }
-    //LoRaMacRxWindowSetup( Channels[Channel].Frequency, datarate, bandwidth, symbTimeout, false );
     LoRaMacRxWindowSetup( 923.3e6 + ( Channel % 8 ) * 600e3, datarate, bandwidth, symbTimeout, false );
 #else
     #error "Please define a frequency band in the compiler options."
@@ -2338,7 +2423,6 @@
                 {
                     UpLinkCounter++;
                 }
-                LoRaMacEventInfo.Status = LORAMAC_EVENT_INFO_STATUS_OK;
             }
         }
     }
@@ -2350,6 +2434,7 @@
     if( LoRaMacState == MAC_IDLE )
     {
         LoRaMacNotify( &LoRaMacEventFlags, &LoRaMacEventInfo );
+        LoRaMacEventFlags.Bits.Tx = 0;
     }
     else
     {
--- a/LoRaMac.h	Tue Oct 20 13:21:26 2015 +0000
+++ b/LoRaMac.h	Mon Nov 23 10:09:43 2015 +0000
@@ -298,7 +298,7 @@
  * LoRaMAC events structure
  * Used to notify upper layers of MAC events
  */
-typedef struct sLoRaMacEvent
+typedef struct sLoRaMacCallbacks
 {
     /*!
      * MAC layer event callback prototype.
@@ -307,17 +307,21 @@
      * \param [IN] info  Details about MAC events occurred
      */
     void ( *MacEvent )( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info );
-}LoRaMacEvent_t;
+    /*!
+     * Function callback to get the current battery level
+     *
+     * \retval batteryLevel Current battery level
+     */
+    uint8_t ( *GetBatteryLevel )( void );
+}LoRaMacCallbacks_t;
 
 /*!
  * LoRaMAC layer initialization
  *
- * \param [IN] events          Pointer to a structure defining the LoRaMAC
+ * \param [IN] callabcks       Pointer to a structure defining the LoRaMAC
  *                             callback functions.
- * \param [IN] getBatteryLevel Function callback to get the current
- *                             battery level
  */
-void LoRaMacInit( LoRaMacEvent_t *events, uint8_t ( *getBatteryLevel )( ) );
+void LoRaMacInit( LoRaMacCallbacks_t *callabcks );
 
 /*!
  * Enables/Disables the ADR (Adaptive Data Rate)
--- a/LoRaMacCrypto.cpp	Tue Oct 20 13:21:26 2015 +0000
+++ b/LoRaMacCrypto.cpp	Mon Nov 23 10:09:43 2015 +0000
@@ -12,8 +12,8 @@
 
 Maintainer: Miguel Luis and Gregory Cristian
 */
-#include "mbed.h"
-#include "board.h"
+#include <stdlib.h>
+#include <stdint.h>
 #include "utilities.h"
 
 #include "aes.h"
@@ -54,7 +54,7 @@
  * AES computation context variable
  */
 static aes_context AesContext;
-                   
+
 /*!
  * CMAC computation context variable
  */
--- a/crypto/aes.cpp	Tue Oct 20 13:21:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,935 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
-
- LICENSE TERMS
-
- The redistribution and use of this software (with or without changes)
- is allowed without the payment of fees or royalties provided that:
-
-  1. source code distributions include the above copyright notice, this
-     list of conditions and the following disclaimer;
-
-  2. binary distributions include the above copyright notice, this list
-     of conditions and the following disclaimer in their documentation;
-
-  3. the name of the copyright holder is not used to endorse products
-     built using this software without specific written permission.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue 09/09/2006
-
- This is an AES implementation that uses only 8-bit byte operations on the
- cipher state (there are options to use 32-bit types if available).
-
- The combination of mix columns and byte substitution used here is based on
- that developed by Karl Malbrain. His contribution is acknowledged.
- */
-
-/* define if you have a fast memcpy function on your system */
-#if 0
-#  define HAVE_MEMCPY
-#  include <string.h>
-#  if defined( _MSC_VER )
-#    include <intrin.h>
-#    pragma intrinsic( memcpy )
-#  endif
-#endif
-
-
-#include "mbed.h"
-
-/* define if you have fast 32-bit types on your system */
-#if 1
-#  define HAVE_UINT_32T
-#endif
-
-/* define if you don't want any tables */
-#if 1
-#  define USE_TABLES
-#endif
-
-/*  On Intel Core 2 duo VERSION_1 is faster */
-
-/* alternative versions (test for performance on your system) */
-#if 1
-#  define VERSION_1
-#endif
-
-#include "aes.h"
-
-#if defined( HAVE_UINT_32T )
-  typedef unsigned long uint_32t;
-#endif
-
-/* functions for finite field multiplication in the AES Galois field    */
-
-#define WPOLY   0x011b
-#define BPOLY     0x1b
-#define DPOLY   0x008d
-
-#define f1(x)   (x)
-#define f2(x)   ((x << 1) ^ (((x >> 7) & 1) * WPOLY))
-#define f4(x)   ((x << 2) ^ (((x >> 6) & 1) * WPOLY) ^ (((x >> 6) & 2) * WPOLY))
-#define f8(x)   ((x << 3) ^ (((x >> 5) & 1) * WPOLY) ^ (((x >> 5) & 2) * WPOLY) \
-                          ^ (((x >> 5) & 4) * WPOLY))
-#define d2(x)   (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))
-
-#define f3(x)   (f2(x) ^ x)
-#define f9(x)   (f8(x) ^ x)
-#define fb(x)   (f8(x) ^ f2(x) ^ x)
-#define fd(x)   (f8(x) ^ f4(x) ^ x)
-#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))
-
-#if defined( USE_TABLES )
-
-#define sb_data(w) {    /* S Box data values */                            \
-    w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
-    w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
-    w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
-    w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
-    w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
-    w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
-    w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
-    w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
-    w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
-    w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
-    w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
-    w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
-    w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
-    w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
-    w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
-    w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
-    w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
-    w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
-    w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
-    w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
-    w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
-    w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
-    w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
-    w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
-    w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
-    w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
-    w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
-    w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
-    w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
-    w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
-    w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
-    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
-
-#define isb_data(w) {   /* inverse S Box data values */                    \
-    w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
-    w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
-    w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
-    w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
-    w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
-    w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
-    w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
-    w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
-    w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
-    w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
-    w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
-    w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
-    w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
-    w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
-    w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
-    w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
-    w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
-    w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
-    w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
-    w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
-    w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
-    w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
-    w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
-    w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
-    w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
-    w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
-    w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
-    w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
-    w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
-    w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
-    w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
-    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
-
-#define mm_data(w) {    /* basic data for forming finite field tables */   \
-    w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
-    w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
-    w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
-    w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
-    w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
-    w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
-    w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
-    w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
-    w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
-    w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
-    w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
-    w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
-    w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
-    w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
-    w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
-    w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
-    w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
-    w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
-    w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
-    w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
-    w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
-    w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
-    w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
-    w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
-    w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
-    w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
-    w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
-    w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
-    w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
-    w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
-    w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
-    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
-
-static const uint_8t sbox[256]  =  sb_data(f1);
-
-#if defined( AES_DEC_PREKEYED )
-static const uint_8t isbox[256] = isb_data(f1);
-#endif
-
-static const uint_8t gfm2_sbox[256] = sb_data(f2);
-static const uint_8t gfm3_sbox[256] = sb_data(f3);
-
-#if defined( AES_DEC_PREKEYED )
-static const uint_8t gfmul_9[256] = mm_data(f9);
-static const uint_8t gfmul_b[256] = mm_data(fb);
-static const uint_8t gfmul_d[256] = mm_data(fd);
-static const uint_8t gfmul_e[256] = mm_data(fe);
-#endif
-
-#define s_box(x)     sbox[(x)]
-#if defined( AES_DEC_PREKEYED )
-#define is_box(x)    isbox[(x)]
-#endif
-#define gfm2_sb(x)   gfm2_sbox[(x)]
-#define gfm3_sb(x)   gfm3_sbox[(x)]
-#if defined( AES_DEC_PREKEYED )
-#define gfm_9(x)     gfmul_9[(x)]
-#define gfm_b(x)     gfmul_b[(x)]
-#define gfm_d(x)     gfmul_d[(x)]
-#define gfm_e(x)     gfmul_e[(x)]
-#endif
-#else
-
-/* this is the high bit of x right shifted by 1 */
-/* position. Since the starting polynomial has  */
-/* 9 bits (0x11b), this right shift keeps the   */
-/* values of all top bits within a byte         */
-
-static uint_8t hibit(const uint_8t x)
-{   uint_8t r = (uint_8t)((x >> 1) | (x >> 2));
-
-    r |= (r >> 2);
-    r |= (r >> 4);
-    return (r + 1) >> 1;
-}
-
-/* return the inverse of the finite field element x */
-
-static uint_8t gf_inv(const uint_8t x)
-{   uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-
-    if(x < 2) 
-        return x;
-
-    for( ; ; )
-    {
-        if(n1)
-            while(n2 >= n1)             /* divide polynomial p2 by p1    */
-            {
-                n2 /= n1;               /* shift smaller polynomial left */ 
-                p2 ^= (p1 * n2) & 0xff; /* and remove from larger one    */
-                v2 ^= (v1 * n2);        /* shift accumulated value and   */ 
-                n2 = hibit(p2);         /* add into result               */
-            }
-        else
-            return v1;
-
-        if(n2)                          /* repeat with values swapped    */ 
-            while(n1 >= n2)
-            {
-                n1 /= n2; 
-                p1 ^= p2 * n1; 
-                v1 ^= v2 * n1; 
-                n1 = hibit(p1);
-            }
-        else
-            return v2;
-    }
-}
-
-/* The forward and inverse affine transformations used in the S-box */
-uint_8t fwd_affine(const uint_8t x)
-{   
-#if defined( HAVE_UINT_32T )
-    uint_32t w = x;
-    w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
-    return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
-#else
-    return 0x63 ^ x ^ (x << 1) ^ (x << 2) ^ (x << 3) ^ (x << 4) 
-                    ^ (x >> 7) ^ (x >> 6) ^ (x >> 5) ^ (x >> 4);
-#endif
-}
-
-uint_8t inv_affine(const uint_8t x)
-{
-#if defined( HAVE_UINT_32T )
-    uint_32t w = x;
-    w = (w << 1) ^ (w << 3) ^ (w << 6);
-    return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
-#else
-    return 0x05 ^ (x << 1) ^ (x << 3) ^ (x << 6) 
-                ^ (x >> 7) ^ (x >> 5) ^ (x >> 2);
-#endif
-}
-
-#define s_box(x)   fwd_affine(gf_inv(x))
-#define is_box(x)  gf_inv(inv_affine(x))
-#define gfm2_sb(x) f2(s_box(x))
-#define gfm3_sb(x) f3(s_box(x))
-#define gfm_9(x)   f9(x)
-#define gfm_b(x)   fb(x)
-#define gfm_d(x)   fd(x)
-#define gfm_e(x)   fe(x)
-
-#endif
-
-#if defined( HAVE_MEMCPY )
-#  define block_copy_nn(d, s, l)    memcpy(d, s, l)
-#  define block_copy(d, s)          memcpy(d, s, N_BLOCK)
-#else
-#  define block_copy_nn(d, s, l)    copy_block_nn(d, s, l)
-#  define block_copy(d, s)          copy_block(d, s)
-#endif
-
-static void copy_block( void *d, const void *s )
-{
-#if defined( HAVE_UINT_32T )
-    ((uint_32t*)d)[ 0] = ((uint_32t*)s)[ 0];
-    ((uint_32t*)d)[ 1] = ((uint_32t*)s)[ 1];
-    ((uint_32t*)d)[ 2] = ((uint_32t*)s)[ 2];
-    ((uint_32t*)d)[ 3] = ((uint_32t*)s)[ 3];
-#else
-    ((uint_8t*)d)[ 0] = ((uint_8t*)s)[ 0];
-    ((uint_8t*)d)[ 1] = ((uint_8t*)s)[ 1];
-    ((uint_8t*)d)[ 2] = ((uint_8t*)s)[ 2];
-    ((uint_8t*)d)[ 3] = ((uint_8t*)s)[ 3];
-    ((uint_8t*)d)[ 4] = ((uint_8t*)s)[ 4];
-    ((uint_8t*)d)[ 5] = ((uint_8t*)s)[ 5];
-    ((uint_8t*)d)[ 6] = ((uint_8t*)s)[ 6];
-    ((uint_8t*)d)[ 7] = ((uint_8t*)s)[ 7];
-    ((uint_8t*)d)[ 8] = ((uint_8t*)s)[ 8];
-    ((uint_8t*)d)[ 9] = ((uint_8t*)s)[ 9];
-    ((uint_8t*)d)[10] = ((uint_8t*)s)[10];
-    ((uint_8t*)d)[11] = ((uint_8t*)s)[11];
-    ((uint_8t*)d)[12] = ((uint_8t*)s)[12];
-    ((uint_8t*)d)[13] = ((uint_8t*)s)[13];
-    ((uint_8t*)d)[14] = ((uint_8t*)s)[14];
-    ((uint_8t*)d)[15] = ((uint_8t*)s)[15];
-#endif
-}
-
-static void copy_block_nn( uint_8t * d, const uint_8t *s, uint_8t nn )
-{
-    while( nn-- )
-        //*((uint_8t*)d)++ = *((uint_8t*)s)++;
-        *d++ = *s++;
-}
-
-static void xor_block( void *d, const void *s )
-{
-#if defined( HAVE_UINT_32T )
-    ((uint_32t*)d)[ 0] ^= ((uint_32t*)s)[ 0];
-    ((uint_32t*)d)[ 1] ^= ((uint_32t*)s)[ 1];
-    ((uint_32t*)d)[ 2] ^= ((uint_32t*)s)[ 2];
-    ((uint_32t*)d)[ 3] ^= ((uint_32t*)s)[ 3];
-#else
-    ((uint_8t*)d)[ 0] ^= ((uint_8t*)s)[ 0];
-    ((uint_8t*)d)[ 1] ^= ((uint_8t*)s)[ 1];
-    ((uint_8t*)d)[ 2] ^= ((uint_8t*)s)[ 2];
-    ((uint_8t*)d)[ 3] ^= ((uint_8t*)s)[ 3];
-    ((uint_8t*)d)[ 4] ^= ((uint_8t*)s)[ 4];
-    ((uint_8t*)d)[ 5] ^= ((uint_8t*)s)[ 5];
-    ((uint_8t*)d)[ 6] ^= ((uint_8t*)s)[ 6];
-    ((uint_8t*)d)[ 7] ^= ((uint_8t*)s)[ 7];
-    ((uint_8t*)d)[ 8] ^= ((uint_8t*)s)[ 8];
-    ((uint_8t*)d)[ 9] ^= ((uint_8t*)s)[ 9];
-    ((uint_8t*)d)[10] ^= ((uint_8t*)s)[10];
-    ((uint_8t*)d)[11] ^= ((uint_8t*)s)[11];
-    ((uint_8t*)d)[12] ^= ((uint_8t*)s)[12];
-    ((uint_8t*)d)[13] ^= ((uint_8t*)s)[13];
-    ((uint_8t*)d)[14] ^= ((uint_8t*)s)[14];
-    ((uint_8t*)d)[15] ^= ((uint_8t*)s)[15];
-#endif
-}
-
-static void copy_and_key( void *d, const void *s, const void *k )
-{
-#if defined( HAVE_UINT_32T )
-    ((uint_32t*)d)[ 0] = ((uint_32t*)s)[ 0] ^ ((uint_32t*)k)[ 0];
-    ((uint_32t*)d)[ 1] = ((uint_32t*)s)[ 1] ^ ((uint_32t*)k)[ 1];
-    ((uint_32t*)d)[ 2] = ((uint_32t*)s)[ 2] ^ ((uint_32t*)k)[ 2];
-    ((uint_32t*)d)[ 3] = ((uint_32t*)s)[ 3] ^ ((uint_32t*)k)[ 3];
-#elif 1
-    ((uint_8t*)d)[ 0] = ((uint_8t*)s)[ 0] ^ ((uint_8t*)k)[ 0];
-    ((uint_8t*)d)[ 1] = ((uint_8t*)s)[ 1] ^ ((uint_8t*)k)[ 1];
-    ((uint_8t*)d)[ 2] = ((uint_8t*)s)[ 2] ^ ((uint_8t*)k)[ 2];
-    ((uint_8t*)d)[ 3] = ((uint_8t*)s)[ 3] ^ ((uint_8t*)k)[ 3];
-    ((uint_8t*)d)[ 4] = ((uint_8t*)s)[ 4] ^ ((uint_8t*)k)[ 4];
-    ((uint_8t*)d)[ 5] = ((uint_8t*)s)[ 5] ^ ((uint_8t*)k)[ 5];
-    ((uint_8t*)d)[ 6] = ((uint_8t*)s)[ 6] ^ ((uint_8t*)k)[ 6];
-    ((uint_8t*)d)[ 7] = ((uint_8t*)s)[ 7] ^ ((uint_8t*)k)[ 7];
-    ((uint_8t*)d)[ 8] = ((uint_8t*)s)[ 8] ^ ((uint_8t*)k)[ 8];
-    ((uint_8t*)d)[ 9] = ((uint_8t*)s)[ 9] ^ ((uint_8t*)k)[ 9];
-    ((uint_8t*)d)[10] = ((uint_8t*)s)[10] ^ ((uint_8t*)k)[10];
-    ((uint_8t*)d)[11] = ((uint_8t*)s)[11] ^ ((uint_8t*)k)[11];
-    ((uint_8t*)d)[12] = ((uint_8t*)s)[12] ^ ((uint_8t*)k)[12];
-    ((uint_8t*)d)[13] = ((uint_8t*)s)[13] ^ ((uint_8t*)k)[13];
-    ((uint_8t*)d)[14] = ((uint_8t*)s)[14] ^ ((uint_8t*)k)[14];
-    ((uint_8t*)d)[15] = ((uint_8t*)s)[15] ^ ((uint_8t*)k)[15];
-#else
-    block_copy(d, s);
-    xor_block(d, k);
-#endif
-}
-
-static void add_round_key( uint_8t d[N_BLOCK], const uint_8t k[N_BLOCK] )
-{
-    xor_block(d, k);
-}
-
-static void shift_sub_rows( uint_8t st[N_BLOCK] )
-{   uint_8t tt;
-
-    st[ 0] = s_box(st[ 0]); st[ 4] = s_box(st[ 4]);
-    st[ 8] = s_box(st[ 8]); st[12] = s_box(st[12]);
-
-    tt = st[1]; st[ 1] = s_box(st[ 5]); st[ 5] = s_box(st[ 9]);
-    st[ 9] = s_box(st[13]); st[13] = s_box( tt );
-
-    tt = st[2]; st[ 2] = s_box(st[10]); st[10] = s_box( tt );
-    tt = st[6]; st[ 6] = s_box(st[14]); st[14] = s_box( tt );
-
-    tt = st[15]; st[15] = s_box(st[11]); st[11] = s_box(st[ 7]);
-    st[ 7] = s_box(st[ 3]); st[ 3] = s_box( tt );
-}
-
-#if defined( AES_DEC_PREKEYED )
-
-static void inv_shift_sub_rows( uint_8t st[N_BLOCK] )
-{   uint_8t tt;
-
-    st[ 0] = is_box(st[ 0]); st[ 4] = is_box(st[ 4]);
-    st[ 8] = is_box(st[ 8]); st[12] = is_box(st[12]);
-
-    tt = st[13]; st[13] = is_box(st[9]); st[ 9] = is_box(st[5]);
-    st[ 5] = is_box(st[1]); st[ 1] = is_box( tt );
-
-    tt = st[2]; st[ 2] = is_box(st[10]); st[10] = is_box( tt );
-    tt = st[6]; st[ 6] = is_box(st[14]); st[14] = is_box( tt );
-
-    tt = st[3]; st[ 3] = is_box(st[ 7]); st[ 7] = is_box(st[11]);
-    st[11] = is_box(st[15]); st[15] = is_box( tt );
-}
-
-#endif
-
-#if defined( VERSION_1 )
-  static void mix_sub_columns( uint_8t dt[N_BLOCK] )
-  { uint_8t st[N_BLOCK];
-    block_copy(st, dt);
-#else
-  static void mix_sub_columns( uint_8t dt[N_BLOCK], uint_8t st[N_BLOCK] )
-  {
-#endif
-    dt[ 0] = gfm2_sb(st[0]) ^ gfm3_sb(st[5]) ^ s_box(st[10]) ^ s_box(st[15]);
-    dt[ 1] = s_box(st[0]) ^ gfm2_sb(st[5]) ^ gfm3_sb(st[10]) ^ s_box(st[15]);
-    dt[ 2] = s_box(st[0]) ^ s_box(st[5]) ^ gfm2_sb(st[10]) ^ gfm3_sb(st[15]);
-    dt[ 3] = gfm3_sb(st[0]) ^ s_box(st[5]) ^ s_box(st[10]) ^ gfm2_sb(st[15]);
-
-    dt[ 4] = gfm2_sb(st[4]) ^ gfm3_sb(st[9]) ^ s_box(st[14]) ^ s_box(st[3]);
-    dt[ 5] = s_box(st[4]) ^ gfm2_sb(st[9]) ^ gfm3_sb(st[14]) ^ s_box(st[3]);
-    dt[ 6] = s_box(st[4]) ^ s_box(st[9]) ^ gfm2_sb(st[14]) ^ gfm3_sb(st[3]);
-    dt[ 7] = gfm3_sb(st[4]) ^ s_box(st[9]) ^ s_box(st[14]) ^ gfm2_sb(st[3]);
-
-    dt[ 8] = gfm2_sb(st[8]) ^ gfm3_sb(st[13]) ^ s_box(st[2]) ^ s_box(st[7]);
-    dt[ 9] = s_box(st[8]) ^ gfm2_sb(st[13]) ^ gfm3_sb(st[2]) ^ s_box(st[7]);
-    dt[10] = s_box(st[8]) ^ s_box(st[13]) ^ gfm2_sb(st[2]) ^ gfm3_sb(st[7]);
-    dt[11] = gfm3_sb(st[8]) ^ s_box(st[13]) ^ s_box(st[2]) ^ gfm2_sb(st[7]);
-
-    dt[12] = gfm2_sb(st[12]) ^ gfm3_sb(st[1]) ^ s_box(st[6]) ^ s_box(st[11]);
-    dt[13] = s_box(st[12]) ^ gfm2_sb(st[1]) ^ gfm3_sb(st[6]) ^ s_box(st[11]);
-    dt[14] = s_box(st[12]) ^ s_box(st[1]) ^ gfm2_sb(st[6]) ^ gfm3_sb(st[11]);
-    dt[15] = gfm3_sb(st[12]) ^ s_box(st[1]) ^ s_box(st[6]) ^ gfm2_sb(st[11]);
-  }
-
-#if defined( AES_DEC_PREKEYED )
-
-#if defined( VERSION_1 )
-  static void inv_mix_sub_columns( uint_8t dt[N_BLOCK] )
-  { uint_8t st[N_BLOCK];
-    block_copy(st, dt);
-#else
-  static void inv_mix_sub_columns( uint_8t dt[N_BLOCK], uint_8t st[N_BLOCK] )
-  {
-#endif
-    dt[ 0] = is_box(gfm_e(st[ 0]) ^ gfm_b(st[ 1]) ^ gfm_d(st[ 2]) ^ gfm_9(st[ 3]));
-    dt[ 5] = is_box(gfm_9(st[ 0]) ^ gfm_e(st[ 1]) ^ gfm_b(st[ 2]) ^ gfm_d(st[ 3]));
-    dt[10] = is_box(gfm_d(st[ 0]) ^ gfm_9(st[ 1]) ^ gfm_e(st[ 2]) ^ gfm_b(st[ 3]));
-    dt[15] = is_box(gfm_b(st[ 0]) ^ gfm_d(st[ 1]) ^ gfm_9(st[ 2]) ^ gfm_e(st[ 3]));
-
-    dt[ 4] = is_box(gfm_e(st[ 4]) ^ gfm_b(st[ 5]) ^ gfm_d(st[ 6]) ^ gfm_9(st[ 7]));
-    dt[ 9] = is_box(gfm_9(st[ 4]) ^ gfm_e(st[ 5]) ^ gfm_b(st[ 6]) ^ gfm_d(st[ 7]));
-    dt[14] = is_box(gfm_d(st[ 4]) ^ gfm_9(st[ 5]) ^ gfm_e(st[ 6]) ^ gfm_b(st[ 7]));
-    dt[ 3] = is_box(gfm_b(st[ 4]) ^ gfm_d(st[ 5]) ^ gfm_9(st[ 6]) ^ gfm_e(st[ 7]));
-
-    dt[ 8] = is_box(gfm_e(st[ 8]) ^ gfm_b(st[ 9]) ^ gfm_d(st[10]) ^ gfm_9(st[11]));
-    dt[13] = is_box(gfm_9(st[ 8]) ^ gfm_e(st[ 9]) ^ gfm_b(st[10]) ^ gfm_d(st[11]));
-    dt[ 2] = is_box(gfm_d(st[ 8]) ^ gfm_9(st[ 9]) ^ gfm_e(st[10]) ^ gfm_b(st[11]));
-    dt[ 7] = is_box(gfm_b(st[ 8]) ^ gfm_d(st[ 9]) ^ gfm_9(st[10]) ^ gfm_e(st[11]));
-
-    dt[12] = is_box(gfm_e(st[12]) ^ gfm_b(st[13]) ^ gfm_d(st[14]) ^ gfm_9(st[15]));
-    dt[ 1] = is_box(gfm_9(st[12]) ^ gfm_e(st[13]) ^ gfm_b(st[14]) ^ gfm_d(st[15]));
-    dt[ 6] = is_box(gfm_d(st[12]) ^ gfm_9(st[13]) ^ gfm_e(st[14]) ^ gfm_b(st[15]));
-    dt[11] = is_box(gfm_b(st[12]) ^ gfm_d(st[13]) ^ gfm_9(st[14]) ^ gfm_e(st[15]));
-  }
-
-#endif
-
-#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
-
-/*  Set the cipher key for the pre-keyed version */
-
-return_type aes_set_key( const unsigned char key[], length_type keylen, aes_context ctx[1] )
-{
-    uint_8t cc, rc, hi;
-
-    switch( keylen )
-    {
-    case 16:
-    case 24:
-    case 32:
-        break;
-    default: 
-        ctx->rnd = 0; 
-        return ( uint_8t )-1;
-    }
-    block_copy_nn(ctx->ksch, key, keylen);
-    hi = (keylen + 28) << 2;
-    ctx->rnd = (hi >> 4) - 1;
-    for( cc = keylen, rc = 1; cc < hi; cc += 4 )
-    {   uint_8t tt, t0, t1, t2, t3;
-
-        t0 = ctx->ksch[cc - 4];
-        t1 = ctx->ksch[cc - 3];
-        t2 = ctx->ksch[cc - 2];
-        t3 = ctx->ksch[cc - 1];
-        if( cc % keylen == 0 )
-        {
-            tt = t0;
-            t0 = s_box(t1) ^ rc;
-            t1 = s_box(t2);
-            t2 = s_box(t3);
-            t3 = s_box(tt);
-            rc = f2(rc);
-        }
-        else if( keylen > 24 && cc % keylen == 16 )
-        {
-            t0 = s_box(t0);
-            t1 = s_box(t1);
-            t2 = s_box(t2);
-            t3 = s_box(t3);
-        }
-        tt = cc - keylen;
-        ctx->ksch[cc + 0] = ctx->ksch[tt + 0] ^ t0;
-        ctx->ksch[cc + 1] = ctx->ksch[tt + 1] ^ t1;
-        ctx->ksch[cc + 2] = ctx->ksch[tt + 2] ^ t2;
-        ctx->ksch[cc + 3] = ctx->ksch[tt + 3] ^ t3;
-    }
-    return 0;
-}
-
-#endif
-
-#if defined( AES_ENC_PREKEYED )
-
-/*  Encrypt a single block of 16 bytes */
-
-return_type aes_encrypt( const unsigned char in[N_BLOCK], unsigned char  out[N_BLOCK], const aes_context ctx[1] )
-{
-    if( ctx->rnd )
-    {
-        uint_8t s1[N_BLOCK], r;
-        copy_and_key( s1, in, ctx->ksch );
-
-        for( r = 1 ; r < ctx->rnd ; ++r )
-#if defined( VERSION_1 )
-        {
-            mix_sub_columns( s1 );
-            add_round_key( s1, ctx->ksch + r * N_BLOCK);
-        }
-#else
-        {   uint_8t s2[N_BLOCK];
-            mix_sub_columns( s2, s1 );
-            copy_and_key( s1, s2, ctx->ksch + r * N_BLOCK);
-        }
-#endif
-        shift_sub_rows( s1 );
-        copy_and_key( out, s1, ctx->ksch + r * N_BLOCK );
-    }
-    else
-        return ( uint_8t )-1;
-    return 0;
-}
-
-/* CBC encrypt a number of blocks (input and return an IV) */
-
-return_type aes_cbc_encrypt( const unsigned char *in, unsigned char *out,
-                         int n_block, unsigned char iv[N_BLOCK], const aes_context ctx[1] )
-{
-
-    while(n_block--)
-    {
-        xor_block(iv, in);
-        if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-            return EXIT_FAILURE;
-        //memcpy(out, iv, N_BLOCK);
-        block_copy(out, iv);
-        in += N_BLOCK;
-        out += N_BLOCK;
-    }
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined( AES_DEC_PREKEYED )
-
-/*  Decrypt a single block of 16 bytes */
-
-return_type aes_decrypt( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK], const aes_context ctx[1] )
-{
-    if( ctx->rnd )
-    {
-        uint_8t s1[N_BLOCK], r;
-        copy_and_key( s1, in, ctx->ksch + ctx->rnd * N_BLOCK );
-        inv_shift_sub_rows( s1 );
-
-        for( r = ctx->rnd ; --r ; )
-#if defined( VERSION_1 )
-        {
-            add_round_key( s1, ctx->ksch + r * N_BLOCK );
-            inv_mix_sub_columns( s1 );
-        }
-#else
-        {   uint_8t s2[N_BLOCK];
-            copy_and_key( s2, s1, ctx->ksch + r * N_BLOCK );
-            inv_mix_sub_columns( s1, s2 );
-        }
-#endif
-        copy_and_key( out, s1, ctx->ksch );
-    }
-    else
-        return -1;
-    return 0;
-}
-
-/* CBC decrypt a number of blocks (input and return an IV) */
-
-return_type aes_cbc_decrypt( const unsigned char *in, unsigned char *out,
-                         int n_block, unsigned char iv[N_BLOCK], const aes_context ctx[1] )
-{   
-    while(n_block--)
-    {   uint_8t tmp[N_BLOCK];
-        
-        //memcpy(tmp, in, N_BLOCK);
-        block_copy(tmp, in);
-        if(aes_decrypt(in, out, ctx) != EXIT_SUCCESS)
-            return EXIT_FAILURE;
-        xor_block(out, iv);
-        //memcpy(iv, tmp, N_BLOCK);
-        block_copy(iv, tmp);
-        in += N_BLOCK;
-        out += N_BLOCK;
-    }
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined( AES_ENC_128_OTFK )
-
-/*  The 'on the fly' encryption key update for for 128 bit keys */
-
-static void update_encrypt_key_128( uint_8t k[N_BLOCK], uint_8t *rc )
-{   uint_8t cc;
-
-    k[0] ^= s_box(k[13]) ^ *rc;
-    k[1] ^= s_box(k[14]);
-    k[2] ^= s_box(k[15]);
-    k[3] ^= s_box(k[12]);
-    *rc = f2( *rc );
-
-    for(cc = 4; cc < 16; cc += 4 )
-    {
-        k[cc + 0] ^= k[cc - 4];
-        k[cc + 1] ^= k[cc - 3];
-        k[cc + 2] ^= k[cc - 2];
-        k[cc + 3] ^= k[cc - 1];
-    }
-}
-
-/*  Encrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
-
-void aes_encrypt_128( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
-                     const unsigned char key[N_BLOCK], unsigned char o_key[N_BLOCK] )
-{   uint_8t s1[N_BLOCK], r, rc = 1;
-
-    if(o_key != key)
-        block_copy( o_key, key );
-    copy_and_key( s1, in, o_key );
-
-    for( r = 1 ; r < 10 ; ++r )
-#if defined( VERSION_1 )
-    {
-        mix_sub_columns( s1 );
-        update_encrypt_key_128( o_key, &rc );
-        add_round_key( s1, o_key );
-    }
-#else
-    {   uint_8t s2[N_BLOCK];
-        mix_sub_columns( s2, s1 );
-        update_encrypt_key_128( o_key, &rc );
-        copy_and_key( s1, s2, o_key );
-    }
-#endif
-
-    shift_sub_rows( s1 );
-    update_encrypt_key_128( o_key, &rc );
-    copy_and_key( out, s1, o_key );
-}
-
-#endif
-
-#if defined( AES_DEC_128_OTFK )
-
-/*  The 'on the fly' decryption key update for for 128 bit keys */
-
-static void update_decrypt_key_128( uint_8t k[N_BLOCK], uint_8t *rc )
-{   uint_8t cc;
-
-    for( cc = 12; cc > 0; cc -= 4 )
-    {
-        k[cc + 0] ^= k[cc - 4];
-        k[cc + 1] ^= k[cc - 3];
-        k[cc + 2] ^= k[cc - 2];
-        k[cc + 3] ^= k[cc - 1];
-    }
-    *rc = d2(*rc);
-    k[0] ^= s_box(k[13]) ^ *rc;
-    k[1] ^= s_box(k[14]);
-    k[2] ^= s_box(k[15]);
-    k[3] ^= s_box(k[12]);
-}
-
-/*  Decrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
-
-void aes_decrypt_128( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
-                      const unsigned char key[N_BLOCK], unsigned char o_key[N_BLOCK] )
-{
-    uint_8t s1[N_BLOCK], r, rc = 0x6c;
-    if(o_key != key)
-        block_copy( o_key, key );
-
-    copy_and_key( s1, in, o_key );
-    inv_shift_sub_rows( s1 );
-
-    for( r = 10 ; --r ; )
-#if defined( VERSION_1 )
-    {
-        update_decrypt_key_128( o_key, &rc );
-        add_round_key( s1, o_key );
-        inv_mix_sub_columns( s1 );
-    }
-#else
-    {   uint_8t s2[N_BLOCK];
-        update_decrypt_key_128( o_key, &rc );
-        copy_and_key( s2, s1, o_key );
-        inv_mix_sub_columns( s1, s2 );
-    }
-#endif
-    update_decrypt_key_128( o_key, &rc );
-    copy_and_key( out, s1, o_key );
-}
-
-#endif
-
-#if defined( AES_ENC_256_OTFK )
-
-/*  The 'on the fly' encryption key update for for 256 bit keys */
-
-static void update_encrypt_key_256( uint_8t k[2 * N_BLOCK], uint_8t *rc )
-{   uint_8t cc;
-
-    k[0] ^= s_box(k[29]) ^ *rc;
-    k[1] ^= s_box(k[30]);
-    k[2] ^= s_box(k[31]);
-    k[3] ^= s_box(k[28]);
-    *rc = f2( *rc );
-
-    for(cc = 4; cc < 16; cc += 4)
-    {
-        k[cc + 0] ^= k[cc - 4];
-        k[cc + 1] ^= k[cc - 3];
-        k[cc + 2] ^= k[cc - 2];
-        k[cc + 3] ^= k[cc - 1];
-    }
-
-    k[16] ^= s_box(k[12]);
-    k[17] ^= s_box(k[13]);
-    k[18] ^= s_box(k[14]);
-    k[19] ^= s_box(k[15]);
-
-    for( cc = 20; cc < 32; cc += 4 )
-    {
-        k[cc + 0] ^= k[cc - 4];
-        k[cc + 1] ^= k[cc - 3];
-        k[cc + 2] ^= k[cc - 2];
-        k[cc + 3] ^= k[cc - 1];
-    }
-}
-
-/*  Encrypt a single block of 16 bytes with 'on the fly' 256 bit keying */
-
-void aes_encrypt_256( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
-                      const unsigned char key[2 * N_BLOCK], unsigned char o_key[2 * N_BLOCK] )
-{
-    uint_8t s1[N_BLOCK], r, rc = 1;
-    if(o_key != key)
-    {
-        block_copy( o_key, key );
-        block_copy( o_key + 16, key + 16 );
-    }
-    copy_and_key( s1, in, o_key );
-
-    for( r = 1 ; r < 14 ; ++r )
-#if defined( VERSION_1 )
-    {
-        mix_sub_columns(s1);
-        if( r & 1 )
-            add_round_key( s1, o_key + 16 );
-        else
-        {
-            update_encrypt_key_256( o_key, &rc );
-            add_round_key( s1, o_key );
-        }
-    }
-#else
-    {   uint_8t s2[N_BLOCK];
-        mix_sub_columns( s2, s1 );
-        if( r & 1 )
-            copy_and_key( s1, s2, o_key + 16 );
-        else
-        {
-            update_encrypt_key_256( o_key, &rc );
-            copy_and_key( s1, s2, o_key );
-        }
-    }
-#endif
-
-    shift_sub_rows( s1 );
-    update_encrypt_key_256( o_key, &rc );
-    copy_and_key( out, s1, o_key );
-}
-
-#endif
-
-#if defined( AES_DEC_256_OTFK )
-
-/*  The 'on the fly' encryption key update for for 256 bit keys */
-
-static void update_decrypt_key_256( uint_8t k[2 * N_BLOCK], uint_8t *rc )
-{   uint_8t cc;
-
-    for(cc = 28; cc > 16; cc -= 4)
-    {
-        k[cc + 0] ^= k[cc - 4];
-        k[cc + 1] ^= k[cc - 3];
-        k[cc + 2] ^= k[cc - 2];
-        k[cc + 3] ^= k[cc - 1];
-    }
-
-    k[16] ^= s_box(k[12]);
-    k[17] ^= s_box(k[13]);
-    k[18] ^= s_box(k[14]);
-    k[19] ^= s_box(k[15]);
-
-    for(cc = 12; cc > 0; cc -= 4)
-    {
-        k[cc + 0] ^= k[cc - 4];
-        k[cc + 1] ^= k[cc - 3];
-        k[cc + 2] ^= k[cc - 2];
-        k[cc + 3] ^= k[cc - 1];
-    }
-
-    *rc = d2(*rc);
-    k[0] ^= s_box(k[29]) ^ *rc;
-    k[1] ^= s_box(k[30]);
-    k[2] ^= s_box(k[31]);
-    k[3] ^= s_box(k[28]);
-}
-
-/*  Decrypt a single block of 16 bytes with 'on the fly'
-    256 bit keying
-*/
-void aes_decrypt_256( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
-                      const unsigned char key[2 * N_BLOCK], unsigned char o_key[2 * N_BLOCK] )
-{
-    uint_8t s1[N_BLOCK], r, rc = 0x80;
-
-    if(o_key != key)
-    {
-        block_copy( o_key, key );
-        block_copy( o_key + 16, key + 16 );
-    }
-
-    copy_and_key( s1, in, o_key );
-    inv_shift_sub_rows( s1 );
-
-    for( r = 14 ; --r ; )
-#if defined( VERSION_1 )
-    {
-        if( ( r & 1 ) )
-        {
-            update_decrypt_key_256( o_key, &rc );
-            add_round_key( s1, o_key + 16 );
-        }
-        else
-            add_round_key( s1, o_key );
-        inv_mix_sub_columns( s1 );
-    }
-#else
-    {   uint_8t s2[N_BLOCK];
-        if( ( r & 1 ) )
-        {
-            update_decrypt_key_256( o_key, &rc );
-            copy_and_key( s2, s1, o_key + 16 );
-        }
-        else
-            copy_and_key( s2, s1, o_key );
-        inv_mix_sub_columns( s1, s2 );
-    }
-#endif
-    copy_and_key( out, s1, o_key );
-}
-
-#endif
--- a/crypto/aes.h	Tue Oct 20 13:21:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
-
- LICENSE TERMS
-
- The redistribution and use of this software (with or without changes)
- is allowed without the payment of fees or royalties provided that:
-
-  1. source code distributions include the above copyright notice, this
-     list of conditions and the following disclaimer;
-
-  2. binary distributions include the above copyright notice, this list
-     of conditions and the following disclaimer in their documentation;
-
-  3. the name of the copyright holder is not used to endorse products
-     built using this software without specific written permission.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue 09/09/2006
-
- This is an AES implementation that uses only 8-bit byte operations on the
- cipher state.
- */
-
-#ifndef AES_H
-#define AES_H
-
-#if 1
-#  define AES_ENC_PREKEYED  /* AES encryption with a precomputed key schedule  */
-#endif
-#if 0
-#  define AES_DEC_PREKEYED  /* AES decryption with a precomputed key schedule  */
-#endif
-#if 0
-#  define AES_ENC_128_OTFK  /* AES encryption with 'on the fly' 128 bit keying */
-#endif
-#if 0
-#  define AES_DEC_128_OTFK  /* AES decryption with 'on the fly' 128 bit keying */
-#endif
-#if 0
-#  define AES_ENC_256_OTFK  /* AES encryption with 'on the fly' 256 bit keying */
-#endif
-#if 0
-#  define AES_DEC_256_OTFK  /* AES decryption with 'on the fly' 256 bit keying */
-#endif
-
-#define N_ROW                   4
-#define N_COL                   4
-#define N_BLOCK   (N_ROW * N_COL)
-#define N_MAX_ROUNDS           14
-
-typedef unsigned char uint_8t;
-
-typedef uint_8t return_type;
-
-/*  Warning: The key length for 256 bit keys overflows a byte
-    (see comment below)
-*/
-
-typedef uint_8t length_type;
-
-typedef struct
-{   uint_8t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK];
-    uint_8t rnd;
-} aes_context;
-
-/*  The following calls are for a precomputed key schedule
-
-    NOTE: If the length_type used for the key length is an
-    unsigned 8-bit character, a key length of 256 bits must
-    be entered as a length in bytes (valid inputs are hence
-    128, 192, 16, 24 and 32).
-*/
-
-#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
-
-return_type aes_set_key( const unsigned char key[],
-                         length_type keylen,
-                         aes_context ctx[1] );
-#endif
-
-#if defined( AES_ENC_PREKEYED )
-
-return_type aes_encrypt( const unsigned char in[N_BLOCK],
-                         unsigned char out[N_BLOCK],
-                         const aes_context ctx[1] );
-
-return_type aes_cbc_encrypt( const unsigned char *in,
-                         unsigned char *out,
-                         int n_block,
-                         unsigned char iv[N_BLOCK],
-                         const aes_context ctx[1] );
-#endif
-
-#if defined( AES_DEC_PREKEYED )
-
-return_type aes_decrypt( const unsigned char in[N_BLOCK],
-                         unsigned char out[N_BLOCK],
-                         const aes_context ctx[1] );
-
-return_type aes_cbc_decrypt( const unsigned char *in,
-                         unsigned char *out,
-                         int n_block,
-                         unsigned char iv[N_BLOCK],
-                         const aes_context ctx[1] );
-#endif
-
-/*  The following calls are for 'on the fly' keying.  In this case the
-    encryption and decryption keys are different.
-
-    The encryption subroutines take a key in an array of bytes in
-    key[L] where L is 16, 24 or 32 bytes for key lengths of 128,
-    192, and 256 bits respectively.  They then encrypts the input
-    data, in[] with this key and put the reult in the output array
-    out[].  In addition, the second key array, o_key[L], is used
-    to output the key that is needed by the decryption subroutine
-    to reverse the encryption operation.  The two key arrays can
-    be the same array but in this case the original key will be
-    overwritten.
-
-    In the same way, the decryption subroutines output keys that
-    can be used to reverse their effect when used for encryption.
-
-    Only 128 and 256 bit keys are supported in these 'on the fly'
-    modes.
-*/
-
-#if defined( AES_ENC_128_OTFK )
-void aes_encrypt_128( const unsigned char in[N_BLOCK],
-                      unsigned char out[N_BLOCK],
-                      const unsigned char key[N_BLOCK],
-                      uint_8t o_key[N_BLOCK] );
-#endif
-
-#if defined( AES_DEC_128_OTFK )
-void aes_decrypt_128( const unsigned char in[N_BLOCK],
-                      unsigned char out[N_BLOCK],
-                      const unsigned char key[N_BLOCK],
-                      unsigned char o_key[N_BLOCK] );
-#endif
-
-#if defined( AES_ENC_256_OTFK )
-void aes_encrypt_256( const unsigned char in[N_BLOCK],
-                      unsigned char out[N_BLOCK],
-                      const unsigned char key[2 * N_BLOCK],
-                      unsigned char o_key[2 * N_BLOCK] );
-#endif
-
-#if defined( AES_DEC_256_OTFK )
-void aes_decrypt_256( const unsigned char in[N_BLOCK],
-                      unsigned char out[N_BLOCK],
-                      const unsigned char key[2 * N_BLOCK],
-                      unsigned char o_key[2 * N_BLOCK] );
-#endif
-
-#endif
--- a/crypto/cmac.cpp	Tue Oct 20 13:21:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-/**************************************************************************
-Copyright (C) 2009 Lander Casado, Philippas Tsigas
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files 
-(the "Software"), to deal with the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish, 
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions: 
-
-Redistributions of source code must retain the above copyright notice, 
-this list of conditions and the following disclaimers. Redistributions in
-binary form must reproduce the above copyright notice, this list of
-conditions and the following disclaimers in the documentation and/or 
-other materials provided with the distribution.
-
-In no event shall the authors or copyright holders be liable for any special,
-incidental, indirect or consequential damages of any kind, or any damages 
-whatsoever resulting from loss of use, data or profits, whether or not 
-advised of the possibility of damage, and on any theory of liability, 
-arising out of or in connection with the use or performance of this software.
- 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
-DEALINGS WITH THE SOFTWARE
-
-*****************************************************************************/
-//#include <sys/param.h>
-//#include <sys/systm.h> 
-#include "mbed.h"
-#include "aes.h"
-#include "cmac.h"
-#include "utilities.h"
-
-#define LSHIFT(v, r) do {                                       \
-  int i;                                                  \
-           for (i = 0; i < 15; i++)                                \
-                    (r)[i] = (v)[i] << 1 | (v)[i + 1] >> 7;         \
-            (r)[15] = (v)[15] << 1;                                 \
-    } while (0)
-    
-#define XOR(v, r) do {                                          \
-            int i;                                                  \
-            for (i = 0; i < 16; i++)     \
-        {   \
-                    (r)[i] = (r)[i] ^ (v)[i]; \
-        }                          \
-    } while (0) \
-
-
-//#define MIN(a,b) (((a)<(b))?(a):(b))
-
-/*
-void memcpy1( u_int8_t *dst, const u_int8_t *src, u_int size );
-void memset1( u_int8_t *dst, u_int8_t value, u_int size );
-*/
-
-/*
-static void memcpy1( uint_8t * d, const uint_8t *s, uint_8t nn )
-{
-    while( nn-- )
-        // *((uint_8t*)d)++ = *((uint_8t*)s)++;
-        *d++ = *s++;
-}
-
-static void memset1( uint_8t * d, uint_8t a, uint_8t nn )
-{
-    while( nn-- )
-        // *((uint_8t*)d)++ = *((uint_8t*)s)++;
-        *d++ = a;
-}
-*/
-
-void AES_CMAC_Init(AES_CMAC_CTX *ctx)
-{
-            memset1(ctx->X, 0, sizeof ctx->X);
-            ctx->M_n = 0;
-        memset1(ctx->rijndael.ksch, '\0', 240);
-}
-    
-void AES_CMAC_SetKey(AES_CMAC_CTX *ctx, const u_int8_t key[AES_CMAC_KEY_LENGTH])
-{
-           //rijndael_set_key_enc_only(&ctx->rijndael, key, 128);
-       aes_set_key( key, AES_CMAC_KEY_LENGTH, &ctx->rijndael);
-}
-    
-void AES_CMAC_Update(AES_CMAC_CTX *ctx, const u_int8_t *data, u_int len)
-{
-            u_int mlen;
-        unsigned char in[16];
-    
-            if (ctx->M_n > 0) {
-                  mlen = MIN(16 - ctx->M_n, len);
-                    memcpy1(ctx->M_last + ctx->M_n, ( uint8_t* )data, mlen);
-                    ctx->M_n += mlen;
-                    if (ctx->M_n < 16 || len == mlen)
-                            return;
-                   XOR(ctx->M_last, ctx->X);
-                    //rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X);
-            aes_encrypt( ctx->X, ctx->X, &ctx->rijndael);
-                    data += mlen;
-                    len -= mlen;
-            }
-            while (len > 16) {      /* not last block */
-         
-                    XOR(data, ctx->X);
-                    //rijndael_encrypt(&ctx->rijndael, ctx->X, ctx->X);
-
-                    memcpy1(in, &ctx->X[0], 16); //Bestela ez du ondo iten
-            aes_encrypt( in, in, &ctx->rijndael);
-                    memcpy1(&ctx->X[0], in, 16);
-
-                    data += 16;
-                    len -= 16;
-            }
-            /* potential last block, save it */
-            memcpy1(ctx->M_last, ( uint8_t* )data, len);
-            ctx->M_n = len;
-}
-   
-void AES_CMAC_Final(u_int8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX *ctx)
-{
-            u_int8_t K[16];
-        unsigned char in[16];
-            /* generate subkey K1 */
-            memset1(K, '\0', 16);
-
-            //rijndael_encrypt(&ctx->rijndael, K, K);
-
-            aes_encrypt( K, K, &ctx->rijndael);
-
-            if (K[0] & 0x80) {
-                    LSHIFT(K, K);
-                   K[15] ^= 0x87;
-            } else
-                    LSHIFT(K, K);
-
-       
-            if (ctx->M_n == 16) {
-                    /* last block was a complete block */
-                    XOR(K, ctx->M_last);
-
-           } else {
-                   /* generate subkey K2 */
-                  if (K[0] & 0x80) {
-                          LSHIFT(K, K);
-                          K[15] ^= 0x87;
-                  } else
-                           LSHIFT(K, K);
-
-                   /* padding(M_last) */
-                   ctx->M_last[ctx->M_n] = 0x80;
-                   while (++ctx->M_n < 16)
-                         ctx->M_last[ctx->M_n] = 0;
-   
-                  XOR(K, ctx->M_last);
-          
-           
-           }
-           XOR(ctx->M_last, ctx->X);
-      
-           //rijndael_encrypt(&ctx->rijndael, ctx->X, digest);
-    
-       memcpy1(in, &ctx->X[0], 16); //Bestela ez du ondo iten
-       aes_encrypt(in, digest, &ctx->rijndael);
-           memset1(K, 0, sizeof K);
-
-}
-
--- a/crypto/cmac.h	Tue Oct 20 13:21:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/**************************************************************************
-Copyright (C) 2009 Lander Casado, Philippas Tsigas
-
-All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files 
-(the "Software"), to deal with the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish, 
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions: 
-
-Redistributions of source code must retain the above copyright notice, 
-this list of conditions and the following disclaimers. Redistributions in
-binary form must reproduce the above copyright notice, this list of
-conditions and the following disclaimers in the documentation and/or 
-other materials provided with the distribution.
-
-In no event shall the authors or copyright holders be liable for any special,
-incidental, indirect or consequential damages of any kind, or any damages 
-whatsoever resulting from loss of use, data or profits, whether or not 
-advised of the possibility of damage, and on any theory of liability, 
-arising out of or in connection with the use or performance of this software.
- 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
-DEALINGS WITH THE SOFTWARE
-
-*****************************************************************************/
-
-#ifndef _CMAC_H_
-#define _CMAC_H_
-
-#include "aes.h" 
-  
-#define AES_CMAC_KEY_LENGTH     16
-#define AES_CMAC_DIGEST_LENGTH  16
- 
-
-typedef unsigned char  u_int8_t;
-typedef unsigned int u_int;
-typedef struct _AES_CMAC_CTX {
-            aes_context    rijndael;
-            u_int8_t        X[16];
-            u_int8_t        M_last[16];
-            u_int           M_n;
-    } AES_CMAC_CTX;
-   
-//#include <sys/cdefs.h>
-    
-//__BEGIN_DECLS
-void     AES_CMAC_Init(AES_CMAC_CTX * ctx);
-void     AES_CMAC_SetKey(AES_CMAC_CTX * ctx, const u_int8_t key[AES_CMAC_KEY_LENGTH]);
-void     AES_CMAC_Update(AES_CMAC_CTX * ctx, const u_int8_t * data, u_int len);
-          //          __attribute__((__bounded__(__string__,2,3)));
-void     AES_CMAC_Final(u_int8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX  * ctx);
-            //     __attribute__((__bounded__(__minbytes__,1,AES_CMAC_DIGEST_LENGTH)));
-//__END_DECLS
-
-#endif /* _CMAC_H_ */
-
--- a/radio/SX1276Lib.lib	Tue Oct 20 13:21:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://developer.mbed.org/teams/Semtech/code/SX1276Lib/#e05596ba4166
--- a/system/timer.cpp	Tue Oct 20 13:21:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- / _____)             _              | |
-( (____  _____ ____ _| |_ _____  ____| |__
- \____ \| ___ |    (_   _) ___ |/ ___)  _ \
- _____) ) ____| | | || |_| ____( (___| | | |
-(______/|_____)_|_|_| \__)_____)\____)_| |_|
-    (C)2013 Semtech
-
-Description: Timer objects and scheduling management
-
-License: Revised BSD License, see LICENSE.TXT file include in the project
-
-Maintainer: Miguel Luis and Gregory Cristian
-*/
-#include "board.h"
-
-Timer TimeCounter;
-Ticker LoadTimeCounter;
-
-volatile uint32_t CurrentTime = 0;
-
-void TimerResetTimeCounter( void )
-{
-    CurrentTime = CurrentTime + TimeCounter.read_us( );
-    TimeCounter.reset( );
-    TimeCounter.start( );
-}
-
-void TimerTimeCounterInit( void )
-{
-    TimeCounter.start( );
-    LoadTimeCounter.attach( &TimerResetTimeCounter, 10 );
-}
-
-TimerTime_t TimerGetCurrentTime( void )
-{
-    CurrentTime += TimeCounter.read_us( );
-    TimeCounter.reset( );
-    TimeCounter.start( );
-    return ( ( TimerTime_t )CurrentTime );
-}
-
-void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) )
-{
-    obj->value = 0;
-    obj->Callback = callback;
-}
-
-void TimerStart( TimerEvent_t *obj )
-{
-    obj->Timer.attach_us( obj->Callback, obj->value );
-}
-
-void TimerStop( TimerEvent_t *obj )
-{
-    obj->Timer.detach( );
-}
-
-void TimerSetValue( TimerEvent_t *obj, uint32_t value )
-{
-    obj->value = value;
-}
--- a/system/timer.h	Tue Oct 20 13:21:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- / _____)             _              | |
-( (____  _____ ____ _| |_ _____  ____| |__
- \____ \| ___ |    (_   _) ___ |/ ___)  _ \
- _____) ) ____| | | || |_| ____( (___| | | |
-(______/|_____)_|_|_| \__)_____)\____)_| |_|
-    (C)2013 Semtech
-
-Description: Timer objects and scheduling management
-
-License: Revised BSD License, see LICENSE.TXT file include in the project
-
-Maintainer: Miguel Luis and Gregory Cristian
-*/
-#ifndef __TIMER_H__
-#define __TIMER_H__
-
-#include "mbed.h"
-
-/*!
- * \brief Timer object description
- */
-typedef struct TimerEvent_s
-{
-    uint32_t value;
-    void ( *Callback )( void );
-    Ticker Timer;
-}TimerEvent_t;
-
-/*!
- * \brief Timer time variable definition
- */
-#ifndef TimerTime_t
-typedef uint32_t TimerTime_t;
-#endif
-
-/*!
- * \brief Inializes the timer used to get current time.
- *
- * \remark Current time corresponds to the time since system startup
- */
-void TimerTimeCounterInit( void );
-
-/*!
- * \brief Initializes the timer object
- *
- * \remark TimerSetValue function must be called before starting the timer.
- *         this function initializes timestamp and reload value at 0.
- *
- * \param [IN] obj          Structure containing the timer object parameters
- * \param [IN] callback     Function callback called at the end of the timeout
- */
-void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) );
-
-/*!
- * \brief Starts and adds the timer object to the list of timer events
- *
- * \param [IN] obj Structure containing the timer object parameters
- */
-void TimerStart( TimerEvent_t *obj );
-
-/*!
- * \brief Stops and removes the timer object from the list of timer events
- *
- * \param [IN] obj Structure containing the timer object parameters
- */
-void TimerStop( TimerEvent_t *obj );
-
-/*!
- * \brief Resets the timer object
- *
- * \param [IN] obj Structure containing the timer object parameters
- */
-void TimerReset( TimerEvent_t *obj );
-
-/*!
- * \brief Set timer new timeout value
- *
- * \param [IN] obj   Structure containing the timer object parameters
- * \param [IN] value New timer timeout value
- */
-void TimerSetValue( TimerEvent_t *obj, uint32_t value );
-
-/*!
- * \brief Read the current time
- *
- * \retval time returns current time
- */
-TimerTime_t TimerGetCurrentTime( void );
-
-
-#endif // __TIMER_H__
--- a/system/utilities.cpp	Tue Oct 20 13:21:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- / _____)             _              | |
-( (____  _____ ____ _| |_ _____  ____| |__
- \____ \| ___ |    (_   _) ___ |/ ___)  _ \
- _____) ) ____| | | || |_| ____( (___| | | |
-(______/|_____)_|_|_| \__)_____)\____)_| |_|
-    (C)2013 Semtech
-
-Description: Helper functions implementation
-
-License: Revised BSD License, see LICENSE.TXT file include in the project
-
-Maintainer: Miguel Luis and Gregory Cristian
-*/
-#include <stdlib.h>
-#include <stdio.h>
-#include "board.h"
-#include "utilities.h"
-
-/*!
- * Redefinition of rand() and srand() standard C functions.
- * These functions are redefined in order to get the same behavior across
- * different compiler toolchains implementations.
- */
-// Standard random functions redefinition start
-#define RAND_LOCAL_MAX 2147483647
-
-static unsigned long next = 1;
-
-int rand1( void )
-{
-    return ( ( next = next * 1103515245 + 12345 ) % RAND_LOCAL_MAX );
-}
-
-void srand1( unsigned int seed )
-{
-    next = seed;
-}
-// Standard random functions redefinition end
-
-int32_t randr( int32_t min, int32_t max )
-{
-    return ( int32_t )rand1( ) % ( max - min + 1 ) + min;
-}
-
-void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size )
-{
-    while( size-- )
-    {
-        *dst++ = *src++;
-    }
-}
-
-void memset1( uint8_t *dst, uint8_t value, uint16_t size )
-{
-    while( size-- )
-    {
-        *dst++ = value;
-    }
-}
-
-int8_t Nibble2HexChar( uint8_t a )
-{
-    if( a < 10 )
-    {
-        return '0' + a;
-    }
-    else if( a < 16 )
-    {
-        return 'A' + ( a - 10 );
-    }
-    else
-    {
-        return '?';
-    }
-}
--- a/system/utilities.h	Tue Oct 20 13:21:26 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- / _____)             _              | |
-( (____  _____ ____ _| |_ _____  ____| |__
- \____ \| ___ |    (_   _) ___ |/ ___)  _ \
- _____) ) ____| | | || |_| ____( (___| | | |
-(______/|_____)_|_|_| \__)_____)\____)_| |_|
-    (C)2013 Semtech
-
-Description: Helper functions implementation
-
-License: Revised BSD License, see LICENSE.TXT file include in the project
-
-Maintainer: Miguel Luis and Gregory Cristian
-*/
-#ifndef __UTILITIES_H__
-#define __UTILITIES_H__
-
-/*!
- * \brief Returns the minimum value betwen a and b
- *
- * \param [IN] a 1st value
- * \param [IN] b 2nd value
- * \retval minValue Minimum value
- */
-#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
-
-/*!
- * \brief Returns the maximum value betwen a and b
- *
- * \param [IN] a 1st value
- * \param [IN] b 2nd value
- * \retval maxValue Maximum value
- */
-#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
-
-/*!
- * \brief Returns 2 raised to the power of n
- *
- * \param [IN] n power value
- * \retval result of raising 2 to the power n
- */
-#define POW2( n ) ( 1 << n )
-
-/*!
- * \brief Computes a random number between min and max
- *
- * \param [IN] min range minimum value
- * \param [IN] max range maximum value
- * \retval random random value in range min..max
- */
-int32_t randr( int32_t min, int32_t max );
-
-/*!
- * \brief Copies size elements of src array to dst array
- * 
- * \remark STM32 Standard memcpy function only works on pointers that are aligned
- *
- * \param [OUT] dst  Destination array
- * \param [IN]  src  Source array
- * \param [IN]  size Number of bytes to be copied
- */
-void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size );
-
-/*!
- * \brief Set size elements of dst array with value 
- * 
- * \remark STM32 Standard memset function only works on pointers that are aligned
- *
- * \param [OUT] dst   Destination array
- * \param [IN]  value Default value
- * \param [IN]  size  Number of bytes to be copied
- */
-void memset1( uint8_t *dst, uint8_t value, uint16_t size );
-
-/*!
- * \brief Converts a nibble to an hexadecimal character
- * 
- * \param [IN] a   Nibble to be converted
- * \retval hexChar Converted hexadecimal character
- */
-int8_t Nibble2HexChar( uint8_t a );
-
-#endif // __UTILITIES_H__