Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed Chainable_RGB_LED DigitDisplay LoRaWAN-lib SX1276Lib
Fork of DSP_LoRaWAN by
Revision 0:cb80564f40e1, committed 2016-03-17
- Comitter:
- mluis
- Date:
- Thu Mar 17 09:32:46 2016 +0000
- Child:
- 1:c365eaf833bb
- Commit message:
- Project creation based on LoRaWAN-demo-76
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/Comissioning.h Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,70 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2015 Semtech
+
+Description: End device comissioning parameters
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __LORA_COMISSIONING_H__
+#define __LORA_COMISSIONING_H__
+
+/*!
+ * When set to 1 the application uses the Over-the-Air activation procedure
+ * When set to 0 the application uses the Personalization activation procedure
+ */
+#define OVER_THE_AIR_ACTIVATION 1
+
+/*!
+ * Indicates if the end-device is to be connected to a private or public network
+ */
+#define LORAWAN_PUBLIC_NETWORK true
+
+#if( OVER_THE_AIR_ACTIVATION != 0 )
+
+/*!
+ * Mote device IEEE EUI (big endian)
+ */
+#define LORAWAN_DEVICE_EUI { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }
+
+/*!
+ * Application IEEE EUI (big endian)
+ */
+#define LORAWAN_APPLICATION_EUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+
+/*!
+ * AES encryption/decryption cipher application key
+ */
+#define LORAWAN_APPLICATION_KEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
+
+#else
+
+/*!
+ * Current network ID
+ */
+#define LORAWAN_NETWORK_ID ( uint32_t )0
+
+/*!
+ * Device address on the network (big endian)
+ */
+#define LORAWAN_DEVICE_ADDRESS ( uint32_t )0x12345678
+
+/*!
+ * AES encryption/decryption cipher network session key
+ */
+#define LORAWAN_NWKSKEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
+
+/*!
+ * AES encryption/decryption cipher application session key
+ */
+#define LORAWAN_APPSKEY { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
+
+#endif
+
+#endif // __LORA_COMISSIONING_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/Demo/Chainable_RGB_LED.lib Thu Mar 17 09:32:46 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/Seeed/code/Chainable_RGB_LED/#50d0a66599e1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/Demo/DigitDisplay.lib Thu Mar 17 09:32:46 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/seeed/code/DigitDisplay/#d3173c8bfd48
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/SerialDisplay.cpp Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,444 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2015 Semtech
+
+Description: VT100 serial display management
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#include "board.h"
+#include "vt100.h"
+#include "SerialDisplay.h"
+
+VT100 vt( USBTX, USBRX );
+
+void SerialPrintCheckBox( bool activated, uint8_t color )
+{
+ if( activated == true )
+ {
+ vt.SetAttribute( VT100::ATTR_OFF, color, color );
+ }
+ else
+ {
+ vt.SetAttribute( VT100::ATTR_OFF );
+ }
+ vt.printf( " " );
+ vt.SetAttribute( VT100::ATTR_OFF );
+}
+
+void SerialDisplayUpdateActivationMode( bool otaa )
+{
+ vt.SetCursorPos( 4, 17 );
+ SerialPrintCheckBox( otaa, VT100::WHITE );
+ vt.SetCursorPos( 9, 17 );
+ SerialPrintCheckBox( !otaa, VT100::WHITE );
+}
+
+void SerialDisplayUpdateEui( uint8_t line, uint8_t *eui )
+{
+ vt.SetCursorPos( line, 27 );
+ for( uint8_t i = 0; i < 8; i++ )
+ {
+ vt.printf( "%02X ", eui[i] );
+ }
+ vt.SetCursorPos( line, 50 );
+ vt.printf( "]" );
+}
+
+void SerialDisplayUpdateKey( uint8_t line, uint8_t *key )
+{
+ vt.SetCursorPos( line, 27 );
+ for( uint8_t i = 0; i < 16; i++ )
+ {
+ vt.printf( "%02X ", key[i] );
+ }
+ vt.SetCursorPos( line, 74 );
+ vt.printf( "]" );
+}
+
+void SerialDisplayUpdateNwkId( uint8_t id )
+{
+ vt.SetCursorPos( 10, 27 );
+ vt.printf( "%03d", id );
+}
+
+void SerialDisplayUpdateDevAddr( uint32_t addr )
+{
+ vt.SetCursorPos( 11, 27 );
+ vt.printf( "%02X %02X %02X %02X", ( addr >> 24 ) & 0xFF, ( addr >> 16 ) & 0xFF, ( addr >> 8 ) & 0xFF, addr & 0xFF );
+}
+
+void SerialDisplayUpdateFrameType( bool confirmed )
+{
+ vt.SetCursorPos( 15, 17 );
+ SerialPrintCheckBox( confirmed, VT100::WHITE );
+ vt.SetCursorPos( 15, 32 );
+ SerialPrintCheckBox( !confirmed, VT100::WHITE );
+}
+
+void SerialDisplayUpdateAdr( bool adr )
+{
+ vt.SetCursorPos( 16, 27 );
+ if( adr == true )
+ {
+ vt.printf( " ON" );
+ }
+ else
+ {
+ vt.printf( "OFF" );
+ }
+}
+
+void SerialDisplayUpdateDutyCycle( bool dutyCycle )
+{
+ vt.SetCursorPos( 17, 27 );
+ if( dutyCycle == true )
+ {
+ vt.printf( " ON" );
+ }
+ else
+ {
+ vt.printf( "OFF" );
+ }
+}
+
+void SerialDisplayUpdatePublicNetwork( bool network )
+{
+ vt.SetCursorPos( 19, 17 );
+ SerialPrintCheckBox( network, VT100::WHITE );
+ vt.SetCursorPos( 19, 30 );
+ SerialPrintCheckBox( !network, VT100::WHITE );
+}
+
+void SerialDisplayUpdateNetworkIsJoined( bool state )
+{
+ vt.SetCursorPos( 20, 17 );
+ SerialPrintCheckBox( !state, VT100::RED );
+ vt.SetCursorPos( 20, 30 );
+ SerialPrintCheckBox( state, VT100::GREEN );
+}
+
+void SerialDisplayUpdateLedState( uint8_t id, uint8_t state )
+{
+ switch( id )
+ {
+ case 1:
+ vt.SetCursorPos( 22, 17 );
+ SerialPrintCheckBox( state, VT100::RED );
+ break;
+ case 2:
+ vt.SetCursorPos( 22, 31 );
+ SerialPrintCheckBox( state, VT100::GREEN );
+ break;
+ case 3:
+ vt.SetCursorPos( 22, 45 );
+ SerialPrintCheckBox( state, VT100::BLUE );
+ break;
+ }
+}
+
+void SerialDisplayUpdateData( uint8_t line, uint8_t *buffer, uint8_t size )
+{
+ if( size != 0 )
+ {
+ vt.SetCursorPos( line, 27 );
+ for( uint8_t i = 0; i < size; i++ )
+ {
+ vt.printf( "%02X ", buffer[i] );
+ if( ( ( i + 1 ) % 16 ) == 0 )
+ {
+ line++;
+ vt.SetCursorPos( line, 27 );
+ }
+ }
+ for( uint8_t i = size; i < 64; i++ )
+ {
+ vt.printf( "__ " );
+ if( ( ( i + 1 ) % 16 ) == 0 )
+ {
+ line++;
+ vt.SetCursorPos( line, 27 );
+ }
+ }
+ vt.SetCursorPos( line - 1, 74 );
+ vt.printf( "]" );
+ }
+ else
+ {
+ vt.SetCursorPos( line, 27 );
+ for( uint8_t i = 0; i < 64; i++ )
+ {
+ vt.printf( "__ " );
+ if( ( ( i + 1 ) % 16 ) == 0 )
+ {
+ line++;
+ vt.SetCursorPos( line, 27 );
+ }
+ }
+ vt.SetCursorPos( line - 1, 74 );
+ vt.printf( "]" );
+ }
+}
+
+void SerialDisplayUpdateUplinkAcked( bool state )
+{
+ vt.SetCursorPos( 24, 36 );
+ SerialPrintCheckBox( state, VT100::GREEN );
+}
+
+void SerialDisplayUpdateUplink( bool acked, uint8_t datarate, uint16_t counter, uint8_t port, uint8_t *buffer, uint8_t bufferSize )
+{
+ // Acked
+ SerialDisplayUpdateUplinkAcked( acked );
+ // Datarate
+ vt.SetCursorPos( 25, 33 );
+ vt.printf( "DR%d", datarate );
+ // Counter
+ vt.SetCursorPos( 26, 27 );
+ vt.printf( "%10d", counter );
+ // Port
+ vt.SetCursorPos( 27, 34 );
+ vt.printf( "%3d", port );
+ // Data
+ SerialDisplayUpdateData( 28, buffer, bufferSize );
+ // Help message
+ vt.SetCursorPos( 42, 1 );
+ vt.printf( "To refresh screen please hit 'r' key." );
+}
+
+void SerialDisplayUpdateDonwlinkRxData( bool state )
+{
+ vt.SetCursorPos( 34, 4 );
+ SerialPrintCheckBox( state, VT100::GREEN );
+}
+
+void SerialDisplayUpdateDownlink( bool rxData, int16_t rssi, int8_t snr, uint16_t counter, uint8_t port, uint8_t *buffer, uint8_t bufferSize )
+{
+ // Rx data
+ SerialDisplayUpdateDonwlinkRxData( rxData );
+ // RSSI
+ vt.SetCursorPos( 33, 32 );
+ vt.printf( "%5d", rssi );
+ // SNR
+ vt.SetCursorPos( 34, 32 );
+ vt.printf( "%5d", snr );
+ // Counter
+ vt.SetCursorPos( 35, 27 );
+ vt.printf( "%10d", counter );
+ if( rxData == true )
+ {
+ // Port
+ vt.SetCursorPos( 36, 34 );
+ vt.printf( "%3d", port );
+ // Data
+ SerialDisplayUpdateData( 37, buffer, bufferSize );
+ }
+ else
+ {
+ // Port
+ vt.SetCursorPos( 36, 34 );
+ vt.printf( " " );
+ // Data
+ SerialDisplayUpdateData( 37, NULL, 0 );
+ }
+}
+
+void SerialDisplayDrawFirstLine( void )
+{
+ vt.PutBoxDrawingChar( 'l' );
+ for( int8_t i = 0; i <= 77; i++ )
+ {
+ vt.PutBoxDrawingChar( 'q' );
+ }
+ vt.PutBoxDrawingChar( 'k' );
+ vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawTitle( const char* title )
+{
+ vt.PutBoxDrawingChar( 'x' );
+ vt.printf( "%s", title );
+ vt.PutBoxDrawingChar( 'x' );
+ vt.printf( "\r\n" );
+}
+void SerialDisplayDrawTopSeparator( void )
+{
+ vt.PutBoxDrawingChar( 't' );
+ for( int8_t i = 0; i <= 11; i++ )
+ {
+ vt.PutBoxDrawingChar( 'q' );
+ }
+ vt.PutBoxDrawingChar( 'w' );
+ for( int8_t i = 0; i <= 64; i++ )
+ {
+ vt.PutBoxDrawingChar( 'q' );
+ }
+ vt.PutBoxDrawingChar( 'u' );
+ vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawColSeparator( void )
+{
+ vt.PutBoxDrawingChar( 'x' );
+ for( int8_t i = 0; i <= 11; i++ )
+ {
+ vt.PutBoxDrawingChar( ' ' );
+ }
+ vt.PutBoxDrawingChar( 't' );
+ for( int8_t i = 0; i <= 64; i++ )
+ {
+ vt.PutBoxDrawingChar( 'q' );
+ }
+ vt.PutBoxDrawingChar( 'u' );
+ vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawSeparator( void )
+{
+ vt.PutBoxDrawingChar( 't' );
+ for( int8_t i = 0; i <= 11; i++ )
+ {
+ vt.PutBoxDrawingChar( 'q' );
+ }
+ vt.PutBoxDrawingChar( 'n' );
+ for( int8_t i = 0; i <= 64; i++ )
+ {
+ vt.PutBoxDrawingChar( 'q' );
+ }
+ vt.PutBoxDrawingChar( 'u' );
+ vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawLine( const char* firstCol, const char* secondCol )
+{
+ vt.PutBoxDrawingChar( 'x' );
+ vt.printf( "%s", firstCol );
+ vt.PutBoxDrawingChar( 'x' );
+ vt.printf( "%s", secondCol );
+ vt.PutBoxDrawingChar( 'x' );
+ vt.printf( "\r\n" );
+}
+
+void SerialDisplayDrawBottomLine( void )
+{
+ vt.PutBoxDrawingChar( 'm' );
+ for( int8_t i = 0; i <= 11; i++ )
+ {
+ vt.PutBoxDrawingChar( 'q' );
+ }
+ vt.PutBoxDrawingChar( 'v' );
+ for( int8_t i = 0; i <= 64; i++ )
+ {
+ vt.PutBoxDrawingChar( 'q' );
+ }
+ vt.PutBoxDrawingChar( 'j' );
+ vt.printf( "\r\n" );
+}
+
+void SerialDisplayInit( void )
+{
+ vt.ClearScreen( 2 );
+ vt.SetCursorMode( false );
+ vt.SetCursorPos( 0, 0 );
+
+ // "+-----------------------------------------------------------------------------+" );
+ SerialDisplayDrawFirstLine( );
+ // "¦ LoRaWAN Demonstration Application ¦" );
+ SerialDisplayDrawTitle( " LoRaWAN Demonstration Application " );
+ // "+------------+----------------------------------------------------------------¦" );
+ SerialDisplayDrawTopSeparator( );
+ // "¦ Activation ¦ [ ]Over The Air ¦" );
+ SerialDisplayDrawLine( " Activation ", " [ ]Over The Air " );
+ // "¦ ¦ DevEui [__ __ __ __ __ __ __ __] ¦" );
+ SerialDisplayDrawLine( " ", " DevEui [__ __ __ __ __ __ __ __] " );
+ // "¦ ¦ AppEui [__ __ __ __ __ __ __ __] ¦" );
+ SerialDisplayDrawLine( " ", " AppEui [__ __ __ __ __ __ __ __] " );
+ // "¦ ¦ AppKey [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __] ¦" );
+ SerialDisplayDrawLine( " ", " AppKey [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __] " );
+ // "¦ +----------------------------------------------------------------¦" );
+ SerialDisplayDrawColSeparator( );
+ // "¦ ¦ [x]Personalisation ¦" );
+ SerialDisplayDrawLine( " ", " [ ]Personalisation " );
+ // "¦ ¦ NwkId [___] ¦" );
+ SerialDisplayDrawLine( " ", " NwkId [___] " );
+ // "¦ ¦ DevAddr [__ __ __ __] ¦" );
+ SerialDisplayDrawLine( " ", " DevAddr [__ __ __ __] " );
+ // "¦ ¦ NwkSKey [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __] ¦" );
+ SerialDisplayDrawLine( " ", " NwkSKey [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __] " );
+ // "¦ ¦ AppSKey [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __] ¦" );
+ SerialDisplayDrawLine( " ", " AppSKey [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __] " );
+ // "+------------+----------------------------------------------------------------¦" );
+ SerialDisplayDrawSeparator( );
+ // "¦ MAC params ¦ [ ]Confirmed / [ ]Unconfirmed ¦" );
+ SerialDisplayDrawLine( " MAC params ", " [ ]Confirmed / [ ]Unconfirmed " );
+ // "¦ ¦ ADR [ ] ¦" );
+ SerialDisplayDrawLine( " ", " ADR [ ] " );
+ // "¦ ¦ Duty cycle[ ] ¦" );
+ SerialDisplayDrawLine( " ", " Duty cycle[ ] " );
+ // "+------------+----------------------------------------------------------------¦" );
+ SerialDisplayDrawSeparator( );
+ // "¦ Network ¦ [ ]Public / [ ]Private ¦" );
+ SerialDisplayDrawLine( " Network ", " [ ]Public / [ ]Private " );
+ // "¦ ¦ [ ]Joining / [ ]Joined ¦" );
+ SerialDisplayDrawLine( " ", " [ ]Joining / [ ]Joined " );
+ // "+------------+----------------------------------------------------------------¦" );
+ SerialDisplayDrawSeparator( );
+ // "¦ LED status ¦ [ ]LED1(Tx) / [ ]LED2(Rx) / [ ]LED3(App) ¦" );
+ SerialDisplayDrawLine( " LED status ", " [ ]LED1(Tx) / [ ]LED2(Rx) / [ ]LED3(App) " );
+ // "+------------+----------------------------------------------------------------¦" );
+ SerialDisplayDrawSeparator( );
+ // "¦ Uplink ¦ Acked [ ] ¦" );
+ SerialDisplayDrawLine( " Uplink ", " Acked [ ] " );
+ // "¦ ¦ Datarate [ ] ¦" );
+ SerialDisplayDrawLine( " ", " Datarate [ ] " );
+ // "¦ ¦ Counter [ ] ¦" );
+ SerialDisplayDrawLine( " ", " Counter [ ] " );
+ // "¦ ¦ Port [ ] ¦" );
+ SerialDisplayDrawLine( " ", " Port [ ] " );
+ // "¦ ¦ Data [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ ¦" );
+ SerialDisplayDrawLine( " ", " Data [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ " );
+ // "¦ ¦ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ ¦" );
+ SerialDisplayDrawLine( " ", " __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ " );
+ // "¦ ¦ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ ¦" );
+ SerialDisplayDrawLine( " ", " __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ " );
+ // "¦ ¦ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ ¦" );
+ SerialDisplayDrawLine( " ", " __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ " );
+ // "+------------+----------------------------------------------------------------¦" );
+ SerialDisplayDrawSeparator( );
+ // "¦ Downlink ¦ RSSI [ ] dBm ¦" );
+ SerialDisplayDrawLine( " Downlink ", " RSSI [ ] dBm " );
+ // "¦ [ ]Data ¦ SNR [ ] dB ¦" );
+ SerialDisplayDrawLine( " [ ]Data ", " SNR [ ] dB " );
+ // "¦ ¦ Counter [ ] ¦" );
+ // "¦ ¦ Counter [ ] ¦" );
+ SerialDisplayDrawLine( " ", " Counter [ ] " );
+ // "¦ ¦ Port [ ] ¦" );
+ SerialDisplayDrawLine( " ", " Port [ ] " );
+ // "¦ ¦ Data [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ ¦" );
+ SerialDisplayDrawLine( " ", " Data [__ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ " );
+ // "¦ ¦ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ ¦" );
+ SerialDisplayDrawLine( " ", " __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ " );
+ // "¦ ¦ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ ¦" );
+ SerialDisplayDrawLine( " ", " __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ " );
+ // "¦ ¦ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ ¦" );
+ SerialDisplayDrawLine( " ", " __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ " );
+ // "+------------+----------------------------------------------------------------+" );
+ SerialDisplayDrawBottomLine( );
+ vt.printf( "To refresh screen please hit 'r' key.\r\n" );
+}
+
+bool SerialDisplayReadable( void )
+{
+ return vt.Readable( );
+}
+
+uint8_t SerialDisplayGetChar( void )
+{
+ return vt.GetChar( );
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/SerialDisplay.h Thu Mar 17 09:32:46 2016 +0000 @@ -0,0 +1,39 @@ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2015 Semtech + +Description: VT100 serial display management + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian +*/ +#ifndef __SERIAL_DISPLAY_H__ +#define __SERIAL_DISPLAY_H__ + +void SerialDisplayInit( void ); +void SerialDisplayUpdateUplink( bool acked, uint8_t datarate, uint16_t counter, uint8_t port, uint8_t *buffer, uint8_t bufferSize ); +void SerialDisplayUpdateDownlink( bool rxData, int16_t rssi, int8_t snr, uint16_t counter, uint8_t port, uint8_t *buffer, uint8_t bufferSize ); +void SerialDisplayPrintCheckBox( bool activated ); +void SerialDisplayUpdateLedState( uint8_t id, uint8_t state ); +void SerialDisplayUpdateActivationMode( bool otaa ); +void SerialDisplayUpdateEui( uint8_t line, uint8_t *eui ); +void SerialDisplayUpdateKey( uint8_t line, uint8_t *key ); +void SerialDisplayUpdateNwkId( uint8_t id ); +void SerialDisplayUpdateDevAddr( uint32_t addr ); +void SerialDisplayUpdateFrameType( bool confirmed ); +void SerialDisplayUpdateAdr( bool adr ); +void SerialDisplayUpdateDutyCycle( bool dutyCycle ); +void SerialDisplayUpdatePublicNetwork( bool network ); +void SerialDisplayUpdateData( uint8_t *buffer ); +void SerialDisplayUpdateNetworkIsJoined( bool state ); +void SerialDisplayUpdateUplinkAcked( bool state ); +void SerialDisplayUpdateDonwlinkRxData( bool state ); +bool SerialDisplayReadable( void ); +uint8_t SerialDisplayGetChar( void ); + +#endif // __SERIAL_DISPLAY_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/main.cpp Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,981 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2015 Semtech
+
+Description: LoRaMac classA device implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#include "mbed.h"
+#include "board.h"
+#include "radio.h"
+
+#include "LoRaMac.h"
+#include "Comissioning.h"
+#include "SerialDisplay.h"
+#include "DigitDisplay.h"
+#include "ChainableLED.h"
+/*!
+ * Join requests trials duty cycle.
+ */
+#define OVER_THE_AIR_ACTIVATION_DUTYCYCLE 10000000 // 10 [s] value in us
+
+/*!
+ * Defines the application data transmission duty cycle. 5s, value in [us].
+ */
+#define APP_TX_DUTYCYCLE 5000000
+
+/*!
+ * Defines a random delay for application data transmission duty cycle. 1s,
+ * value in [us].
+ */
+#define APP_TX_DUTYCYCLE_RND 1000000
+
+/*!
+ * Default mote datarate
+ */
+#define LORAWAN_DEFAULT_DATARATE DR_5
+
+/*!
+ * LoRaWAN confirmed messages
+ */
+#define LORAWAN_CONFIRMED_MSG_ON false
+
+/*!
+ * LoRaWAN Adaptive Data Rate
+ *
+ * \remark Please note that when ADR is enabled the end-device should be static
+ */
+#define LORAWAN_ADR_ON 1
+
+#if defined( USE_BAND_868 )
+
+#include "LoRaMacTest.h"
+
+/*!
+ * LoRaWAN ETSI duty cycle control enable/disable
+ *
+ * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
+ */
+#define LORAWAN_DUTYCYCLE_ON false
+
+#endif
+
+/*!
+ * LoRaWAN application port
+ */
+#define LORAWAN_APP_PORT 10
+
+/*!
+ * User application data buffer size
+ */
+#if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
+#define LORAWAN_APP_DATA_SIZE 6
+
+#else
+#define LORAWAN_APP_DATA_SIZE 5
+
+#endif
+
+#if( OVER_THE_AIR_ACTIVATION != 0 )
+
+static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
+static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
+static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY;
+
+#else
+
+static uint8_t NwkSKey[] = LORAWAN_NWKSKEY;
+static uint8_t AppSKey[] = LORAWAN_APPSKEY;
+
+/*!
+ * Device address
+ */
+static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
+
+#endif
+
+/*!
+ * Application port
+ */
+static uint8_t AppPort = LORAWAN_APP_PORT;
+
+/*!
+ * User application data size
+ */
+static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE;
+
+/*!
+ * User application data buffer size
+ */
+#define LORAWAN_APP_DATA_MAX_SIZE 64
+
+/*!
+ * User application data
+ */
+static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
+
+/*!
+ * Indicates if the node is sending confirmed or unconfirmed messages
+ */
+static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
+
+/*!
+ * Defines the application data transmission duty cycle
+ */
+static uint32_t TxDutyCycleTime;
+
+/*!
+ * Timer to handle the application data transmission duty cycle
+ */
+static TimerEvent_t TxNextPacketTimer;
+
+/*!
+ * Specifies the state of the application LED
+ */
+static bool AppLedStateOn = false;
+volatile bool Led3StateChanged = false;
+/*!
+ * Timer to handle the state of LED1
+ */
+static TimerEvent_t Led1Timer;
+volatile bool Led1State = false;
+volatile bool Led1StateChanged = false;
+/*!
+ * Timer to handle the state of LED2
+ */
+static TimerEvent_t Led2Timer;
+volatile bool Led2State = false;
+volatile bool Led2StateChanged = false;
+
+/*!
+ * Indicates if a new packet can be sent
+ */
+static bool NextTx = true;
+
+/*!
+ * Hold the value returned from the Light Sensor
+ */
+static float LightValue = 0.0;
+
+/*!
+ * Control the 3-color LED
+ * 0: automatic (LED goes brigther as the light decrease,
+ * 1: manual (The LED is controlled by the user)
+ */
+static uint8_t LightMode = 0; // 0:automatic, 1:manual
+
+/*!
+ * Ticker to create a PWM for the buzzer
+ */
+Ticker BuzTimer;
+
+
+/*!
+ * Constructor for Buzzer
+ */
+DigitalOut buzzer(A3);
+
+/*!
+ * Constructor for the 3-color LED
+ */
+#define NUM_LED 3
+ChainableLED color_led(D6, D7, NUM_LED);
+
+/*!
+ * Constructor for Light Sensor
+ */
+AnalogIn LightSens( A1 );
+
+/*!
+ * Constructor for 4 Digit 7 semgent display
+ */
+DigitDisplay display(D8, D9);
+
+/*!
+ * Device states
+ */
+static enum eDevicState
+{
+ DEVICE_STATE_INIT,
+ DEVICE_STATE_JOIN,
+ DEVICE_STATE_SEND,
+ DEVICE_STATE_CYCLE,
+ DEVICE_STATE_SLEEP
+}DeviceState;
+
+/*!
+ * LoRaWAN compliance tests support data
+ */
+struct ComplianceTest_s
+{
+ bool Running;
+ uint8_t State;
+ bool IsTxConfirmed;
+ uint8_t AppPort;
+ uint8_t AppDataSize;
+ uint8_t *AppDataBuffer;
+ uint16_t DownLinkCounter;
+ bool LinkCheck;
+ uint8_t DemodMargin;
+ uint8_t NbGateways;
+}ComplianceTest;
+
+/*
+ * SerialDisplay managment variables
+ */
+
+/*!
+ * Indicates if the MAC layer network join status has changed.
+ */
+static bool IsNetworkJoinedStatusUpdate = false;
+
+/*!
+ * Strucure containing the Uplink status
+ */
+struct sLoRaMacUplinkStatus
+{
+ uint8_t Acked;
+ int8_t Datarate;
+ uint16_t UplinkCounter;
+ uint8_t Port;
+ uint8_t *Buffer;
+ uint8_t BufferSize;
+}LoRaMacUplinkStatus;
+volatile bool UplinkStatusUpdated = false;
+
+/*!
+ * Strucure containing the Downlink status
+ */
+struct sLoRaMacDownlinkStatus
+{
+ int16_t Rssi;
+ int8_t Snr;
+ uint16_t DownlinkCounter;
+ bool RxData;
+ uint8_t Port;
+ uint8_t *Buffer;
+ uint8_t BufferSize;
+}LoRaMacDownlinkStatus;
+volatile bool DownlinkStatusUpdated = false;
+
+void SerialDisplayRefresh( void )
+{
+ MibRequestConfirm_t mibReq;
+
+ SerialDisplayInit( );
+ SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
+
+#if( OVER_THE_AIR_ACTIVATION == 0 )
+ SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
+ SerialDisplayUpdateDevAddr( DevAddr );
+ SerialDisplayUpdateKey( 12, NwkSKey );
+ SerialDisplayUpdateKey( 13, AppSKey );
+#else
+ SerialDisplayUpdateEui( 5, DevEui );
+ SerialDisplayUpdateEui( 6, AppEui );
+ SerialDisplayUpdateKey( 7, AppKey );
+#endif
+
+ mibReq.Type = MIB_NETWORK_JOINED;
+ LoRaMacMibGetRequestConfirm( &mibReq );
+ SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
+
+ SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
+#if defined( USE_BAND_868 )
+ SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
+#else
+ SerialDisplayUpdateDutyCycle( false );
+#endif
+ SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
+
+ SerialDisplayUpdateLedState( 3, AppLedStateOn );
+}
+
+void SerialRxProcess( void )
+{
+ if( SerialDisplayReadable( ) == true )
+ {
+ switch( SerialDisplayGetChar( ) )
+ {
+ case 'R':
+ case 'r':
+ // Refresh Serial screen
+ SerialDisplayRefresh( );
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+/*!
+ * \brief Prepares the payload of the frame
+ */
+static void PrepareTxFrame( uint8_t port )
+{
+ uint32_t tempValue;
+
+ switch( port )
+ {
+ case 10:
+ {
+ tempValue = ( uint32_t )( LightValue * 1000000.0 );
+ AppData[0] = LightMode;
+ AppData[1] = ( ( tempValue & 0xFF000000 ) >> 24 ) & 0xFF;
+ AppData[2] = ( ( tempValue & 0x00FF0000 ) >> 16 ) & 0xFF;
+ AppData[3] = ( ( tempValue & 0x0000FF00 ) >> 8 ) & 0xFF;
+ AppData[4] = ( tempValue & 0x000000FF );
+ }
+ break;
+ case 15:
+ {
+ AppData[0] = AppLedStateOn;
+ if( IsTxConfirmed == true )
+ {
+ AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
+ AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
+ AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
+ AppData[4] = LoRaMacDownlinkStatus.Rssi;
+ AppData[5] = LoRaMacDownlinkStatus.Snr;
+ }
+ }
+ break;
+ case 224:
+ if( ComplianceTest.LinkCheck == true )
+ {
+ ComplianceTest.LinkCheck = false;
+ AppDataSize = 3;
+ AppData[0] = 5;
+ AppData[1] = ComplianceTest.DemodMargin;
+ AppData[2] = ComplianceTest.NbGateways;
+ ComplianceTest.State = 1;
+ }
+ else
+ {
+ switch( ComplianceTest.State )
+ {
+ case 4:
+ ComplianceTest.State = 1;
+ break;
+ case 1:
+ AppDataSize = 2;
+ AppData[0] = ComplianceTest.DownLinkCounter >> 8;
+ AppData[1] = ComplianceTest.DownLinkCounter;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * \brief Prepares the payload of the frame
+ *
+ * \retval [0: frame could be send, 1: error]
+ */
+static bool SendFrame( void )
+{
+ McpsReq_t mcpsReq;
+ LoRaMacTxInfo_t txInfo;
+
+ if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
+ {
+ // Send empty frame in order to flush MAC commands
+ mcpsReq.Type = MCPS_UNCONFIRMED;
+ mcpsReq.Req.Unconfirmed.fBuffer = NULL;
+ mcpsReq.Req.Unconfirmed.fBufferSize = 0;
+ mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
+
+ LoRaMacUplinkStatus.Acked = false;
+ LoRaMacUplinkStatus.Port = 0;
+ LoRaMacUplinkStatus.Buffer = NULL;
+ LoRaMacUplinkStatus.BufferSize = 0;
+ SerialDisplayUpdateFrameType( false );
+ }
+ else
+ {
+ LoRaMacUplinkStatus.Acked = false;
+ LoRaMacUplinkStatus.Port = AppPort;
+ LoRaMacUplinkStatus.Buffer = AppData;
+ LoRaMacUplinkStatus.BufferSize = AppDataSize;
+ SerialDisplayUpdateFrameType( IsTxConfirmed );
+
+ if( IsTxConfirmed == false )
+ {
+ mcpsReq.Type = MCPS_UNCONFIRMED;
+ mcpsReq.Req.Unconfirmed.fPort = AppPort;
+ mcpsReq.Req.Unconfirmed.fBuffer = AppData;
+ mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
+ mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
+ }
+ else
+ {
+ mcpsReq.Type = MCPS_CONFIRMED;
+ mcpsReq.Req.Confirmed.fPort = AppPort;
+ mcpsReq.Req.Confirmed.fBuffer = AppData;
+ mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
+ mcpsReq.Req.Confirmed.NbTrials = 8;
+ mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
+ }
+ }
+
+ if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
+ {
+ return false;
+ }
+ return true;
+}
+
+/*!
+ * \brief Function executed on TxNextPacket Timeout event
+ */
+static void OnTxNextPacketTimerEvent( void )
+{
+ MibRequestConfirm_t mibReq;
+ LoRaMacStatus_t status;
+
+ TimerStop( &TxNextPacketTimer );
+
+ mibReq.Type = MIB_NETWORK_JOINED;
+ status = LoRaMacMibGetRequestConfirm( &mibReq );
+
+ if( status == LORAMAC_STATUS_OK )
+ {
+ if( mibReq.Param.IsNetworkJoined == true )
+ {
+ DeviceState = DEVICE_STATE_SEND;
+ NextTx = true;
+ }
+ else
+ {
+ DeviceState = DEVICE_STATE_JOIN;
+ }
+ }
+}
+
+/*!
+ * \brief Function executed on Led 1 Timeout event
+ */
+static void OnLed1TimerEvent( void )
+{
+ TimerStop( &Led1Timer );
+ // Switch LED 1 OFF
+ Led1State = false;
+ Led1StateChanged = true;
+}
+
+/*!
+ * \brief Function executed on Led 2 Timeout event
+ */
+static void OnLed2TimerEvent( void )
+{
+ TimerStop( &Led2Timer );
+ // Switch LED 2 OFF
+ Led2State = false;
+ Led2StateChanged = true;
+}
+
+/*!
+ * \brief Function executed on Buzzer Timeout event
+ */
+static void OnBuzTimerEvent( void )
+{
+ buzzer = 0;
+ BuzTimer.detach( );
+}
+
+/*!
+ * \brief MCPS-Confirm event function
+ *
+ * \param [IN] McpsConfirm - Pointer to the confirm structure,
+ * containing confirm attributes.
+ */
+static void McpsConfirm( McpsConfirm_t *McpsConfirm )
+{
+ if( McpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
+ {
+ switch( McpsConfirm->McpsRequest )
+ {
+ case MCPS_UNCONFIRMED:
+ {
+ // Check Datarate
+ // Check TxPower
+ break;
+ }
+ case MCPS_CONFIRMED:
+ {
+ // Check Datarate
+ // Check TxPower
+ // Check AckReceived
+ // Check NbRetries
+ LoRaMacUplinkStatus.Acked = McpsConfirm->AckReceived;
+ break;
+ }
+ case MCPS_PROPRIETARY:
+ {
+ break;
+ }
+ default:
+ break;
+ }
+ LoRaMacUplinkStatus.Datarate = McpsConfirm->Datarate;
+ LoRaMacUplinkStatus.UplinkCounter = McpsConfirm->UpLinkCounter;
+
+ UplinkStatusUpdated = true;
+ }
+ NextTx = true;
+}
+
+/*!
+ * \brief MCPS-Indication event function
+ *
+ * \param [IN] McpsIndication - Pointer to the indication structure,
+ * containing indication attributes.
+ */
+static void McpsIndication( McpsIndication_t *McpsIndication )
+{
+ if( McpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
+ {
+ return;
+ }
+
+ switch( McpsIndication->McpsIndication )
+ {
+ case MCPS_UNCONFIRMED:
+ {
+ break;
+ }
+ case MCPS_CONFIRMED:
+ {
+ break;
+ }
+ case MCPS_PROPRIETARY:
+ {
+ break;
+ }
+ case MCPS_MULTICAST:
+ {
+ break;
+ }
+ default:
+ break;
+ }
+
+ // Check Multicast
+ // Check Port
+ // Check Datarate
+ // Check FramePending
+ // Check Buffer
+ // Check BufferSize
+ // Check Rssi
+ // Check Snr
+ // Check RxSlot
+ LoRaMacDownlinkStatus.Rssi = McpsIndication->Rssi;
+ if( McpsIndication->Snr & 0x80 ) // The SNR sign bit is 1
+ {
+ // Invert and divide by 4
+ LoRaMacDownlinkStatus.Snr = ( ( ~McpsIndication->Snr + 1 ) & 0xFF ) >> 2;
+ LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
+ }
+ else
+ {
+ // Divide by 4
+ LoRaMacDownlinkStatus.Snr = ( McpsIndication->Snr & 0xFF ) >> 2;
+ }
+ LoRaMacDownlinkStatus.DownlinkCounter++;
+ LoRaMacDownlinkStatus.RxData = McpsIndication->RxData;
+ LoRaMacDownlinkStatus.Port = McpsIndication->Port;
+ LoRaMacDownlinkStatus.Buffer = McpsIndication->Buffer;
+ LoRaMacDownlinkStatus.BufferSize = McpsIndication->BufferSize;
+
+ if( ComplianceTest.Running == true )
+ {
+ ComplianceTest.DownLinkCounter++;
+ }
+
+ if( McpsIndication->RxData == true )
+ {
+ switch( McpsIndication->Port )
+ {
+ case 1: // The application LED can be controlled on port 1 or 2
+ case 2:
+ if( McpsIndication->BufferSize == 1 )
+ {
+ AppLedStateOn = McpsIndication->Buffer[0] & 0x01;
+ Led3StateChanged = true;
+ }
+ break;
+
+ case 10:
+ display.write( 0, McpsIndication->Buffer[0] );
+ display.write( 1, McpsIndication->Buffer[1] );
+ display.write( 2, McpsIndication->Buffer[2] );
+ display.write( 3, McpsIndication->Buffer[3] );
+ break;
+
+ case 20:
+ LightMode = McpsIndication->Buffer[0];
+ if( LightMode )
+ {
+ color_led.setColorRGB(0, McpsIndication->Buffer[1], McpsIndication->Buffer[2], McpsIndication->Buffer[3] );
+ }
+ break;
+
+ case 30:
+ BuzTimer.attach_us( &OnBuzTimerEvent, 200000 );
+ buzzer = 1;
+ break;
+
+ case 224:
+ if( ComplianceTest.Running == false )
+ {
+ // Check compliance test enable command (i)
+ if( ( McpsIndication->BufferSize == 4 ) &&
+ ( McpsIndication->Buffer[0] == 0x01 ) &&
+ ( McpsIndication->Buffer[1] == 0x01 ) &&
+ ( McpsIndication->Buffer[2] == 0x01 ) &&
+ ( McpsIndication->Buffer[3] == 0x01 ) )
+ {
+ IsTxConfirmed = false;
+ AppPort = 224;
+ AppDataSize = 2;
+ ComplianceTest.DownLinkCounter = 0;
+ ComplianceTest.LinkCheck = false;
+ ComplianceTest.DemodMargin = 0;
+ ComplianceTest.NbGateways = 0;
+ ComplianceTest.Running = true;
+ ComplianceTest.State = 1;
+
+ MibRequestConfirm_t mibReq;
+ mibReq.Type = MIB_ADR;
+ mibReq.Param.AdrEnable = true;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+#if defined( USE_BAND_868 )
+ LoRaMacTestSetDutyCycleOn( false );
+#endif
+ }
+ }
+ else
+ {
+ ComplianceTest.State = McpsIndication->Buffer[0];
+ switch( ComplianceTest.State )
+ {
+ case 0: // Check compliance test disable command (ii)
+ IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
+ AppPort = LORAWAN_APP_PORT;
+ AppDataSize = LORAWAN_APP_DATA_SIZE;
+ ComplianceTest.DownLinkCounter = 0;
+ ComplianceTest.Running = false;
+
+ MibRequestConfirm_t mibReq;
+ mibReq.Type = MIB_ADR;
+ mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+#if defined( USE_BAND_868 )
+ LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
+#endif
+ break;
+ case 1: // (iii, iv)
+ AppDataSize = 2;
+ break;
+ case 2: // Enable confirmed messages (v)
+ IsTxConfirmed = true;
+ ComplianceTest.State = 1;
+ break;
+ case 3: // Disable confirmed messages (vi)
+ IsTxConfirmed = false;
+ ComplianceTest.State = 1;
+ break;
+ case 4: // (vii)
+ AppDataSize = McpsIndication->BufferSize;
+
+ AppData[0] = 4;
+ for( uint8_t i = 1; i < AppDataSize; i++ )
+ {
+ AppData[i] = McpsIndication->Buffer[i] + 1;
+ }
+ break;
+ case 5: // (viii)
+ {
+ MlmeReq_t mlmeReq;
+ mlmeReq.Type = MLME_LINK_CHECK;
+ LoRaMacMlmeRequest( &mlmeReq );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Switch LED 2 ON for each received downlink
+ Led2State = true;
+ Led2StateChanged = true;
+ TimerStart( &Led2Timer );
+ DownlinkStatusUpdated = true;
+}
+
+/*!
+ * \brief MLME-Confirm event function
+ *
+ * \param [IN] MlmeConfirm - Pointer to the confirm structure,
+ * containing confirm attributes.
+ */
+static void MlmeConfirm( MlmeConfirm_t *MlmeConfirm )
+{
+ if( MlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
+ {
+ switch( MlmeConfirm->MlmeRequest )
+ {
+ case MLME_JOIN:
+ {
+ // Status is OK, node has joined the network
+ IsNetworkJoinedStatusUpdate = true;
+ break;
+ }
+ case MLME_LINK_CHECK:
+ {
+ // Check DemodMargin
+ // Check NbGateways
+ if( ComplianceTest.Running == true )
+ {
+ ComplianceTest.LinkCheck = true;
+ ComplianceTest.DemodMargin = MlmeConfirm->DemodMargin;
+ ComplianceTest.NbGateways = MlmeConfirm->NbGateways;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ NextTx = true;
+ UplinkStatusUpdated = true;
+}
+
+/**
+ * Main application entry point.
+ */
+int main( void )
+{
+ float tempLightValue = 0.0;
+
+ LightMode = 0; // 0: manual, 1: automatic
+ buzzer = 0; // 0: OFF, 1: ON
+
+ LoRaMacPrimitives_t LoRaMacPrimitives;
+ LoRaMacCallback_t LoRaMacCallbacks;
+ MibRequestConfirm_t mibReq;
+
+ BoardInit( );
+ SerialDisplayInit( );
+
+ DeviceState = DEVICE_STATE_INIT;
+
+ while( 1 )
+ {
+ SerialRxProcess( );
+ if( IsNetworkJoinedStatusUpdate == true )
+ {
+ IsNetworkJoinedStatusUpdate = false;
+ mibReq.Type = MIB_NETWORK_JOINED;
+ LoRaMacMibGetRequestConfirm( &mibReq );
+ SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
+ }
+ if( Led1StateChanged == true )
+ {
+ Led1StateChanged = false;
+ SerialDisplayUpdateLedState( 1, Led1State );
+ }
+ if( Led2StateChanged == true )
+ {
+ Led2StateChanged = false;
+ SerialDisplayUpdateLedState( 2, Led2State );
+ }
+ if( Led3StateChanged == true )
+ {
+ Led3StateChanged = false;
+ SerialDisplayUpdateLedState( 3, AppLedStateOn );
+ }
+ if( UplinkStatusUpdated == true )
+ {
+ UplinkStatusUpdated = false;
+ SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize );
+ }
+ if( DownlinkStatusUpdated == true )
+ {
+ DownlinkStatusUpdated = false;
+ SerialDisplayUpdateLedState( 2, Led2State );
+ SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
+ }
+
+ switch( DeviceState )
+ {
+ case DEVICE_STATE_INIT:
+ {
+ LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
+ LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
+ LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
+ LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
+ LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
+
+ TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent );
+
+ TimerInit( &Led1Timer, OnLed1TimerEvent );
+ TimerSetValue( &Led1Timer, 25000 );
+
+ TimerInit( &Led2Timer, OnLed2TimerEvent );
+ TimerSetValue( &Led2Timer, 25000 );
+
+ mibReq.Type = MIB_ADR;
+ mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_PUBLIC_NETWORK;
+ mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+#if defined( USE_BAND_868 )
+ LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
+ SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
+#endif
+ SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
+ SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
+ SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
+
+ LoRaMacDownlinkStatus.DownlinkCounter = 0;
+
+ DeviceState = DEVICE_STATE_JOIN;
+ break;
+ }
+ case DEVICE_STATE_JOIN:
+ {
+#if( OVER_THE_AIR_ACTIVATION != 0 )
+ MlmeReq_t mlmeReq;
+
+ mlmeReq.Type = MLME_JOIN;
+
+ mlmeReq.Req.Join.DevEui = DevEui;
+ mlmeReq.Req.Join.AppEui = AppEui;
+ mlmeReq.Req.Join.AppKey = AppKey;
+
+ if( NextTx == true )
+ {
+ LoRaMacMlmeRequest( &mlmeReq );
+ }
+
+ SerialDisplayUpdateEui( 5, DevEui );
+ SerialDisplayUpdateEui( 6, AppEui );
+ SerialDisplayUpdateKey( 7, AppKey );
+
+ // Schedule next packet transmission
+ TxDutyCycleTime = OVER_THE_AIR_ACTIVATION_DUTYCYCLE;
+ DeviceState = DEVICE_STATE_CYCLE;
+
+#else
+ mibReq.Type = MIB_NET_ID;
+ mibReq.Param.NetID = LORAWAN_NETWORK_ID;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_DEV_ADDR;
+ mibReq.Param.DevAddr = DevAddr;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_NWK_SKEY;
+ mibReq.Param.NwkSKey = NwkSKey;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_APP_SKEY;
+ mibReq.Param.AppSKey = AppSKey;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ mibReq.Type = MIB_NETWORK_JOINED;
+ mibReq.Param.IsNetworkJoined = true;
+ LoRaMacMibSetRequestConfirm( &mibReq );
+
+ SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
+ SerialDisplayUpdateDevAddr( DevAddr );
+ SerialDisplayUpdateKey( 12, NwkSKey );
+ SerialDisplayUpdateKey( 13, AppSKey );
+
+ DeviceState = DEVICE_STATE_SEND;
+#endif
+ IsNetworkJoinedStatusUpdate = true;
+ break;
+ }
+ case DEVICE_STATE_SEND:
+ {
+ if( NextTx == true )
+ {
+ SerialDisplayUpdateUplinkAcked( false );
+ SerialDisplayUpdateDonwlinkRxData( false );
+ PrepareTxFrame( AppPort );
+
+ NextTx = SendFrame( );
+
+ // Switch LED 1 ON
+ Led1State = true;
+ Led1StateChanged = true;
+ TimerStart( &Led1Timer );
+ }
+ if( ComplianceTest.Running == true )
+ {
+ // Schedule next packet transmission as soon as possible
+ TxDutyCycleTime = 1000; // 1 ms
+ }
+ else
+ {
+ // Schedule next packet transmission
+ TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
+ }
+ DeviceState = DEVICE_STATE_CYCLE;
+ break;
+ }
+ case DEVICE_STATE_CYCLE:
+ {
+ // Schedule next packet transmission
+ TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
+ TimerStart( &TxNextPacketTimer );
+
+ DeviceState = DEVICE_STATE_SLEEP;
+ break;
+ }
+ case DEVICE_STATE_SLEEP:
+ {
+ // Wake up through events
+ break;
+ }
+ default:
+ {
+ DeviceState = DEVICE_STATE_INIT;
+ break;
+ }
+
+ }
+
+ // Read light sensor
+ tempLightValue = LightSens.read( ) * 1.65;
+
+ LightValue = ( 1 - tempLightValue );
+
+ // Set automatic RGB from light sensor
+ if( LightMode == 0 )
+ {
+ color_led.setColorRGB( 0, ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ) );
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/vt100.h Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,213 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2015 Semtech
+
+Description: VT100 terminal support class
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#ifndef __VT100_H__
+#define __VT100_H__
+
+#ifndef STRING_STACK_LIMIT
+#define STRING_STACK_LIMIT 120
+#endif
+
+/**
+ * Implements VT100 terminal commands support.
+ * Implments also the same behaviour has RawSerial class. The only difference
+ * is located in putc fucntion where writeable check is made befor sending the character.
+ */
+class VT100 : public SerialBase
+{
+public:
+ enum TextAttributes
+ {
+ ATTR_OFF = 0,
+ BOLD = 1,
+ USCORE = 4,
+ BLINK = 5,
+ REVERSE = 7,
+ BOLD_OFF = 21,
+ USCORE_OFF = 24,
+ BLINK_OFF = 25,
+ REVERSE_OFF = 27,
+ };
+
+ enum Colors
+ {
+ BLACK = 0,
+ RED = 1,
+ GREEN = 2,
+ BROWN = 3,
+ BLUE = 4,
+ MAGENTA = 5,
+ CYAN = 6,
+ WHITE = 7,
+ };
+
+ VT100( PinName tx, PinName rx ): SerialBase( tx, rx )
+ {
+ this->baud( 115200 );
+ // initializes terminal to "power-on" settings
+ // ESC c
+ this->printf( "\x1B\x63" );
+ }
+
+ void ClearScreen( uint8_t param )
+ {
+ // ESC [ Ps J
+ // 0 Clear screen from cursor down
+ // 1 Clear screen from cursor up
+ // 2 Clear entire screen
+ this->printf( "\x1B[%dJ", param );
+ }
+
+ void ClearLine( uint8_t param )
+ {
+ // ESC [ Ps K
+ // 0 Erase from the active position to the end of the line, inclusive (default)
+ // 1 Erase from the start of the screen to the active position, inclusive
+ // 2 Erase all of the line, inclusive
+ this->printf( "\x1B[%dK", param );
+ }
+
+ void SetAttribute( uint8_t attr )
+ {
+ // ESC [ Ps;...;Ps m
+ this->printf( "\x1B[%dm", attr );
+ }
+
+ void SetAttribute( uint8_t attr, uint8_t fgcolor, uint8_t bgcolor )
+ {
+ // ESC [ Ps;...;Ps m
+ this->printf( "\x1B[%d;%d;%dm", attr, fgcolor + 30, bgcolor + 40 );
+ }
+
+ void SetCursorMode( uint8_t visible )
+ {
+ if( visible == true )
+ {
+ // ESC [ ? 25 h
+ this->printf( "\x1B[?25h" );
+ }
+ else
+ {
+ // ESC [ ? 25 l
+ this->printf( "\x1B[?25l" );
+ }
+ }
+
+ void SetCursorPos( uint8_t line, uint8_t col )
+ {
+ // ESC [ Pl ; Pc H
+ this->printf( "\x1B[%d;%dH", line, col );
+ }
+
+ void PutStringAt( uint8_t line, uint8_t col, const char *s )
+ {
+ this->SetCursorPos( line, col );
+ this->printf( "%s", s );
+ }
+
+ void PutCharAt( uint8_t line, uint8_t col, uint8_t c )
+ {
+ this->SetCursorPos( line, col );
+ this->printf( "%c", c );
+ }
+
+ void PutHexAt( uint8_t line, uint8_t col, uint16_t n )
+ {
+ this->SetCursorPos( line, col );
+ this->printf( "%X", n );
+ }
+
+ void PutBoxDrawingChar( uint8_t c )
+ {
+ this->printf( "\x1B(0%c\x1b(B", c );
+ }
+
+ bool Readable( void )
+ {
+ return this->readable( );
+ }
+
+ uint8_t GetChar( void )
+ {
+ return this->getc( );
+ }
+
+ /*
+ * RawSerial class implmentation copy.
+ */
+ /** Read a char from the serial port
+ *
+ * @returns The char read from the serial port
+ */
+ int getc( )
+ {
+ return _base_getc();
+ }
+
+ /** Write a char to the serial port
+ *
+ * @param c The char to write
+ *
+ * @returns The written char or -1 if an error occured
+ */
+ int putc( int c )
+ {
+ while( this->writeable( ) != 1 );
+ return _base_putc( c );
+ }
+
+ /** Write a string to the serial port
+ *
+ * @param str The string to write
+ *
+ * @returns 0 if the write succeeds, EOF for error
+ */
+ int puts( const char *str )
+ {
+ while( *str )
+ putc( *str++ );
+ return 0;
+ }
+
+ // Experimental support for printf in RawSerial. No Stream inheritance
+ // means we can't call printf() directly, so we use sprintf() instead.
+ // We only call malloc() for the sprintf() buffer if the buffer
+ // length is above a certain threshold, otherwise we use just the stack.
+ int printf( const char *format, ... )
+ {
+ std::va_list arg;
+ va_start( arg, format );
+ int len = vsnprintf( NULL, 0, format, arg );
+ if( len < STRING_STACK_LIMIT )
+ {
+ char temp[STRING_STACK_LIMIT];
+ vsprintf( temp, format, arg );
+ puts( temp );
+ }
+ else
+ {
+ char *temp = new char[len + 1];
+ vsprintf( temp, format, arg );
+ puts( temp );
+ delete[] temp;
+ }
+ va_end( arg );
+ return len;
+ }
+
+private:
+
+};
+
+#endif // __VT100_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/board/board.cpp Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,29 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (C)2015 Semtech
+
+Description: Target board general functions implementation
+
+License: Revised BSD License, see LICENSE.TXT file include in the project
+
+Maintainer: Miguel Luis and Gregory Cristian
+*/
+#include "mbed.h"
+#include "board.h"
+
+SX1276MB1xAS Radio( NULL );
+
+void BoardInit( void )
+{
+ TimerTimeCounterInit( );
+}
+
+
+uint8_t BoardGetBatteryLevel( void )
+{
+ return 0xFE;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/board/board.h Thu Mar 17 09:32:46 2016 +0000 @@ -0,0 +1,40 @@ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2015 Semtech + +Description: Target board general functions implementation + +License: Revised BSD License, see LICENSE.TXT file include in the project + +Maintainer: Miguel Luis and Gregory Cristian +*/ +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include "mbed.h" +#include "system/timer.h" +#include "debug.h" +#include "system/utilities.h" +#include "sx1276-hal.h" + +#define USE_BAND_868 + +extern SX1276MB1xAS Radio; + +/*! + * \brief Initializes the target board peripherals. + */ +void BoardInit( void ); + +/*! + * \brief Measure the Battery level + * + * \retval value battery level ( 0: very low, 254: fully charged ) + */ +uint8_t BoardGetBatteryLevel( void ); + +#endif // __BOARD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mac/LoRaWAN-lib.lib Thu Mar 17 09:32:46 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/Semtech/code/LoRaWAN-lib/#b9d87593a8ae
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Mar 17 09:32:46 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/87f2f5183dfb \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/radio/SX1276Lib.lib Thu Mar 17 09:32:46 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/teams/Semtech/code/SX1276Lib/#79c5b50b2b9c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/system/crypto/aes.cpp Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,936 @@
+/*
+ ---------------------------------------------------------------------------
+ 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 <stdlib.h>
+#include <stdint.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 uint32_t;
+//#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 uint8_t sbox[256] = sb_data(f1);
+
+#if defined( AES_DEC_PREKEYED )
+static const uint8_t isbox[256] = isb_data(f1);
+#endif
+
+static const uint8_t gfm2_sbox[256] = sb_data(f2);
+static const uint8_t gfm3_sbox[256] = sb_data(f3);
+
+#if defined( AES_DEC_PREKEYED )
+static const uint8_t gfmul_9[256] = mm_data(f9);
+static const uint8_t gfmul_b[256] = mm_data(fb);
+static const uint8_t gfmul_d[256] = mm_data(fd);
+static const uint8_t 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 uint8_t hibit(const uint8_t x)
+{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2));
+
+ r |= (r >> 2);
+ r |= (r >> 4);
+ return (r + 1) >> 1;
+}
+
+/* return the inverse of the finite field element x */
+
+static uint8_t gf_inv(const uint8_t x)
+{ uint8_t 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 */
+uint8_t fwd_affine(const uint8_t x)
+{
+#if defined( HAVE_UINT_32T )
+ uint32_t 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
+}
+
+uint8_t inv_affine(const uint8_t x)
+{
+#if defined( HAVE_UINT_32T )
+ uint32_t 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 )
+ ((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0];
+ ((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1];
+ ((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2];
+ ((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3];
+#else
+ ((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0];
+ ((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1];
+ ((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2];
+ ((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3];
+ ((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4];
+ ((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5];
+ ((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6];
+ ((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7];
+ ((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8];
+ ((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9];
+ ((uint8_t*)d)[10] = ((uint8_t*)s)[10];
+ ((uint8_t*)d)[11] = ((uint8_t*)s)[11];
+ ((uint8_t*)d)[12] = ((uint8_t*)s)[12];
+ ((uint8_t*)d)[13] = ((uint8_t*)s)[13];
+ ((uint8_t*)d)[14] = ((uint8_t*)s)[14];
+ ((uint8_t*)d)[15] = ((uint8_t*)s)[15];
+#endif
+}
+
+static void copy_block_nn( uint8_t * d, const uint8_t *s, uint8_t nn )
+{
+ while( nn-- )
+ //*((uint8_t*)d)++ = *((uint8_t*)s)++;
+ *d++ = *s++;
+}
+
+static void xor_block( void *d, const void *s )
+{
+#if defined( HAVE_UINT_32T )
+ ((uint32_t*)d)[ 0] ^= ((uint32_t*)s)[ 0];
+ ((uint32_t*)d)[ 1] ^= ((uint32_t*)s)[ 1];
+ ((uint32_t*)d)[ 2] ^= ((uint32_t*)s)[ 2];
+ ((uint32_t*)d)[ 3] ^= ((uint32_t*)s)[ 3];
+#else
+ ((uint8_t*)d)[ 0] ^= ((uint8_t*)s)[ 0];
+ ((uint8_t*)d)[ 1] ^= ((uint8_t*)s)[ 1];
+ ((uint8_t*)d)[ 2] ^= ((uint8_t*)s)[ 2];
+ ((uint8_t*)d)[ 3] ^= ((uint8_t*)s)[ 3];
+ ((uint8_t*)d)[ 4] ^= ((uint8_t*)s)[ 4];
+ ((uint8_t*)d)[ 5] ^= ((uint8_t*)s)[ 5];
+ ((uint8_t*)d)[ 6] ^= ((uint8_t*)s)[ 6];
+ ((uint8_t*)d)[ 7] ^= ((uint8_t*)s)[ 7];
+ ((uint8_t*)d)[ 8] ^= ((uint8_t*)s)[ 8];
+ ((uint8_t*)d)[ 9] ^= ((uint8_t*)s)[ 9];
+ ((uint8_t*)d)[10] ^= ((uint8_t*)s)[10];
+ ((uint8_t*)d)[11] ^= ((uint8_t*)s)[11];
+ ((uint8_t*)d)[12] ^= ((uint8_t*)s)[12];
+ ((uint8_t*)d)[13] ^= ((uint8_t*)s)[13];
+ ((uint8_t*)d)[14] ^= ((uint8_t*)s)[14];
+ ((uint8_t*)d)[15] ^= ((uint8_t*)s)[15];
+#endif
+}
+
+static void copy_and_key( void *d, const void *s, const void *k )
+{
+#if defined( HAVE_UINT_32T )
+ ((uint32_t*)d)[ 0] = ((uint32_t*)s)[ 0] ^ ((uint32_t*)k)[ 0];
+ ((uint32_t*)d)[ 1] = ((uint32_t*)s)[ 1] ^ ((uint32_t*)k)[ 1];
+ ((uint32_t*)d)[ 2] = ((uint32_t*)s)[ 2] ^ ((uint32_t*)k)[ 2];
+ ((uint32_t*)d)[ 3] = ((uint32_t*)s)[ 3] ^ ((uint32_t*)k)[ 3];
+#elif 1
+ ((uint8_t*)d)[ 0] = ((uint8_t*)s)[ 0] ^ ((uint8_t*)k)[ 0];
+ ((uint8_t*)d)[ 1] = ((uint8_t*)s)[ 1] ^ ((uint8_t*)k)[ 1];
+ ((uint8_t*)d)[ 2] = ((uint8_t*)s)[ 2] ^ ((uint8_t*)k)[ 2];
+ ((uint8_t*)d)[ 3] = ((uint8_t*)s)[ 3] ^ ((uint8_t*)k)[ 3];
+ ((uint8_t*)d)[ 4] = ((uint8_t*)s)[ 4] ^ ((uint8_t*)k)[ 4];
+ ((uint8_t*)d)[ 5] = ((uint8_t*)s)[ 5] ^ ((uint8_t*)k)[ 5];
+ ((uint8_t*)d)[ 6] = ((uint8_t*)s)[ 6] ^ ((uint8_t*)k)[ 6];
+ ((uint8_t*)d)[ 7] = ((uint8_t*)s)[ 7] ^ ((uint8_t*)k)[ 7];
+ ((uint8_t*)d)[ 8] = ((uint8_t*)s)[ 8] ^ ((uint8_t*)k)[ 8];
+ ((uint8_t*)d)[ 9] = ((uint8_t*)s)[ 9] ^ ((uint8_t*)k)[ 9];
+ ((uint8_t*)d)[10] = ((uint8_t*)s)[10] ^ ((uint8_t*)k)[10];
+ ((uint8_t*)d)[11] = ((uint8_t*)s)[11] ^ ((uint8_t*)k)[11];
+ ((uint8_t*)d)[12] = ((uint8_t*)s)[12] ^ ((uint8_t*)k)[12];
+ ((uint8_t*)d)[13] = ((uint8_t*)s)[13] ^ ((uint8_t*)k)[13];
+ ((uint8_t*)d)[14] = ((uint8_t*)s)[14] ^ ((uint8_t*)k)[14];
+ ((uint8_t*)d)[15] = ((uint8_t*)s)[15] ^ ((uint8_t*)k)[15];
+#else
+ block_copy(d, s);
+ xor_block(d, k);
+#endif
+}
+
+static void add_round_key( uint8_t d[N_BLOCK], const uint8_t k[N_BLOCK] )
+{
+ xor_block(d, k);
+}
+
+static void shift_sub_rows( uint8_t st[N_BLOCK] )
+{ uint8_t 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( uint8_t st[N_BLOCK] )
+{ uint8_t 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( uint8_t dt[N_BLOCK] )
+ { uint8_t st[N_BLOCK];
+ block_copy(st, dt);
+#else
+ static void mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t 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( uint8_t dt[N_BLOCK] )
+ { uint8_t st[N_BLOCK];
+ block_copy(st, dt);
+#else
+ static void inv_mix_sub_columns( uint8_t dt[N_BLOCK], uint8_t 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 uint8_t key[], length_type keylen, aes_context ctx[1] )
+{
+ uint8_t cc, rc, hi;
+
+ switch( keylen )
+ {
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ ctx->rnd = 0;
+ return ( uint8_t )-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 )
+ { uint8_t 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 uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] )
+{
+ if( ctx->rnd )
+ {
+ uint8_t 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
+ { uint8_t 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 ( uint8_t )-1;
+ return 0;
+}
+
+/* CBC encrypt a number of blocks (input and return an IV) */
+
+return_type aes_cbc_encrypt( const uint8_t *in, uint8_t *out,
+ int32_t n_block, uint8_t 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 uint8_t in[N_BLOCK], uint8_t out[N_BLOCK], const aes_context ctx[1] )
+{
+ if( ctx->rnd )
+ {
+ uint8_t 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
+ { uint8_t 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 uint8_t *in, uint8_t *out,
+ int32_t n_block, uint8_t iv[N_BLOCK], const aes_context ctx[1] )
+{
+ while(n_block--)
+ { uint8_t 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( uint8_t k[N_BLOCK], uint8_t *rc )
+{ uint8_t 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 uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
+ const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] )
+{ uint8_t 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
+ { uint8_t 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( uint8_t k[N_BLOCK], uint8_t *rc )
+{ uint8_t 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 uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
+ const uint8_t key[N_BLOCK], uint8_t o_key[N_BLOCK] )
+{
+ uint8_t 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
+ { uint8_t 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( uint8_t k[2 * N_BLOCK], uint8_t *rc )
+{ uint8_t 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 uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
+ const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] )
+{
+ uint8_t 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
+ { uint8_t 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( uint8_t k[2 * N_BLOCK], uint8_t *rc )
+{ uint8_t 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 uint8_t in[N_BLOCK], uint8_t out[N_BLOCK],
+ const uint8_t key[2 * N_BLOCK], uint8_t o_key[2 * N_BLOCK] )
+{
+ uint8_t 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
+ { uint8_t 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/system/crypto/aes.h Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,160 @@
+/*
+ ---------------------------------------------------------------------------
+ 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 uint8_t return_type;
+
+/* Warning: The key length for 256 bit keys overflows a byte
+ (see comment below)
+*/
+
+typedef uint8_t length_type;
+
+typedef struct
+{ uint8_t ksch[(N_MAX_ROUNDS + 1) * N_BLOCK];
+ uint8_t 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 uint8_t key[],
+ length_type keylen,
+ aes_context ctx[1] );
+#endif
+
+#if defined( AES_ENC_PREKEYED )
+
+return_type aes_encrypt( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const aes_context ctx[1] );
+
+return_type aes_cbc_encrypt( const uint8_t *in,
+ uint8_t *out,
+ int32_t n_block,
+ uint8_t iv[N_BLOCK],
+ const aes_context ctx[1] );
+#endif
+
+#if defined( AES_DEC_PREKEYED )
+
+return_type aes_decrypt( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const aes_context ctx[1] );
+
+return_type aes_cbc_decrypt( const uint8_t *in,
+ uint8_t *out,
+ int32_t n_block,
+ uint8_t 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 uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const uint8_t key[N_BLOCK],
+ uint8_t o_key[N_BLOCK] );
+#endif
+
+#if defined( AES_DEC_128_OTFK )
+void aes_decrypt_128( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const uint8_t key[N_BLOCK],
+ uint8_t o_key[N_BLOCK] );
+#endif
+
+#if defined( AES_ENC_256_OTFK )
+void aes_encrypt_256( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const uint8_t key[2 * N_BLOCK],
+ uint8_t o_key[2 * N_BLOCK] );
+#endif
+
+#if defined( AES_DEC_256_OTFK )
+void aes_decrypt_256( const uint8_t in[N_BLOCK],
+ uint8_t out[N_BLOCK],
+ const uint8_t key[2 * N_BLOCK],
+ uint8_t o_key[2 * N_BLOCK] );
+#endif
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/system/crypto/cmac.cpp Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,153 @@
+/**************************************************************************
+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 <stdint.h>
+#include "aes.h"
+#include "cmac.h"
+#include "utilities.h"
+
+#define LSHIFT(v, r) do { \
+ int32_t 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 { \
+ int32_t i; \
+ for (i = 0; i < 16; i++) \
+ { \
+ (r)[i] = (r)[i] ^ (v)[i]; \
+ } \
+ } while (0) \
+
+
+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 uint8_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 uint8_t *data, uint32_t len)
+{
+ uint32_t mlen;
+ uint8_t in[16];
+
+ if (ctx->M_n > 0) {
+ mlen = MIN(16 - ctx->M_n, len);
+ memcpy1(ctx->M_last + ctx->M_n, 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, data, len);
+ ctx->M_n = len;
+}
+
+void AES_CMAC_Final(uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX *ctx)
+{
+ uint8_t K[16];
+ uint8_t 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);
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/system/crypto/cmac.h Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,63 @@
+/**************************************************************************
+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 struct _AES_CMAC_CTX {
+ aes_context rijndael;
+ uint8_t X[16];
+ uint8_t M_last[16];
+ uint32_t 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 uint8_t key[AES_CMAC_KEY_LENGTH]);
+void AES_CMAC_Update(AES_CMAC_CTX * ctx, const uint8_t * data, uint32_t len);
+ // __attribute__((__bounded__(__string__,2,3)));
+void AES_CMAC_Final(uint8_t digest[AES_CMAC_DIGEST_LENGTH], AES_CMAC_CTX * ctx);
+ // __attribute__((__bounded__(__minbytes__,1,AES_CMAC_DIGEST_LENGTH)));
+//__END_DECLS
+
+#endif /* _CMAC_H_ */
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/system/timer.cpp Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,62 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/system/timer.h Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,92 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (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__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/system/utilities.cpp Thu Mar 17 09:32:46 2016 +0000
@@ -0,0 +1,85 @@
+/*
+ / _____) _ | |
+( (____ _____ ____ _| |_ _____ ____| |__
+ \____ \| ___ | (_ _) ___ |/ ___) _ \
+ _____) ) ____| | | || |_| ____( (___| | | |
+(______/|_____)_|_|_| \__)_____)\____)_| |_|
+ (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 2147483647L
+
+static uint32_t next = 1;
+
+int32_t rand1( void )
+{
+ return ( ( next = next * 1103515245L + 12345L ) % RAND_LOCAL_MAX );
+}
+
+void srand1( uint32_t 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 memcpyr( uint8_t *dst, const uint8_t *src, uint16_t size )
+{
+ dst = dst + ( size - 1 );
+ 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 '?';
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/system/utilities.h Thu Mar 17 09:32:46 2016 +0000 @@ -0,0 +1,99 @@ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (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 Initializes the pseudo ramdom generator initial value + * + * \param [IN] seed Pseudo ramdom generator initial value + */ +void srand1( uint32_t seed ); + +/*! + * \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 Copies size elements of src array to dst array reversing the byte order + * + * \param [OUT] dst Destination array + * \param [IN] src Source array + * \param [IN] size Number of bytes to be copied + */ +void memcpyr( 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__
