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@0:2325d1d28df3, 2017-12-15 (annotated)
- Committer:
- fholin
- Date:
- Fri Dec 15 13:15:04 2017 +0000
- Revision:
- 0:2325d1d28df3
- Child:
- 1:eda561b01daf
Initial commit
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 | 0:2325d1d28df3 | 111 | int LoraWanContainer::DecodeRxFrame( void ) { |
fholin | 0:2325d1d28df3 | 112 | int status = OKLORAWAN ; |
fholin | 0:2325d1d28df3 | 113 | uint32_t micIn ; |
fholin | 0:2325d1d28df3 | 114 | status += CheckRxPayloadLength ( ); |
fholin | 0:2325d1d28df3 | 115 | status += ExtractRxMhdr ( ) ; |
fholin | 0:2325d1d28df3 | 116 | |
fholin | 0:2325d1d28df3 | 117 | /************************************************************************/ |
fholin | 0:2325d1d28df3 | 118 | /* Case : the receive packet is a JoinResponse */ |
fholin | 0:2325d1d28df3 | 119 | /************************************************************************/ |
fholin | 0:2325d1d28df3 | 120 | if ( MtypeRx == JOINACCEPT ) { |
fholin | 0:2325d1d28df3 | 121 | |
fholin | 0:2325d1d28df3 | 122 | LoRaMacJoinDecrypt( &Phy.RxPhyPayload[1], Phy.RxPhyPayloadSize-1, LoRaMacAppKey, &MacRxPayload[1] ); |
fholin | 0:2325d1d28df3 | 123 | MacRxPayload[0] = Phy.RxPhyPayload[0]; |
fholin | 0:2325d1d28df3 | 124 | MacRxPayloadSize = Phy.RxPhyPayloadSize - MICSIZE ; |
fholin | 0:2325d1d28df3 | 125 | memcpy((uint8_t *)&micIn, &MacRxPayload[MacRxPayloadSize], MICSIZE); |
fholin | 0:2325d1d28df3 | 126 | status += LoRaMacCheckJoinMic( MacRxPayload, MacRxPayloadSize, LoRaMacAppKey, micIn); |
fholin | 0:2325d1d28df3 | 127 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 128 | return JOINACCEPTPACKET; |
fholin | 0:2325d1d28df3 | 129 | } |
fholin | 0:2325d1d28df3 | 130 | } else { |
fholin | 0:2325d1d28df3 | 131 | /************************************************************************/ |
fholin | 0:2325d1d28df3 | 132 | /* Case : the receive packet is not a JoinResponse */ |
fholin | 0:2325d1d28df3 | 133 | /************************************************************************/ |
fholin | 0:2325d1d28df3 | 134 | uint16_t FcntDownTmp = 0; |
fholin | 0:2325d1d28df3 | 135 | status += ExtractRxFhdr ( &FcntDownTmp) ; |
fholin | 0:2325d1d28df3 | 136 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 137 | MacRxPayloadSize = Phy.RxPhyPayloadSize - MICSIZE ; |
fholin | 0:2325d1d28df3 | 138 | memcpy((uint8_t *)&micIn, &Phy.RxPhyPayload[MacRxPayloadSize], MICSIZE); |
fholin | 0:2325d1d28df3 | 139 | status += LoRaMacCheckMic(&Phy.RxPhyPayload[0], MacRxPayloadSize, nwkSKey, DevAddr, FcntDownTmp, micIn ); // @note api discussion see at the end of this file |
fholin | 0:2325d1d28df3 | 140 | } |
fholin | 0:2325d1d28df3 | 141 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 142 | status = AcceptFcntDwn ( FcntDownTmp ) ; |
fholin | 0:2325d1d28df3 | 143 | } |
fholin | 0:2325d1d28df3 | 144 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 145 | MacRxPayloadSize = MacRxPayloadSize - FHDROFFSET - FoptsLength ; |
fholin | 0:2325d1d28df3 | 146 | LoRaMacPayloadDecrypt( &Phy.RxPhyPayload[FHDROFFSET + FoptsLength], MacRxPayloadSize, (FportRx == 0 )?nwkSKey:appSKey, DevAddr, 1, FcntDwn, &MacRxPayload[0] ); |
fholin | 0:2325d1d28df3 | 147 | pcf.printf( " MtypeRx = %d \n ",MtypeRx ); |
fholin | 0:2325d1d28df3 | 148 | pcf.printf( " FcntDwn = %d \n ",FcntDwn ); |
fholin | 0:2325d1d28df3 | 149 | } |
fholin | 0:2325d1d28df3 | 150 | } |
fholin | 0:2325d1d28df3 | 151 | if (status != OKLORAWAN ) { |
fholin | 0:2325d1d28df3 | 152 | return ( NOVALIDRXPACKET ); |
fholin | 0:2325d1d28df3 | 153 | } |
fholin | 0:2325d1d28df3 | 154 | else if ( FportRx == 0 ) { |
fholin | 0:2325d1d28df3 | 155 | return ( NWKRXPACKET ) ; |
fholin | 0:2325d1d28df3 | 156 | } else { |
fholin | 0:2325d1d28df3 | 157 | AvailableRxPacketForUser = LORARXPACKETAVAILABLE; //@note in this case fopts should be not equal to zero and so there are also management frame available + user data |
fholin | 0:2325d1d28df3 | 158 | return ( USERRXPACKET ) ; |
fholin | 0:2325d1d28df3 | 159 | } |
fholin | 0:2325d1d28df3 | 160 | } |
fholin | 0:2325d1d28df3 | 161 | /*********************************/ |
fholin | 0:2325d1d28df3 | 162 | /* End of Decode Frame */ |
fholin | 0:2325d1d28df3 | 163 | /*********************************/ |
fholin | 0:2325d1d28df3 | 164 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 165 | /* NWK MANAGEMENTS Methods */ |
fholin | 0:2325d1d28df3 | 166 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 167 | void LoraWanContainer::ParseManagementPacket( void ) { |
fholin | 0:2325d1d28df3 | 168 | uint8_t CmdIdentifier; |
fholin | 0:2325d1d28df3 | 169 | CmdIdentifier = MacRxPayload[0]; |
fholin | 0:2325d1d28df3 | 170 | switch ( CmdIdentifier ) { |
fholin | 0:2325d1d28df3 | 171 | case LINK_CHECK_ANS : |
fholin | 0:2325d1d28df3 | 172 | LinkCheckParser( ); |
fholin | 0:2325d1d28df3 | 173 | break; |
fholin | 0:2325d1d28df3 | 174 | case LINK_ADR_REQ : |
fholin | 0:2325d1d28df3 | 175 | LinkADRParser( ); |
fholin | 0:2325d1d28df3 | 176 | break; |
fholin | 0:2325d1d28df3 | 177 | case DUTY_CYCLE_REQ : |
fholin | 0:2325d1d28df3 | 178 | DutyCycleParser( ); |
fholin | 0:2325d1d28df3 | 179 | break; |
fholin | 0:2325d1d28df3 | 180 | case RXPARRAM_SETUP_REQ : |
fholin | 0:2325d1d28df3 | 181 | RXParamSetupParser( ); |
fholin | 0:2325d1d28df3 | 182 | break; |
fholin | 0:2325d1d28df3 | 183 | case DEV_STATUS_REQ : |
fholin | 0:2325d1d28df3 | 184 | DevStatusParser( ); |
fholin | 0:2325d1d28df3 | 185 | break; |
fholin | 0:2325d1d28df3 | 186 | case NEW_CHANNEL_REQ : |
fholin | 0:2325d1d28df3 | 187 | NewChannelParser( ); |
fholin | 0:2325d1d28df3 | 188 | break; |
fholin | 0:2325d1d28df3 | 189 | case RXTIMING_SETUP_REQ : |
fholin | 0:2325d1d28df3 | 190 | RXTimingSetupParser( ); |
fholin | 0:2325d1d28df3 | 191 | break; |
fholin | 0:2325d1d28df3 | 192 | } |
fholin | 0:2325d1d28df3 | 193 | |
fholin | 0:2325d1d28df3 | 194 | } |
fholin | 0:2325d1d28df3 | 195 | |
fholin | 0:2325d1d28df3 | 196 | void LoraWanContainer::UpdateMacLayer ( void ) { |
fholin | 0:2325d1d28df3 | 197 | FcntUp++; //@note case Retry not yet manage |
fholin | 0:2325d1d28df3 | 198 | /*Store Context In ROM */ |
fholin | 0:2325d1d28df3 | 199 | if (( FcntUp % FLASH_UPDATE_PERIOD ) == 0 ){ |
fholin | 0:2325d1d28df3 | 200 | SaveInFlash ( ); |
fholin | 0:2325d1d28df3 | 201 | } |
fholin | 0:2325d1d28df3 | 202 | |
fholin | 0:2325d1d28df3 | 203 | switch ( IsFrameToSend ) { |
fholin | 0:2325d1d28df3 | 204 | case NOFRAME_TOSEND : |
fholin | 0:2325d1d28df3 | 205 | |
fholin | 0:2325d1d28df3 | 206 | break; |
fholin | 0:2325d1d28df3 | 207 | case NWKFRAME_TOSEND : |
fholin | 0:2325d1d28df3 | 208 | memcpy( &Phy.TxPhyPayload[FHDROFFSET], MacNwkAns, MacNwkAnsSize ); |
fholin | 0:2325d1d28df3 | 209 | UserPayloadSize = MacNwkAnsSize; |
fholin | 0:2325d1d28df3 | 210 | fPort = PORTNWK; |
fholin | 0:2325d1d28df3 | 211 | MType = UNCONFDATAUP; //@note Mtype have to be confirm |
fholin | 0:2325d1d28df3 | 212 | BuildTxLoraFrame( ); |
fholin | 0:2325d1d28df3 | 213 | EncryptTxFrame( ); |
fholin | 0:2325d1d28df3 | 214 | |
fholin | 0:2325d1d28df3 | 215 | break; |
fholin | 0:2325d1d28df3 | 216 | case USERACK_TOSEND : |
fholin | 0:2325d1d28df3 | 217 | |
fholin | 0:2325d1d28df3 | 218 | break; |
fholin | 0:2325d1d28df3 | 219 | } |
fholin | 0:2325d1d28df3 | 220 | } |
fholin | 0:2325d1d28df3 | 221 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 222 | /* Special Case Join OTA */ |
fholin | 0:2325d1d28df3 | 223 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 224 | void LoraWanContainer::UpdateJoinProcedure ( void ) { |
fholin | 0:2325d1d28df3 | 225 | pcf.printf( " receive a Join Response \n"); |
fholin | 0:2325d1d28df3 | 226 | uint8_t AppNonce[3]; |
fholin | 0:2325d1d28df3 | 227 | memcpy( AppNonce, &MacRxPayload[1], 6); |
fholin | 0:2325d1d28df3 | 228 | LoRaMacJoinComputeSKeys(LoRaMacAppKey, AppNonce, DevNonce, nwkSKey, appSKey ); |
fholin | 0:2325d1d28df3 | 229 | DevAddr = MacRxPayload[7] + ( MacRxPayload[8] << 8 ) + ( MacRxPayload[9] << 16 )+ ( MacRxPayload[10] << 24 ); |
fholin | 0:2325d1d28df3 | 230 | Phy.DevAddrIsr = DevAddr ; |
fholin | 0:2325d1d28df3 | 231 | MacRx1SfOffset = ( MacRxPayload[11] & 0x70 ) >> 3 ; |
fholin | 0:2325d1d28df3 | 232 | MacRx2Sf = ( MacRxPayload[11] & 0x0F ); |
fholin | 0:2325d1d28df3 | 233 | MacRx1Delay = MacRxPayload[12] ; |
fholin | 0:2325d1d28df3 | 234 | JoinedStatus = 1; |
fholin | 0:2325d1d28df3 | 235 | //@note have to manage option byte for channel frequency planned |
fholin | 0:2325d1d28df3 | 236 | } |
fholin | 0:2325d1d28df3 | 237 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 238 | /* End Of Called During LP.Process */ |
fholin | 0:2325d1d28df3 | 239 | /**********************************************************************/ |
fholin | 0:2325d1d28df3 | 240 | |
fholin | 0:2325d1d28df3 | 241 | |
fholin | 0:2325d1d28df3 | 242 | |
fholin | 0:2325d1d28df3 | 243 | |
fholin | 0:2325d1d28df3 | 244 | |
fholin | 0:2325d1d28df3 | 245 | /********************************************************/ |
fholin | 0:2325d1d28df3 | 246 | /* Called During LP.Join() */ |
fholin | 0:2325d1d28df3 | 247 | /********************************************************/ |
fholin | 0:2325d1d28df3 | 248 | |
fholin | 0:2325d1d28df3 | 249 | void LoraWanContainer::BuildJoinLoraFrame( void ) { |
fholin | 0:2325d1d28df3 | 250 | DevNonce = randr( 0, 65535 ); |
fholin | 0:2325d1d28df3 | 251 | MType = JOINREQUEST ; |
fholin | 0:2325d1d28df3 | 252 | SetMacHeader ( ); |
fholin | 0:2325d1d28df3 | 253 | for (int i = 0; i <8; i++){ |
fholin | 0:2325d1d28df3 | 254 | Phy.TxPhyPayload[1+i] = AppEui[7-i]; |
fholin | 0:2325d1d28df3 | 255 | Phy.TxPhyPayload[9+i] = DevEui[7-i]; |
fholin | 0:2325d1d28df3 | 256 | } |
fholin | 0:2325d1d28df3 | 257 | Phy.TxPhyPayload[17] = ( uint8_t )( ( DevNonce & 0x00FF ) ); |
fholin | 0:2325d1d28df3 | 258 | Phy.TxPhyPayload[18] = ( uint8_t )( ( DevNonce & 0xFF00 ) >> 8 ); |
fholin | 0:2325d1d28df3 | 259 | MacPayloadSize = 19 ; |
fholin | 0:2325d1d28df3 | 260 | uint32_t mic ; |
fholin | 0:2325d1d28df3 | 261 | LoRaMacJoinComputeMic( &Phy.TxPhyPayload[0], MacPayloadSize, LoRaMacAppKey, &mic ); |
fholin | 0:2325d1d28df3 | 262 | memcpy(&Phy.TxPhyPayload[MacPayloadSize], (uint8_t *)&mic, 4); |
fholin | 0:2325d1d28df3 | 263 | MacPayloadSize = MacPayloadSize + 4; |
fholin | 0:2325d1d28df3 | 264 | } |
fholin | 0:2325d1d28df3 | 265 | |
fholin | 0:2325d1d28df3 | 266 | |
fholin | 0:2325d1d28df3 | 267 | /********************************************************/ |
fholin | 0:2325d1d28df3 | 268 | /* Called During LP.Send () */ |
fholin | 0:2325d1d28df3 | 269 | /********************************************************/ |
fholin | 0:2325d1d28df3 | 270 | |
fholin | 0:2325d1d28df3 | 271 | void LoraWanContainer::BuildTxLoraFrame( void ) { |
fholin | 0:2325d1d28df3 | 272 | Fctrl = 0; // @todo in V1.0 Adr isn't manage and ack is done by an empty packet |
fholin | 0:2325d1d28df3 | 273 | Fctrl = ( AckBitForTx << 5 ); |
fholin | 0:2325d1d28df3 | 274 | AckBitForTx = 0; |
fholin | 0:2325d1d28df3 | 275 | SetMacHeader( ); |
fholin | 0:2325d1d28df3 | 276 | SetFrameHeader( ); |
fholin | 0:2325d1d28df3 | 277 | MacPayloadSize = UserPayloadSize+FHDROFFSET; |
fholin | 0:2325d1d28df3 | 278 | }; |
fholin | 0:2325d1d28df3 | 279 | void LoraWanContainer::EncryptTxFrame( void ) { |
fholin | 0:2325d1d28df3 | 280 | LoRaMacPayloadEncrypt( &Phy.TxPhyPayload[FHDROFFSET], UserPayloadSize, appSKey, DevAddr, UP_LINK, FcntUp, &Phy.TxPhyPayload[FHDROFFSET] ); |
fholin | 0:2325d1d28df3 | 281 | LoRaMacComputeAndAddMic( &Phy.TxPhyPayload[0], MacPayloadSize, nwkSKey, DevAddr, UP_LINK, FcntUp ); |
fholin | 0:2325d1d28df3 | 282 | MacPayloadSize = MacPayloadSize + 4; |
fholin | 0:2325d1d28df3 | 283 | }; |
fholin | 0:2325d1d28df3 | 284 | |
fholin | 0:2325d1d28df3 | 285 | |
fholin | 0:2325d1d28df3 | 286 | |
fholin | 0:2325d1d28df3 | 287 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 288 | /* Private Methods */ |
fholin | 0:2325d1d28df3 | 289 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 290 | void LoraWanContainer::SetMacHeader( void ) { |
fholin | 0:2325d1d28df3 | 291 | Phy.TxPhyPayload[0] = ( ( MType & 0x7 ) <<5 ) + ( MajorBits & 0x3 ); |
fholin | 0:2325d1d28df3 | 292 | }; |
fholin | 0:2325d1d28df3 | 293 | void LoraWanContainer::SetFrameHeader( ) { |
fholin | 0:2325d1d28df3 | 294 | Phy.TxPhyPayload[1] = ( uint8_t )( ( DevAddr & 0x000000FF ) ); |
fholin | 0:2325d1d28df3 | 295 | Phy.TxPhyPayload[2] = ( uint8_t )( ( DevAddr & 0x0000FF00 ) >> 8 ); |
fholin | 0:2325d1d28df3 | 296 | Phy.TxPhyPayload[3] = ( uint8_t )( ( DevAddr & 0x00FF0000 ) >> 16 ); |
fholin | 0:2325d1d28df3 | 297 | Phy.TxPhyPayload[4] = ( uint8_t )( ( DevAddr & 0xFF000000 ) >> 24 ); |
fholin | 0:2325d1d28df3 | 298 | Phy.TxPhyPayload[5] = Fctrl; |
fholin | 0:2325d1d28df3 | 299 | Phy.TxPhyPayload[6] = ( uint8_t )( ( FcntUp & 0x00FF ) ); |
fholin | 0:2325d1d28df3 | 300 | Phy.TxPhyPayload[7] = ( uint8_t )( ( FcntUp & 0x00FF00 ) >> 8 ); |
fholin | 0:2325d1d28df3 | 301 | Phy.TxPhyPayload[8] = fPort; |
fholin | 0:2325d1d28df3 | 302 | } |
fholin | 0:2325d1d28df3 | 303 | |
fholin | 0:2325d1d28df3 | 304 | int LoraWanContainer::CheckRxPayloadLength ( void ) { |
fholin | 0:2325d1d28df3 | 305 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 306 | if ( Phy.RxPhyPayloadSize < MINLORAWANPAYLOADSIZE ) { |
fholin | 0:2325d1d28df3 | 307 | status = ERRORLORAWAN; |
fholin | 0:2325d1d28df3 | 308 | return (status); |
fholin | 0:2325d1d28df3 | 309 | } |
fholin | 0:2325d1d28df3 | 310 | return (status); |
fholin | 0:2325d1d28df3 | 311 | } |
fholin | 0:2325d1d28df3 | 312 | |
fholin | 0:2325d1d28df3 | 313 | int LoraWanContainer::ExtractRxMhdr ( void ) { |
fholin | 0:2325d1d28df3 | 314 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 315 | MtypeRx = Phy.RxPhyPayload[0] >> 5 ; |
fholin | 0:2325d1d28df3 | 316 | MajorRx = Phy.RxPhyPayload[0] & 0x3 ; |
fholin | 0:2325d1d28df3 | 317 | if (( MtypeRx == JOINREQUEST) || ( MtypeRx == UNCONFDATAUP ) || ( MtypeRx == CONFDATAUP) || ( MtypeRx == REJOINREQUEST )) { |
fholin | 0:2325d1d28df3 | 318 | status = ERRORLORAWAN; |
fholin | 0:2325d1d28df3 | 319 | } |
fholin | 0:2325d1d28df3 | 320 | AckBitForTx = ( MtypeRx == CONFDATADOWN ) ? 1 : 0 ; |
fholin | 0:2325d1d28df3 | 321 | |
fholin | 0:2325d1d28df3 | 322 | return (status); |
fholin | 0:2325d1d28df3 | 323 | } |
fholin | 0:2325d1d28df3 | 324 | |
fholin | 0:2325d1d28df3 | 325 | int LoraWanContainer::ExtractRxFhdr ( uint16_t *FcntDwnTmp ) { //@note Not yet at all finalized have to initiate action on each field |
fholin | 0:2325d1d28df3 | 326 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 327 | uint32_t DevAddrtmp = 0 ; |
fholin | 0:2325d1d28df3 | 328 | DevAddrtmp = Phy.RxPhyPayload[1] + ( Phy.RxPhyPayload[2] << 8 ) + ( Phy.RxPhyPayload[3] << 16 )+ ( Phy.RxPhyPayload[4] << 24 ); |
fholin | 0:2325d1d28df3 | 329 | status = (DevAddrtmp == DevAddr) ? OKLORAWAN : ERRORLORAWAN; |
fholin | 0:2325d1d28df3 | 330 | FctrlRx = Phy.RxPhyPayload[5] ; |
fholin | 0:2325d1d28df3 | 331 | *FcntDwnTmp = Phy.RxPhyPayload[6] + ( Phy.RxPhyPayload[7] << 8 ); |
fholin | 0:2325d1d28df3 | 332 | FoptsLength = FctrlRx & 0x7; |
fholin | 0:2325d1d28df3 | 333 | memcpy(&Fopts[0], &Phy.RxPhyPayload[8], FoptsLength); |
fholin | 0:2325d1d28df3 | 334 | FportRx = Phy.RxPhyPayload[8+FoptsLength]; |
fholin | 0:2325d1d28df3 | 335 | /**************************/ |
fholin | 0:2325d1d28df3 | 336 | /* manage Fctrl Byte */ |
fholin | 0:2325d1d28df3 | 337 | /**************************/ |
fholin | 0:2325d1d28df3 | 338 | |
fholin | 0:2325d1d28df3 | 339 | return (status); |
fholin | 0:2325d1d28df3 | 340 | } |
fholin | 0:2325d1d28df3 | 341 | int LoraWanContainer::AcceptFcntDwn ( uint16_t FcntDwnTmp ) { |
fholin | 0:2325d1d28df3 | 342 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 343 | uint16_t FcntDwnLsb = ( FcntDwn & 0x0000FFFF ); |
fholin | 0:2325d1d28df3 | 344 | uint16_t FcntDwnMsb = ( FcntDwn & 0xFFFF0000 ) >> 16; |
fholin | 0:2325d1d28df3 | 345 | #ifdef CHECKFCNTDOWN |
fholin | 0:2325d1d28df3 | 346 | if ( FcntDwnmtp > FcntDwnLsb ) { |
fholin | 0:2325d1d28df3 | 347 | FcntDwn = FcntDwnTmp ; |
fholin | 0:2325d1d28df3 | 348 | } else if ( ( FcntDwnLsb - FcntDwnmtp ) > MAX_FCNT_GAP ) ) { |
fholin | 0:2325d1d28df3 | 349 | FcntDwn = ( ( FcntDwnMsb + 1 ) << 16 ) + FcntDwnTmp ; |
fholin | 0:2325d1d28df3 | 350 | } else { |
fholin | 0:2325d1d28df3 | 351 | status = ERRORLORAWAN ; |
fholin | 0:2325d1d28df3 | 352 | } |
fholin | 0:2325d1d28df3 | 353 | |
fholin | 0:2325d1d28df3 | 354 | #else |
fholin | 0:2325d1d28df3 | 355 | if ( ( FcntDwnLsb - FcntDwnTmp ) > MAX_FCNT_GAP ) { |
fholin | 0:2325d1d28df3 | 356 | FcntDwn = ( ( FcntDwnMsb + 1 ) << 16 ) + FcntDwnTmp ; |
fholin | 0:2325d1d28df3 | 357 | } else { |
fholin | 0:2325d1d28df3 | 358 | FcntDwn = FcntDwnTmp ; |
fholin | 0:2325d1d28df3 | 359 | } |
fholin | 0:2325d1d28df3 | 360 | #endif |
fholin | 0:2325d1d28df3 | 361 | return ( status ) ; |
fholin | 0:2325d1d28df3 | 362 | } |
fholin | 0:2325d1d28df3 | 363 | |
fholin | 0:2325d1d28df3 | 364 | void LoraWanContainer::GiveNextSf( void ) { |
fholin | 0:2325d1d28df3 | 365 | switch ( AdrModeSelect ) { |
fholin | 0:2325d1d28df3 | 366 | case STATICADRMODE : |
fholin | 0:2325d1d28df3 | 367 | MacTxSf = 7; |
fholin | 0:2325d1d28df3 | 368 | break; |
fholin | 0:2325d1d28df3 | 369 | case MOBILELONGRANGEADRMODE: |
fholin | 0:2325d1d28df3 | 370 | if ( MacTxSf == 12 ) { |
fholin | 0:2325d1d28df3 | 371 | MacTxSf = 7; |
fholin | 0:2325d1d28df3 | 372 | } else { |
fholin | 0:2325d1d28df3 | 373 | MacTxSf = 12; |
fholin | 0:2325d1d28df3 | 374 | } |
fholin | 0:2325d1d28df3 | 375 | break; |
fholin | 0:2325d1d28df3 | 376 | case MOBILELOWPOWERADRMODE: |
fholin | 0:2325d1d28df3 | 377 | ( MacTxSf == 12 ) ? MacTxSf = 7 : MacTxSf++ ; |
fholin | 0:2325d1d28df3 | 378 | break; |
fholin | 0:2325d1d28df3 | 379 | default: |
fholin | 0:2325d1d28df3 | 380 | MacTxSf = 12; |
fholin | 0:2325d1d28df3 | 381 | } |
fholin | 0:2325d1d28df3 | 382 | MacTxSf = ( MacTxSf > 12 ) ? 12 : MacTxSf; |
fholin | 0:2325d1d28df3 | 383 | MacTxSf = ( MacTxSf < 7 ) ? 7 : MacTxSf; |
fholin | 0:2325d1d28df3 | 384 | } |
fholin | 0:2325d1d28df3 | 385 | uint8_t LoraWanContainer::GiveNextChannel( void ) { |
fholin | 0:2325d1d28df3 | 386 | return ( randr( 0, NbOfActiveChannel - 1 ) ); |
fholin | 0:2325d1d28df3 | 387 | |
fholin | 0:2325d1d28df3 | 388 | }; |
fholin | 0:2325d1d28df3 | 389 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 390 | /* Private NWK MANAGEMENTS Methods */ |
fholin | 0:2325d1d28df3 | 391 | /************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 392 | |
fholin | 0:2325d1d28df3 | 393 | void LoraWanContainer::LinkCheckParser( void ) { |
fholin | 0:2325d1d28df3 | 394 | |
fholin | 0:2325d1d28df3 | 395 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 396 | } |
fholin | 0:2325d1d28df3 | 397 | /*****************************************************/ |
fholin | 0:2325d1d28df3 | 398 | /* Private NWK MANAGEMENTS : LinkADR */ |
fholin | 0:2325d1d28df3 | 399 | /*****************************************************/ |
fholin | 0:2325d1d28df3 | 400 | void LoraWanContainer::LinkADRParser( void ) { |
fholin | 0:2325d1d28df3 | 401 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 402 | uint8_t StatusAns = 0x7 ; // initilised for ans answer ok |
fholin | 0:2325d1d28df3 | 403 | uint8_t temp ; |
fholin | 0:2325d1d28df3 | 404 | uint16_t temp2 ; |
fholin | 0:2325d1d28df3 | 405 | /* Valid DataRate And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 406 | temp = ( ( MacRxPayload[1] & 0xF0 ) >> 4 ); |
fholin | 0:2325d1d28df3 | 407 | status = isValidDataRate( temp ); |
fholin | 0:2325d1d28df3 | 408 | (status == OKLORAWAN ) ? MacTxPower = temp : StatusAns &= 0x5 ; |
fholin | 0:2325d1d28df3 | 409 | |
fholin | 0:2325d1d28df3 | 410 | /* Valid TxPower And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 411 | temp = ( MacRxPayload[1] & 0x0F ); |
fholin | 0:2325d1d28df3 | 412 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 413 | status = isValidTxPower( temp ); |
fholin | 0:2325d1d28df3 | 414 | (status == OKLORAWAN ) ? MacTxPower = temp : StatusAns &= 0x5 ; |
fholin | 0:2325d1d28df3 | 415 | |
fholin | 0:2325d1d28df3 | 416 | /* Valid DataRate Channel Mask And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 417 | temp2 = MacRxPayload[2] + ( MacRxPayload[3] << 8 ) ; |
fholin | 0:2325d1d28df3 | 418 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 419 | status = isValidChannelMask( temp2 ); |
fholin | 0:2325d1d28df3 | 420 | (status == OKLORAWAN ) ? MacChMask = temp2 : StatusAns &= 0x6 ; |
fholin | 0:2325d1d28df3 | 421 | |
fholin | 0:2325d1d28df3 | 422 | /* Valid Redundancy And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 423 | temp = MacRxPayload[4]; |
fholin | 0:2325d1d28df3 | 424 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 425 | status = isValidNbRep( temp ); |
fholin | 0:2325d1d28df3 | 426 | (status == OKLORAWAN ) ? MacNbRepUnconfirmedTx = temp : StatusAns &= 0x3 ; |
fholin | 0:2325d1d28df3 | 427 | |
fholin | 0:2325d1d28df3 | 428 | /* Prepare Ans*/ |
fholin | 0:2325d1d28df3 | 429 | MacNwkAns [0] = MacRxPayload[0] ; // copy Cid |
fholin | 0:2325d1d28df3 | 430 | MacNwkAns [1] = StatusAns ; |
fholin | 0:2325d1d28df3 | 431 | MacNwkAnsSize = 2 ; |
fholin | 0:2325d1d28df3 | 432 | IsFrameToSend = NWKFRAME_TOSEND ; |
fholin | 0:2325d1d28df3 | 433 | } |
fholin | 0:2325d1d28df3 | 434 | |
fholin | 0:2325d1d28df3 | 435 | void LoraWanContainer::DutyCycleParser( void ) { |
fholin | 0:2325d1d28df3 | 436 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 437 | } |
fholin | 0:2325d1d28df3 | 438 | /*****************************************************/ |
fholin | 0:2325d1d28df3 | 439 | /* Private NWK MANAGEMENTS : RXParamSetupParser */ |
fholin | 0:2325d1d28df3 | 440 | /*****************************************************/ |
fholin | 0:2325d1d28df3 | 441 | void LoraWanContainer::RXParamSetupParser( void ) { |
fholin | 0:2325d1d28df3 | 442 | //@note not valid case or error case have been yet implemented |
fholin | 0:2325d1d28df3 | 443 | int status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 444 | uint8_t StatusAns = 0x7 ; // initilised for ans answer ok |
fholin | 0:2325d1d28df3 | 445 | int temp ; |
fholin | 0:2325d1d28df3 | 446 | /* Valid Rx1SfOffset And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 447 | temp = ( MacRxPayload[1] & 0x70 ) >> 3 ; |
fholin | 0:2325d1d28df3 | 448 | status = isValidRx1SfOffset( temp ); |
fholin | 0:2325d1d28df3 | 449 | (status == OKLORAWAN ) ? MacRx1SfOffset = temp : StatusAns &= 0x6 ; |
fholin | 0:2325d1d28df3 | 450 | |
fholin | 0:2325d1d28df3 | 451 | /* Valid MacRx2Sf And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 452 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 453 | temp = ( MacRxPayload[1] & 0x0F ); |
fholin | 0:2325d1d28df3 | 454 | status = isValidMacRx2Sf( temp ); |
fholin | 0:2325d1d28df3 | 455 | (status == OKLORAWAN ) ? MacRx2Sf = temp : StatusAns &= 0x5 ; |
fholin | 0:2325d1d28df3 | 456 | |
fholin | 0:2325d1d28df3 | 457 | /* Valid MacRx2Frequency And Prepare Ans */ |
fholin | 0:2325d1d28df3 | 458 | status = OKLORAWAN; |
fholin | 0:2325d1d28df3 | 459 | temp = ( MacRxPayload[2] ) + ( MacRxPayload[3] << 8 ) + ( MacRxPayload[4] << 16 ); |
fholin | 0:2325d1d28df3 | 460 | status = isValidMacRx2Frequency( temp ); |
fholin | 0:2325d1d28df3 | 461 | (status == OKLORAWAN ) ? MacRx2Frequency = temp : StatusAns &= 0x3 ; |
fholin | 0:2325d1d28df3 | 462 | |
fholin | 0:2325d1d28df3 | 463 | /* Prepare Ans*/ |
fholin | 0:2325d1d28df3 | 464 | MacNwkAns [0] = MacRxPayload[0] ; // copy Cid |
fholin | 0:2325d1d28df3 | 465 | MacNwkAns [1] = StatusAns ; |
fholin | 0:2325d1d28df3 | 466 | MacNwkAnsSize = 2 ; |
fholin | 0:2325d1d28df3 | 467 | IsFrameToSend = NWKFRAME_TOSEND ; |
fholin | 0:2325d1d28df3 | 468 | } |
fholin | 0:2325d1d28df3 | 469 | |
fholin | 0:2325d1d28df3 | 470 | void LoraWanContainer::DevStatusParser( void ) { |
fholin | 0:2325d1d28df3 | 471 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 472 | } |
fholin | 0:2325d1d28df3 | 473 | void LoraWanContainer::NewChannelParser( void ) { |
fholin | 0:2325d1d28df3 | 474 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 475 | } |
fholin | 0:2325d1d28df3 | 476 | void LoraWanContainer::RXTimingSetupParser( void ) { |
fholin | 0:2325d1d28df3 | 477 | //@NOTE NOT YET IMPLEMENTED |
fholin | 0:2325d1d28df3 | 478 | } |
fholin | 0:2325d1d28df3 | 479 | |
fholin | 0:2325d1d28df3 | 480 | |
fholin | 0:2325d1d28df3 | 481 | |
fholin | 0:2325d1d28df3 | 482 | |
fholin | 0:2325d1d28df3 | 483 | uint8_t LoraWanContainer::isValidRx1SfOffset ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 484 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 485 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 486 | } |
fholin | 0:2325d1d28df3 | 487 | uint8_t LoraWanContainer::isValidMacRx2Sf ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 488 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 489 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 490 | } |
fholin | 0:2325d1d28df3 | 491 | uint8_t LoraWanContainer::isValidMacRx2Frequency ( uint32_t temp ) { |
fholin | 0:2325d1d28df3 | 492 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 493 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 494 | } |
fholin | 0:2325d1d28df3 | 495 | uint8_t LoraWanContainer::isValidDataRate ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 496 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 497 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 498 | } |
fholin | 0:2325d1d28df3 | 499 | uint8_t LoraWanContainer::isValidTxPower ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 500 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 501 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 502 | } |
fholin | 0:2325d1d28df3 | 503 | |
fholin | 0:2325d1d28df3 | 504 | uint8_t LoraWanContainer::isValidChannelMask ( uint16_t temp ) { |
fholin | 0:2325d1d28df3 | 505 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 506 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 507 | } |
fholin | 0:2325d1d28df3 | 508 | uint8_t LoraWanContainer::isValidNbRep ( uint8_t temp ) { |
fholin | 0:2325d1d28df3 | 509 | // @note not yet implemented |
fholin | 0:2325d1d28df3 | 510 | return ( OKLORAWAN ); |
fholin | 0:2325d1d28df3 | 511 | } |
fholin | 0:2325d1d28df3 | 512 | void LoraWanContainer::SaveInFlash ( ) { |
fholin | 0:2325d1d28df3 | 513 | BackUpFlash.MacTxSf = MacTxSf; |
fholin | 0:2325d1d28df3 | 514 | BackUpFlash.MacTxPower = MacTxPower; |
fholin | 0:2325d1d28df3 | 515 | BackUpFlash.MacChMask = MacChMask; |
fholin | 0:2325d1d28df3 | 516 | BackUpFlash.MacNbRepUnconfirmedTx = MacNbRepUnconfirmedTx; |
fholin | 0:2325d1d28df3 | 517 | BackUpFlash.MacRx2Frequency = MacRx2Frequency; |
fholin | 0:2325d1d28df3 | 518 | BackUpFlash.MacRx2Sf = MacRx2Sf; |
fholin | 0:2325d1d28df3 | 519 | BackUpFlash.MacRx1SfOffset = MacRx1SfOffset; |
fholin | 0:2325d1d28df3 | 520 | BackUpFlash.NbOfActiveChannel = NbOfActiveChannel; |
fholin | 0:2325d1d28df3 | 521 | BackUpFlash.MacRx1Delay = MacRx1Delay; |
fholin | 0:2325d1d28df3 | 522 | BackUpFlash.FcntUp = FcntUp; |
fholin | 0:2325d1d28df3 | 523 | BackUpFlash.FcntDwn = FcntDwn; |
fholin | 0:2325d1d28df3 | 524 | BackUpFlash.DevAddr = DevAddr; |
fholin | 0:2325d1d28df3 | 525 | BackUpFlash.JoinedStatus = JoinedStatus; |
fholin | 0:2325d1d28df3 | 526 | memcpy( &BackUpFlash.MacTxFrequency[0], &MacTxFrequency[0], 16); |
fholin | 0:2325d1d28df3 | 527 | memcpy( &BackUpFlash.MacMinMaxSFChannel[0], &MacMinMaxSFChannel[0], 16); |
fholin | 0:2325d1d28df3 | 528 | memcpy( &BackUpFlash.nwkSKey[0], &nwkSKey[0], 16); |
fholin | 0:2325d1d28df3 | 529 | memcpy( &BackUpFlash.appSKey[0], &appSKey[0], 16); |
fholin | 0:2325d1d28df3 | 530 | gFlash.program( &BackUpFlash, USERFLASHADRESS, sizeof(sBackUpFlash) ); |
fholin | 0:2325d1d28df3 | 531 | } |
fholin | 0:2325d1d28df3 | 532 | |
fholin | 0:2325d1d28df3 | 533 | |
fholin | 0:2325d1d28df3 | 534 | void LoraWanContainer::LoadFromFlash ( ) { |
fholin | 0:2325d1d28df3 | 535 | gFlash.read((uint8_t *)(&BackUpFlash), USERFLASHADRESS, sizeof(sBackUpFlash)); |
fholin | 0:2325d1d28df3 | 536 | BackUpFlash.FcntUp += FLASH_UPDATE_PERIOD; //@note automatic increment |
fholin | 0:2325d1d28df3 | 537 | MacTxSf = BackUpFlash.MacTxSf; |
fholin | 0:2325d1d28df3 | 538 | MacTxPower = BackUpFlash.MacTxPower; |
fholin | 0:2325d1d28df3 | 539 | MacChMask = BackUpFlash.MacChMask ; |
fholin | 0:2325d1d28df3 | 540 | MacNbRepUnconfirmedTx = BackUpFlash.MacNbRepUnconfirmedTx ; |
fholin | 0:2325d1d28df3 | 541 | MacRx2Frequency = BackUpFlash.MacRx2Frequency ; |
fholin | 0:2325d1d28df3 | 542 | MacRx2Sf = BackUpFlash.MacRx2Sf ; |
fholin | 0:2325d1d28df3 | 543 | MacRx1SfOffset = BackUpFlash.MacRx1SfOffset; |
fholin | 0:2325d1d28df3 | 544 | NbOfActiveChannel = BackUpFlash.NbOfActiveChannel; |
fholin | 0:2325d1d28df3 | 545 | MacRx1Delay = BackUpFlash.MacRx1Delay ; |
fholin | 0:2325d1d28df3 | 546 | FcntUp = BackUpFlash.FcntUp ; |
fholin | 0:2325d1d28df3 | 547 | FcntDwn = BackUpFlash.FcntDwn ; |
fholin | 0:2325d1d28df3 | 548 | DevAddr = BackUpFlash.DevAddr; |
fholin | 0:2325d1d28df3 | 549 | JoinedStatus = BackUpFlash.JoinedStatus; |
fholin | 0:2325d1d28df3 | 550 | memcpy( &MacTxFrequency[0], &BackUpFlash.MacTxFrequency[0], 16); |
fholin | 0:2325d1d28df3 | 551 | memcpy( &MacMinMaxSFChannel[0], &BackUpFlash.MacMinMaxSFChannel[0], 16); |
fholin | 0:2325d1d28df3 | 552 | memcpy( &nwkSKey[0], &BackUpFlash.nwkSKey[0], 16); |
fholin | 0:2325d1d28df3 | 553 | memcpy( &appSKey[0], &BackUpFlash.appSKey[0], 16); |
fholin | 0:2325d1d28df3 | 554 | gFlash.program( &BackUpFlash, USERFLASHADRESS, sizeof(sBackUpFlash) ); |
fholin | 0:2325d1d28df3 | 555 | } |
fholin | 0:2325d1d28df3 | 556 | /**************************************TIMER PART**********************************************************/ |
fholin | 0:2325d1d28df3 | 557 | /**********************************************************************************************************/ |
fholin | 0:2325d1d28df3 | 558 | /*@Note Probably to create a new directory or may be an timer Object to be discuss */ |
fholin | 0:2325d1d28df3 | 559 | |
fholin | 0:2325d1d28df3 | 560 | |
fholin | 0:2325d1d28df3 | 561 | /************************************************************************************/ |
fholin | 0:2325d1d28df3 | 562 | /* Rx1 Timer Isr Routine */ |
fholin | 0:2325d1d28df3 | 563 | /* Called when Alarm expires */ |
fholin | 0:2325d1d28df3 | 564 | /************************************************************************************/ |
fholin | 0:2325d1d28df3 | 565 | void LoraWanContainer::SetAlarm (uint32_t alarmInMs) { |
fholin | 0:2325d1d28df3 | 566 | TimerLora.attach_us(this, &LoraWanContainer::IsrTimerRx, alarmInMs * 1000); |
fholin | 0:2325d1d28df3 | 567 | } |
fholin | 0:2325d1d28df3 | 568 | |
fholin | 0:2325d1d28df3 | 569 | void LoraWanContainer::IsrTimerRx( void ) { |
fholin | 0:2325d1d28df3 | 570 | StateTimer = TIMERSTATE_SLEEP; |
fholin | 0:2325d1d28df3 | 571 | Phy.Radio.Rx(0); //@note No More timeout FW on RX use only timeout impplement in the HW radio |
fholin | 0:2325d1d28df3 | 572 | }; |
fholin | 0:2325d1d28df3 | 573 | |
fholin | 0:2325d1d28df3 | 574 | |
fholin | 0:2325d1d28df3 | 575 | /****************************************API Crypto ***********************/ |
fholin | 0:2325d1d28df3 | 576 | 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 | 577 | uint32_t DevAddrtmp = 0; |
fholin | 0:2325d1d28df3 | 578 | uint16_t FcntDwnmtp = 0; |
fholin | 0:2325d1d28df3 | 579 | int status = OKLORAWAN ; |
fholin | 0:2325d1d28df3 | 580 | if ( keySet == UNICASTKEY) { |
fholin | 0:2325d1d28df3 | 581 | DevAddrtmp = frame_header[1] + ( frame_header[2] << 8 ) + ( frame_header[3] << 16 )+ ( frame_header[4] << 24 ); |
fholin | 0:2325d1d28df3 | 582 | FcntDwnmtp = frame_header[6] + ( frame_header[7] << 8 ); |
fholin | 0:2325d1d28df3 | 583 | status += LoRaMacCheckMic(frame_header, PayloadSize, nwkSKey, DevAddrtmp, FcntDwnmtp, micIn ); |
fholin | 0:2325d1d28df3 | 584 | |
fholin | 0:2325d1d28df3 | 585 | //@note note sure that it is better to sen dheader because extract again devaddr fcntdwn fopts etc .... |
fholin | 0:2325d1d28df3 | 586 | |
fholin | 0:2325d1d28df3 | 587 | PayloadSize = PayloadSize - FHDROFFSET - FoptsLength ; |
fholin | 0:2325d1d28df3 | 588 | if ( status == OKLORAWAN) { |
fholin | 0:2325d1d28df3 | 589 | LoRaMacPayloadDecrypt( &Phy.RxPhyPayload[FHDROFFSET + FoptsLength], MacRxPayloadSize, (FportRx == 0 )?nwkSKey:appSKey, DevAddr, 1, FcntDwn, &MacRxPayload[0] ); |
fholin | 0:2325d1d28df3 | 590 | } |
fholin | 0:2325d1d28df3 | 591 | } |
fholin | 0:2325d1d28df3 | 592 | } |