/*! * \file LoRaMacParser.c * * \brief LoRa MAC layer message parser functionality implementation * * \copyright Revised BSD License, see section \ref LICENSE. * * \code * ______ _ * / _____) _ | | * ( (____ _____ ____ _| |_ _____ ____| |__ * \____ \| ___ | (_ _) ___ |/ ___) _ \ * _____) ) ____| | | || |_| ____( (___| | | | * (______/|_____)_|_|_| \__)_____)\____)_| |_| * (C)2013 Semtech * * ___ _____ _ ___ _ _____ ___ ___ ___ ___ * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| * embedded.connectivity.solutions=============== * * \endcode * * \author Miguel Luis ( Semtech ) * * \author Gregory Cristian ( Semtech ) * * \author Daniel Jaeckle ( STACKFORCE ) * * \author Johannes Bruder ( STACKFORCE ) */ #include "LoRaMacParser.h" #include "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; memcpy1( macMsg->FHDR.FOpts, &macMsg->Buffer[bufItr], macMsg->FHDR.FCtrl.Bits.FOptsLen ); bufItr = bufItr + macMsg->FHDR.FCtrl.Bits.FOptsLen; // 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; }