1 /****************************************************************************** 2 * 3 * Copyright (C) 2009-2018 Realtek Corporation. 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 /****************************************************************************** 19 * 20 * Module Name: 21 * bt_skbuff.h 22 * 23 * Abstract: 24 * Data buffer managerment through whole bluetooth stack. 25 * 26 * Major Change History: 27 * When Who What 28 * -------------------------------------------------------------- 29 * 2010-06-11 W.Bi Created. 30 * 31 * Notes: 32 * To reduce memory copy when pass data buffer to other layers, 33 * RTK_BUFFER is designed referring to linux socket buffer. 34 * But I still wonder its effect, since RTK_BUFFER is much bigger 35 * than original data buffer.RTK_BUFFER will reduce its member if 36 * it would not reach what i had expected. 37 * 38 ******************************************************************************/ 39 40 #ifndef BT_SKBUFF_H 41 #define BT_SKBUFF_H 42 #include "bt_list.h" 43 #include <stdbool.h> 44 #include <sys/types.h> 45 #include "bt_vendor_lib.h" 46 47 #ifndef EXTERN 48 #define EXTERN 49 #endif 50 51 #ifndef IN 52 #define IN 53 #endif 54 55 #ifndef OUT 56 #define OUT 57 #endif 58 /*---------------------------------------------------------------------------------- 59 CONSTANT DEFINITION 60 ----------------------------------------------------------------------------------*/ 61 #define RTK_CONTEXT_SIZE 12 62 63 #define RTB_QUEUE_ID_LENGTH 64 64 65 /*---------------------------------------------------------------------------------- 66 STRUCTURE DEFINITION 67 ----------------------------------------------------------------------------------*/ 68 /** 69 Rtk buffer definition 70 Head -->|<---Data--->|<-----Length------>| <---End 71 _________________________________ 72 |_____________|___________________| 73 |<-headroom->|<--RealDataBuffer-->| 74 75 Compared to socket buffer, there exists no tail and end pointer and tailroom as tail is rarely used in bluetooth stack 76 \param List : List structure used to list same type rtk buffer and manipulate rtk buffer like list. 77 \param Head : Pointer to truly allocated data buffer. It point to the headroom 78 \param Data : Pointer to real data buffer. 79 \param Length : currently data length 80 \param HeadRoom : Record initialize headroom size. 81 \param RefCount : Reference count. zero means able to be freed, otherwise somebody is handling it. 82 \param Priv : Reserved for multi-device support. Record Hci pointer which will handles this packet 83 \param Contest : Control buffer, put private variables here. 84 */ 85 typedef struct _RTK_BUFFER 86 { 87 RT_LIST_ENTRY List; 88 uint8_t *Head; 89 uint8_t *Data; 90 uint8_t *Tail; 91 uint8_t *End; 92 uint32_t Length; 93 uint32_t HeadRoom; 94 // RT_U16 TailRoom; 95 signed char RefCount; 96 97 void *Priv; 98 uint8_t Context[RTK_CONTEXT_SIZE]; 99 } RTK_BUFFER, *PRTK_BUFFER; 100 101 /** 102 RTK_BUFFER Control Buffer Context 103 \param PacketType : HCI data types, Command/Acl/... 104 \param LastFrag : Is Current Acl buffer the last fragment.(0 for no, 1 for yes) 105 \param TxSeq : Current packet tx sequence 106 \param Retries : Current packet retransmission times 107 \param Sar : L2cap control field segmentation and reassembly bits 108 */ 109 struct BT_RTB_CONTEXT 110 { 111 uint8_t PacketType; 112 uint16_t Handle; 113 }; 114 115 /// definition to get rtk_buffer's control buffer context pointer 116 #define BT_CONTEXT(_Rtb) ((struct BT_RTB_CONTEXT *)((_Rtb)->Context)) 117 118 /** 119 Since RTBs are always used into/from list, so abstract this struct and provide APIs to easy process on RTBs 120 */ 121 typedef struct _RTB_QUEUE_HEAD RTB_QUEUE_HEAD; 122 /*---------------------------------------------------------------------------------- 123 EXTERNAL FUNCTION 124 ----------------------------------------------------------------------------------*/ 125 /** 126 Allocate a RTK_BUFFER with specified data length and reserved headroom. 127 If caller does not know actual headroom to reserve for further usage, specify it to zero to use default value. 128 \param [IN] Length <uint32_t> : current data buffer length to allcated 129 \param [IN] HeadRoom <uint32_t> : if caller knows reserved head space, set it; otherwise set 0 to use default value 130 \return pointer to RTK_BUFFER if succeed, null otherwise 131 */ 132 RTK_BUFFER * 133 RtbAllocate( 134 IN uint32_t Length, 135 IN uint32_t HeadRoom); 136 137 /** 138 Free specified Rtk_buffer 139 \param [IN] RtkBuffer <RTK_BUFFER*> : buffer to free 140 */ 141 void RtbFree( 142 IN RTK_BUFFER *RtkBuffer); 143 144 /** 145 increment reference count 146 */ 147 void RtbIncreaseRefCount( 148 IN RTK_BUFFER *RtkBuffer); 149 150 /** 151 Recycle a rtk_buffer after its usage if specified rtb could 152 if rtb total length is not smaller than specified rtbsize to be recycled for, it will succeeded recycling 153 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : buffer to recycle 154 \param [IN] RtbSize <uint32_t> : size of buffer to be recycled for 155 */ 156 /* 157 BOOLEAN 158 RtbCheckRecycle( 159 IN OUT RTK_BUFFER* RtkBuffer, 160 IN uint32_t RtbSize 161 ); 162 */ 163 /** 164 Add a specified length protocol header to the start of data buffer hold by specified rtk_buffer. 165 This function extends used data area of the buffer at the buffer start. 166 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add 167 \param [IN] Length <uint32_t> : header length 168 \return Pointer to the first byte of the extra data is returned 169 */ 170 uint8_t * 171 RtbAddHead( 172 IN OUT RTK_BUFFER *RtkBuffer, 173 IN uint32_t Length); 174 175 /** 176 Remove a specified length data from the start of data buffer hold by specified rtk_buffer. 177 This function returns the memory to the headroom. 178 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to remove 179 \param [IN] Length <uint32_t> : header length 180 \return Pointer to the next data in the buffer is returned, usually useless 181 */ 182 unsigned char 183 RtbRemoveHead( 184 IN OUT RTK_BUFFER *RtkBuffer, 185 IN uint32_t Length); 186 187 /** 188 Add a specified length protocol header to the end of data buffer hold by specified rtk_buffer. 189 This function extends used data area of the buffer at the buffer end. 190 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add 191 \param [IN] Length <uint32_t> : header length 192 \return Pointer to the first byte of the extra data is returned 193 */ 194 EXTERN uint8_t * 195 RtbAddTail( 196 IN OUT RTK_BUFFER *RtkBuffer, 197 IN uint32_t Length); 198 199 /** 200 Remove a specified length data from the end of data buffer hold by specified rtk_buffer. 201 */ 202 EXTERN unsigned char 203 RtbRemoveTail( 204 IN OUT RTK_BUFFER *RtkBuffer, 205 IN uint32_t Length); 206 207 /** 208 Initialize a rtb queue. 209 \return Initialized rtb queue if succeed, otherwise NULL 210 */ 211 EXTERN RTB_QUEUE_HEAD * 212 RtbQueueInit(); 213 214 /** 215 Free a rtb queue. 216 \param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 217 */ 218 EXTERN void 219 RtbQueueFree( 220 RTB_QUEUE_HEAD *RtkQueueHead); 221 /** 222 Queue specified RtkBuffer into a RtkQueue at list tail. 223 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 224 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add 225 */ 226 EXTERN void 227 RtbQueueTail( 228 IN OUT RTB_QUEUE_HEAD *RtkQueueHead, 229 IN RTK_BUFFER *RtkBuffer); 230 231 /** 232 Queue specified RtkBuffer into a RtkQueue at list Head. 233 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 234 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add 235 */ 236 EXTERN void 237 RtbQueueHead( 238 IN OUT RTB_QUEUE_HEAD *RtkQueueHead, 239 IN RTK_BUFFER *RtkBuffer); 240 241 /** 242 Remove a RtkBuffer from specified rtkqueue at list tail. 243 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 244 \return removed rtkbuffer if succeed, otherwise NULL 245 */ 246 EXTERN RTK_BUFFER * 247 RtbDequeueTail( 248 IN OUT RTB_QUEUE_HEAD *RtkQueueHead); 249 250 /** 251 Remove a RtkBuffer from specified rtkqueue at list head. 252 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 253 \return removed rtkbuffer if succeed, otherwise NULL 254 */ 255 EXTERN RTK_BUFFER * 256 RtbDequeueHead( 257 IN OUT RTB_QUEUE_HEAD *RtkQueueHead); 258 259 /** 260 Get current rtb queue's length. 261 \param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 262 \return current queue's length 263 */ 264 EXTERN signed long 265 RtbGetQueueLen( 266 IN RTB_QUEUE_HEAD *RtkQueueHead); 267 268 /** 269 Empty the rtkqueue. 270 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 271 */ 272 EXTERN void 273 RtbEmptyQueue( 274 IN OUT RTB_QUEUE_HEAD *RtkQueueHead); 275 276 /** 277 Get the RtkBuffer which is the head of a RtkQueue 278 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 279 \return head of the RtkQueue , otherwise NULL 280 */ 281 EXTERN RTK_BUFFER * 282 RtbTopQueue( 283 IN RTB_QUEUE_HEAD *RtkQueueHead); 284 285 /** 286 Insert new Rtkbuffer in the old buffer 287 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 288 \param [IN] OldRtkBuffer <RTK_BUFFER*> : old rtk buffer 289 \param [IN] NewRtkBuffer <RTK_BUFFER*> : Rtk buffer to add 290 */ 291 EXTERN void 292 RtbInsertBefore( 293 IN OUT RTB_QUEUE_HEAD *RtkQueueHead, 294 IN RTK_BUFFER *pOldRtkBuffer, 295 IN RTK_BUFFER *pNewRtkBuffer); 296 297 /** 298 check whether the buffer is the last node in the queue 299 */ 300 EXTERN unsigned char 301 RtbNodeIsLast( 302 IN RTB_QUEUE_HEAD *RtkQueueHead, 303 IN RTK_BUFFER *pRtkBuffer); 304 305 /** 306 get the next buffer node after the specified buffer in the queue 307 if the specified buffer is the last node in the queue , return NULL 308 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk Queue 309 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer 310 \return node after the specified buffer 311 */ 312 EXTERN RTK_BUFFER * 313 RtbQueueNextNode( 314 IN RTB_QUEUE_HEAD *RtkQueueHead, 315 IN RTK_BUFFER *pRtkBuffer); 316 317 /** 318 check whether queue is empty 319 */ 320 EXTERN bool 321 RtbQueueIsEmpty( 322 IN RTB_QUEUE_HEAD *RtkQueueHead); 323 324 // annie_tmp 325 EXTERN unsigned char 326 RtbCheckQueueLen( 327 IN RTB_QUEUE_HEAD *RtkQueueHead, 328 IN uint8_t Len); 329 330 EXTERN void 331 RtbRemoveNode( 332 IN OUT RTB_QUEUE_HEAD *RtkQueueHead, 333 IN RTK_BUFFER *RtkBuffer); 334 335 EXTERN RTK_BUFFER * 336 RtbCloneBuffer( 337 IN RTK_BUFFER *pDataBuffer); 338 339 #endif /*BT_SKBUFF_H*/ 340