1 #ifndef L2CC_H_
2 #define L2CC_H_
3 
4 /**
5  ****************************************************************************************
6  * @addtogroup L2CC L2CAP Controller
7  * @ingroup L2C
8  * @brief L2CAP block for data processing and per device connection
9  *
10  * The L2CC is responsible for all the data processing related
11  * functions of the L2CAP block per device connection.
12  *
13  * @{
14  ****************************************************************************************
15  */
16 
17 /*
18  * INCLUDE FILES
19  ****************************************************************************************
20  */
21 
22 #include "rwip_config.h"
23 
24 #if (BLE_L2CC)
25 
26 #include "l2cc_task.h"
27 #include "l2cc_pdu.h"
28 
29 #include <stdint.h>
30 #include <stdbool.h>
31 #include "co_list.h"
32 #include "ke_task.h"
33 
34 /*
35  * DEFINES
36  ****************************************************************************************
37  */
38 
39 /**
40  ****************************************************************************************
41  * @brief Generic way to creates and allocate a Signaling PDU message that can be then
42  *        sent to peer device
43  *
44  * @param[in] conidx        Connection Index
45  * @param[in] code          PDU code
46  * @param[in] src_id        Source task ID
47  *
48  * @return Pointer to the PDU payload
49  ****************************************************************************************
50  */
51 #define L2CC_SIG_PDU_ALLOC(conidx, code, src_id, type) \
52     ((struct type*) l2cc_pdu_alloc(conidx, L2C_CID_LE_SIGNALING, code, src_id, 0))
53 
54 /// from PDU, retrieve the send command
55 #define L2CC_PDU_TO_CMD(_pdu) \
56     ((struct l2cc_pdu_send_cmd*) (((uint8_t*)_pdu) - offsetof(struct l2cc_pdu_send_cmd, pdu.data.code)))
57 
58 /// from PDU, retrieve the receive indication
59 #define L2CC_PDU_TO_IND(_pdu) \
60     ((struct l2cc_pdu_recv_ind*) (((uint8_t*)_pdu) - offsetof(struct l2cc_pdu_recv_ind, pdu.data.code)))
61 
62 
63 /**
64  ****************************************************************************************
65  * @brief Generic way to creates and allocate a SMP PDU message that can be then sent to
66  *        peer device
67  *
68  * @param[in] conidx        Connection Index
69  * @param[in] code          PDU code
70  * @param[in] src_id        Source task ID
71  *
72  * @return Pointer to the PDU payload
73  ****************************************************************************************
74  */
75 #define L2CC_SMP_PDU_ALLOC(conidx, code, src_id, type) \
76     ((struct type*) l2cc_pdu_alloc(conidx, L2C_CID_SECURITY, code, src_id, 0))
77 
78 
79 /**
80  ****************************************************************************************
81  * @brief Generic way to creates and allocate an ATT PDU message that can be then sent to
82  *        peer device
83  *
84  * @param[in] conidx        Connection Index
85  * @param[in] code          PDU code
86  * @param[in] src_id        Source task ID
87  *
88  * @return Pointer to the PDU payload
89  ****************************************************************************************
90  */
91 #define L2CC_ATT_PDU_ALLOC(conidx, code, src_id, type)\
92     ((struct type*) l2cc_pdu_alloc(conidx, L2C_CID_ATTRIBUTE, code, src_id, 0))
93 
94 
95 /**
96  ****************************************************************************************
97  * @brief Generic way to creates and allocate an ATT PDU message that can be then sent to
98  *        peer device
99  *
100  * @param[in] conidx        Connection Index
101  * @param[in] code          PDU code
102  * @param[in] src_id        Source task ID
103  * @param[in] length        Dynamic payload length to allocate
104  *
105  * @return Pointer to the PDU payload
106  ****************************************************************************************
107  */
108 #define L2CC_ATT_PDU_ALLOC_DYN(conidx, code, src_id, type, length)\
109     ((struct type*) l2cc_pdu_alloc(conidx, L2C_CID_ATTRIBUTE, code, src_id, length))
110 
111 /*
112  * INTERNAL MESSAGES API TYPES
113  ****************************************************************************************
114  */
115 
116 
117 
118 /// Send Debug PDU data
119 struct l2cc_dbg_pdu_send_cmd
120 {
121     /// L2CC request type (@see enum l2cc_operation):
122     /// - L2CC_DBG_PDU_SEND: Send a PDU
123     uint8_t operation;
124     /// offset value information
125     uint16_t offset;
126     /// PDU Data
127     struct l2cc_dbg_pdu pdu;
128 };
129 
130 /// Debug PDU data received
131 struct l2cc_dbg_pdu_recv_ind
132 {
133     /// Status information
134     uint8_t status;
135     /// offset value information
136     uint16_t offset;
137     /// PDU Data
138     struct l2cc_dbg_pdu pdu;
139 };
140 
141 /// Send Legacy PDU data
142 struct l2cc_pdu_send_cmd
143 {
144     /// L2CC request type (@see enum l2cc_operation):
145     /// - L2CC_PDU_SEND: Send internal LE Legacy PDU
146     uint8_t operation;
147     /// offset value information
148     uint16_t offset;
149     /// PDU Data
150     struct l2cc_pdu pdu;
151 };
152 
153 
154 /// Legacy PDU data received
155 struct l2cc_pdu_recv_ind
156 {
157     /// Status information
158     uint8_t status;
159     /// offset value information
160     uint16_t offset;
161     /// PDU Data
162     struct l2cc_pdu pdu;
163 };
164 
165 /// Operation type
166 enum l2cc_op_type
167 {
168     /// Operation used for signaling protocol message exchange
169     L2CC_OP_SIG      = 0x00,
170     /// Max number of operations
171     L2CC_OP_MAX,
172 };
173 
174 /*
175  * STRUCTURES
176  ****************************************************************************************
177  */
178 
179 
180 
181 /// L2CAP environment structure
182 struct l2cc_env_tag
183 {
184     /// Ongoing operation
185     void* operation[L2CC_OP_MAX];
186 
187     /// Buffer in TX queue
188     struct co_list tx_queue;
189     /// Buffer currently receiving data
190     struct ke_msg* rx_buffer;
191     #if (BLE_LECB)
192     /// List of LE credit based connections
193     struct co_list lecb_list;
194     #endif // (BLE_LECB)
195 
196     /// Length of PDU still expected
197     uint16_t rx_pdu_rem_len;
198 
199 };
200 
201 
202 
203 /*
204  * FUNCTION DECLARATIONS
205  ****************************************************************************************
206  */
207 
208 /**
209  ****************************************************************************************
210  * @brief Generic way to creates and allocate a PDU message that can be then sent to peer
211  *        device
212  *
213  * @note use L2CC_SIG_PDU_ALLOC, L2CC_SMP_PDU_ALLOC, L2CC_ATT_PDU_ALLOC
214  *       or L2CC_ATT_PDU_ALLOC_DYN instead of direct function call
215  *
216  * @param[in] conidx        Connection Index
217  * @param[in] cid           Channel Identifier
218  * @param[in] code          PDU code
219  * @param[in] src_id        Source task ID
220  * @param[in] length        Dynamic payload length to allocate
221  *
222  * @return Generic pointer to the PDU payload
223  ****************************************************************************************
224  */
225 void* l2cc_pdu_alloc(uint8_t conidx, uint16_t cid, uint8_t code, ke_task_id_t src_id, uint16_t length);
226 
227 /**
228  ****************************************************************************************
229  * @brief Generic way to send the PDU message
230  *
231  * @param[in] pdu           PDU message to send to peer device
232  ****************************************************************************************
233  */
234 void l2cc_pdu_send(void* pdu);
235 
236 #endif //(BLE_L2CC)
237 
238 /// @} L2CC
239 
240 #endif // L2CC_H_
241