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