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 <stdbool.h> 43 #include <sys/types.h> 44 #include "bt_list.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 76 stack \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 RT_LIST_ENTRY List; 87 uint8_t *Head; 88 uint8_t *Data; 89 uint8_t *Tail; 90 uint8_t *End; 91 uint32_t Length; 92 uint32_t HeadRoom; 93 signed char RefCount; 94 95 void *Priv; 96 uint8_t Context[RTK_CONTEXT_SIZE]; 97 } RTK_BUFFER, *PRTK_BUFFER; 98 99 /** 100 RTK_BUFFER Control Buffer Context 101 \param PacketType : HCI data types, Command/Acl/... 102 \param LastFrag : Is Current Acl buffer the last fragment.(0 for no, 1 for yes) 103 \param TxSeq : Current packet tx sequence 104 \param Retries : Current packet retransmission times 105 \param Sar : L2cap control field segmentation and reassembly bits 106 */ 107 struct BT_RTB_CONTEXT { 108 uint8_t PacketType; 109 uint16_t Handle; 110 }; 111 112 /// definition to get rtk_buffer's control buffer context pointer 113 #define BT_CONTEXT(_Rtb) ((struct BT_RTB_CONTEXT *)((_Rtb)->Context)) 114 115 /** 116 Since RTBs are always used into/from list, so abstract this struct and provide APIs to easy process on RTBs 117 */ 118 typedef struct _RTB_QUEUE_HEAD RTB_QUEUE_HEAD; 119 /*---------------------------------------------------------------------------------- 120 EXTERNAL FUNCTION 121 ----------------------------------------------------------------------------------*/ 122 /** 123 Allocate a RTK_BUFFER with specified data length and reserved headroom. 124 If caller does not know actual headroom to reserve for further usage, specify it to zero to use default value. 125 \param [IN] Length <uint32_t> : current data buffer length to allcated 126 \param [IN] HeadRoom <uint32_t> : if caller knows reserved head space, set it; otherwise set 0 to 127 use default value \return pointer to RTK_BUFFER if succeed, null otherwise 128 */ 129 RTK_BUFFER *RtbAllocate(IN uint32_t Length, IN uint32_t HeadRoom); 130 131 /** 132 Free specified Rtk_buffer 133 \param [IN] RtkBuffer <RTK_BUFFER*> : buffer to free 134 */ 135 void RtbFree(IN RTK_BUFFER *RtkBuffer); 136 137 /** 138 increment reference count 139 */ 140 void RtbIncreaseRefCount(IN RTK_BUFFER *RtkBuffer); 141 142 /** 143 Recycle a rtk_buffer after its usage if specified rtb could 144 if rtb total length is not smaller than specified rtbsize to be recycled for, it will succeeded recycling 145 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : buffer to recycle 146 \param [IN] RtbSize <uint32_t> : size of buffer to be recycled for 147 */ 148 /** 149 Add a specified length protocol header to the start of data buffer hold by specified rtk_buffer. 150 This function extends used data area of the buffer at the buffer start. 151 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add 152 \param [IN] Length <uint32_t> : header length 153 \return Pointer to the first byte of the extra data is returned 154 */ 155 uint8_t *RtbAddHead(IN OUT RTK_BUFFER *RtkBuffer, IN uint32_t Length); 156 157 /** 158 Remove a specified length data from the start of data buffer hold by specified rtk_buffer. 159 This function returns the memory to the headroom. 160 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to remove 161 \param [IN] Length <uint32_t> : header length 162 \return Pointer to the next data in the buffer is returned, usually useless 163 */ 164 unsigned char RtbRemoveHead(IN OUT RTK_BUFFER *RtkBuffer, IN uint32_t Length); 165 166 /** 167 Add a specified length protocol header to the end of data buffer hold by specified rtk_buffer. 168 This function extends used data area of the buffer at the buffer end. 169 \param [IN OUT] RtkBuffer <RTK_BUFFER*> : data buffer to add 170 \param [IN] Length <uint32_t> : header length 171 \return Pointer to the first byte of the extra data is returned 172 */ 173 EXTERN uint8_t *RtbAddTail(IN OUT RTK_BUFFER *RtkBuffer, IN uint32_t Length); 174 175 /** 176 Remove a specified length data from the end of data buffer hold by specified rtk_buffer. 177 */ 178 EXTERN unsigned char RtbRemoveTail(IN OUT RTK_BUFFER *RtkBuffer, IN uint32_t Length); 179 180 /** 181 Initialize a rtb queue. 182 \return Initialized rtb queue if succeed, otherwise NULL 183 */ 184 EXTERN RTB_QUEUE_HEAD *RtbQueueInit(void); 185 186 /** 187 Free a rtb queue. 188 \param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 189 */ 190 EXTERN void RtbQueueFree(RTB_QUEUE_HEAD *RtkQueueHead); 191 /** 192 Queue specified RtkBuffer into a RtkQueue at list tail. 193 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 194 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add 195 */ 196 EXTERN void RtbQueueTail(IN OUT RTB_QUEUE_HEAD *RtkQueueHead, IN RTK_BUFFER *RtkBuffer); 197 198 /** 199 Queue specified RtkBuffer into a RtkQueue at list Head. 200 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 201 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer to add 202 */ 203 EXTERN void RtbQueueHead(IN OUT RTB_QUEUE_HEAD *RtkQueueHead, IN RTK_BUFFER *RtkBuffer); 204 205 /** 206 Remove a RtkBuffer from specified rtkqueue at list tail. 207 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 208 \return removed rtkbuffer if succeed, otherwise NULL 209 */ 210 EXTERN RTK_BUFFER *RtbDequeueTail(IN OUT RTB_QUEUE_HEAD *RtkQueueHead); 211 212 /** 213 Remove a RtkBuffer from specified rtkqueue at list head. 214 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 215 \return removed rtkbuffer if succeed, otherwise NULL 216 */ 217 EXTERN RTK_BUFFER *RtbDequeueHead(IN OUT RTB_QUEUE_HEAD *RtkQueueHead); 218 219 /** 220 Get current rtb queue's length. 221 \param [IN] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 222 \return current queue's length 223 */ 224 EXTERN signed long RtbGetQueueLen(IN RTB_QUEUE_HEAD *RtkQueueHead); 225 226 /** 227 Empty the rtkqueue. 228 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 229 */ 230 EXTERN void RtbEmptyQueue(IN OUT RTB_QUEUE_HEAD *RtkQueueHead); 231 232 /** 233 Get the RtkBuffer which is the head of a RtkQueue 234 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 235 \return head of the RtkQueue , otherwise NULL 236 */ 237 EXTERN RTK_BUFFER *RtbTopQueue(IN RTB_QUEUE_HEAD *RtkQueueHead); 238 239 /** 240 Insert new Rtkbuffer in the old buffer 241 \param [IN OUT] RtkQueueHead <RTB_QUEUE_HEAD*> : Rtk Queue 242 \param [IN] OldRtkBuffer <RTK_BUFFER*> : old rtk buffer 243 \param [IN] NewRtkBuffer <RTK_BUFFER*> : Rtk buffer to add 244 */ 245 EXTERN void RtbInsertBefore(IN OUT RTB_QUEUE_HEAD *RtkQueueHead, IN RTK_BUFFER *pOldRtkBuffer, 246 IN RTK_BUFFER *pNewRtkBuffer); 247 248 /** 249 check whether the buffer is the last node in the queue 250 */ 251 EXTERN unsigned char RtbNodeIsLast(IN RTB_QUEUE_HEAD *RtkQueueHead, IN RTK_BUFFER *pRtkBuffer); 252 253 /** 254 get the next buffer node after the specified buffer in the queue 255 if the specified buffer is the last node in the queue , return NULL 256 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk Queue 257 \param [IN] RtkBuffer <RTK_BUFFER*> : Rtk buffer 258 \return node after the specified buffer 259 */ 260 EXTERN RTK_BUFFER *RtbQueueNextNode(IN RTB_QUEUE_HEAD *RtkQueueHead, IN RTK_BUFFER *pRtkBuffer); 261 262 /** 263 check whether queue is empty 264 */ 265 EXTERN bool RtbQueueIsEmpty(IN RTB_QUEUE_HEAD *RtkQueueHead); 266 267 // annie_tmp 268 EXTERN unsigned char RtbCheckQueueLen(IN RTB_QUEUE_HEAD *RtkQueueHead, IN uint8_t Len); 269 270 EXTERN void RtbRemoveNode(IN OUT RTB_QUEUE_HEAD *RtkQueueHead, IN RTK_BUFFER *RtkBuffer); 271 272 EXTERN RTK_BUFFER *RtbCloneBuffer(IN RTK_BUFFER *pDataBuffer); 273 274 #endif /* BT_SKBUFF_H */ 275