/* Allocate a RTK_BUFFER with specified data length and reserved headroom. If caller does not know actual headroom to reserve for further usage, specify it to zero to use default value.  */
RTK_BUFFER* RtbAllocate(uint32_t Length, uint32_t HeadRoom)
/* Allocate a RTK_BUFFER with specified data length and reserved headroom. If caller does not know actual headroom to reserve for further usage, specify it to zero to use default value.  */
RTK_BUFFER* RtbAllocate(uint32_t Length, uint32_t HeadRoom)
{
    RTK_BUFFER* Rtb = NULL;
    Rtb = malloc( sizeof(RTK_BUFFER) );
    if(Rtb)
    {
        uint32_t BufferLen = HeadRoom ? (Length + HeadRoom) : (Length + DEFAULT_HEADER_SIZE);
        BufferLen = RTB_DATA_ALIGN(BufferLen);
        Rtb->Head = malloc(BufferLen);
        if(Rtb->Head)
        {
            Rtb->HeadRoom = HeadRoom ? HeadRoom : DEFAULT_HEADER_SIZE;
            Rtb->Data = Rtb->Head + Rtb->HeadRoom;
            Rtb->End = Rtb->Data;
            Rtb->Tail = Rtb->End + Length;
            Rtb->Length = 0;
            ListInitializeHeader(&Rtb->List);
            Rtb->RefCount = 1;
            return Rtb;
        }
    }
    if (Rtb)
    {
        if (Rtb->Head)
        {
            free(Rtb->Head);
        }
        free(Rtb);
    }
    return NULL;
}