end node on synchronous star LoRa network.

Dependencies:   SX127x sx12xx_hal TSL2561

radio chip selection

Radio chip driver is not included, allowing choice of radio device.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
if you're using SX1280, then import sx1280 driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.

This project for use with LoRaWAN_singlechannel_gateway project.

Alternately gateway running on raspberry pi can be used as gateway.

LoRaWAN on single radio channel

Network description is at gateway project page. Synchronous star network.

Hardware Support

This project supports SX1276 and SX1272, sx126x kit, sx126x shield, and sx128x 2.4GHz. The ST board B-L072Z-LRWAN1 is also supported (TypeABZ module). When B-L072Z-LRWAN1 target is selected, TARGET_DISCO_L072CZ_LRWAN1 is defined by tools, allowing correct radio driver configuration for this platform. Alternately, any mbed board that can use LoRa radio shield board should work, but NUCLEO boards are tested.

End-node Unique ID

DevEUI is created from CPU serial number. AppEUI and AppKey are declared as software constants.

End-node Configuration

Data rate definition LORAMAC_DEFAULT_DATARATE configured in LoRaMac-definitions.h. See gateway project page for configuration of gateway.
LoRaWAN addressing is configured in Comissioning.h; only OTA mode is functional.
Header file board/lora_config.h, selects application layer options (i.e. sensors) to be compiled in.

Serial Interface

Serial port operates at 115200bps.
Application layer single_us915_main.cpp User button triggers uplink (i.e. blue button on nucleo board), or jumper enables continuously sends repeated uplink packets. The MAC layer holds each uplink request until the allocated timeslot.

commandargumentsdescription
?-print available commands
. (period)-print status (DevEUI, DevAddr, etc)
ullength integerset payload length of test uplink packets

sensor demo

Selected grove sensors may be plugged into SX1272 shield.
To enable, edit lora_config.h to define SENSORS.

Sensor connections on SX1272MB2xAS:

D8 D9: buttonRX TX: (unused)A3 A4: Rotary Angle Sensor
D6 D7: RGB LEDSCL SDA: digital light sensorA1 A2: Rotary Angle Sensor

Digital input pin, state reported via uplink: PC8
Digital output pin, controlled via downlink: PC6
PWM out: PB_10

Jumper enables auto-repeated transmit: PC10 and PC12 on NUCLEO board, located on end of morpho headers nearby JP4.

Revision:
0:8f0d0ae0a077
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/system/crypto/gladman_cmac.cpp	Thu May 18 15:11:53 2017 -0700
@@ -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 "gladman_aes.h"
+#include "gladman_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);
+
+}
+