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