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.
MinimouseSrc/MacLayer.cpp@1:eda561b01daf, 2017-12-18 (annotated)
- Committer:
- fholin
- Date:
- Mon Dec 18 16:31:11 2017 +0000
- Revision:
- 1:eda561b01daf
- Parent:
- 0:2325d1d28df3
inline with github repository : ; https://github.com/LoRaWanMiniMouse/Mini-Mouse.git
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fholin | 0:2325d1d28df3 | 1 | /* |
fholin | 0:2325d1d28df3 | 2 | |
fholin | 0:2325d1d28df3 | 3 | __ __ _ _ |
fholin | 0:2325d1d28df3 | 4 | | \/ ( _) ( _) |
fholin | 0:2325d1d28df3 | 5 | | \ / |_ _ __ _ _ __ ___ ___ _ _ ___ ___ |
fholin | 0:2325d1d28df3 | 6 | | |\/| | | '_ \| | '_ ` _ \ / _ \| | | / __|/ _ \ |
fholin | 0:2325d1d28df3 | 7 | | | | | | | | | | | | | | | ( _) | |_| \__ \ __/ |
fholin | 0:2325d1d28df3 | 8 | |_| |_|_|_| |_|_|_| |_| |_|\___/ \__,_|___/\___| |
fholin | 0:2325d1d28df3 | 9 | |
fholin | 0:2325d1d28df3 | 10 | |
fholin | 0:2325d1d28df3 | 11 | Description : LoraWan Mac Layer objets. |
fholin | 0:2325d1d28df3 | 12 | License : Revised BSD License, see LICENSE.TXT file include in the project |
fholin | 0:2325d1d28df3 | 13 | Maintainer : Fabien Holin ( SEMTECH) |
fholin | 0:2325d1d28df3 | 14 | */ |
fholin | 0:2325d1d28df3 | 15 | #include "MacLayer.h" |
fholin | 0:2325d1d28df3 | 16 | #include "LoRaMacCrypto.h" |
fholin | 0:2325d1d28df3 | 17 | #include "LoraWanProcess.h" |
fholin | 0:2325d1d28df3 | 18 | #include "ApiRtc.h" |
fholin | 0:2325d1d28df3 | 19 | #include "Define.h" |
fholin | 0:2325d1d28df3 | 20 | #include "utilities.h" |
fholin | 0:2325d1d28df3 | 21 | #include "ApiFlash.h" |
fholin | 0:2325d1d28df3 | 22 | |
fholin | 0:2325d1d28df3 | 23 | /*************************************************/ |
fholin | 0:2325d1d28df3 | 24 | /* Constructors */ |
fholin | 0:2325d1d28df3 | 25 | /*@note have to check init values */ |
fholin | 0:2325d1d28df3 | 26 | /*************************************************/ |
fholin | 0:2325d1d28df3 | 27 | LoraWanContainer::LoraWanContainer( PinName interrupt ) |
fholin | 0:2325d1d28df3 | 28 | :Phy( interrupt ) { |
fholin | 0:2325d1d28df3 | 29 | FcntUp = 0; |
fholin | 0:2325d1d28df3 | 30 | Phy.RadioContainerInit( ); |
fholin | 0:2325d1d28df3 | 31 | StateTimer = TIMERSTATE_SLEEP; |
fholin | 0:2325d1d28df3 | 32 | FcntDwn = 0; |
fholin | 0:2325d1d28df3 | 33 | AvailableRxPacketForUser = NOLORARXPACKETAVAILABLE; |
fholin | 0:2325d1d28df3 | 34 | MacTxFrequency[0] = 868100000; |
fholin | 0:2325d1d28df3 | 35 | MacTxFrequency[1] = 868300000; |
fholin | 0:2325d1d28df3 | 36 | MacTxFrequency[2] = 868500000; |
fholin | 0:2325d1d28df3 | 37 | NbOfActiveChannel = 3; |
fholin | 0:2325d1d28df3 | 38 | MacTxSf = 7; |
fholin | 0:2325d1d28df3 | 39 | MacTxPower = 14; |
fholin | 0:2325d1d28df3 | 40 | MacRx1SfOffset = 0; |
fholin | 0:2325d1d28df3 | 41 | MacRx2Frequency = 869525000; |
fholin | 0:2325d1d28df3 | 42 | MacRx2Sf = 9; |
fholin | 0:2325d1d28df3 | 43 | MacRx1Delay = RX1DELAY; |
fholin | 0:2325d1d28df3 | 44 | JoinedStatus = 0 ; |
fholin | 0:2325d1d28df3 | 45 | memcpy( appSKey, LoRaMacAppSKey, 16 ); |
fholin | 0:2325d1d28df3 | 46 | memcpy( nwkSKey, LoRaMacNwkSKey, 16 ); |
fholin | 0:2325d1d28df3 | 47 | DevAddr = 0x26011918; |
fholin | 0:2325d1d28df3 | 48 | }; |
fholin | 0:2325d1d28df3 | 49 | LoraWanContainer::~LoraWanContainer( ) { |
fholin | 0:2325d1d28df3 | 50 | }; |
fholin | 0:2325d1d28df3 | 51 | |
fholin | 0:2325d1d28df3 | 52 | |
fholin | 0:2325d1d28df3 | 53 | /***********************************************************************************************/ |
fholin | 0:2325d1d28df3 | 54 | /* Public Methods */ |
fholin | 0:2325d1d28df3 | 55 | /***********************************************************************************************/ |
fholin | 0:2325d1d28df3 | 56 | //@note Partionning Public/private not yet finalized |
fholin | 0:2325d1d28df3 | 57 | |
fholin | 0:2325d1d28df3 | 58 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 59 | /* Called During LP.Process */ |
fholin | 0:2325d1d28df3 | 60 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 61 | void LoraWanContainer::ConfigureRadioAndSend( void ) { |
fholin | 0:2325d1d28df3 | 62 | GiveNextSf( ); |
fholin | 0:2325d1d28df3 | 63 | uint8_t ChannelIndex = GiveNextChannel ( );//@note have to be completed |
fholin | 0:2325d1d28df3 | 64 | Phy.DevAddrIsr = DevAddr ; //@note copy of the mac devaddr in order to filter it in the radio isr routine. |
fholin | 0:2325d1d28df3 | 65 | Phy.TxFrequency = MacTxFrequency[ChannelIndex]; |
fholin | 0:2325d1d28df3 | 66 | Phy.TxPower = MacTxPower; |
fholin | 0:2325d1d28df3 | 67 | Phy.TxSf = MacTxSf; |
fholin | 0:2325d1d28df3 | 68 | Phy.SetTxConfig( ); |
fholin | 0:2325d1d28df3 | 69 | Phy.TxPayloadSize = MacPayloadSize; |
fholin | 0:2325d1d28df3 | 70 | Phy.Send( ); |
fholin | 0:2325d1d28df3 | 71 | }; |
fholin | 0:2325d1d28df3 | 72 | void LoraWanContainer::ConfigureRadioForRx1 ( void ) { |
fholin | 0:2325d1d28df3 | 73 | Phy.RxFrequency = Phy.TxFrequency; |
fholin | 0:2325d1d28df3 | 74 | Phy.RxSf = Phy.TxSf + MacRx1SfOffset;//@note + sf offset |
fholin | 0:2325d1d28df3 | 75 | Phy.SetRxConfig( ); |
fholin | 0:2325d1d28df3 | 76 | }; |
fholin | 0:2325d1d28df3 | 77 | |
fholin | 0:2325d1d28df3 | 78 | void LoraWanContainer::ConfigureRadioForRx2 ( void ) { |
fholin | 0:2325d1d28df3 | 79 | Phy.RxFrequency = MacRx2Frequency; |
fholin | 0:2325d1d28df3 | 80 | Phy.RxSf = MacRx2Sf; |
fholin | 0:2325d1d28df3 | 81 | Phy.SetRxConfig( ); |
fholin | 0:2325d1d28df3 | 82 | }; |
fholin | 0:2325d1d28df3 | 83 | |
fholin | 0:2325d1d28df3 | 84 | void LoraWanContainer::ConfigureTimerForRx ( int type ) { |
fholin | 0:2325d1d28df3 | 85 | int status = OKLORAWAN ; |
fholin | 0:2325d1d28df3 | 86 | uint32_t tCurrentMillisec; |
fholin | 0:2325d1d28df3 | 87 | uint32_t tAlarmMillisec; |
fholin | 0:2325d1d28df3 | 88 | int toffset = 8; // @note created a Define? |
fholin | 0:2325d1d28df3 | 89 | tCurrentMillisec = RtcGetTimeMs( ); |
fholin | 0:2325d1d28df3 | 90 | if (type == RX1) { |
fholin | 0:2325d1d28df3 | 91 | tAlarmMillisec = MacRx1Delay + Phy.TimestampRtcIsr - tCurrentMillisec - toffset ; |
fholin | 0:2325d1d28df3 | 92 | if ( tAlarmMillisec <= toffset ) {// too late to launch a timer |
fholin | 0:2325d1d28df3 | 93 | Phy.StateRadioProcess = RADIOSTATE_RX1FINISHED ; |
fholin | 0:2325d1d28df3 | 94 | } else { |
fholin | 0:2325d1d28df3 | 95 | SetAlarm( tAlarmMillisec ); |
fholin | 0:2325d1d28df3 | 96 | } |
fholin | 0:2325d1d28df3 | 97 | } else { |
fholin | 0:2325d1d28df3 | 98 | tAlarmMillisec = MacRx1Delay + 1000 + Phy.TimestampRtcIsr - tCurrentMillisec ;// @note Rx2 Dalay is alway RX1DELAY + 1 second |
fholin | 0:2325d1d28df3 | 99 | if ( tAlarmMillisec <= toffset ) {// too late to launch a timer |
fholin | 0:2325d1d28df3 | 100 | Phy.StateRadioProcess = RADIOSTATE_IDLE ; |
fholin | 0:2325d1d28df3 | 101 | } else { |
fholin | 0:2325d1d28df3 | 102 | SetAlarm( tAlarmMillisec ); |
fholin | 0:2325d1d28df3 | 103 | } |
fholin | 0:2325d1d28df3 | 104 | } |
fholin | 0:2325d1d28df3 | 105 | pcf.printf( " timer will expire in %d ms\n", tAlarmMillisec ); |
fholin | 0:2325d1d28df3 | 106 | } |
fholin | 0:2325d1d28df3 | 107 | |
fholin | 0:2325d1d28df3 | 108 | /****************************/ |
fholin | 0:2325d1d28df3 | 109 | /* DecodeRxFrame */ |
fholin | 0:2325d1d28df3 | 110 | /****************************/ |
fholin | 1:eda561b01daf | 111 | eRxPacketType LoraWanContainer::DecodeRxFrame( void ) { |
fholin | 0:2325d1d28df3 | 112 | int status = OKLORAWAN ; |
fholin | 1:eda561b01daf | 113 | eRxPacketType RxPacketType = NOVALIDRXPACKET ; |
fholin | 0:2325d1d28df3 | 114 | uint32_t micIn ; |
fholin | 0:2325d1d28df3 | 115 | status += CheckRxPayloadLength ( ); |
fholin | 0:2325d1d28df3 | 116 | status += ExtractRxMhdr ( ) ; |
fholin | 0:2325d1d28df3 | 117 | |
fholin | 0:2325d1d28df3 | 118 | /************************************************************************/ |
fholin | 0:2325d1d28df3 | 119 | /* Case : the receive packet is a JoinResponse */ |
fholin | 0:2325d1d28df3 | 120 | /************************************************************************/ |
fholin | 0:2325d1d28df3 | 121 | if ( MtypeRx == JOINACCEPT ) { |
fholin | 0:2325d1d28df3 | 122 | |
fholin | 0:2325d1d28df3 | 123 | LoRaMacJoinDecrypt( &Phy.RxPhyPayload[1], Phy.RxPhyPayloadSize-1, LoRaMacAppKey, &MacRxPayload[1] ); |
fholin | 0:2325d1d28df3 | 124 | MacRxPayload[0] = Phy.RxPhyPayload[0]; |
fholin | 0:2325d1d28df3 | 125 | MacRxPayloadSize = Phy.RxPhyPayloadSize - MICSIZE ; |
fholin | 0:2325d1d28df3 | 126 | memcpy((uint8_t *)&micIn, &MacRxPayload[MacRxPayloadSize], MICSIZE); |
fholin | 0:2325d1d28df3 | 127 | status += LoRaMacCheckJoinMic( MacRxPayload, MacRxPayloadSize, LoRaMacAppKey, micIn); |
fholin | 0:2325d1d28df3 | 128 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 129 | return JOINACCEPTPACKET; |
fholin | 0:2325d1d28df3 | 130 | } |
fholin | 0:2325d1d28df3 | 131 | } else { |
fholin | 0:2325d1d28df3 | 132 | /************************************************************************/ |
fholin | 0:2325d1d28df3 | 133 | /* Case : the receive packet is not a JoinResponse */ |
fholin | 0:2325d1d28df3 | 134 | /************************************************************************/ |
fholin | 0:2325d1d28df3 | 135 | uint16_t FcntDownTmp = 0; |
fholin | 0:2325d1d28df3 | 136 | status += ExtractRxFhdr ( &FcntDownTmp) ; |
fholin | 0:2325d1d28df3 | 137 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 138 | MacRxPayloadSize = Phy.RxPhyPayloadSize - MICSIZE ; |
fholin | 0:2325d1d28df3 | 139 | memcpy((uint8_t *)&micIn, &Phy.RxPhyPayload[MacRxPayloadSize], MICSIZE); |
fholin | 0:2325d1d28df3 | 140 | status += LoRaMacCheckMic(&Phy.RxPhyPayload[0], MacRxPayloadSize, nwkSKey, DevAddr, FcntDownTmp, micIn ); // @note api discussion see at the end of this file |
fholin | 0:2325d1d28df3 | 141 | } |
fholin | 0:2325d1d28df3 | 142 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 143 | status = AcceptFcntDwn ( FcntDownTmp ) ; |
fholin | 0:2325d1d28df3 | 144 | } |
fholin | 0:2325d1d28df3 | 145 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 146 | MacRxPayloadSize = MacRxPayloadSize - FHDROFFSET - FoptsLength ; |
fholin | 1:eda561b01daf | 147 | if ( FportRx == 0 ) { |
fholin | 1:eda561b01daf | 148 | LoRaMacPayloadDecrypt( &Phy.RxPhyPayload[FHDROFFSET + FoptsLength], MacRxPayloadSize, nwkSKey, DevAddr, 1, FcntDwn, &MacNwkPayload[0] ); |
fholin | 1:eda561b01daf | 149 | MacNwkPayloadSize = MacRxPayloadSize; |
fholin | 1:eda561b01daf | 150 | RxPacketType = NWKRXPACKET ; |
fholin | 1:eda561b01daf | 151 | } else { |
fholin | 1:eda561b01daf | 152 | LoRaMacPayloadDecrypt( &Phy.RxPhyPayload[FHDROFFSET + FoptsLength], MacRxPayloadSize, appSKey, DevAddr, 1, FcntDwn, &MacRxPayload[0] ); |
fholin | 1:eda561b01daf | 153 | if ( FoptsLength != 0 ) { |
fholin | 1:eda561b01daf | 154 | memcpy ( MacNwkPayload, Fopts, FoptsLength); |
fholin | 1:eda561b01daf | 155 | MacNwkPayloadSize = FoptsLength; |
fholin | 1:eda561b01daf | 156 | RxPacketType = USERRX_FOPTSPACKET ; |
fholin | 1:eda561b01daf | 157 | } else { |
fholin | 1:eda561b01daf | 158 | AvailableRxPacketForUser = LORARXPACKETAVAILABLE; |
fholin | 1:eda561b01daf | 159 | RxPacketType = USERRXPACKET ; |
fholin | 1:eda561b01daf | 160 | } |
fholin | 1:eda561b01daf | 161 | } |
fholin | 0:2325d1d28df3 | 162 | pcf.printf( " MtypeRx = %d \n ",MtypeRx ); |
fholin | 0:2325d1d28df3 | 163 | pcf.printf( " FcntDwn = %d \n ",FcntDwn ); |
fholin | 0:2325d1d28df3 | 164 | } |
fholin | 0:2325d1d28df3 | 165 | } |
fholin | 1:eda561b01daf | 166 | return ( RxPacketType ); |
fholin | 0:2325d1d28df3 | 167 | } |
fholin | 0:2325d1d28df3 | 168 | /*********************************/ |
fholin | 0:2325d1d28df3 | 169 | /* End of Decode Frame */ |
fholin | 0:2325d1d28df3 | 170 | /*********************************/ |
fholin | 0:2325d1d28df3 | 171 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 172 | /* NWK MANAGEMENTS Methods */ |
fholin | 0:2325d1d28df3 | 173 | /************************************************************************************************/ |
fholin | 1:eda561b01daf | 174 | eStatusLoRaWan LoraWanContainer::ParseManagementPacket( void ) { |
fholin | 0:2325d1d28df3 | 175 | uint8_t CmdIdentifier; |
fholin | 1:eda561b01daf | 176 | eStatusLoRaWan status = OKLORAWAN ; |
fholin | 1:eda561b01daf | 177 | uint8_t MaxCmdNum = 16 ; //@note security to avoid an infinite While erro |
fholin | 1:eda561b01daf | 178 | while ( ( MacNwkPayloadSize > 0 ) || ( MaxCmdNum > 0 ) ) { //@note MacNwkPayloadSize and MacNwkPayload[0] are updated in Parser's method |
fholin | 1:eda561b01daf | 179 | MaxCmdNum --; |
fholin | 1:eda561b01daf | 180 | if ( MaxCmdNum == 0 ) { |
fholin | 1:eda561b01daf | 181 | return ( ERRORLORAWAN ); |
fholin | 1:eda561b01daf | 182 | } |
fholin | 1:eda561b01daf | 183 | CmdIdentifier = MacNwkPayload[0]; |
fholin | 1:eda561b01daf | 184 | switch ( CmdIdentifier ) { |
fholin | 1:eda561b01daf | 185 | case LINK_CHECK_ANS : |
fholin | 1:eda561b01daf | 186 | LinkCheckParser( ); |
fholin | 1:eda561b01daf | 187 | break; |
fholin | 1:eda561b01daf | 188 | case LINK_ADR_REQ : |
fholin | 1:eda561b01daf | 189 | LinkADRParser( ); |
fholin | 1:eda561b01daf | 190 | break; |
fholin | 1:eda561b01daf | 191 | case DUTY_CYCLE_REQ : |
fholin | 1:eda561b01daf | 192 | DutyCycleParser( ); |
fholin | 1:eda561b01daf | 193 | break; |
fholin | 1:eda561b01daf | 194 | case RXPARRAM_SETUP_REQ : |
fholin | 1:eda561b01daf | 195 | RXParamSetupParser( ); |
fholin | 1:eda561b01daf | 196 | break; |
fholin | 1:eda561b01daf | 197 | case DEV_STATUS_REQ : |
fholin | 1:eda561b01daf | 198 | DevStatusParser( ); |
fholin | 1:eda561b01daf | 199 | break; |
fholin | 1:eda561b01daf | 200 | case NEW_CHANNEL_REQ : |
fholin | 1:eda561b01daf | 201 | NewChannelParser( ); |
fholin | 1:eda561b01daf | 202 | break; |
fholin | 1:eda561b01daf | 203 | case RXTIMING_SETUP_REQ : |
fholin | 1:eda561b01daf | 204 | RXTimingSetupParser( ); |
fholin | 1:eda561b01daf | 205 | break; |
fholin | 1:eda561b01daf | 206 | } |
fholin | 0:2325d1d28df3 | 207 | } |
fholin | 1:eda561b01daf | 208 | return ( status ); |
fholin | 0:2325d1d28df3 | 209 | } |
fholin | 0:2325d1d28df3 | 210 | |
fholin | 0:2325d1d28df3 | 211 | void LoraWanContainer::UpdateMacLayer ( void ) { |
fholin | 0:2325d1d28df3 | 212 | FcntUp++; //@note case Retry not yet manage |
fholin | 0:2325d1d28df3 | 213 | /*Store Context In ROM */ |
fholin | 0:2325d1d28df3 | 214 | if (( FcntUp % FLASH_UPDATE_PERIOD ) == 0 ){ |
fholin | 0:2325d1d28df3 | 215 | SaveInFlash ( ); |
fholin | 0:2325d1d28df3 | 216 | } |
fholin | 0:2325d1d28df3 | 217 | |
fholin | 0:2325d1d28df3 | 218 | switch ( IsFrameToSend ) { |
fholin | 0:2325d1d28df3 | 219 | case NOFRAME_TOSEND : |
fholin | 0:2325d1d28df3 | 220 | |
fholin | 0:2325d1d28df3 | 221 | break; |
fholin | 0:2325d1d28df3 | 222 | case NWKFRAME_TOSEND : |
fholin | 0:2325d1d28df3 | 223 | memcpy( &Phy.TxPhyPayload[FHDROFFSET], MacNwkAns, MacNwkAnsSize ); |
fholin | 0:2325d1d28df3 | 224 | UserPayloadSize = MacNwkAnsSize; |
fholin | 0:2325d1d28df3 | 225 | fPort = PORTNWK; |
fholin | 0:2325d1d28df3 | 226 | MType = UNCONFDATAUP; //@note Mtype have to be confirm |
fholin | 0:2325d1d28df3 | 227 | BuildTxLoraFrame( ); |
fholin | 0:2325d1d28df3 | 228 | EncryptTxFrame( ); |
fholin | 0:2325d1d28df3 | 229 | |
fholin | 0:2325d1d28df3 | 230 | break; |
fholin | 0:2325d1d28df3 | 231 | case USERACK_TOSEND : |
fholin | 0:2325d1d28df3 | 232 | |
fholin | 0:2325d1d28df3 | 233 | break; |
fholin | 0:2325d1d28df3 | 234 | } |
fholin | 0:2325d1d28df3 | 235 | } |
fholin | 0:2325d1d28df3 | 236 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 237 | /* Special Case Join OTA */ |
fholin | 0:2325d1d28df3 | 238 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 239 | void LoraWanContainer::UpdateJoinProcedure ( void ) { |
fholin | 0:2325d1d28df3 | 240 | pcf.printf( " receive a Join Response \n"); |
fholin | 0:2325d1d28df3 | 241 | uint8_t AppNonce[3]; |
fholin | 0:2325d1d28df3 | 242 | memcpy( AppNonce, &MacRxPayload[1], 6); |
fholin | 0:2325d1d28df3 | 243 | LoRaMacJoinComputeSKeys(LoRaMacAppKey, AppNonce, DevNonce, nwkSKey, appSKey ); |
fholin | 0:2325d1d28df3 | 244 | DevAddr = MacRxPayload[7] + ( MacRxPayload[8] << 8 ) + ( MacRxPayload[9] << 16 )+ ( MacRxPayload[10] << 24 ); |
fholin | 0:2325d1d28df3 | 245 | Phy.DevAddrIsr = DevAddr ; |
fholin | 0:2325d1d28df3 | 246 | MacRx1SfOffset = ( MacRxPayload[11] & 0x70 ) >> 3 ; |
fholin | 0:2325d1d28df3 | 247 | MacRx2Sf = ( MacRxPayload[11] & 0x0F ); |
fholin | 0:2325d1d28df3 | 248 | MacRx1Delay = MacRxPayload[12] ; |
fholin | 0:2325d1d28df3 | 249 | JoinedStatus = 1; |
fholin | 0:2325d1d28df3 | 250 | //@note have to manage option byte for channel frequency planned |
fholin | 0:2325d1d28df3 | 251 | } |
fholin | 0:2325d1d28df3 | 252 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 253 | /* End Of Called During LP.Process */ |
fholin | 0:2325d1d28df3 | 254 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 255 | |
fholin | 0:2325d1d28df3 | 256 | |
fholin | 0:2325d1d28df3 | 257 | |
fholin | 0:2325d1d28df3 | 258 | |
fholin | 0:2325d1d28df3 | 259 | |
fholin | 0:2325d1d28df3 | 260 | /********************************************************/ |
fholin | 0:2325d1d28df3 | 261 | /* Called During LP.Join() */ |
fholin | 0:2325d1d28df3 | 262 | /********************************************************/ |
fholin | 0:2325d1d28df3 | 263 | |
fholin | 0:2325d1d28df3 | 264 | void LoraWanContainer::BuildJoinLoraFrame( void ) { |
fholin | 0:2325d1d28df3 | 265 | DevNonce = randr( 0, 65535 ); |
fholin | 0:2325d1d28df3 | 266 | MType = JOINREQUEST ; |
fholin | 0:2325d1d28df3 | 267 | SetMacHeader ( ); |
fholin | 0:2325d1d28df3 | 268 | for (int i = 0; i <8; i++){ |
fholin | 0:2325d1d28df3 | 269 | Phy.TxPhyPayload[1+i] = AppEui[7-i]; |
fholin | 0:2325d1d28df3 | 270 | Phy.TxPhyPayload[9+i] = DevEui[7-i]; |
fholin | 0:2325d1d28df3 | 271 | } |
fholin | 0:2325d1d28df3 | 272 | Phy.TxPhyPayload[17] = ( uint8_t )( ( DevNonce & 0x00FF ) ); |
fholin | 0:2325d1d28df3 | 273 | Phy.TxPhyPayload[18] = ( uint8_t )( ( DevNonce & 0xFF00 ) >> 8 ); |
fholin | 0:2325d1d28df3 | 274 | MacPayloadSize = 19 ; |
fholin | 0:2325d1d28df3 | 275 | uint32_t mic ; |
fholin | 0:2325d1d28df3 | 276 | LoRaMacJoinComputeMic( &Phy.TxPhyPayload[0], MacPayloadSize, LoRaMacAppKey, &mic ); |
fholin | 0:2325d1d28df3 | 277 | memcpy(&Phy.TxPhyPayload[MacPayloadSize], (uint8_t *)&mic, 4); |
fholin | 0:2325d1d28df3 | 278 | MacPayloadSize = MacPayloadSize + 4; |
fholin | 0:2325d1d28df3 | 279 | } |
fholin | 0:2325d1d28df3 | 280 | |
fholin | 0:2325d1d28df3 | 281 | |
fholin | 0:2325d1d28df3 | 282 | /********************************************************/ |
fholin | 0:2325d1d28df3 | 283 | /* Called During LP.Send () */ |
fholin | 0:2325d1d28df3 | 284 | /********************************************************/ |
fholin | 0:2325d1d28df3 | 285 | |
fholin | 0:2325d1d28df3 | 286 | void LoraWanContainer::BuildTxLoraFrame( void ) { |
fholin | 0:2325d1d28df3 | 287 | Fctrl = 0; // @todo in V1.0 Adr isn't manage and ack is done by an empty packet |
fholin | 0:2325d1d28df3 | 288 | Fctrl = ( AckBitForTx << 5 ); |
fholin | 0:2325d1d28df3 | 289 | AckBitForTx = 0; |
fholin | 0:2325d1d28df3 | 290 | SetMacHeader( ); |
fholin | 0:2325d1d28df3 | 291 | SetFrameHeader( ); |
fholin | 0:2325d1d28df3 | 292 | MacPayloadSize = UserPayloadSize+FHDROFFSET; |
fholin | 0:2325d1d28df3 | 293 | }; |
fholin | 0:2325d1d28df3 | 294 | void LoraWanContainer::EncryptTxFrame( void ) { |
fholin | 0:2325d1d28df3 | 295 | LoRaMacPayloadEncrypt( &Phy.TxPhyPayload[FHDROFFSET], UserPayloadSize, appSKey, DevAddr, UP_LINK, FcntUp, &Phy.TxPhyPayload[FHDROFFSET] ); |
fholin | 0:2325d1d28df3 | 296 | LoRaMacComputeAndAddMic( &Phy.TxPhyPayload[0], MacPayloadSize, nwkSKey, DevAddr, UP_LINK, FcntUp ); |
fholin | 0:2325d1d28df3 | 297 | MacPayloadSize = MacPayloadSize + 4; |
fholin | 0:2325d1d28df3 | 298 | }; |
fholin | 0:2325d1d28df3 | 299 | |
fholin | 0:2325d1d28df3 | 300 | |
fholin | 0:2325d1d28df3 | 301 | |
fholin | 0:2325d1d28df3 | 302 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 303 | /* Private Methods */ |
fholin | 0:2325d1d28df3 | 304 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 305 | void LoraWanContainer::SetMacHeader( void ) { |
fholin | 0:2325d1d28df3 | 306 | Phy.TxPhyPayload[0] = ( ( MType & 0x7 ) <<5 ) + ( MajorBits & 0x3 ); |
fholin | 0:2325d1d28df3 | 307 | }; |
fholin | 0:2325d1d28df3 | 308 | void LoraWanContainer::SetFrameHeader( ) { |
fholin | 0:2325d1d28df3 | 309 | Phy.TxPhyPayload[1] = ( uint8_t )( ( DevAddr & 0x000000FF ) ); |
fholin | 0:2325d1d28df3 | 310 | Phy.TxPhyPayload[2] = ( uint8_t )( ( DevAddr & 0x0000FF00 ) >> 8 ); |
fholin | 0:2325d1d28df3 | 311 | Phy.TxPhyPayload[3] = ( uint8_t )( ( DevAddr & 0x00FF0000 ) >> 16 ); |
fholin | 0:2325d1d28df3 | 312 | Phy.TxPhyPayload[4] = ( uint8_t )( ( DevAddr & 0xFF000000 ) >> 24 ); |
fholin | 0:2325d1d28df3 | 313 | Phy.TxPhyPayload[5] = Fctrl; |
fholin | 0:2325d1d28df3 | 314 | Phy.TxPhyPayload[6] = ( uint8_t )( ( FcntUp & 0x00FF ) ); |
fholin | 0:2325d1d28df3 | 315 | Phy.TxPhyPayload[7] = ( uint8_t )( ( FcntUp & 0x00FF00 ) >> 8 ); |
fholin | 0:2325d1d28df3 | 316 | Phy.TxPhyPayload[8] = fPort; |
fholin | 0:2325d1d28df3 | 317 | } |
fholin | 0:2325d1d28df3 | 318 | |
fholin | 0:2325d1d28df3 | 319 | int LoraWanContainer::CheckRxPayloadLength ( void ) { |
fholin | 0:2325d1d28df3 | 320 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 321 | if ( Phy.RxPhyPayloadSize < MINLORAWANPAYLOADSIZE ) { |
fholin | 0:2325d1d28df3 | 322 | status = ERRORLORAWAN; |
fholin | 0:2325d1d28df3 | 323 | return (status); |
fholin | 0:2325d1d28df3 | 324 | } |
fholin | 0:2325d1d28df3 | 325 | return (status); |
fholin | 0:2325d1d28df3 | 326 | } |
fholin | 0:2325d1d28df3 | 327 | |
fholin | 0:2325d1d28df3 | 328 | int LoraWanContainer::ExtractRxMhdr ( void ) { |
fholin | 0:2325d1d28df3 | 329 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 330 | MtypeRx = Phy.RxPhyPayload[0] >> 5 ; |
fholin | 0:2325d1d28df3 | 331 | MajorRx = Phy.RxPhyPayload[0] & 0x3 ; |
fholin | 0:2325d1d28df3 | 332 | if (( MtypeRx == JOINREQUEST) || ( MtypeRx == UNCONFDATAUP ) || ( MtypeRx == CONFDATAUP) || ( MtypeRx == REJOINREQUEST )) { |
fholin | 0:2325d1d28df3 | 333 | status = ERRORLORAWAN; |
fholin | 0:2325d1d28df3 | 334 | } |
fholin | 0:2325d1d28df3 | 335 | AckBitForTx = ( MtypeRx == CONFDATADOWN ) ? 1 : 0 ; |
fholin | 0:2325d1d28df3 | 336 | |
fholin | 0:2325d1d28df3 | 337 | return (status); |
fholin | 0:2325d1d28df3 | 338 | } |
fholin | 0:2325d1d28df3 | 339 | |
fholin | 0:2325d1d28df3 | 340 | int LoraWanContainer::ExtractRxFhdr ( uint16_t *FcntDwnTmp ) { //@note Not yet at all finalized have to initiate action on each field |
fholin | 0:2325d1d28df3 | 341 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 342 | uint32_t DevAddrtmp = 0 ; |
fholin | 0:2325d1d28df3 | 343 | DevAddrtmp = Phy.RxPhyPayload[1] + ( Phy.RxPhyPayload[2] << 8 ) + ( Phy.RxPhyPayload[3] << 16 )+ ( Phy.RxPhyPayload[4] << 24 ); |
fholin | 0:2325d1d28df3 | 344 | status = (DevAddrtmp == DevAddr) ? OKLORAWAN : ERRORLORAWAN; |
fholin | 0:2325d1d28df3 | 345 | FctrlRx = Phy.RxPhyPayload[5] ; |
fholin | 0:2325d1d28df3 | 346 | *FcntDwnTmp = Phy.RxPhyPayload[6] + ( Phy.RxPhyPayload[7] << 8 ); |
fholin | 0:2325d1d28df3 | 347 | FoptsLength = FctrlRx & 0x7; |
fholin | 0:2325d1d28df3 | 348 | memcpy(&Fopts[0], &Phy.RxPhyPayload[8], FoptsLength); |
fholin | 0:2325d1d28df3 | 349 | FportRx = Phy.RxPhyPayload[8+FoptsLength]; |
fholin | 0:2325d1d28df3 | 350 | /**************************/ |
fholin | 0:2325d1d28df3 | 351 | /* manage Fctrl Byte */ |
fholin | 0:2325d1d28df3 | 352 | /**************************/ |
fholin | 0:2325d1d28df3 | 353 | |
fholin | 0:2325d1d28df3 | 354 | return (status); |
fholin | 0:2325d1d28df3 | 355 | } |
fholin | 0:2325d1d28df3 | 356 | int LoraWanContainer::AcceptFcntDwn ( uint16_t FcntDwnTmp ) { |
fholin | 0:2325d1d28df3 | 357 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 358 | uint16_t FcntDwnLsb = ( FcntDwn & 0x0000FFFF ); |
fholin | 0:2325d1d28df3 | 359 | uint16_t FcntDwnMsb = ( FcntDwn & 0xFFFF0000 ) >> 16; |
fholin | 0:2325d1d28df3 | 360 | #ifdef CHECKFCNTDOWN |
fholin | 0:2325d1d28df3 | 361 | if ( FcntDwnmtp > FcntDwnLsb ) { |
fholin | 0:2325d1d28df3 | 362 | FcntDwn = FcntDwnTmp ; |
fholin | 0:2325d1d28df3 | 363 | } else if ( ( FcntDwnLsb - FcntDwnmtp ) > MAX_FCNT_GAP ) ) { |
fholin | 0:2325d1d28df3 | 364 | FcntDwn = ( ( FcntDwnMsb + 1 ) << 16 ) + FcntDwnTmp ; |
fholin | 0:2325d1d28df3 | 365 | } else { |
fholin | 0:2325d1d28df3 | 366 | status = ERRORLORAWAN ; |
fholin | 0:2325d1d28df3 | 367 | } |
fholin | 0:2325d1d28df3 | 368 | |
fholin | 0:2325d1d28df3 | 369 | #else |
fholin | 0:2325d1d28df3 | 370 | if ( ( FcntDwnLsb - FcntDwnTmp ) > MAX_FCNT_GAP ) { |
fholin | 0:2325d1d28df3 | 371 | FcntDwn = ( ( FcntDwnMsb + 1 ) << 16 ) + FcntDwnTmp ; |
fholin | 0:2325d1d28df3 | 372 | } else { |
fholin | 0:2325d1d28df3 | 373 | FcntDwn = FcntDwnTmp ; |
fholin | 0:2325d1d28df3 | 374 | } |
fholin | 0:2325d1d28df3 | 375 | #endif |
fholin | 0:2325d1d28df3 | 376 | return ( status ) ; |
fholin | 0:2325d1d28df3 | 377 | } |
fholin | 0:2325d1d28df3 | 378 | |
fholin | 0:2325d1d28df3 | 379 | void LoraWanContainer::GiveNextSf( void ) { |
fholin | 0:2325d1d28df3 | 380 | switch ( AdrModeSelect ) { |
fholin | 0:2325d1d28df3 | 381 | case STATICADRMODE : |
fholin | 0:2325d1d28df3 | 382 | MacTxSf = 7; |
fholin | 0:2325d1d28df3 | 383 | break; |
fholin | 0:2325d1d28df3 | 384 | case MOBILELONGRANGEADRMODE: |
fholin | 0:2325d1d28df3 | 385 | if ( MacTxSf == 12 ) { |
fholin | 0:2325d1d28df3 | 386 | MacTxSf = 7; |
fholin | 0:2325d1d28df3 | 387 | } else { |
fholin | 0:2325d1d28df3 | 388 | MacTxSf = 12; |
fholin | 0:2325d1d28df3 | 389 | } |
fholin | 0:2325d1d28df3 | 390 | break; |
fholin | 0:2325d1d28df3 | 391 | case MOBILELOWPOWERADRMODE: |
fholin | 0:2325d1d28df3 | 392 | ( MacTxSf == 12 ) ? MacTxSf = 7 : MacTxSf++ ; |
fholin | 0:2325d1d28df3 | 393 | break; |
fholin | 0:2325d1d28df3 | 394 | default: |
fholin | 0:2325d1d28df3 | 395 | MacTxSf = 12; |
fholin | 0:2325d1d28df3 | 396 | } |
fholin | 0:2325d1d28df3 | 397 | MacTxSf = ( MacTxSf > 12 ) ? 12 : MacTxSf; |
fholin | 0:2325d1d28df3 | 398 | MacTxSf = ( MacTxSf < 7 ) ? 7 : MacTxSf; |
fholin | 0:2325d1d28df3 | 399 | } |
fholin | 0:2325d1d28df3 | 400 | uint8_t LoraWanContainer::GiveNextChannel( void ) { |
fholin | 0:2325d1d28df3 | 401 | return ( randr( 0, NbOfActiveChannel - 1 ) ); |
fholin | 0:2325d1d28df3 | 402 | |
fholin | 0:2325d1d28df3 | 403 | }; |
fholin | 0:2325d1d28df3 | 404 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 405 | /* Private NWK MANAGEMENTS Methods */ |
fholin | 0:2325d1d28df3 | 406 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 407 | |
fholin | 0:2325d1d28df3 | 408 | void LoraWanContainer::LinkCheckParser( void ) { |
fholin | 0:2325d1d28df3 | 409 | |
fholin | 0:2325d1d28df3 | 410 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 411 | } |
fholin | 0:2325d1d28df3 | 412 | /*****************************************************/ |
fholin | 0:2325d1d28df3 | 413 | /* Private NWK MANAGEMENTS : LinkADR */ |
fholin | 0:2325d1d28df3 | 414 | /*****************************************************/ |
fholin | 0:2325d1d28df3 | 415 | void LoraWanContainer::LinkADRParser( void ) { |
fholin | 0:2325d1d28df3 | 416 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 417 | uint8_t StatusAns = 0x7 ; // initilised for ans answer ok |
fholin | 0:2325d1d28df3 | 418 | uint8_t temp ; |
fholin | 0:2325d1d28df3 | 419 | uint16_t temp2 ; |
fholin | 0:2325d1d28df3 | 420 | /* Valid DataRate And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 421 | temp = ( ( MacRxPayload[1] & 0xF0 ) >> 4 ); |
fholin | 0:2325d1d28df3 | 422 | status = isValidDataRate( temp ); |
fholin | 0:2325d1d28df3 | 423 | (status == OKLORAWAN ) ? MacTxPower = temp : StatusAns &= 0x5 ; |
fholin | 0:2325d1d28df3 | 424 | |
fholin | 0:2325d1d28df3 | 425 | /* Valid TxPower And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 426 | temp = ( MacRxPayload[1] & 0x0F ); |
fholin | 0:2325d1d28df3 | 427 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 428 | status = isValidTxPower( temp ); |
fholin | 0:2325d1d28df3 | 429 | (status == OKLORAWAN ) ? MacTxPower = temp : StatusAns &= 0x5 ; |
fholin | 0:2325d1d28df3 | 430 | |
fholin | 0:2325d1d28df3 | 431 | /* Valid DataRate Channel Mask And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 432 | temp2 = MacRxPayload[2] + ( MacRxPayload[3] << 8 ) ; |
fholin | 0:2325d1d28df3 | 433 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 434 | status = isValidChannelMask( temp2 ); |
fholin | 0:2325d1d28df3 | 435 | (status == OKLORAWAN ) ? MacChMask = temp2 : StatusAns &= 0x6 ; |
fholin | 0:2325d1d28df3 | 436 | |
fholin | 0:2325d1d28df3 | 437 | /* Valid Redundancy And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 438 | temp = MacRxPayload[4]; |
fholin | 0:2325d1d28df3 | 439 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 440 | status = isValidNbRep( temp ); |
fholin | 0:2325d1d28df3 | 441 | (status == OKLORAWAN ) ? MacNbRepUnconfirmedTx = temp : StatusAns &= 0x3 ; |
fholin | 0:2325d1d28df3 | 442 | |
fholin | 0:2325d1d28df3 | 443 | /* Prepare Ans*/ |
fholin | 0:2325d1d28df3 | 444 | MacNwkAns [0] = MacRxPayload[0] ; // copy Cid |
fholin | 0:2325d1d28df3 | 445 | MacNwkAns [1] = StatusAns ; |
fholin | 0:2325d1d28df3 | 446 | MacNwkAnsSize = 2 ; |
fholin | 0:2325d1d28df3 | 447 | IsFrameToSend = NWKFRAME_TOSEND ; |
fholin | 0:2325d1d28df3 | 448 | } |
fholin | 0:2325d1d28df3 | 449 | |
fholin | 0:2325d1d28df3 | 450 | void LoraWanContainer::DutyCycleParser( void ) { |
fholin | 0:2325d1d28df3 | 451 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 452 | } |
fholin | 0:2325d1d28df3 | 453 | /*****************************************************/ |
fholin | 0:2325d1d28df3 | 454 | /* Private NWK MANAGEMENTS : RXParamSetupParser */ |
fholin | 0:2325d1d28df3 | 455 | /*****************************************************/ |
fholin | 0:2325d1d28df3 | 456 | void LoraWanContainer::RXParamSetupParser( void ) { |
fholin | 0:2325d1d28df3 | 457 | //@note not valid case or error case have been yet implemented |
fholin | 0:2325d1d28df3 | 458 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 459 | uint8_t StatusAns = 0x7 ; // initilised for ans answer ok |
fholin | 0:2325d1d28df3 | 460 | int temp ; |
fholin | 0:2325d1d28df3 | 461 | /* Valid Rx1SfOffset And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 462 | temp = ( MacRxPayload[1] & 0x70 ) >> 3 ; |
fholin | 0:2325d1d28df3 | 463 | status = isValidRx1SfOffset( temp ); |
fholin | 0:2325d1d28df3 | 464 | (status == OKLORAWAN ) ? MacRx1SfOffset = temp : StatusAns &= 0x6 ; |
fholin | 0:2325d1d28df3 | 465 | |
fholin | 0:2325d1d28df3 | 466 | /* Valid MacRx2Sf And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 467 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 468 | temp = ( MacRxPayload[1] & 0x0F ); |
fholin | 0:2325d1d28df3 | 469 | status = isValidMacRx2Sf( temp ); |
fholin | 0:2325d1d28df3 | 470 | (status == OKLORAWAN ) ? MacRx2Sf = temp : StatusAns &= 0x5 ; |
fholin | 0:2325d1d28df3 | 471 | |
fholin | 0:2325d1d28df3 | 472 | /* Valid MacRx2Frequency And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 473 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 474 | temp = ( MacRxPayload[2] ) + ( MacRxPayload[3] << 8 ) + ( MacRxPayload[4] << 16 ); |
fholin | 0:2325d1d28df3 | 475 | status = isValidMacRx2Frequency( temp ); |
fholin | 0:2325d1d28df3 | 476 | (status == OKLORAWAN ) ? MacRx2Frequency = temp : StatusAns &= 0x3 ; |
fholin | 0:2325d1d28df3 | 477 | |
fholin | 0:2325d1d28df3 | 478 | /* Prepare Ans*/ |
fholin | 0:2325d1d28df3 | 479 | MacNwkAns [0] = MacRxPayload[0] ; // copy Cid |
fholin | 0:2325d1d28df3 | 480 | MacNwkAns [1] = StatusAns ; |
fholin | 0:2325d1d28df3 | 481 | MacNwkAnsSize = 2 ; |
fholin | 0:2325d1d28df3 | 482 | IsFrameToSend = NWKFRAME_TOSEND ; |
fholin | 0:2325d1d28df3 | 483 | } |
fholin | 0:2325d1d28df3 | 484 | |
fholin | 0:2325d1d28df3 | 485 | void LoraWanContainer::DevStatusParser( void ) { |
fholin | 0:2325d1d28df3 | 486 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 487 | } |
fholin | 0:2325d1d28df3 | 488 | void LoraWanContainer::NewChannelParser( void ) { |
fholin | 0:2325d1d28df3 | 489 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 490 | } |
fholin | 0:2325d1d28df3 | 491 | void LoraWanContainer::RXTimingSetupParser( void ) { |
fholin | 0:2325d1d28df3 | 492 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 493 | } |
fholin | 0:2325d1d28df3 | 494 | |
fholin | 0:2325d1d28df3 | 495 | |
fholin | 0:2325d1d28df3 | 496 | |
fholin | 0:2325d1d28df3 | 497 | |
fholin | 0:2325d1d28df3 | 498 | uint8_t LoraWanContainer::isValidRx1SfOffset ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 499 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 500 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 501 | } |
fholin | 0:2325d1d28df3 | 502 | uint8_t LoraWanContainer::isValidMacRx2Sf ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 503 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 504 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 505 | } |
fholin | 0:2325d1d28df3 | 506 | uint8_t LoraWanContainer::isValidMacRx2Frequency ( uint32_t temp ) { |
fholin | 0:2325d1d28df3 | 507 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 508 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 509 | } |
fholin | 0:2325d1d28df3 | 510 | uint8_t LoraWanContainer::isValidDataRate ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 511 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 512 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 513 | } |
fholin | 0:2325d1d28df3 | 514 | uint8_t LoraWanContainer::isValidTxPower ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 515 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 516 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 517 | } |
fholin | 0:2325d1d28df3 | 518 | |
fholin | 0:2325d1d28df3 | 519 | uint8_t LoraWanContainer::isValidChannelMask ( uint16_t temp ) { |
fholin | 0:2325d1d28df3 | 520 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 521 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 522 | } |
fholin | 0:2325d1d28df3 | 523 | uint8_t LoraWanContainer::isValidNbRep ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 524 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 525 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 526 | } |
fholin | 0:2325d1d28df3 | 527 | void LoraWanContainer::SaveInFlash ( ) { |
fholin | 0:2325d1d28df3 | 528 | BackUpFlash.MacTxSf = MacTxSf; |
fholin | 0:2325d1d28df3 | 529 | BackUpFlash.MacTxPower = MacTxPower; |
fholin | 0:2325d1d28df3 | 530 | BackUpFlash.MacChMask = MacChMask; |
fholin | 0:2325d1d28df3 | 531 | BackUpFlash.MacNbRepUnconfirmedTx = MacNbRepUnconfirmedTx; |
fholin | 0:2325d1d28df3 | 532 | BackUpFlash.MacRx2Frequency = MacRx2Frequency; |
fholin | 0:2325d1d28df3 | 533 | BackUpFlash.MacRx2Sf = MacRx2Sf; |
fholin | 0:2325d1d28df3 | 534 | BackUpFlash.MacRx1SfOffset = MacRx1SfOffset; |
fholin | 0:2325d1d28df3 | 535 | BackUpFlash.NbOfActiveChannel = NbOfActiveChannel; |
fholin | 0:2325d1d28df3 | 536 | BackUpFlash.MacRx1Delay = MacRx1Delay; |
fholin | 0:2325d1d28df3 | 537 | BackUpFlash.FcntUp = FcntUp; |
fholin | 0:2325d1d28df3 | 538 | BackUpFlash.FcntDwn = FcntDwn; |
fholin | 0:2325d1d28df3 | 539 | BackUpFlash.DevAddr = DevAddr; |
fholin | 0:2325d1d28df3 | 540 | BackUpFlash.JoinedStatus = JoinedStatus; |
fholin | 0:2325d1d28df3 | 541 | memcpy( &BackUpFlash.MacTxFrequency[0], &MacTxFrequency[0], 16); |
fholin | 0:2325d1d28df3 | 542 | memcpy( &BackUpFlash.MacMinMaxSFChannel[0], &MacMinMaxSFChannel[0], 16); |
fholin | 0:2325d1d28df3 | 543 | memcpy( &BackUpFlash.nwkSKey[0], &nwkSKey[0], 16); |
fholin | 0:2325d1d28df3 | 544 | memcpy( &BackUpFlash.appSKey[0], &appSKey[0], 16); |
fholin | 1:eda561b01daf | 545 | gFlash.StoreContext( &BackUpFlash, USERFLASHADRESS, sizeof(sBackUpFlash) ); |
fholin | 0:2325d1d28df3 | 546 | } |
fholin | 0:2325d1d28df3 | 547 | |
fholin | 0:2325d1d28df3 | 548 | |
fholin | 0:2325d1d28df3 | 549 | void LoraWanContainer::LoadFromFlash ( ) { |
fholin | 1:eda561b01daf | 550 | gFlash.RestoreContext((uint8_t *)(&BackUpFlash), USERFLASHADRESS, sizeof(sBackUpFlash)); |
fholin | 0:2325d1d28df3 | 551 | BackUpFlash.FcntUp += FLASH_UPDATE_PERIOD; //@note automatic increment |
fholin | 0:2325d1d28df3 | 552 | MacTxSf = BackUpFlash.MacTxSf; |
fholin | 0:2325d1d28df3 | 553 | MacTxPower = BackUpFlash.MacTxPower; |
fholin | 0:2325d1d28df3 | 554 | MacChMask = BackUpFlash.MacChMask ; |
fholin | 0:2325d1d28df3 | 555 | MacNbRepUnconfirmedTx = BackUpFlash.MacNbRepUnconfirmedTx ; |
fholin | 0:2325d1d28df3 | 556 | MacRx2Frequency = BackUpFlash.MacRx2Frequency ; |
fholin | 0:2325d1d28df3 | 557 | MacRx2Sf = BackUpFlash.MacRx2Sf ; |
fholin | 0:2325d1d28df3 | 558 | MacRx1SfOffset = BackUpFlash.MacRx1SfOffset; |
fholin | 0:2325d1d28df3 | 559 | NbOfActiveChannel = BackUpFlash.NbOfActiveChannel; |
fholin | 0:2325d1d28df3 | 560 | MacRx1Delay = BackUpFlash.MacRx1Delay ; |
fholin | 0:2325d1d28df3 | 561 | FcntUp = BackUpFlash.FcntUp ; |
fholin | 0:2325d1d28df3 | 562 | FcntDwn = BackUpFlash.FcntDwn ; |
fholin | 0:2325d1d28df3 | 563 | DevAddr = BackUpFlash.DevAddr; |
fholin | 0:2325d1d28df3 | 564 | JoinedStatus = BackUpFlash.JoinedStatus; |
fholin | 0:2325d1d28df3 | 565 | memcpy( &MacTxFrequency[0], &BackUpFlash.MacTxFrequency[0], 16); |
fholin | 0:2325d1d28df3 | 566 | memcpy( &MacMinMaxSFChannel[0], &BackUpFlash.MacMinMaxSFChannel[0], 16); |
fholin | 0:2325d1d28df3 | 567 | memcpy( &nwkSKey[0], &BackUpFlash.nwkSKey[0], 16); |
fholin | 0:2325d1d28df3 | 568 | memcpy( &appSKey[0], &BackUpFlash.appSKey[0], 16); |
fholin | 1:eda561b01daf | 569 | gFlash.StoreContext( &BackUpFlash, USERFLASHADRESS, sizeof(sBackUpFlash) ); |
fholin | 0:2325d1d28df3 | 570 | } |
fholin | 0:2325d1d28df3 | 571 | /**************************************TIMER PART**********************************************************/ |
fholin | 0:2325d1d28df3 | 572 | /**********************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 573 | /*@Note Probably to create a new directory or may be an timer Object to be discuss */ |
fholin | 0:2325d1d28df3 | 574 | |
fholin | 0:2325d1d28df3 | 575 | |
fholin | 0:2325d1d28df3 | 576 | /************************************************************************************/ |
fholin | 0:2325d1d28df3 | 577 | /* Rx1 Timer Isr Routine */ |
fholin | 0:2325d1d28df3 | 578 | /* Called when Alarm expires */ |
fholin | 0:2325d1d28df3 | 579 | /************************************************************************************/ |
fholin | 0:2325d1d28df3 | 580 | void LoraWanContainer::SetAlarm (uint32_t alarmInMs) { |
fholin | 0:2325d1d28df3 | 581 | TimerLora.attach_us(this, &LoraWanContainer::IsrTimerRx, alarmInMs * 1000); |
fholin | 0:2325d1d28df3 | 582 | } |
fholin | 0:2325d1d28df3 | 583 | |
fholin | 0:2325d1d28df3 | 584 | void LoraWanContainer::IsrTimerRx( void ) { |
fholin | 0:2325d1d28df3 | 585 | StateTimer = TIMERSTATE_SLEEP; |
fholin | 0:2325d1d28df3 | 586 | Phy.Radio.Rx(0); //@note No More timeout FW on RX use only timeout impplement in the HW radio |
fholin | 0:2325d1d28df3 | 587 | }; |
fholin | 0:2325d1d28df3 | 588 | |
fholin | 0:2325d1d28df3 | 589 | |
fholin | 0:2325d1d28df3 | 590 | /****************************************API Crypto ***********************/ |
fholin | 0:2325d1d28df3 | 591 | uint8_t LoraWanContainer::crypto_verifyMICandDecrypt( uint8_t *frame_header, const uint8_t *encrypted_payload ,uint32_t micIn, uint8_t keySet, uint8_t *decrypted_payload, uint8_t PayloadSize){ |
fholin | 0:2325d1d28df3 | 592 | uint32_t DevAddrtmp = 0; |
fholin | 0:2325d1d28df3 | 593 | uint16_t FcntDwnmtp = 0; |
fholin | 0:2325d1d28df3 | 594 | int status = OKLORAWAN ; |
fholin | 0:2325d1d28df3 | 595 | if ( keySet == UNICASTKEY) { |
fholin | 0:2325d1d28df3 | 596 | DevAddrtmp = frame_header[1] + ( frame_header[2] << 8 ) + ( frame_header[3] << 16 )+ ( frame_header[4] << 24 ); |
fholin | 0:2325d1d28df3 | 597 | FcntDwnmtp = frame_header[6] + ( frame_header[7] << 8 ); |
fholin | 0:2325d1d28df3 | 598 | status += LoRaMacCheckMic(frame_header, PayloadSize, nwkSKey, DevAddrtmp, FcntDwnmtp, micIn ); |
fholin | 0:2325d1d28df3 | 599 | |
fholin | 0:2325d1d28df3 | 600 | //@note note sure that it is better to sen dheader because extract again devaddr fcntdwn fopts etc .... |
fholin | 0:2325d1d28df3 | 601 | |
fholin | 0:2325d1d28df3 | 602 | PayloadSize = PayloadSize - FHDROFFSET - FoptsLength ; |
fholin | 0:2325d1d28df3 | 603 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 604 | LoRaMacPayloadDecrypt( &Phy.RxPhyPayload[FHDROFFSET + FoptsLength], MacRxPayloadSize, (FportRx == 0 )?nwkSKey:appSKey, DevAddr, 1, FcntDwn, &MacRxPayload[0] ); |
fholin | 0:2325d1d28df3 | 605 | } |
fholin | 0:2325d1d28df3 | 606 | } |
fholin | 0:2325d1d28df3 | 607 | } |