IBM LoRa MAC in C (LMiC) mbed library port

Dependents:   lora-temperature LoRaWAN-lmic-app_HS LoRaWAN-lmic-app_huynh

LoRa WAN in C for sx1276 shield

Currently version 1.5


LoRaWAN network configuration for end-device

The following three pieces of information uniquely identifies end-device to network to allow over-the-air activation. These are stored in the end-device prior to join procedure.

AppEUI

Uniquely identifies application provider of end-device.

Least-significant byte first, 8 bytes, use reverse memcpy() to keep same order as shown on lora server.

example C code

static const u1_t APPEUI[8]  = { 0x01, 0x00, 0x01, 0x00, 0x00, 0x0C, 0x25, 0x00 };

This is copied into LMIC by os_getArtEui() callback function in application.

DevEUI

End-device ID, unique to each end-node.

Least-significant byte first, 8 bytes, use reverse memcpy() to keep same order as shown on lora server.

example C code

static const u1_t DEVEUI[8]  = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x25, 0x00 }; 

This is copied into LMIC by os_getDevEui() callback function in application.

AppKey (aka DevKey)

128-bit (16byte) AES key.

example C code

static const u1_t DEVKEY[16] = { 0xe4, 0x72, 0x71, 0xc5, 0xf5, 0x30, 0xa9, 0x9f, 0xcf, 0xc4, 0x0e, 0xab, 0xea, 0xd7, 0x19, 0x42 };

This is copied into LMIC by os_getDevKey() callback function in application.

Using over-the air activation, the end-device (LMIC) performs a join procedure every time it starts for first time, or has lost session context information. When join procedure has successfully completed, the end-device will have a network session key (NwkSKey) and an application session key (AppSKey), which are used for encryption and message integrity check.


US915 configuration with http://us01-iot.semtech.com/

  • log in to server
  • click on Applications
  • find your application and click it
  • go to configure motes
  • to create a mote, you may enter a new DevEUI
    • you may copy-paste the 16byte application key from an already existing mote, if you desire.
