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/LoraWanProcess.cpp
- Committer:
- fholin
- Date:
- 2017-12-15
- Revision:
- 0:2325d1d28df3
- Child:
- 1:eda561b01daf
File content as of revision 0:2325d1d28df3:
/*
__ __ _ _
| \/ (_) (_)
| \ / |_ _ __ _ _ __ ___ ___ _ _ ___ ___
| |\/| | | '_ \| | '_ ` _ \ / _ \| | | / __|/ _ \
| | | | | | | | | | | | | | (_) | |_| \__ \ __/
|_| |_|_|_| |_|_|_| |_| |_|\___/ \__,_|___/\___|
Description : LoraWanProcess Class definition.
License : Revised BSD License, see LICENSE.TXT file include in the project
Maintainer : Fabien Holin (SEMTECH)
*/
#include "LoraWanProcess.h"
#include "ApiRtc.h"
#include "utilities.h"
Serial pcf( PA_9, PA_10 );
LoraWanObjet::LoraWanObjet( PinName interrupt ):packet( interrupt ){
StateLoraWanProcess=LWPSTATE_IDLE;
packet.MajorBits= LORAWANR1;
};
LoraWanObjet::~LoraWanObjet() {
};
/************************************************************************************************/
/* Public Methods */
/************************************************************************************************/
/***********************************************************************************************/
/* LoraWanProcess Method */
/***********************************************************************************************/
eLoraWan_Process_States LoraWanObjet::LoraWanProcess( uint8_t * AvailableRxPacket ) {
*AvailableRxPacket = NOLORARXPACKETAVAILABLE; //@note AvailableRxPacket should be set to "yes" only in Last state before to return to LWPSTATE_IDLE*
switch ( StateLoraWanProcess ) {
/************************************************************************************/
/* STATE IDLE */
/************************************************************************************/
case LWPSTATE_IDLE :
break;
/************************************************************************************/
/* STATE TX */
/************************************************************************************/
case LWPSTATE_SEND:
switch ( GetRadioState( ) ) {
case RADIOSTATE_IDLE :
packet.ConfigureRadioAndSend( );
pcf.printf( " **************************\n " );
pcf.printf( " * Send Payload *\n " );
pcf.printf( " **************************\n " );
break ;
case RADIOSTATE_TXFINISHED :
packet.ConfigureRadioForRx1 ( );
packet.ConfigureTimerForRx ( RX1 );
StateLoraWanProcess = LWPSTATE_RX1;
break ;
default :
break;
}
break;
/************************************************************************************/
/* STATE RX1 */
/* RX1DELAY is defined in ms */
/************************************************************************************/
case LWPSTATE_RX1:
if ( GetRadioState( ) == RADIOSTATE_RX1FINISHED ) {
if ( GetRadioIrqFlag ( ) == RECEIVEPACKETIRQFLAG) {
//@todo process downlink
pcf.printf( " **************************\n " );
pcf.printf( " * Receive a downlink RX1 *\n " );
pcf.printf( " **************************\n " );
StateLoraWanProcess = LWPSTATE_PROCESSDOWNLINK;
} else { // So rxtimeout case @note manage error case
pcf.printf( " **************************\n " );
pcf.printf( " * RX1 Timeout *\n " );
pcf.printf( " **************************\n " );
packet.ConfigureRadioForRx2 ( );
packet.ConfigureTimerForRx ( RX2 );
StateLoraWanProcess = LWPSTATE_RX2;
}
}
break;
/************************************************************************************/
/* STATE RX2 */
/************************************************************************************/
case LWPSTATE_RX2:
if ( GetRadioState( ) == RADIOSTATE_IDLE ) {
if ( GetRadioIrqFlag ( ) == RECEIVEPACKETIRQFLAG) {
pcf.printf( " **************************\n " );
pcf.printf( " * Receive a downlink RX2 *\n " );
pcf.printf( " **************************\n " );
StateLoraWanProcess = LWPSTATE_PROCESSDOWNLINK; //@note to be discuss if it is necessary to create a dedicated state?
} else {
pcf.printf( " **************************\n " );
pcf.printf( " * RX2 Timeout *\n " );
pcf.printf( " **************************\n " );
StateLoraWanProcess = LWPSTATE_UPDATEMAC;
}
}
break;
/************************************************************************************/
/* STATE PROCESS DOWNLINK */
/* At this step crc is valid */
/* Step 1 : CheckRxPayloadLength */
/* Step 2 : ExtractRxMhdr */
/* Step 3 : ExtractRxFhdr */
/* Step 4 : Check Mic */
/* Step 5 : Decrypt Payload */
/* Step 6 : Extract Fport to select Between App/nwm Payload */
/************************************************************************************/
case LWPSTATE_PROCESSDOWNLINK:
pcf.printf( " **************************\n " );
pcf.printf( " * Process Downlink *\n " );
pcf.printf( " **************************\n " );
ValidRxPacket = packet.DecodeRxFrame( ); // return NOVALIDRXPACKET or USERRXPACKET or NWKRXPACKET or JOINACCEPTPACKET.
StateLoraWanProcess = LWPSTATE_UPDATEMAC;
break;
/************************************************************************************/
/* STATE UPDATE MAC */
/************************************************************************************/
case LWPSTATE_UPDATEMAC:
packet.Phy.StateRadioProcess = RADIOSTATE_IDLE;
pcf.printf( " **************************\n " );
pcf.printf( " * UpdateMac *\n " );
pcf.printf( " **************************\n " );
if ( ValidRxPacket == JOINACCEPTPACKET){
packet.UpdateJoinProcedure( );
}
if ( ValidRxPacket == NWKRXPACKET){
packet.ParseManagementPacket( );
}
packet.UpdateMacLayer();
*AvailableRxPacket = packet.AvailableRxPacketForUser;
if ( ( packet.IsFrameToSend == NWKFRAME_TOSEND ) ) {// @note ack send during the next tx|| ( packet.IsFrameToSend == USERACK_TOSEND ) ) {
RtcTargetTimer = RtcGetTimeSecond( ) + randr( 5, 25 ); //@note RtcGetTime in s so no wrap before 136 year since 1970 discuss wait between 5s and 25s
StateLoraWanProcess = LWPSTATE_TXWAIT;
} else {
RadioReset ( ) ;
StateLoraWanProcess = LWPSTATE_IDLE;
}
break;
/************************************************************************************/
/* STATE TXWAIT MAC */
/************************************************************************************/
case LWPSTATE_TXWAIT:
pcf.printf( " **************************\n " );
pcf.printf( " * TXWAIT MAC *\n " );
pcf.printf( " **************************\n " );
if ( RtcGetTimeSecond( ) > RtcTargetTimer) {
StateLoraWanProcess = LWPSTATE_SEND; //@note the frame have already been prepare in Upadate Mac Layer
}
break;
default:
pcf.printf( " Illegal state\n " );
break;
}
return ( StateLoraWanProcess );
}
/***********************************************************************************************/
/* End Of LoraWanProcess Method */
/***********************************************************************************************/
/**************************************************/
/* LoraWan Join Method */
/**************************************************/
uint8_t LoraWanObjet::Join ( void ) {
packet.BuildJoinLoraFrame( );
packet.MacRx1Delay = RX1DELAYJOIN;
packet.MacTxSf = 12;
packet.MacRx2Sf = 12;
StateLoraWanProcess = LWPSTATE_SEND;
return( StateLoraWanProcess );
};
/**************************************************/
/* LoraWan IsJoined Method */
/**************************************************/
uint8_t LoraWanObjet::IsJoined( void ) {
uint8_t status;
pcf.printf( " New DevAddr = 0x%.8x \n",packet.DevAddr);
status = packet.JoinedStatus;
return ( status );
}
/**************************************************/
/* LoraWan SendPayload Method */
/**************************************************/
eLoraWan_Process_States LoraWanObjet::SendPayload ( uint8_t fPort, const uint8_t* dataIn, const uint16_t sizeIn, uint8_t PacketType ) {
if ( StateLoraWanProcess != LWPSTATE_IDLE ) {
return ( LWPSTATE_ERROR );
}
RadioReset ( ) ;
CopyUserPayload( dataIn,sizeIn );
packet.UserPayloadSize = sizeIn;
packet.fPort = fPort;
packet.MType = PacketType;
packet.BuildTxLoraFrame( );
packet.EncryptTxFrame( );
StateLoraWanProcess = LWPSTATE_SEND;
return( StateLoraWanProcess );
};
/**************************************************/
/* LoraWan Receive Method */
/**************************************************/
uint8_t LoraWanObjet::ReceivePayload ( uint8_t* UserRxFport, uint8_t* UserRxPayload, uint8_t* UserRxPayloadSize ) {
int status = OKLORAWAN;
if (packet.AvailableRxPacketForUser == NOLORARXPACKETAVAILABLE) {
status = ERRORLORAWAN ;
} else {
*UserRxPayloadSize = packet.MacRxPayloadSize;
*UserRxFport = packet.FportRx;
memcpy( UserRxPayload, &packet.MacRxPayload[0], packet.MacRxPayloadSize);
packet.AvailableRxPacketForUser = NOLORARXPACKETAVAILABLE ;
}
return( status );
};
/**************************************************/
/* LoraWan AdrModeSelect Method */
/**************************************************/
void LoraWanObjet::SetDataRateStrategy( eDataRateStrategy adrModeSelect ) {
packet.AdrModeSelect = adrModeSelect;
};
/**************************************************/
/* LoraWan TryToJoin Method */
/**************************************************/
uint8_t LoraWanObjet::TryToJoin ( void ) {
//@NOTE NOT YET IMPLEMENTED
}
/**************************************************/
/* LoraWan GetNextMaxPayloadLength Method */
/**************************************************/
uint32_t LoraWanObjet::GetNextMaxPayloadLength ( void ) {
//@NOTE NOT YET IMPLEMENTED
}
/**************************************************/
/* LoraWan GetDevAddr Method */
/**************************************************/
uint32_t LoraWanObjet::GetDevAddr ( void ) {
//@NOTE NOT YET IMPLEMENTED
}
/**************************************************/
/* LoraWan GetNextPower Method */
/**************************************************/
uint8_t LoraWanObjet::GetNextPower ( void ) {
//@NOTE NOT YET IMPLEMENTED
}
/**************************************************/
/* LoraWan GetNextDataRate Method */
/**************************************************/
uint8_t LoraWanObjet::GetNextDataRate ( void ) {
//@NOTE NOT YET IMPLEMENTED
}
/**************************************************/
/* LoraWan GetLorawanProcessState Method */
/**************************************************/
uint8_t LoraWanObjet::GetLorawanProcessState ( void ) {
//@NOTE NOT YET IMPLEMENTED
}
/**************************************************/
/* LoraWan RestoreContext Method */
/**************************************************/
void LoraWanObjet::RestoreContext ( void ) {
packet.LoadFromFlash ( );
};
/************************************************************************************************/
/* Private Methods */
/************************************************************************************************/
void LoraWanObjet::CopyUserPayload( const uint8_t* dataIn, const uint16_t sizeIn ) {
memcpy( &packet.Phy.TxPhyPayload[FHDROFFSET], dataIn, sizeIn );
};
uint8_t LoraWanObjet::GetStateTimer(void) {
return (packet.StateTimer);
}
uint8_t LoraWanObjet::GetRadioState ( void ) {
return packet.Phy.GetRadioState( );
};
uint8_t LoraWanObjet::GetRadioIrqFlag ( void ) {
return packet.Phy.RegIrqFlag;
};
void LoraWanObjet::RadioReset ( void ) {
//NOT YET IMPLEMENTED
}