1 /*!
2  * \file      FragDecoder.h
3  *
4  * \brief     Implements the LoRa-Alliance fragmentation decoder
5  *            Specification: https://lora-alliance.org/sites/default/files/2018-09/fragmented_data_block_transport_v1.0.0.pdf
6  *
7  * \copyright Revised BSD License, see section \ref LICENSE.
8  *
9  * \code
10  *                ______                              _
11  *               / _____)             _              | |
12  *              ( (____  _____ ____ _| |_ _____  ____| |__
13  *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
14  *               _____) ) ____| | | || |_| ____( (___| | | |
15  *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
16  *              (C)2013-2018 Semtech
17  *
18  * \endcode
19  *
20  * \author    Fabien Holin ( Semtech )
21  * \author    Miguel Luis ( Semtech )
22  */
23 #ifndef __FRAG_DECODER_H__
24 #define __FRAG_DECODER_H__
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include <stdint.h>
31 
32 /*!
33  * If set to 1 the new API defining \ref FragDecoderWrite and
34  * \ref FragDecoderReadfunction callbacks is used.
35  */
36 #define FRAG_DECODER_FILE_HANDLING_NEW_API          1
37 
38 /*!
39  * Maximum number of fragment that can be handled.
40  *
41  * \remark This parameter has an impact on the memory footprint.
42  */
43 #ifdef __ZEPHYR__
44 #define FRAG_MAX_NB \
45     (CONFIG_LORAWAN_FRAG_TRANSPORT_IMAGE_SIZE / CONFIG_LORAWAN_FRAG_TRANSPORT_MIN_FRAG_SIZE + 1)
46 #else
47 #define FRAG_MAX_NB                                 21
48 #endif
49 
50 /*!
51  * Maximum fragment size that can be handled.
52  *
53  * \remark This parameter has an impact on the memory footprint.
54  */
55 #ifdef __ZEPHYR__
56 #define FRAG_MAX_SIZE CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_FRAG_SIZE
57 #else
58 #define FRAG_MAX_SIZE                               50
59 #endif
60 
61 /*!
62  * Maximum number of extra frames that can be handled.
63  *
64  * \remark This parameter has an impact on the memory footprint.
65  */
66 #ifdef __ZEPHYR__
67 #define FRAG_MAX_REDUNDANCY \
68     (FRAG_MAX_NB * CONFIG_LORAWAN_FRAG_TRANSPORT_MAX_REDUNDANCY / 100)
69 #else
70 #define FRAG_MAX_REDUNDANCY                         5
71 #endif
72 
73 #define FRAG_SESSION_FINISHED                       ( int32_t )0
74 #define FRAG_SESSION_NOT_STARTED                    ( int32_t )-2
75 #define FRAG_SESSION_ONGOING                        ( int32_t )-1
76 
77 typedef struct sFragDecoderStatus
78 {
79     uint16_t FragNbRx;
80     uint16_t FragNbLost;
81     uint16_t FragNbLastRx;
82     uint8_t MatrixError;
83 }FragDecoderStatus_t;
84 
85 #if( FRAG_DECODER_FILE_HANDLING_NEW_API == 1 )
86 typedef struct sFragDecoderCallbacks
87 {
88     /*!
89      * Writes `data` buffer of `size` starting at address `addr`
90      *
91      * \param [IN] addr Address start index to write to.
92      * \param [IN] data Data buffer to be written.
93      * \param [IN] size Size of data buffer to be written.
94      *
95      * \retval status Write operation status [0: Success, -1 Fail]
96      */
97     int8_t ( *FragDecoderWrite )( uint32_t addr, uint8_t *data, uint32_t size );
98     /*!
99      * Reads `data` buffer of `size` starting at address `addr`
100      *
101      * \param [IN] addr Address start index to read from.
102      * \param [IN] data Data buffer to be read.
103      * \param [IN] size Size of data buffer to be read.
104      *
105      * \retval status Read operation status [0: Success, -1 Fail]
106      */
107     int8_t ( *FragDecoderRead )( uint32_t addr, uint8_t *data, uint32_t size );
108 }FragDecoderCallbacks_t;
109 #endif
110 
111 #if( FRAG_DECODER_FILE_HANDLING_NEW_API == 1 )
112 /*!
113  * \brief Initializes the fragmentation decoder
114  *
115  * \param [IN] fragNb     Number of expected fragments (without redundancy packets)
116  * \param [IN] fragSize   Size of a fragment
117  * \param [IN] callbacks  Pointer to the Write/Read functions.
118  */
119 void FragDecoderInit( uint16_t fragNb, uint8_t fragSize, FragDecoderCallbacks_t *callbacks );
120 #else
121 /*!
122  * \brief Initializes the fragmentation decoder
123  *
124  * \param [IN] fragNb     Number of expected fragments (without redundancy packets)
125  * \param [IN] fragSize   Size of a fragment
126  * \param [IN] file       Pointer to file buffer size
127  * \param [IN] fileSize   File buffer size
128  */
129 void FragDecoderInit( uint16_t fragNb, uint8_t fragSize, uint8_t *file, uint32_t fileSize );
130 #endif
131 
132 #if( FRAG_DECODER_FILE_HANDLING_NEW_API == 1 )
133 /*!
134  * \brief Gets the maximum file size that can be received
135  *
136  * \retval size FileSize
137  */
138 uint32_t FragDecoderGetMaxFileSize( void );
139 #endif
140 
141 /*!
142  * \brief Function to decode and reconstruct the binary file
143  *        Called for each receive frame
144  *
145  * \param [IN] fragCounter Fragment counter [1..(FragDecoder.FragNb + FragDecoder.Redundancy)]
146  * \param [IN] rawData     Pointer to the fragment to be processed (length = FragDecoder.FragSize)
147  *
148  * \retval status          Process status. [FRAG_SESSION_ONGOING,
149  *                                          FRAG_SESSION_FINISHED or
150  *                                          FragDecoder.Status.FragNbLost]
151  */
152 int32_t FragDecoderProcess( uint16_t fragCounter, uint8_t *rawData );
153 
154 /*!
155  * \brief Gets the current fragmentation status
156  *
157  * \retval status Fragmentation decoder status
158  */
159 FragDecoderStatus_t FragDecoderGetStatus( void );
160 
161 #ifdef __cplusplus
162 }
163 #endif
164 
165 #endif // __FRAG_DECODER_H__
166