text: /*
   / _____)             _              | |
  ( (____  _____ ____ _| |_ _____  ____| |__
   \____ \| ___ |    (_   _) ___ |/ ___)  _ \
   _____) ) ____| | | || |_| ____( (___| | | |
  (______/|_____)_|_|_| \__)_____)\____)_| |_|
      (C)2013 Semtech
   ___ _____ _   ___ _  _____ ___  ___  ___ ___
  / __|_   _/_\ / __| |/ / __/ _ \| _ \/ __| __|
  \__ \ | |/ _ \ (__| ' <| _| (_) |   / (__| _|
  |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
  embedded.connectivity.solutions===============
  
  Description: LoRa MAC layer message parser functionality implementation
  
  License: Revised BSD License, see LICENSE.TXT file include in the project
  
  Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ),
              Daniel Jaeckle ( STACKFORCE ),  Johannes Bruder ( STACKFORCE )
  */
  #include "LoRaMacParser.h"
  #include "../boards/utilities.h"
  
  LoRaMacParserStatus_t LoRaMacParserJoinAccept( LoRaMacMessageJoinAccept_t* macMsg )
  {
      if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
      {
          return LORAMAC_PARSER_ERROR_NPE;
      }
  
      uint16_t bufItr = 0;
  
      macMsg->MHDR.Value = macMsg->Buffer[bufItr++];
  
      memcpy1( macMsg->JoinNonce, &macMsg->Buffer[bufItr], 3 );
      bufItr = bufItr + 3;
  
      memcpy1( macMsg->NetID, &macMsg->Buffer[bufItr], 3 );
      bufItr = bufItr + 3;
  
      macMsg->DevAddr = ( uint32_t ) macMsg->Buffer[bufItr++];
      macMsg->DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 8 );
      macMsg->DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 16 );
      macMsg->DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 24 );
  
      macMsg->DLSettings.Value = macMsg->Buffer[bufItr++];
  
      macMsg->RxDelay = macMsg->Buffer[bufItr++];
  
      if( ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE - bufItr ) == LORAMAC_CF_LIST_FIELD_SIZE )
      {
          memcpy1( macMsg->CFList, &macMsg->Buffer[bufItr], LORAMAC_CF_LIST_FIELD_SIZE );
          bufItr = bufItr + LORAMAC_CF_LIST_FIELD_SIZE;
      }
      else if( ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE - bufItr ) > 0 )
      {
          return LORAMAC_PARSER_FAIL;
      }
  
      macMsg->MIC = ( uint32_t ) macMsg->Buffer[bufItr++];
      macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 8 );
      macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 16 );
      macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 24 );
  
      return LORAMAC_PARSER_SUCCESS;
  }
  
  LoRaMacParserStatus_t LoRaMacParserData( LoRaMacMessageData_t* macMsg )
  {
      if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
      {
          return LORAMAC_PARSER_ERROR_NPE;
      }
  
      uint16_t bufItr = 0;
  
      macMsg->MHDR.Value = macMsg->Buffer[bufItr++];
  
      macMsg->FHDR.DevAddr = macMsg->Buffer[bufItr++];
      macMsg->FHDR.DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 8 );
      macMsg->FHDR.DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 16 );
      macMsg->FHDR.DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 24 );
  
      macMsg->FHDR.FCtrl.Value = macMsg->Buffer[bufItr++];
  
      macMsg->FHDR.FCnt = macMsg->Buffer[bufItr++];
      macMsg->FHDR.FCnt |= macMsg->Buffer[bufItr++] << 8;
  
      if( macMsg->FHDR.FCtrl.Bits.FOptsLen <= 15 )
      {
          memcpy1( macMsg->FHDR.FOpts, &macMsg->Buffer[bufItr], macMsg->FHDR.FCtrl.Bits.FOptsLen );
          bufItr = bufItr + macMsg->FHDR.FCtrl.Bits.FOptsLen;
      }
      else
      {
          return LORAMAC_PARSER_FAIL;
      }
  
      // Initialize anyway with zero.
      macMsg->FPort = 0;
      macMsg->FRMPayloadSize = 0;
  
      if( ( macMsg->BufSize - bufItr - LORAMAC_MIC_FIELD_SIZE ) > 0 )
      {
          macMsg->FPort = macMsg->Buffer[bufItr++];
  
          macMsg->FRMPayloadSize = ( macMsg->BufSize - bufItr - LORAMAC_MIC_FIELD_SIZE );
          memcpy1( macMsg->FRMPayload, &macMsg->Buffer[bufItr], macMsg->FRMPayloadSize );
          bufItr = bufItr + macMsg->FRMPayloadSize;
      }
  
      macMsg->MIC = ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE )];
      macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ) + 1] << 8 );
      macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ) + 2] << 16 );
      macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ) + 3] << 24 );
  
      return LORAMAC_PARSER_SUCCESS;
  }
  