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 #include <stdint.h>
27 
28 /*!
29  * If set to 1 the new API defining \ref FragDecoderWrite and
30  * \ref FragDecoderReadfunction callbacks is used.
31  */
32 #define FRAG_DECODER_FILE_HANDLING_NEW_API          1
33 
34 /*!
35  * Maximum number of fragment that can be handled.
36  *
37  * \remark This parameter has an impact on the memory footprint.
38  */
39 #define FRAG_MAX_NB                                 21
40 
41 /*!
42  * Maximum fragment size that can be handled.
43  *
44  * \remark This parameter has an impact on the memory footprint.
45  */
46 #define FRAG_MAX_SIZE                               50
47 
48 /*!
49  * Maximum number of extra frames that can be handled.
50  *
51  * \remark This parameter has an impact on the memory footprint.
52  */
53 #define FRAG_MAX_REDUNDANCY                         5
54 
55 #define FRAG_SESSION_FINISHED                       ( int32_t )0
56 #define FRAG_SESSION_NOT_STARTED                    ( int32_t )-2
57 #define FRAG_SESSION_ONGOING                        ( int32_t )-1
58 
59 typedef struct sFragDecoderStatus
60 {
61     uint16_t FragNbRx;
62     uint16_t FragNbLost;
63     uint16_t FragNbLastRx;
64     uint8_t MatrixError;
65 }FragDecoderStatus_t;
66 
67 #if( FRAG_DECODER_FILE_HANDLING_NEW_API == 1 )
68 typedef struct sFragDecoderCallbacks
69 {
70     /*!
71      * Writes `data` buffer of `size` starting at address `addr`
72      *
73      * \param [IN] addr Address start index to write to.
74      * \param [IN] data Data buffer to be written.
75      * \param [IN] size Size of data buffer to be written.
76      *
77      * \retval status Write operation status [0: Success, -1 Fail]
78      */
79     int8_t ( *FragDecoderWrite )( uint32_t addr, uint8_t *data, uint32_t size );
80     /*!
81      * Reads `data` buffer of `size` starting at address `addr`
82      *
83      * \param [IN] addr Address start index to read from.
84      * \param [IN] data Data buffer to be read.
85      * \param [IN] size Size of data buffer to be read.
86      *
87      * \retval status Read operation status [0: Success, -1 Fail]
88      */
89     int8_t ( *FragDecoderRead )( uint32_t addr, uint8_t *data, uint32_t size );
90 }FragDecoderCallbacks_t;
91 #endif
92 
93 #if( FRAG_DECODER_FILE_HANDLING_NEW_API == 1 )
94 /*!
95  * \brief Initializes the fragmentation decoder
96  *
97  * \param [IN] fragNb     Number of expected fragments (without redundancy packets)
98  * \param [IN] fragSize   Size of a fragment
99  * \param [IN] callbacks  Pointer to the Write/Read functions.
100  */
101 void FragDecoderInit( uint16_t fragNb, uint8_t fragSize, FragDecoderCallbacks_t *callbacks );
102 #else
103 /*!
104  * \brief Initializes the fragmentation decoder
105  *
106  * \param [IN] fragNb     Number of expected fragments (without redundancy packets)
107  * \param [IN] fragSize   Size of a fragment
108  * \param [IN] file       Pointer to file buffer size
109  * \param [IN] fileSize   File buffer size
110  */
111 void FragDecoderInit( uint16_t fragNb, uint8_t fragSize, uint8_t *file, uint32_t fileSize );
112 #endif
113 
114 #if( FRAG_DECODER_FILE_HANDLING_NEW_API == 1 )
115 /*!
116  * \brief Gets the maximum file size that can be received
117  *
118  * \retval size FileSize
119  */
120 uint32_t FragDecoderGetMaxFileSize( void );
121 #endif
122 
123 /*!
124  * \brief Function to decode and reconstruct the binary file
125  *        Called for each receive frame
126  *
127  * \param [IN] fragCounter Fragment counter [1..(FragDecoder.FragNb + FragDecoder.Redundancy)]
128  * \param [IN] rawData     Pointer to the fragment to be processed (length = FragDecoder.FragSize)
129  *
130  * \retval status          Process status. [FRAG_SESSION_ONGOING,
131  *                                          FRAG_SESSION_FINISHED or
132  *                                          FragDecoder.Status.FragNbLost]
133  */
134 int32_t FragDecoderProcess( uint16_t fragCounter, uint8_t *rawData );
135 
136 /*!
137  * \brief Gets the current fragmentation status
138  *
139  * \retval status Fragmentation decoder status
140  */
141 FragDecoderStatus_t FragDecoderGetStatus( void );
142 
143 #endif // __FRAG_DECODER_H__
144