1 /*
2  / _____)             _              | |
3 ( (____  _____ ____ _| |_ _____  ____| |__
4  \____ \| ___ |    (_   _) ___ |/ ___)  _ \
5  _____) ) ____| | | || |_| ____( (___| | | |
6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
7     (C)2013 Semtech
8  ___ _____ _   ___ _  _____ ___  ___  ___ ___
9 / __|_   _/_\ / __| |/ / __/ _ \| _ \/ __| __|
10 \__ \ | |/ _ \ (__| ' <| _| (_) |   / (__| _|
11 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
12 embedded.connectivity.solutions===============
13 
14 Description: LoRa MAC layer message parser functionality implementation
15 
16 License: Revised BSD License, see LICENSE.TXT file include in the project
17 
18 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ),
19             Daniel Jaeckle ( STACKFORCE ),  Johannes Bruder ( STACKFORCE )
20 */
21 #include "LoRaMacParser.h"
22 #include "utilities.h"
23 
LoRaMacParserJoinAccept(LoRaMacMessageJoinAccept_t * macMsg)24 LoRaMacParserStatus_t LoRaMacParserJoinAccept( LoRaMacMessageJoinAccept_t* macMsg )
25 {
26     if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
27     {
28         return LORAMAC_PARSER_ERROR_NPE;
29     }
30 
31     uint16_t bufItr = 0;
32 
33     macMsg->MHDR.Value = macMsg->Buffer[bufItr++];
34 
35     memcpy1( macMsg->JoinNonce, &macMsg->Buffer[bufItr], 3 );
36     bufItr = bufItr + 3;
37 
38     memcpy1( macMsg->NetID, &macMsg->Buffer[bufItr], 3 );
39     bufItr = bufItr + 3;
40 
41     macMsg->DevAddr = ( uint32_t ) macMsg->Buffer[bufItr++];
42     macMsg->DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 8 );
43     macMsg->DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 16 );
44     macMsg->DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 24 );
45 
46     macMsg->DLSettings.Value = macMsg->Buffer[bufItr++];
47 
48     macMsg->RxDelay = macMsg->Buffer[bufItr++];
49 
50     if( ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE - bufItr ) == LORAMAC_CF_LIST_FIELD_SIZE )
51     {
52         memcpy1( macMsg->CFList, &macMsg->Buffer[bufItr], LORAMAC_CF_LIST_FIELD_SIZE );
53         bufItr = bufItr + LORAMAC_CF_LIST_FIELD_SIZE;
54     }
55     else if( ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE - bufItr ) > 0 )
56     {
57         return LORAMAC_PARSER_FAIL;
58     }
59 
60     macMsg->MIC = ( uint32_t ) macMsg->Buffer[bufItr++];
61     macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 8 );
62     macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 16 );
63     macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 24 );
64 
65     return LORAMAC_PARSER_SUCCESS;
66 }
67 
LoRaMacParserData(LoRaMacMessageData_t * macMsg)68 LoRaMacParserStatus_t LoRaMacParserData( LoRaMacMessageData_t* macMsg )
69 {
70     if( ( macMsg == 0 ) || ( macMsg->Buffer == 0 ) )
71     {
72         return LORAMAC_PARSER_ERROR_NPE;
73     }
74 
75     uint16_t bufItr = 0;
76 
77     macMsg->MHDR.Value = macMsg->Buffer[bufItr++];
78 
79     macMsg->FHDR.DevAddr = macMsg->Buffer[bufItr++];
80     macMsg->FHDR.DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 8 );
81     macMsg->FHDR.DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 16 );
82     macMsg->FHDR.DevAddr |= ( ( uint32_t ) macMsg->Buffer[bufItr++] << 24 );
83 
84     macMsg->FHDR.FCtrl.Value = macMsg->Buffer[bufItr++];
85 
86     macMsg->FHDR.FCnt = macMsg->Buffer[bufItr++];
87     macMsg->FHDR.FCnt |= macMsg->Buffer[bufItr++] << 8;
88 
89     if( macMsg->FHDR.FCtrl.Bits.FOptsLen <= 15 )
90     {
91         memcpy1( macMsg->FHDR.FOpts, &macMsg->Buffer[bufItr], macMsg->FHDR.FCtrl.Bits.FOptsLen );
92         bufItr = bufItr + macMsg->FHDR.FCtrl.Bits.FOptsLen;
93     }
94     else
95     {
96         return LORAMAC_PARSER_FAIL;
97     }
98 
99     // Initialize anyway with zero.
100     macMsg->FPort = 0;
101     macMsg->FRMPayloadSize = 0;
102 
103     if( ( macMsg->BufSize - bufItr - LORAMAC_MIC_FIELD_SIZE ) > 0 )
104     {
105         macMsg->FPort = macMsg->Buffer[bufItr++];
106 
107         macMsg->FRMPayloadSize = ( macMsg->BufSize - bufItr - LORAMAC_MIC_FIELD_SIZE );
108         memcpy1( macMsg->FRMPayload, &macMsg->Buffer[bufItr], macMsg->FRMPayloadSize );
109         bufItr = bufItr + macMsg->FRMPayloadSize;
110     }
111 
112     macMsg->MIC = ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE )];
113     macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ) + 1] << 8 );
114     macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ) + 2] << 16 );
115     macMsg->MIC |= ( ( uint32_t ) macMsg->Buffer[( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ) + 3] << 24 );
116 
117     return LORAMAC_PARSER_SUCCESS;
118 }
119