1 /****************************************************************************** 2 * 3 * Copyright (C) 2016 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 41 #ifndef BT_SKBUFF_H 42 #define BT_SKBUFF_H 43 #include "bt_list.h" 44 #include <stdint.h> 45 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 struct BT_RTB_CONTEXT{ 66 uint8_t PacketType; 67 uint16_t Handle; 68 }; 69 70 /*---------------------------------------------------------------------------------- 71 STRUCTURE DEFINITION 72 ----------------------------------------------------------------------------------*/ 73 /** 74 Rtk buffer definition 75 Head -->|<---Data--->|<-----Length------>| <---End 76 _________________________________ 77 |_____________|___________________| 78 |<-headroom->|<--RealDataBuffer-->| 79 80 Compared to socket buffer, there exists no tail and end pointer and tailroom as tail is rarely used in bluetooth stack 81 \param List : List structure used to list same type rtk buffer and manipulate rtk buffer like list. 82 \param Head : Pointer to truely allocated data buffer. It point to the headroom 83 \param Data : Pointer to real data buffer. 84 \param Length : currently data length 85 \param HeadRoom : Record initialize headroom size. 86 \param RefCount : Reference count. zero means able to be freed, otherwise somebody is handling it. 87 \param Priv : Reserved for multi-device support. Record Hci pointer which will handles this packet 88 \param Contest : Control buffer, put private variables here. 89 */ 90 typedef struct _RTK_BUFFER 91 { 92 RT_LIST_ENTRY List; 93 uint8_t *Head; 94 uint8_t *Data; 95 uint8_t *Tail; 96 uint8_t *End; 97 uint32_t Length; 98 uint32_t HeadRoom; 99 // RT_U16 TailRoom; 100 signed char RefCount; 101 102 void* Priv; 103 union { 104 uint8_t Context[RTK_CONTEXT_SIZE]; 105 struct BT_RTB_CONTEXT rtb_ctx; 106 }; 107 }RTK_BUFFER, *PRTK_BUFFER; 108 109 /** 110 RTK_BUFFER Control Buffer Context 111 \param PacketType : HCI data types, Command/Acl/... 112 \param LastFrag : Is Current Acl buffer the last fragment.(0 for no, 1 for yes) 113 \param TxSeq : Current packet tx sequence 114 \param Retries : Current packet retransmission times 115 \param Sar : L2cap control field segmentation and reassembly bits 116 */ 117 118 ///definition to get rtk_buffer's control buffer context pointer 119 #define BT_CONTEXT(_Rtb) (&((_Rtb)->rtb_ctx)) 120 121 /** 122 Since RTBs are always used into/from list, so abstract this struct and provide APIs to easy process on RTBs 123 */ 124 typedef struct _RTB_QUEUE_HEAD RTB_QUEUE_HEAD; 125 /*---------------------------------------------------------------------------------- 126 EXTERNAL FUNCTION 127 ----------------------------------------------------------------------------------*/ 128 /** 129 Allocate a RTK_BUFFER with specified data length and reserved headroom. 130 If caller does not know actual headroom to reserve for further usage, specify it to zero to use default value. 131 \param [IN] Length <uint32_t> : current data buffer length to allcated 132 \param [IN] HeadRoom <uint32_t> : if caller knows reserved head space, set it; otherwise set 0 to use default value 133 \return pointer to RTK_BUFFER if succeed, null otherwise 134 */ 135 RTK_BUFFER* 136 RtbAllocate( 137 IN uint32_t Length, 138 IN uint32_t HeadRoom 139 ); 140 141 /** 142 Free specified Rtk_buffer 143 \param [IN] RtkBuffer <RTK_BUFFER*> : buffer to free 144 */ 145 void 146 RtbFree( 147 IN RTK_BUFFER* RtkBuffer 148 ); 149 150 /** 151 increament reference count 152 */ 153 void 154 RtbIncreaseRefCount( 155 IN RTK_BUFFER* RtkBuffer 156 ); 157 158 /** 159 Recycle a rtk_buffer after its usage if specified rtb could 160 if rtb total length is not smaller than specified rtbsize to be recycled for, it will succeeded recycling 161 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : buffer to recycle 162 \param [IN] RtbSize <uint32_t> : size of buffer to be recycled for 163 */ 164 /* 165 BOOLEAN 166 RtbCheckRecycle( 167 IN OUT RTK_BUFFER* RtkBuffer, 168 IN uint32_t RtbSize 169 ); 170 */ 171 /** 172 Add a specified length protocal header to the start of data buffer hold by specified rtk_buffer. 173 This function extends used data area of the buffer at the buffer start. 174 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add 175 \param [IN] Length <uint32_t> : header length 176 \return Pointer to the first byte of the extra data is returned 177 */ 178 uint8_t* 179 RtbAddHead( 180 IN OUT RTK_BUFFER* RtkBuffer, 181 IN uint32_t Length 182 ); 183 184 /** 185 Remove a specified length data from the start of data buffer hold by specified rtk_buffer. 186 This function returns the memory to the headroom. 187 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to remove 188 \param [IN] Length <uint32_t> : header length 189 \return Pointer to the next data in the buffer is returned, usually useless 190 */ 191 unsigned char 192 RtbRemoveHead( 193 IN OUT RTK_BUFFER* RtkBuffer, 194 IN uint32_t Length 195 ); 196 197 /** 198 Add a specified length protocal header to the end of data buffer hold by specified rtk_buffer. 199 This function extends used data area of the buffer at the buffer end. 200 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add 201 \param [IN] Length <uint32_t> : header length 202 \return Pointer to the first byte of the extra data is returned 203 */ 204 EXTERN uint8_t* 205 RtbAddTail( 206 IN OUT RTK_BUFFER* RtkBuffer, 207 IN uint32_t Length 208 ); 209 210 /** 211 Remove a specified length data from the end of data buffer hold by specified rtk_buffer. 212 */ 213 EXTERN unsigned char 214 RtbRemoveTail( 215 IN OUT RTK_BUFFER * RtkBuffer, 216 IN uint32_t Length 217 ); 218 219 /** 220 Initialize a rtb queue. 221 \return Initilized rtb queue if succeed, otherwise NULL 222 */ 223 EXTERN RTB_QUEUE_HEAD* 224 RtbQueueInit( 225 ); 226 227 /** 228 Free a rtb queue. 229 \param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 230 */ 231 EXTERN void 232 RtbQueueFree( 233 RTB_QUEUE_HEAD* RtkQueueHead 234 ); 235 /** 236 Queue specified RtkBuffer into a RtkQueue at list tail. 237 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 238 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add 239 */ 240 EXTERN void 241 RtbQueueTail( 242 IN OUT RTB_QUEUE_HEAD* RtkQueueHead, 243 IN RTK_BUFFER* RtkBuffer 244 ); 245 246 /** 247 Queue specified RtkBuffer into a RtkQueue at list Head. 248 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 249 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add 250 */ 251 EXTERN void 252 RtbQueueHead( 253 IN OUT RTB_QUEUE_HEAD* RtkQueueHead, 254 IN RTK_BUFFER* RtkBuffer 255 ); 256 257 /** 258 Remove a RtkBuffer from specified rtkqueue at list tail. 259 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 260 \return removed rtkbuffer if succeed, otherwise NULL 261 */ 262 EXTERN RTK_BUFFER* 263 RtbDequeueTail( 264 IN OUT RTB_QUEUE_HEAD* RtkQueueHead 265 ); 266 267 /** 268 Remove a RtkBuffer from specified rtkqueue at list head. 269 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 270 \return removed rtkbuffer if succeed, otherwise NULL 271 */ 272 EXTERN RTK_BUFFER* 273 RtbDequeueHead( 274 IN OUT RTB_QUEUE_HEAD* RtkQueueHead 275 ); 276 277 /** 278 Get current rtb queue's length. 279 \param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 280 \return current queue's length 281 */ 282 EXTERN signed long 283 RtbGetQueueLen( 284 IN RTB_QUEUE_HEAD* RtkQueueHead 285 ); 286 287 /** 288 Empty the rtkqueue. 289 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 290 */ 291 EXTERN void 292 RtbEmptyQueue( 293 IN OUT RTB_QUEUE_HEAD* RtkQueueHead 294 ); 295 296 /** 297 Get the RtkBuffer which is the head of a RtkQueue 298 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 299 \return head of the RtkQueue , otherwise NULL 300 */ 301 EXTERN RTK_BUFFER* 302 RtbTopQueue( 303 IN RTB_QUEUE_HEAD* RtkQueueHead 304 ); 305 306 /** 307 Insert new Rtkbuffer in the old buffer 308 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 309 \param [IN] OldRtkBuffer <RTK_BUFFER*> : old rtk buffer 310 \param [IN] NewRtkBuffer <RTK_BUFFER*> : Rtk buffer to add 311 */ 312 EXTERN void 313 RtbInsertBefore( 314 IN OUT RTB_QUEUE_HEAD* RtkQueueHead, 315 IN RTK_BUFFER* pOldRtkBuffer, 316 IN RTK_BUFFER* pNewRtkBuffer 317 ); 318 319 /** 320 check whether the buffer is the last node in the queue 321 */ 322 EXTERN unsigned char 323 RtbNodeIsLast( 324 IN RTB_QUEUE_HEAD* RtkQueueHead, 325 IN RTK_BUFFER* pRtkBuffer 326 ); 327 328 /** 329 get the next buffer node after the specified buffer in the queue 330 if the specified buffer is the last node in the queue , return NULL 331 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk Queue 332 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer 333 \return node after the specified buffer 334 */ 335 EXTERN RTK_BUFFER* 336 RtbQueueNextNode( 337 IN RTB_QUEUE_HEAD* RtkQueueHead, 338 IN RTK_BUFFER* pRtkBuffer 339 ); 340 341 /** 342 check whether queue is empty 343 */ 344 /*EXTERN BOOLEAN 345 RtbQueueIsEmpty( 346 IN RTB_QUEUE_HEAD* RtkQueueHead 347 ); 348 */ 349 350 //annie_tmp 351 EXTERN unsigned char 352 RtbCheckQueueLen( 353 IN RTB_QUEUE_HEAD* RtkQueueHead, 354 IN uint8_t Len 355 ); 356 357 EXTERN void 358 RtbRemoveNode( 359 IN OUT RTB_QUEUE_HEAD* RtkQueueHead, 360 IN RTK_BUFFER* RtkBuffer 361 ); 362 363 EXTERN RTK_BUFFER* 364 RtbCloneBuffer( 365 IN RTK_BUFFER* pDataBuffer 366 ); 367 368 typedef RTK_BUFFER sk_buff; 369 370 uint8_t *hci_skb_get_data(IN sk_buff *skb); 371 uint32_t hci_skb_get_data_length(IN sk_buff *skb); 372 sk_buff *hci_skb_alloc(IN unsigned int len); 373 void hci_skb_free(IN OUT sk_buff **skb); 374 void hci_skb_unlink(sk_buff *skb, struct _RTB_QUEUE_HEAD *list); 375 uint8_t *hci_skb_put(OUT sk_buff *skb, IN uint32_t len); 376 void hci_skb_trim(sk_buff *skb, unsigned int len); 377 uint8_t hci_skb_get_pkt_type(sk_buff *skb); 378 void hci_skb_set_pkt_type(sk_buff *skb, uint8_t pkt_type); 379 void hci_skb_pull(OUT sk_buff *skb, IN uint32_t len); 380 sk_buff *hci_skb_alloc_and_init(IN uint8_t PktType, IN uint8_t *Data, IN uint32_t DataLen); 381 void hci_skb_queue_head(IN RTB_QUEUE_HEAD *skb_head, IN RTK_BUFFER *skb); 382 void hci_skb_queue_tail(IN RTB_QUEUE_HEAD *skb_head, IN RTK_BUFFER *skb); 383 RTK_BUFFER *hci_skb_dequeue_head(IN RTB_QUEUE_HEAD *skb_head); 384 RTK_BUFFER *hci_skb_dequeue_tail(IN RTB_QUEUE_HEAD *skb_head); 385 uint32_t hci_skb_queue_get_length(IN RTB_QUEUE_HEAD *skb_head); 386 387 #endif /*BT_SKBUFF_H*/ 388