CHNL_HYBRID125KHz500KHz
defined valuechannelschannel
00 to 764
18 to 1565
216 to 2366
324 to 3167
432 to 3968
540 to 4769
648 to 5570
756 to 6371
undef0 to 6364 to 71
Committer:
mluis
Date:
Thu Nov 26 17:17:08 2015 +0000
Revision:
4:85b2b647cb64
Parent:
1:d3b7bde3995c
Merged branches

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:62d1edcc13d1 1 /*******************************************************************************
mluis 1:d3b7bde3995c 2 * Copyright (c) 2014-2015 IBM Corporation.
mluis 0:62d1edcc13d1 3 * All rights reserved. This program and the accompanying materials
mluis 0:62d1edcc13d1 4 * are made available under the terms of the Eclipse Public License v1.0
mluis 0:62d1edcc13d1 5 * which accompanies this distribution, and is available at
mluis 0:62d1edcc13d1 6 * http://www.eclipse.org/legal/epl-v10.html
mluis 0:62d1edcc13d1 7 *
mluis 0:62d1edcc13d1 8 * Contributors:
mluis 0:62d1edcc13d1 9 * IBM Zurich Research Lab - initial API, implementation and documentation
mluis 0:62d1edcc13d1 10 *******************************************************************************/
mluis 0:62d1edcc13d1 11
mluis 1:d3b7bde3995c 12 //! \file
mluis 0:62d1edcc13d1 13 #ifndef _oslmic_h_
mluis 0:62d1edcc13d1 14 #define _oslmic_h_
mluis 0:62d1edcc13d1 15
mluis 0:62d1edcc13d1 16 // Dependencies required for the LoRa MAC in C to run.
mluis 0:62d1edcc13d1 17 // These settings can be adapted to the underlying system.
mluis 0:62d1edcc13d1 18 // You should not, however, change the lmic.[hc]
mluis 0:62d1edcc13d1 19
mluis 0:62d1edcc13d1 20
mluis 0:62d1edcc13d1 21
mluis 0:62d1edcc13d1 22 //================================================================================
mluis 0:62d1edcc13d1 23 //================================================================================
mluis 0:62d1edcc13d1 24 // Target platform as C library
mluis 0:62d1edcc13d1 25 typedef unsigned char bit_t;
mluis 0:62d1edcc13d1 26 typedef unsigned char u1_t;
mluis 0:62d1edcc13d1 27 typedef signed char s1_t;
mluis 0:62d1edcc13d1 28 typedef unsigned short u2_t;
mluis 0:62d1edcc13d1 29 typedef short s2_t;
mluis 0:62d1edcc13d1 30 typedef unsigned int u4_t;
mluis 0:62d1edcc13d1 31 typedef int s4_t;
mluis 0:62d1edcc13d1 32 typedef unsigned long long u8_t;
mluis 0:62d1edcc13d1 33 typedef long long s8_t;
mluis 0:62d1edcc13d1 34 typedef unsigned int uint;
mluis 0:62d1edcc13d1 35 typedef const char* str_t;
mluis 0:62d1edcc13d1 36
mluis 0:62d1edcc13d1 37 #include <string.h>
mluis 0:62d1edcc13d1 38 #include "hal.h"
mluis 0:62d1edcc13d1 39 #define EV(a,b,c) /**/
mluis 1:d3b7bde3995c 40 #define DO_DEVDB(field1,field2) /**/
mluis 1:d3b7bde3995c 41 #if !defined(CFG_noassert)
mluis 0:62d1edcc13d1 42 #define ASSERT(cond) if(!(cond)) hal_failed()
mluis 0:62d1edcc13d1 43 #else
mluis 0:62d1edcc13d1 44 #define ASSERT(cond) /**/
mluis 0:62d1edcc13d1 45 #endif
mluis 0:62d1edcc13d1 46
mluis 0:62d1edcc13d1 47 #define os_clearMem(a,b) memset(a,0,b)
mluis 0:62d1edcc13d1 48 #define os_copyMem(a,b,c) memcpy(a,b,c)
mluis 0:62d1edcc13d1 49
mluis 0:62d1edcc13d1 50 typedef struct osjob_t osjob_t;
mluis 0:62d1edcc13d1 51 typedef struct band_t band_t;
mluis 0:62d1edcc13d1 52 typedef struct chnldef_t chnldef_t;
mluis 0:62d1edcc13d1 53 typedef struct rxsched_t rxsched_t;
mluis 0:62d1edcc13d1 54 typedef struct bcninfo_t bcninfo_t;
mluis 0:62d1edcc13d1 55 typedef const u1_t* xref2cu1_t;
mluis 0:62d1edcc13d1 56 typedef u1_t* xref2u1_t;
mluis 0:62d1edcc13d1 57 #define TYPEDEF_xref2rps_t typedef rps_t* xref2rps_t
mluis 0:62d1edcc13d1 58 #define TYPEDEF_xref2rxsched_t typedef rxsched_t* xref2rxsched_t
mluis 0:62d1edcc13d1 59 #define TYPEDEF_xref2chnldef_t typedef chnldef_t* xref2chnldef_t
mluis 0:62d1edcc13d1 60 #define TYPEDEF_xref2band_t typedef band_t* xref2band_t
mluis 0:62d1edcc13d1 61 #define TYPEDEF_xref2osjob_t typedef osjob_t* xref2osjob_t
mluis 0:62d1edcc13d1 62
mluis 0:62d1edcc13d1 63 #define SIZEOFEXPR(x) sizeof(x)
mluis 0:62d1edcc13d1 64
mluis 0:62d1edcc13d1 65 #define ON_LMIC_EVENT(ev) onEvent(ev)
mluis 0:62d1edcc13d1 66 #define DECL_ON_LMIC_EVENT void onEvent(ev_t e)
mluis 0:62d1edcc13d1 67
mluis 0:62d1edcc13d1 68 extern u4_t AESAUX[];
mluis 0:62d1edcc13d1 69 extern u4_t AESKEY[];
mluis 0:62d1edcc13d1 70 #define AESkey ((u1_t*)AESKEY)
mluis 0:62d1edcc13d1 71 #define AESaux ((u1_t*)AESAUX)
mluis 0:62d1edcc13d1 72 #define FUNC_ADDR(func) (&(func))
mluis 0:62d1edcc13d1 73
mluis 0:62d1edcc13d1 74 u1_t radio_rand1 (void);
mluis 0:62d1edcc13d1 75 #define os_getRndU1() radio_rand1()
mluis 0:62d1edcc13d1 76
mluis 0:62d1edcc13d1 77 #define DEFINE_LMIC struct lmic_t LMIC
mluis 0:62d1edcc13d1 78 #define DECLARE_LMIC extern struct lmic_t LMIC
mluis 0:62d1edcc13d1 79
mluis 1:d3b7bde3995c 80 void radio_init (void);
mluis 0:62d1edcc13d1 81 void radio_irq_handler (u1_t dio);
mluis 0:62d1edcc13d1 82 void os_init (void);
mluis 0:62d1edcc13d1 83 void os_runloop (void);
mluis 0:62d1edcc13d1 84
mluis 0:62d1edcc13d1 85 //================================================================================
mluis 0:62d1edcc13d1 86
mluis 0:62d1edcc13d1 87
mluis 0:62d1edcc13d1 88 #ifndef RX_RAMPUP
mluis 0:62d1edcc13d1 89 #define RX_RAMPUP (us2osticks(2000))
mluis 0:62d1edcc13d1 90 #endif
mluis 0:62d1edcc13d1 91 #ifndef TX_RAMPUP
mluis 0:62d1edcc13d1 92 #define TX_RAMPUP (us2osticks(2000))
mluis 0:62d1edcc13d1 93 #endif
mluis 0:62d1edcc13d1 94
mluis 0:62d1edcc13d1 95 #ifndef OSTICKS_PER_SEC
mluis 0:62d1edcc13d1 96 #define OSTICKS_PER_SEC 15625
mluis 0:62d1edcc13d1 97 #elif OSTICKS_PER_SEC < 10000 || OSTICKS_PER_SEC > 64516
mluis 0:62d1edcc13d1 98 #error Illegal OSTICKS_PER_SEC - must be in range [10000:64516]. One tick must be 15.5us .. 100us long.
mluis 0:62d1edcc13d1 99 #endif
mluis 0:62d1edcc13d1 100
mluis 0:62d1edcc13d1 101 typedef s4_t ostime_t;
mluis 0:62d1edcc13d1 102
mluis 0:62d1edcc13d1 103 #if !HAS_ostick_conv
mluis 0:62d1edcc13d1 104 #define us2osticks(us) ((ostime_t)( ((s8_t)(us) * OSTICKS_PER_SEC) / 1000000))
mluis 0:62d1edcc13d1 105 #define ms2osticks(ms) ((ostime_t)( ((s8_t)(ms) * OSTICKS_PER_SEC) / 1000))
mluis 0:62d1edcc13d1 106 #define sec2osticks(sec) ((ostime_t)( (s8_t)(sec) * OSTICKS_PER_SEC))
mluis 0:62d1edcc13d1 107 #define osticks2ms(os) ((s4_t)(((os)*(s8_t)1000 ) / OSTICKS_PER_SEC))
mluis 0:62d1edcc13d1 108 #define osticks2us(os) ((s4_t)(((os)*(s8_t)1000000 ) / OSTICKS_PER_SEC))
mluis 0:62d1edcc13d1 109 // Special versions
mluis 0:62d1edcc13d1 110 #define us2osticksCeil(us) ((ostime_t)( ((s8_t)(us) * OSTICKS_PER_SEC + 999999) / 1000000))
mluis 0:62d1edcc13d1 111 #define us2osticksRound(us) ((ostime_t)( ((s8_t)(us) * OSTICKS_PER_SEC + 500000) / 1000000))
mluis 0:62d1edcc13d1 112 #define ms2osticksCeil(ms) ((ostime_t)( ((s8_t)(ms) * OSTICKS_PER_SEC + 999) / 1000))
mluis 0:62d1edcc13d1 113 #define ms2osticksRound(ms) ((ostime_t)( ((s8_t)(ms) * OSTICKS_PER_SEC + 500) / 1000))
mluis 0:62d1edcc13d1 114 #endif
mluis 0:62d1edcc13d1 115
mluis 0:62d1edcc13d1 116
mluis 0:62d1edcc13d1 117 struct osjob_t; // fwd decl.
mluis 0:62d1edcc13d1 118 typedef void (*osjobcb_t) (struct osjob_t*);
mluis 0:62d1edcc13d1 119 struct osjob_t {
mluis 0:62d1edcc13d1 120 struct osjob_t* next;
mluis 0:62d1edcc13d1 121 ostime_t deadline;
mluis 0:62d1edcc13d1 122 osjobcb_t func;
mluis 0:62d1edcc13d1 123 };
mluis 0:62d1edcc13d1 124 TYPEDEF_xref2osjob_t;
mluis 0:62d1edcc13d1 125
mluis 0:62d1edcc13d1 126
mluis 1:d3b7bde3995c 127 #ifndef HAS_os_calls
mluis 0:62d1edcc13d1 128
mluis 0:62d1edcc13d1 129 #ifndef os_getDevKey
mluis 0:62d1edcc13d1 130 void os_getDevKey (xref2u1_t buf);
mluis 0:62d1edcc13d1 131 #endif
mluis 0:62d1edcc13d1 132 #ifndef os_getArtEui
mluis 0:62d1edcc13d1 133 void os_getArtEui (xref2u1_t buf);
mluis 0:62d1edcc13d1 134 #endif
mluis 0:62d1edcc13d1 135 #ifndef os_getDevEui
mluis 0:62d1edcc13d1 136 void os_getDevEui (xref2u1_t buf);
mluis 0:62d1edcc13d1 137 #endif
mluis 0:62d1edcc13d1 138 #ifndef os_setCallback
mluis 0:62d1edcc13d1 139 void os_setCallback (xref2osjob_t job, osjobcb_t cb);
mluis 0:62d1edcc13d1 140 #endif
mluis 0:62d1edcc13d1 141 #ifndef os_setTimedCallback
mluis 0:62d1edcc13d1 142 void os_setTimedCallback (xref2osjob_t job, ostime_t time, osjobcb_t cb);
mluis 0:62d1edcc13d1 143 #endif
mluis 0:62d1edcc13d1 144 #ifndef os_clearCallback
mluis 0:62d1edcc13d1 145 void os_clearCallback (xref2osjob_t job);
mluis 0:62d1edcc13d1 146 #endif
mluis 0:62d1edcc13d1 147 #ifndef os_getTime
mluis 0:62d1edcc13d1 148 ostime_t os_getTime (void);
mluis 0:62d1edcc13d1 149 #endif
mluis 0:62d1edcc13d1 150 #ifndef os_getTimeSecs
mluis 0:62d1edcc13d1 151 uint os_getTimeSecs (void);
mluis 0:62d1edcc13d1 152 #endif
mluis 0:62d1edcc13d1 153 #ifndef os_radio
mluis 0:62d1edcc13d1 154 void os_radio (u1_t mode);
mluis 0:62d1edcc13d1 155 #endif
mluis 0:62d1edcc13d1 156 #ifndef os_getBattLevel
mluis 0:62d1edcc13d1 157 u1_t os_getBattLevel (void);
mluis 0:62d1edcc13d1 158 #endif
mluis 0:62d1edcc13d1 159
mluis 0:62d1edcc13d1 160 #ifndef os_rlsbf4
mluis 0:62d1edcc13d1 161 //! Read 32-bit quantity from given pointer in little endian byte order.
mluis 0:62d1edcc13d1 162 u4_t os_rlsbf4 (xref2cu1_t buf);
mluis 0:62d1edcc13d1 163 #endif
mluis 0:62d1edcc13d1 164 #ifndef os_wlsbf4
mluis 0:62d1edcc13d1 165 //! Write 32-bit quntity into buffer in little endian byte order.
mluis 0:62d1edcc13d1 166 void os_wlsbf4 (xref2u1_t buf, u4_t value);
mluis 0:62d1edcc13d1 167 #endif
mluis 0:62d1edcc13d1 168 #ifndef os_rmsbf4
mluis 0:62d1edcc13d1 169 //! Read 32-bit quantity from given pointer in big endian byte order.
mluis 0:62d1edcc13d1 170 u4_t os_rmsbf4 (xref2cu1_t buf);
mluis 0:62d1edcc13d1 171 #endif
mluis 0:62d1edcc13d1 172 #ifndef os_wmsbf4
mluis 0:62d1edcc13d1 173 //! Write 32-bit quntity into buffer in big endian byte order.
mluis 0:62d1edcc13d1 174 void os_wmsbf4 (xref2u1_t buf, u4_t value);
mluis 0:62d1edcc13d1 175 #endif
mluis 0:62d1edcc13d1 176 #ifndef os_rlsbf2
mluis 0:62d1edcc13d1 177 //! Read 16-bit quantity from given pointer in little endian byte order.
mluis 0:62d1edcc13d1 178 u2_t os_rlsbf2 (xref2cu1_t buf);
mluis 0:62d1edcc13d1 179 #endif
mluis 0:62d1edcc13d1 180 #ifndef os_wlsbf2
mluis 0:62d1edcc13d1 181 //! Write 16-bit quntity into buffer in little endian byte order.
mluis 0:62d1edcc13d1 182 void os_wlsbf2 (xref2u1_t buf, u2_t value);
mluis 0:62d1edcc13d1 183 #endif
mluis 0:62d1edcc13d1 184
mluis 0:62d1edcc13d1 185 //! Get random number (default impl for u2_t).
mluis 0:62d1edcc13d1 186 #ifndef os_getRndU2
mluis 0:62d1edcc13d1 187 #define os_getRndU2() ((u2_t)((os_getRndU1()<<8)|os_getRndU1()))
mluis 0:62d1edcc13d1 188 #endif
mluis 0:62d1edcc13d1 189 #ifndef os_crc16
mluis 0:62d1edcc13d1 190 u2_t os_crc16 (xref2u1_t d, uint len);
mluis 0:62d1edcc13d1 191 #endif
mluis 0:62d1edcc13d1 192
mluis 0:62d1edcc13d1 193 #endif // !HAS_os_calls
mluis 0:62d1edcc13d1 194
mluis 0:62d1edcc13d1 195 // ======================================================================
mluis 0:62d1edcc13d1 196 // AES support
mluis 0:62d1edcc13d1 197 // !!Keep in sync with lorabase.hpp!!
mluis 0:62d1edcc13d1 198
mluis 0:62d1edcc13d1 199 #ifndef AES_ENC // if AES_ENC is defined as macro all other values must be too
mluis 0:62d1edcc13d1 200 #define AES_ENC 0x00
mluis 0:62d1edcc13d1 201 #define AES_DEC 0x01
mluis 0:62d1edcc13d1 202 #define AES_MIC 0x02
mluis 0:62d1edcc13d1 203 #define AES_CTR 0x04
mluis 0:62d1edcc13d1 204 #define AES_MICNOAUX 0x08
mluis 0:62d1edcc13d1 205 #endif
mluis 0:62d1edcc13d1 206 #ifndef AESkey // if AESkey is defined as macro all other values must be too
mluis 0:62d1edcc13d1 207 extern xref2u1_t AESkey;
mluis 0:62d1edcc13d1 208 extern xref2u1_t AESaux;
mluis 0:62d1edcc13d1 209 #endif
mluis 0:62d1edcc13d1 210 #ifndef os_aes
mluis 0:62d1edcc13d1 211 u4_t os_aes (u1_t mode, xref2u1_t buf, u2_t len);
mluis 0:62d1edcc13d1 212 #endif
mluis 0:62d1edcc13d1 213
mluis 0:62d1edcc13d1 214
mluis 0:62d1edcc13d1 215
mluis 0:62d1edcc13d1 216 #endif // _oslmic_h_