ble_l2cap.h
Go to the documentation of this file.
1 /**
2 ****************************************************************************************
3 *
4 * @file ble_l2cap.h
5 *
6 * @brief BLE L2CAP API
7 *
8 ****************************************************************************************
9 * @attention
10 #####Copyright (c) 2019 GOODIX
11 All rights reserved.
12
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions are met:
15 * Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
17 * Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
20 * Neither the name of GOODIX nor the names of its contributors may be used
21 to endorse or promote products derived from this software without
22 specific prior written permission.
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 POSSIBILITY OF SUCH DAMAGE.
35 *****************************************************************************************
36 */
37
38 /**
39 * @addtogroup BLE
40 * @{
41 */
42
43 /**
44 @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP)
45 @{
46 @brief Definitions and prototypes for the L2CAP interface.
47 */
48
49 #ifndef __BLE_L2CAP_H__
50 #define __BLE_L2CAP_H__
51
52 #include "ble_error.h"
53 #include "gr55xx_sys_cfg.h"
54 #include <stdint.h>
55 #include <stdbool.h>
56
57 /**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations
58 * @{ */
59
60 /**@brief LE credit based disconnection reasons. */
61 typedef enum
62 {
63 REMOTE_USER_TERM_CON = 0x00, /**< Remote user terminates the connection. */
64 LOCAL_USER_TERM_CON = 0x01, /**< Local user terminates the connection. */
65 } lecb_disconnect_reason_t;
66
67 /** @} */
68
69 /** @addtogroup BLE_L2CAP_STRUCTURES Structures
70 * @{ */
71 /** @brief The parameter of LE credit based connection request packet sending.
72 * @note The le_psm should be registered by the peer device, otherwise the peer device will reject this request with result of LE_PSM not supported.
73 * @note The local_cid should be 0x0040-0x007F. If the local_cid is set to 0, the stack will assign it dynamically.
74 * @note The local_credit is required to be sure that at least one SDU can be received, otherwise the stack will use the default value: (MTU + MPS + 1) /MPS + 1.
75 * @note The MTU range is [23~max_mtu].
76 * @note The MPS range is [23~max_mps].
77 * @note About max_mtu and max_mps config, please see @ref ble_gap_l2cap_params_set.
78 */
79 typedef struct
80 {
81 uint16_t le_psm; /**< The le_psm number. */
82 uint16_t local_cid; /**< The local CID. */
83 uint16_t local_credits; /**< The local credits indicate the number of LE-frames that the peer device can send to the L2CAP layer entity sending the LE Credit Based Connection Request. */
84 uint16_t mtu; /**< The MTU field specifies the maximum SDU size (in octets) that the L2CAP layer entity sending the LE Credit Based Connection Request can receive on this channel. */
85 uint16_t mps; /**< The MPS field specifies the maximum payload size (in octets) that the L2CAP layer entity sending the LE Credit Based Connection Request is capable of receiving on this channel. */
86 } lecb_conn_req_t;
87
88 /** @brief LE credit based connection confirm parameter.
89 * @note The accept flag indicates whether the App accepts the LE Credit Based connection request.
90 * @note The peer_cid represents the channel endpoint on the peer device.
91 * @note The local_cid should be 0x0040-0x007F. If the local_cid is set to 0, the stack will assign it dynamically.
92 * @note The local_credits required to be sure that at least one SDU can be received, otherwise the stack will use the default value: (MTU + MPS + 1) /MPS + 1.
93 * @note The MTU range is [23~max_mtu].
94 * @note The MPS range is [23~max_mps].
95 * @note About the max_mtu and max_mps config, please see @ref ble_gap_l2cap_params_set.
96 */
97 typedef struct
98 {
99 bool accept; /**< Whether to accept the connection request. */
100 uint16_t peer_cid; /**< It represents the channel endpoint on the device sending the request and receiving the response. */
101 uint16_t local_cid; /**< Local CID. */
102 uint16_t local_credits; /**< It indicates the number of LE-frames that the peer device can send to the L2CAP layer entity sending the LE Credit Based Connection Respone. */
103 uint16_t mtu; /**< The MTU field specifies the maximum SDU size (in octets) that the L2CAP layer entity sending
104 the LE Credit Based Connection Request can receive on this channel. */
105 uint16_t mps; /**< The MPS field specifies the maximum payload size (in octets) that the L2CAP layer entity sending
106 the LE Credit Based Connection Request is capable of receiving on this channel. */
107 } lecb_cfm_conn_t;
108
109 /** @brief LE flow control credit packet parameter. */
110 typedef struct
111 {
112 uint16_t local_cid; /**< The local source channel ID. */
113 uint16_t credits; /**< Number of credits that the receiving device can increment. */
114 } lecb_add_credits_t;
115
116 /** @brief SDU packet parameter.
117 * @note The length should be less than peer_mtu when sending sdu packet.
118 * @note The credits is 0 if this packet is being sent, or it represents the number of credits consumed by this sdu if this packet is received.
119 * @note When the application receives a sdu, it should firstly copy this sdu packet before handling it, because the stack will free it after invoking the callback function.
120 * @note Similarly, the application should free the packet if it is malloced after invoking the function to send sdu packet.
121 */
122 typedef struct
123 {
124 uint16_t cid; /**< The local source channel. */
125 uint16_t credits; /**< The credits is 0 if this packet is being sent, otherwise it represents the number of credits consumed by the sdu. */
126 uint16_t length; /**< The lenght of data. */
127 uint8_t data[__ARRAY_EMPTY]; /**< The data of this sdu packet. */
128 } lecb_sdu_t;
129
130 /** @brief Receive LE credit based connection request packet indication. */
131 typedef struct
132 {
133 uint16_t le_psm; /**< Le_psm number that should be registered by local device. */
134 uint16_t peer_cid; /**< It represents the channel endpoint on the device sending the request and receiving the response. */
135 uint16_t peer_mtu; /**< It indicates the maximum SDU size (in octets) that the L2CAP layer entity sending the LE Credit
136 Based Connection Request can receive on this channel. */
137 uint16_t peer_mps; /**< It indicates the maximum payload size (in octets) that the L2CAP layer entity sending the LE Credit
138 Based Connection Request is capable of receiving on this channe. */
139 } lecb_conn_req_ind_t;
140
141 /** @brief LE credit based connection created indication. */
142 typedef struct
143 {
144 uint16_t le_psm; /**< Le_psm number. */
145 uint16_t local_cid; /**< The local source channel ID. */
146 uint16_t local_credits; /**< It indicates the number of LE-frames that the local device can receive. */
147 uint16_t peer_credits; /**< It indicates the number of LE-frames that the peer device can receive. */
148 uint16_t peer_mtu; /**< It indicates the maximum SDU size (in octets) that the L2CAP layer entity sending the LE Credit
149 Based Connection Request can receive on this channel. */
150 uint16_t peer_mps; /**< It indicates the maximum payload size (in octets) that the L2CAP layer entity sending the LE Credit
151 Based Connection Request is capable of receiving on this channe. */
152 } lecb_conn_ind_t;
153
154 /** @brief LE credit based disconnect indication. */
155 typedef struct
156 {
157 uint16_t local_cid; /**< The local source channel ID. */
158 uint8_t reason; /**< The reason for disconnection, see @ref lecb_disconnect_reason_t . */
159 } lecb_disconn_ind_t;
160
161 /** @brief LE credit based connection addition indication. */
162 typedef struct
163 {
164 uint16_t local_cid; /**< The local source channel ID. */
165 uint16_t peer_added_credits; /**< Represent number of credits the receiving device can increment. */
166 } lecb_add_credits_ind_t;
167
168 /** @brief LE credit based SDU sending complete event. */
169 typedef struct
170 {
171 uint16_t cid; /**< Channel ID that is the local CID. */
172 uint16_t credits; /**< Number of peer credit used. */
173 }lecb_sdu_send_evt_t;
174
175 /**@brief Callback registered by APP. */
176 typedef struct
177 {
178 void (*app_l2cap_lecb_conn_req_cb)(uint8_t conn_idx, lecb_conn_req_ind_t *p_conn_req); /**< Callback for receiving LE credit based connection request. */
179 void (*app_l2cap_lecb_conn_cb)(uint8_t conn_idx, uint8_t status, lecb_conn_ind_t *p_conn_ind); /**< Callback for receiving LE credit based connection created indication. */
180 void (*app_l2cap_lecb_add_credits_ind_cb)(uint8_t conn_idx, lecb_add_credits_ind_t *p_add_credits_ind); /**< Callback for receiving LE credit based connection addition indication. */
181 void (*app_l2cap_lecb_disconn_cb)(uint8_t conn_idx, uint8_t status, lecb_disconn_ind_t *p_disconn_ind); /**< Callback for receiving LE credit based disconnection indication. */
182 void (*app_l2cap_lecb_sdu_recv_cb)(uint8_t conn_idx, lecb_sdu_t *p_sdu); /**< Callback for receiving SDU packet. */
183 void (*app_l2cap_lecb_sdu_send_cb)(uint8_t conn_idx, uint8_t status, lecb_sdu_send_evt_t *p_sdu_send_evt); /**< Callback for sending SDU operation complete event. */
184 void (*app_l2cap_lecb_credit_add_cmp_cb)(uint8_t conn_idx, uint8_t status, uint16_t local_cid); /**< Callback for LE credit add complete event. */
185 } l2cap_lecb_cb_fun_t;
186
187
188 /** @} */
189
190 /** @addtogroup BLE_L2CAP_FUNCTIONS Functions
191 * @{ */
192 /**
193 ****************************************************************************************
194 * @brief Create the LE credit based connection.
195 * @note After the COC created, the callback @ref l2cap_lecb_cb_fun_t::app_l2cap_lecb_conn_cb will be called.
196 *
197 * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0, and the index will be increased one by one.
198 * @param[in] p_conn_req: Pointer to the LE Credit Based Connection Request structure.
199 *
200 * @retval ::SDK_SUCCESS: The LE Credit Based connection request is successfully set to the BLE stack.
201 * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied.
202 * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied.
203 * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources.
204 ****************************************************************************************
205 */
206 uint16_t ble_l2cap_lecb_conn_create(uint8_t conn_idx, const lecb_conn_req_t *p_conn_req);
207
208 /**
209 ****************************************************************************************
210 * @brief Confirm the LE credit based connection after receiving the connection request packet from the peer device.
211 * @note This function should be invoked in the handle of callback @ref l2cap_lecb_cb_fun_t::app_l2cap_lecb_conn_req_cb. And after the COC created,
212 * the callback @ref l2cap_lecb_cb_fun_t::app_l2cap_lecb_conn_cb should be called.
213 * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0 and the index will be increased one by one.
214 * @param[in] p_cfm_conn: Pointer to the LE Credit Based Connection Confirm structure.
215 *
216 * @retval ::SDK_SUCCESS: The LE Credit Based connection confirmation is successfully set to the BLE stack.
217 * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied.
218 * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied.
219 * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied.
220 * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources.
221 ****************************************************************************************
222 */
223 uint16_t ble_l2cap_lecb_conn_cfm(uint8_t conn_idx, const lecb_cfm_conn_t *p_cfm_conn);
224
225 /**
226 ****************************************************************************************
227 * @brief Disconnect the LE credit based connection.
228 * @note After COC disconnected, the callback @ref l2cap_lecb_cb_fun_t::app_l2cap_lecb_disconn_cb should be called.
229 *
230 * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0 and the index will be increased one by one.
231 * @param[in] local_cid: The local source channel ID.
232 *
233 * @retval ::SDK_SUCCESS: LE Credit Based disconnection request is successfully set to the BLE stack.
234 * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied.
235 * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources.
236 ****************************************************************************************
237 */
238 uint16_t ble_l2cap_lecb_disconnect(uint8_t conn_idx, uint16_t local_cid);
239
240 /**
241 ****************************************************************************************
242 * @brief Send a LE Flow Control Credit packet when the device is capable of receiving additional LE-frames (for example after the device has processed the sdu).
243 *
244 * @param[in] conn_idx: ACL connection index, the first ACL connection index is 0, and increased one by one.
245 * @param[in] p_add_credits: Pointer to the LE Flow Control Credit structure.
246 *
247 * @retval ::SDK_SUCCESS: LE Flow Control Credit packet is successfully set to the BLE stack.
248 * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied.
249 * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied.
250 * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources.
251 ****************************************************************************************
252 */
253 uint16_t ble_l2cap_lecb_credits_add(uint8_t conn_idx, const lecb_add_credits_t *p_add_credits);
254
255 /**
256 ****************************************************************************************
257 * @brief Send an SDU packet to the peer device.
258 *
259 * @param[in] conn_idx: ACL connection index. The first ACL connection index is 0 and the index will be increased one by one.
260 * @param[in] p_sdu: Pointer to the sdu packet structure.
261 *
262 * @retval ::SDK_SUCCESS: The sdu packet is successfully set to the BLE stack.
263 * @retval ::SDK_ERR_POINTER_NULL: Invalid pointer supplied.
264 * @retval ::SDK_ERR_INVALID_CONN_IDX: Invalid connection index supplied.
265 * @retval ::SDK_ERR_NO_RESOURCES: Not enough resources.
266 ****************************************************************************************
267 */
268 uint16_t ble_l2cap_lecb_sdu_send(uint8_t conn_idx, const lecb_sdu_t *p_sdu);
269
270 /**
271 ****************************************************************************************
272 * @brief Register the callback for the PSM.
273 *
274 * @param[in] le_psm: The le_psm number.
275 * @param[in] p_cb: Pointer to the callback structure.
276 *
277 * @retval ::SDK_SUCCESS: The callback is successfully registered to the BLE stack.
278 * @retval ::SDK_ERR_INVALID_PARAM: Invalid parameter supplied.
279 * @retval ::SDK_ERR_INVALID_PSM_EXCEEDED_MAX_PSM_NUM: The maximum PSM number limit is exceeded.
280 ****************************************************************************************
281 */
282 uint16_t ble_l2cap_lecb_cb_register(uint16_t le_psm, const l2cap_lecb_cb_fun_t *p_cb);
283
284 /** @} */
285
286 #endif
287
288 /**
289 @}
290 */
291 /** @} */
LOCAL_USER_TERM_CON
@ LOCAL_USER_TERM_CON
Local user terminates the connection.
Definition: ble_l2cap.h:64
lecb_conn_req_ind_t::peer_cid
uint16_t peer_cid
It represents the channel endpoint on the device sending the request and receiving the response.
Definition: ble_l2cap.h:134
lecb_add_credits_ind_t::local_cid
uint16_t local_cid
The local source channel ID.
Definition: ble_l2cap.h:164
__ARRAY_EMPTY
#define __ARRAY_EMPTY
Empty Array.
Definition: gr55xx_sys_cfg.h:57
lecb_cfm_conn_t::local_credits
uint16_t local_credits
It indicates the number of LE-frames that the peer device can send to the L2CAP layer entity sending ...
Definition: ble_l2cap.h:102
lecb_cfm_conn_t::peer_cid
uint16_t peer_cid
It represents the channel endpoint on the device sending the request and receiving the response.
Definition: ble_l2cap.h:100
lecb_conn_req_t::mps
uint16_t mps
The MPS field specifies the maximum payload size (in octets) that the L2CAP layer entity sending the ...
Definition: ble_l2cap.h:85
lecb_add_credits_ind_t
LE credit based connection addition indication.
Definition: ble_l2cap.h:163
lecb_cfm_conn_t::mtu
uint16_t mtu
The MTU field specifies the maximum SDU size (in octets) that the L2CAP layer entity sending the LE C...
Definition: ble_l2cap.h:103
lecb_cfm_conn_t
LE credit based connection confirm parameter.
Definition: ble_l2cap.h:98
lecb_add_credits_t::credits
uint16_t credits
Number of credits that the receiving device can increment.
Definition: ble_l2cap.h:113
lecb_conn_req_t::mtu
uint16_t mtu
The MTU field specifies the maximum SDU size (in octets) that the L2CAP layer entity sending the LE C...
Definition: ble_l2cap.h:84
ble_l2cap_lecb_disconnect
uint16_t ble_l2cap_lecb_disconnect(uint8_t conn_idx, uint16_t local_cid)
Disconnect the LE credit based connection.
lecb_sdu_t
SDU packet parameter.
Definition: ble_l2cap.h:123
lecb_sdu_t::cid
uint16_t cid
The local source channel.
Definition: ble_l2cap.h:124
lecb_cfm_conn_t::accept
bool accept
Whether to accept the connection request.
Definition: ble_l2cap.h:99
lecb_conn_ind_t::peer_mtu
uint16_t peer_mtu
It indicates the maximum SDU size (in octets) that the L2CAP layer entity sending the LE Credit Based...
Definition: ble_l2cap.h:148
gr55xx_sys_cfg.h
Define the chip configuration.
lecb_conn_ind_t::peer_credits
uint16_t peer_credits
It indicates the number of LE-frames that the peer device can receive.
Definition: ble_l2cap.h:147
lecb_conn_req_ind_t::peer_mps
uint16_t peer_mps
It indicates the maximum payload size (in octets) that the L2CAP layer entity sending the LE Credit B...
Definition: ble_l2cap.h:137
lecb_sdu_t::credits
uint16_t credits
The credits is 0 if this packet is being sent, otherwise it represents the number of credits consumed...
Definition: ble_l2cap.h:125
REMOTE_USER_TERM_CON
@ REMOTE_USER_TERM_CON
Remote user terminates the connection.
Definition: ble_l2cap.h:63
lecb_conn_req_ind_t::le_psm
uint16_t le_psm
Le_psm number that should be registered by local device.
Definition: ble_l2cap.h:133
lecb_disconn_ind_t::local_cid
uint16_t local_cid
The local source channel ID.
Definition: ble_l2cap.h:157
ble_error.h
File that contains error codes.
ble_l2cap_lecb_sdu_send
uint16_t ble_l2cap_lecb_sdu_send(uint8_t conn_idx, const lecb_sdu_t *p_sdu)
Send an SDU packet to the peer device.
lecb_conn_req_t::local_credits
uint16_t local_credits
The local credits indicate the number of LE-frames that the peer device can send to the L2CAP layer e...
Definition: ble_l2cap.h:83
lecb_disconn_ind_t::reason
uint8_t reason
The reason for disconnection, see lecb_disconnect_reason_t .
Definition: ble_l2cap.h:158
lecb_disconn_ind_t
LE credit based disconnect indication.
Definition: ble_l2cap.h:156
ble_l2cap_lecb_credits_add
uint16_t ble_l2cap_lecb_credits_add(uint8_t conn_idx, const lecb_add_credits_t *p_add_credits)
Send a LE Flow Control Credit packet when the device is capable of receiving additional LE-frames (fo...
lecb_add_credits_t::local_cid
uint16_t local_cid
The local source channel ID.
Definition: ble_l2cap.h:112
lecb_sdu_t::length
uint16_t length
The lenght of data.
Definition: ble_l2cap.h:126
lecb_conn_ind_t
LE credit based connection created indication.
Definition: ble_l2cap.h:143
lecb_add_credits_ind_t::peer_added_credits
uint16_t peer_added_credits
Represent number of credits the receiving device can increment.
Definition: ble_l2cap.h:165
lecb_conn_ind_t::peer_mps
uint16_t peer_mps
It indicates the maximum payload size (in octets) that the L2CAP layer entity sending the LE Credit B...
Definition: ble_l2cap.h:150
lecb_conn_ind_t::le_psm
uint16_t le_psm
Le_psm number.
Definition: ble_l2cap.h:144
lecb_sdu_send_evt_t::cid
uint16_t cid
Channel ID that is the local CID.
Definition: ble_l2cap.h:171
lecb_conn_req_ind_t
Receive LE credit based connection request packet indication.
Definition: ble_l2cap.h:132
ble_l2cap_lecb_conn_cfm
uint16_t ble_l2cap_lecb_conn_cfm(uint8_t conn_idx, const lecb_cfm_conn_t *p_cfm_conn)
Confirm the LE credit based connection after receiving the connection request packet from the peer de...
ble_l2cap_lecb_conn_create
uint16_t ble_l2cap_lecb_conn_create(uint8_t conn_idx, const lecb_conn_req_t *p_conn_req)
Create the LE credit based connection.
lecb_conn_ind_t::local_cid
uint16_t local_cid
The local source channel ID.
Definition: ble_l2cap.h:145
lecb_add_credits_t
LE flow control credit packet parameter.
Definition: ble_l2cap.h:111
ble_l2cap_lecb_cb_register
uint16_t ble_l2cap_lecb_cb_register(uint16_t le_psm, const l2cap_lecb_cb_fun_t *p_cb)
Register the callback for the PSM.
lecb_conn_req_t::le_psm
uint16_t le_psm
The le_psm number.
Definition: ble_l2cap.h:81
lecb_cfm_conn_t::mps
uint16_t mps
The MPS field specifies the maximum payload size (in octets) that the L2CAP layer entity sending the ...
Definition: ble_l2cap.h:105
lecb_conn_ind_t::local_credits
uint16_t local_credits
It indicates the number of LE-frames that the local device can receive.
Definition: ble_l2cap.h:146
l2cap_lecb_cb_fun_t
Callback registered by APP.
Definition: ble_l2cap.h:177
lecb_cfm_conn_t::local_cid
uint16_t local_cid
Local CID.
Definition: ble_l2cap.h:101
lecb_sdu_send_evt_t
LE credit based SDU sending complete event.
Definition: ble_l2cap.h:170
lecb_disconnect_reason_t
lecb_disconnect_reason_t
LE credit based disconnection reasons.
Definition: ble_l2cap.h:62
lecb_sdu_send_evt_t::credits
uint16_t credits
Number of peer credit used.
Definition: ble_l2cap.h:172
lecb_conn_req_t
The parameter of LE credit based connection request packet sending.
Definition: ble_l2cap.h:80
lecb_conn_req_ind_t::peer_mtu
uint16_t peer_mtu
It indicates the maximum SDU size (in octets) that the L2CAP layer entity sending the LE Credit Based...
Definition: ble_l2cap.h:135
lecb_conn_req_t::local_cid
uint16_t local_cid
The local CID.
Definition: ble_l2cap.h:82