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