lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-users] RE: [lwip] pbuf payload length


From: Wurmsdobler, Peter
Subject: [lwip-users] RE: [lwip] pbuf payload length
Date: Thu, 09 Jan 2003 00:20:16 -0000

Hello,

> However if you want to call copy_data2pbuf() repeatedly on the same pbuf
then 
> as you say you should keep an external var.
Yes, this is what I tried to do. As first fix I tried this code:

#define PBUF_FLAG_USR 0x03
#define PBUF_ADD_TO_THE_RIGHT_START
#define PBUF_ADD_TO_THE_RIGHT_STOPP(p) (p->tot_len = p->len)
/*
----------------------------------------------------------------------------
--
SYNTAX  : make_buffer2pbuf
INPUTS  : buffer, offset
OUTPUTS : pbuf
----------------------------------------------------------------------------
--
PURPOSE : If a flat buffer is statically allocated and it should be
          used as pbuf, the buffer is converted into a pbuf by loosing
            offset+sizeof(struct pbuf) bytes. The payload length is 
            set to be zero, the total length is set to be the
          maximum payload size. flag ist set to PBUF_FLAG_USR.

            Note: the allocated memory length of the buffer is not 
            carried in the pbuf structure by default, so caution. 
          If this pbuf is used, don't forget to adjust tot_len
          and len before passing to lwip.
----------------------------------------------------------------------------
--
*/
struct pbuf * make_buffer2pbuf
    (
    u8_t   *buffer,
    u16_t   offset,
    u16_t   size
    )
    {
    u16_t  sysbytes;
    struct pbuf *p;

    sysbytes = sizeof(struct pbuf) + offset;
    if ( size < sysbytes )
        return NULL;   

    p = (struct pbuf *)buffer;
    p->next    = NULL;
    p->payload = (void *)(buffer + sysbytes);
    p->len     = 0;
    p->tot_len = size - sysbytes;
    p->flags   = PBUF_FLAG_USR;
        
    return p;
    }

s8_t append_data_in_pbuf (struct pbuf *p, u8_t *data, u16_t len)
    {
    u8_t *tail;

    if ( (p->len)+(len) > (p->tot->len) )
        return ERR_BUF;

    tail = (u8_t *)(p->payload) + p->len;
    memcpy ((void *)(tail), (const void *)(data), len);
    p->len += len;

    return ERR_OK;
    }

Now, in the application, I would do

void application (void)
    {
    u8_t text1[] = "Hello ";
    u8_t text2[] = " World";
    u8_t buffer[100];
    struct pbuf *p = make_buffer2pbuf (buffer,36,100);
    
    PBUF_ADD_TO_THE_RIGHT_START;

    append_data_in_pbuf (p, text1, sizeof(text1) );
    append_data_in_pbuf (p, text2, sizeof(text2) );

    PBUF_ADD_TO_THE_RIGHT_STOPP(p);

    send_down_the_stack (p);
    }

When then the pbuf is used downwards in the stack, and then also in my 1394
code 
(adding headers and adjusting the payload pointer and length, 36 bytes in
the case
of IP over FireWire) the last function writing out to the Mindready driver
will be

API1394_asyncStream (channel, GASPTAG, 0, (uint8*)(p->payload), p->len);

where (uint8*)(p->payload) should then be nothing else but
buffer+sizeof(struct pbuf)
and p->len would be 36+14. No copying would have been used (except for
copying the
application data) throughout the stack, even in the drive code.

For compatibility with the parts of the stack, I added in the firewire
output code:

s16_t copy_pbuf2buffer 
    (
    struct pbuf *p, 
    char       **buffer,
    u16_t        max
    )
    {
    struct pbuf *q; 

    /* packet contains data in flat buffer, no buffer chain
     * so we overwrite the buffer pointer
     */
    if ((p->next) == NULL)
        {
        *buffer = (char *)(p->payload);
        return (p->len);
        }

    /* packet too big, does not fit into buffer
     */
    if ((p->tot_len) > max)
        return ERR_BUF;

    /* copy pbuf chain to flat buffer we received from the callee
     */
    for (q = p; q != NULL; q = q->next) 
        {
        /* Copy the data from the pbuf to the buffer, one pbuf at a
           time. The size of the data in each pbuf is kept in the 
           q->len variable. 
         */    
        memcpy((void *)(*buffer), (const void *)(q->payload), q->len);
        buffer += q->len;
        }
    
    return (p->tot_len);
    }

which will be used as

char    buffer[MAX_1394_PAYLOAD_SIZE]; 
char   *buffp = buffer;
uint16  length;

length = copy_pbuf2buffer (p, &buffp, MAX_1394_PAYLOAD_SIZE);
if ( length == 0)
    return 0;

API1394_asyncStream (channel, GASPTAG, 0, (uint8*)(buffp), length);

peter
[This message was sent through the lwip discussion list.]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]