• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 #ifndef L2CAP_COC_H_
19 #define L2CAP_COC_H_
20 
21 #if (L2CAP_CREDIT_BASED_FLOW_CONTROL_MODE_EN)
22 
23 #define L2CAP_CHANNEL_MAX_COUNT 64
24 
25 #define L2CAP_COC_CID_START 0X0040
26 #define L2CAP_COC_CID_END   0X007F
27 
28 /**
29  * @brief		Gets the size of the buffer needed to register the service.
30  * @param[in]	srvCount - Maximum number of Services supported.
31  * @param[in]	chCount  - Maximum number of Channels supported. (<L2CAP_CHANNEL_MAX_COUNT)
32  * @param[in]	mtu      - Maximum Transmission Unit.
33  * @return		The size of the buffer needed to register the service.
34  */
35 #define BLC_L2CAP_COC_MTU_NEEDLEN(srvCount, chCount, mtu) (srvCount * chCount * mtu)
36 /**
37  * @brief		Gets the size of the buffer needed to initialize the service.
38  * @param[in]	connCount - Maximum number of connections supported.
39  * @param[in]	srvCount  - Maximum number of Services supported.
40  * @param[in]	chCount   - Maximum number of Channels supported. (<L2CAP_CHANNEL_MAX_COUNT)
41  * @return		The size of the buffer needed to initialize the service.
42  */
43 #define BLC_L2CAP_COC_INIT_NEEDLEN(connCount, srvCount, chCount)                                                      \
44     ((connCount) * sizeof(l2cap_coc_handle_t) + (srvCount) * sizeof(l2cap_coc_service_t) +                            \
45      (chCount) * sizeof(l2cap_coc_channel_t))
46 
47 enum L2CAP_COC_PSM_ENUM {
48     L2CAP_COC_SPSM_EATT = 0x0027,  // L2CAP_COC_START_CREADIT_CONNECT
49     L2CAP_COC_SPSM_OTS = 0x0025,   // L2CAP_COC_START_LE_CREADIT_CONNECT
50                                    // L2CAP_COC_LE_PSM   = L2CAP_COC_SPSM_OTS,
51 };
52 enum L2CAP_COC_START_METHOD_ENUM {
53     L2CAP_COC_START_CREADIT_CONNECT = 0,     // Send blc_l2cap_sendCreditBasedConnectReq
54     L2CAP_COC_START_LE_CREADIT_CONNECT = 1,  // Send blc_l2cap_sendLECreditBasedConnectReq
55 };
56 
57 /**
58  * @brief		The interface type for the Event callback of the COC service.
59  * @param[in]	evtID - The event ID. Refer to "gap_event.h".
60  * @param[in]	pData - The included data of the event.
61  * @param[in]	dataLen - The length of the pData.
62  */
63 typedef int (*blc_l2cap_coc_evtcb)(u16 evtID, u8 *pData, u16 dataLen);
64 /**
65  * @brief		The interface type for the RecvData callback of the COC service.
66  * @param[in]	aclHandle - The connection handle
67  * @param[in]	scid      - Source Channel ID.
68  * @param[in]	dcid      - Destination Channel ID.
69  * @param[in]	pData     - The data received.
70  * @param[in]	dataLen   - The length of the data received.
71  */
72 typedef int (*blc_l2cap_coc_datacb)(u16 aclHandle, u16 scid, u16 dcid, u16 dataLen, u8 *pData);
73 
74 typedef struct {
75     u8 stat : 4;
76     u8 opts : 4;
77     u8 chID;    // channel identifier
78     u8 supChs;  // Bit[7~4]-Supported channel count; bit[3~0]-Now channel count.
79     u8 nowChs;
80     u8 *pBuffer;  // Sdu Buffer
81 
82     u16 newMtu;
83     u16 newMps;
84 
85     u16 spsm;
86     u16 aclHandle;  // connect aclHandle
87 
88     u16 ownMtu;
89     u16 ownMps;
90     u16 ownCredits;
91     u16 peerMtu;
92     u16 peerMps;
93     u16 peerCredits;
94 
95     u16 scid[5];
96     u16 dcid[5];
97 
98     void *pUsrArg;
99     blc_l2cap_coc_evtcb cb;
100     blc_l2cap_coc_evtcb evtCb;
101     blc_l2cap_coc_datacb dataCb;
102 } l2cap_coc_service_t;
103 
104 typedef struct {
105     u8 stat;
106     u8 srvNum;
107     u16 resv;
108 
109     u16 sduLen;
110     u16 recvLen;
111 
112     u16 recvCredits;
113     u16 sendCredits;
114 
115     u8 *pSdu;
116 } l2cap_coc_channel_t;
117 
118 typedef struct {
119     u8 isUsed;
120     u8 isCocPkt;  // Prev Is COC Packet
121     u16 aclHandle;
122     u16 cocPendLen;
123     u16 cocPendScid;
124 } l2cap_coc_handle_t;
125 
126 /**
127  * @brief		Initialize the COC parameters and set the buffer required for the COC.
128  * @param[in]	connCount    - Maximum number of connections supported.
129  * @param[in]	serviceCount - Maximum number of Services supported.
130  * @param[in]	channelCount - Maximum number of Channels supported. (<L2CAP_CHANNEL_MAX_COUNT)
131  * @param[in]	*pBuffer     - The buffer required for the COC.
132  * @param[in]	buffLen      - the size of of "pBuffer", Refer to BLC_L2CAP_COC_INIT_NEEDLEN.
133  * @return		0: success;
134  *             -1: pBuffer is not enough.
135  */
136 int blc_l2cap_cocInit(u8 connCount, u8 serviceCount, u8 channelCount, u8 *pBuffer, u16 buffLen);
137 
138 /**
139  * @brief		Bind a connection to a COC processing flow.
140  *              The received data from the COC is not available until the binding is completed.
141  * @param[in]	aclHandle - The connection handle to be bound.
142  * @return		0: success;
143  *             -1: The handle is already bound.
144  *             -2: The resource is insufficient. (The maximum number of connections was exceeded)
145  */
146 int blc_l2cap_cocConnectHandler(u16 aclHandle);
147 /**
148  * @brief		Release the connection from the COC processing flow.
149  * @param[in]	aclHandle - The connection handle to be bound.
150  * @return		none.
151  */
152 void blc_l2cap_cocDisconnHandler(u16 aclHandle);
153 
154 /**
155  * @brief		Register the COC service into L2CAP. After registration,
156  *              the corresponding service is activated, and then the user can call "startService" to start the service.
157  * @param[in]	spsm - Simplified Protocol/Service Multiplexer. Refer to L2CAP_COC_PSM_ENUM.
158  * @param[in]	srvCount - Number of registered services.
159  * @param[in]	chCount - Number of Channels per service.
160  * @param[in]	mtu     - Maximum Transmission Unit.
161  * @param[in]	mps     - Maximum PDU Payload Size.
162  * @param[in]	credits - Initial Credits. (>0)
163  * @param[in]	pBuffer - A buffer to store data. You can use BLC_L2CAP_COC_MTU_NEEDLEN to calculate the required size.
164  * @param[in]	evtCb   - The callback of Event.
165  * @param[in]	dataCb  - The callback of RecvData.
166  * @return    >=0: Number of services successfully registered;
167  *             -1: Incorrect input parameter;
168  *             -2: The resource is insufficient;
169  *             -3: Unknown Error.
170  */
171 int blc_l2cap_registerService(u16 spsm, u8 srvCount, u8 chCount, u16 mtu, u16 mps, u16 credits, u8 *pBuffer,
172                               blc_l2cap_coc_evtcb evtCb, blc_l2cap_coc_datacb dataCb);
173 /**
174  * @brief		Start the COC service. The interface automatically finds the relevant SPSM service,
175  *              binds it to ConnHandle, and sends the start instruction packet.
176  * @param[in]	aclHandle - The connection handle to be bound.
177  * @param[in]	spsm      - Simplified Protocol/Service Multiplexer. Refer to L2CAP_COC_PSM_ENUM.
178  * @param[in]	method    - Refer to L2CAP_COC_START_METHOD_ENUM.
179  * @return		0: success;
180  *             -1: The AclHandle is not in a connected state;
181  *             -2: There is no available service.
182  *             -3: The service's state is error. (eg, Busy.)
183  *             -4: There is no available channel.
184  *                 (This interface can be called multiple times so that all Channels are created.)
185  *             -5: Failed to push data to Controller.
186  */
187 int blc_l2cap_startService(u16 aclHandle, u16 spsm, u8 method);
188 /**
189  * @brief		Stop the COC service.
190  * @param[in]	aclHandle - The connection handle to be bound.
191  * @param[in]	spsm      - Simplified Protocol/Service Multiplexer. Refer to L2CAP_COC_PSM_ENUM.
192  * @return		0: success;
193  *             -1: The Service is not started;
194  *             -2: The Service's state is error. (eg, Busy.)
195  */
196 int blc_l2cap_stopService(u16 aclHandle, u16 spsm);
197 /**
198  * @brief		Disconnects the specified channel.
199  *              Once disconnected, the user can also call "startService" to recreate it.
200  * @param[in]	aclHandle - The connection handle.
201  * @param[in]	scid      - Source Channel ID. (local CID)
202  * @return		0: success;
203  *             -1: The SCID is no available;
204  *             -2: The Service is not started;
205  *             -3: The Channel's state is error;
206  *             -4: Failed to push data to Controller.
207  */
208 int blc_l2cap_disconnScid(u16 aclHandle, u16 scid);
209 
210 /**
211  * @brief		Reconfigure the MTU and MPS of the COC service.
212  *              This interface can only be invoked when the service is idle.
213  *              It is not stable at the moment, please use with caution!
214  * @param[in]	aclHandle - The connection handle.
215  * @param[in]	srvNum    - Service ID.
216  * @param[in]	mtu     - Maximum Transmission Unit.
217  * @param[in]	mps     - Maximum PDU Payload Size.
218  * @return		0: success;
219  *             -1: The srvNum is no available;
220  *             -2: The Service's state is error;
221  *             >0: Failed to push data to Controller. Refer to ble_sts_t.
222  */
223 int blc_l2cap_reconfigService(u8 srvNum, u16 mtu, u16 mps);
224 /**
225  * @brief		Get the SPSM of the corresponding service.
226  * @param[in]	aclHandle - The connection handle.
227  * @param[in]	srvNum    - Service ID.
228  * @return		SPSM. (0-fail)
229  */
230 u16 blc_l2cap_getSpsmBySrvnum(u8 srvNum);
231 /**
232  * @brief		Get the "SrvNum" by "ConnHandle" and "SPSM".
233  * @param[in]	aclHandle - The connection handle.
234  * @param[in]	spsm      - Simplified Protocol/Service Multiplexer. Refer to L2CAP_COC_PSM_ENUM.
235  * @return		SrvNum. (0-fail)
236  */
237 u8 blc_l2cap_getSrvnumBySpsm(u16 aclHandle, u16 spsm);
238 
239 /**
240  * @brief		Sends data to the specified channel.
241  * @param[in]	aclHandle - The connection handle.
242  * @param[in]	scid      - Source Channel ID. (local CID)
243  * @param[in]	pHead     - The first part of the data to be sent.
244  * @param[in]	headLen   - The length of the data's first part.
245  * @param[in]	pData     - The second part of the data to be sent.
246  * @param[in]	dataLen   - The length of the data's second part.
247  * @return		0: success;
248  *             -1: The parameter is error.
249  *             -2: The SCID is no available.
250  *             >0: Failed to push data to Controller. Refer to ble_sts_t.
251  */
252 int blc_l2cap_cocSendData(u16 aclHandle, u16 scid, u8 *pHead, u8 headLen, u8 *pData, u16 dataLen);
253 
254 #endif  // #if (L2CAP_CREDIT_BASED_FLOW_CONTROL_MODE_EN)
255 
256 #endif /* L2CAP_COC_H_ */
257