예제 #1
0
파일: tcp_out.cs 프로젝트: h7ga40/uITron3
        private static pbuf tcp_pbuf_prealloc(pbuf_layer layer, ushort length, ushort mx,
			out ushort os, tcp_pcb pcb, byte api, byte fst)
        {
            os = 0;
            return lwip.pbuf_alloc(layer, length, pbuf_type.PBUF_RAM);
        }
예제 #2
0
파일: pbuf.cs 프로젝트: h7ga40/uITron3
 /**
  * Creates a single pbuf out of a queue of pbufs.
  *
  * @remark: Either the source pbuf 'p' is freed by this function or the original
  *          pbuf 'p' is returned, therefore the caller has to check the result!
  *
  * @param p the source pbuf
  * @param layer pbuf_layer of the new pbuf
  *
  * @return a new, single pbuf (p.next is null)
  *         or the old pbuf if allocation fails
  */
 public pbuf pbuf_coalesce(pbuf p, pbuf_layer layer)
 {
     pbuf q;
     err_t err;
     if (p.next == null) {
         return p;
     }
     q = pbuf_alloc(layer, p.tot_len, pbuf_type.PBUF_RAM);
     if (q == null) {
         /* @todo: what do we do now? */
         return p;
     }
     err = pbuf_copy(q, p);
     lwip.LWIP_ASSERT("pbuf_copy failed", err == err_t.ERR_OK);
     pbuf_free(p);
     return q;
 }
예제 #3
0
파일: tcp_out.cs 프로젝트: h7ga40/uITron3
        /**
         * Allocate a pbuf_type.PBUF_RAM pbuf, perhaps with extra space at the end.
         *
         * This function is like lwip.pbuf_alloc(layer, length, pbuf_type.PBUF_RAM) except
         * there may be extra bytes available at the end.
         *
         * @param layer flag to define header size.
         * @param length size of the pbuf's payload.
         * @param max_length maximum usable size of payload+oversize.
         * @param oversize pointer to a ushort that will receive the number of usable tail bytes.
         * @param pcb The TCP connection that willo enqueue the pbuf.
         * @param apiflags API flags given to tcp_write.
         * @param first_seg true when this pbuf will be used in the first enqueued segment.
         * @param
         */
        private pbuf tcp_pbuf_prealloc(pbuf_layer layer, ushort length, ushort max_length,
						  ref ushort oversize, tcp_pcb pcb, byte apiflags,
						  byte first_seg)
        {
            pbuf p;
            ushort alloc = length;

            #if LWIP_NETIF_TX_SINGLE_PBUF
            //LWIP_UNUSED_ARG(max_length);
            //LWIP_UNUSED_ARG(pcb);
            //LWIP_UNUSED_ARG(apiflags);
            //LWIP_UNUSED_ARG(first_seg);
            /* always create MSS-sized pbufs */
            alloc = max_length;
            #else // LWIP_NETIF_TX_SINGLE_PBUF
            if (length < max_length)
            {
                /* Should we allocate an oversized pbuf, or just the minimum
                 * length required? If tcp_write is going to be called again
                 * before this segment is transmitted, we want the oversized
                 * buffer. If the segment will be transmitted immediately, we can
                 * save memory by allocating only length. We use a simple
                 * heuristic based on the following information:
                 *
                 * Did the user set TCP_WRITE_FLAG_MORE?
                 *
                 * Will the Nagle algorithm defer transmission of this segment?
                 */
                if ((apiflags & tcp.TCP_WRITE_FLAG_MORE) != 0 ||
                    ((pcb.flags & tcp_pcb.TF_NODELAY) == 0 &&
                     (first_seg == 0 ||
                      pcb.unsent != null ||
                      pcb.unacked != null)))
                {
                    alloc = (ushort)Math.Min(max_length, lwip.LWIP_MEM_ALIGN_SIZE(length + opt.TCP_OVERSIZE));
                }
            }
            #endif // LWIP_NETIF_TX_SINGLE_PBUF
            p = lwip.pbuf_alloc(layer, alloc, pbuf_type.PBUF_RAM);
            if (p == null) {
                return null;
            }
            lwip.LWIP_ASSERT("need unchained pbuf", p.next == null);
            oversize = (ushort)(p.len - length);
            /* trim p.len to the currently used size */
            p.len = p.tot_len = length;
            return p;
        }
예제 #4
0
파일: pbuf.cs 프로젝트: h7ga40/uITron3
        /**
         * Allocates a pbuf of the given type (possibly a chain for pbuf_type.PBUF_POOL type).
         *
         * The actual memory allocated for the pbuf is determined by the
         * layer at which the pbuf is allocated and the requested size
         * (from the size parameter).
         *
         * @param layer flag to define header size
         * @param length size of the pbuf's payload
         * @param type this parameter decides how and where the pbuf
         * should be allocated as follows:
         *
         * - pbuf_type.PBUF_RAM: buffer memory for pbuf is allocated as one large
         *             chunk. This includes protocol headers as well.
         * - pbuf_type.PBUF_ROM: no buffer memory is allocated for the pbuf, even for
         *             protocol headers. Additional headers must be prepended
         *             by allocating another pbuf and chain in to the front of
         *             the ROM pbuf. It is assumed that the memory used is really
         *             similar to ROM in that it is immutable and will not be
         *             changed. Memory which is dynamic should generally not
         *             be attached to pbuf_type.PBUF_ROM pbufs. Use pbuf_type.PBUF_REF instead.
         * - pbuf_type.PBUF_REF: no buffer memory is allocated for the pbuf, even for
         *             protocol headers. It is assumed that the pbuf is only
         *             being used in a single thread. If the pbuf gets queued,
         *             then pbuf_take should be called to copy the buffer.
         * - pbuf_type.PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from
         *              the pbuf pool that is allocated during pbuf_init().
         *
         * @return the allocated pbuf. If multiple pbufs where allocated, this
         * is the first pbuf of a pbuf chain.
         */
        public pbuf pbuf_alloc(pbuf_layer layer, ushort length, pbuf_type type)
        {
            pbuf p, q, r;
            ushort offset;
            int rem_len; /* remaining length */
            lwip.LWIP_DEBUGF(opt.PBUF_DEBUG | lwip.LWIP_DBG_TRACE, "pbuf_alloc(length={0})\n", length);

            /* determine header offset */
            switch (layer) {
            case pbuf_layer.PBUF_TRANSPORT:
                /* add room for transport (often TCP) layer header */
                offset = opt.PBUF_LINK_HLEN + pbuf.PBUF_IP_HLEN + pbuf.PBUF_TRANSPORT_HLEN;
                break;
            case pbuf_layer.PBUF_IP:
                /* add room for IP layer header */
                offset = opt.PBUF_LINK_HLEN + pbuf.PBUF_IP_HLEN;
                break;
            case pbuf_layer.PBUF_LINK:
                /* add room for link layer header */
                offset = opt.PBUF_LINK_HLEN;
                break;
            case pbuf_layer.PBUF_RAW:
                offset = 0;
                break;
            default:
                lwip.LWIP_ASSERT("pbuf_alloc: bad pbuf layer", false);
                return null;
            }

            switch (type) {
            case pbuf_type.PBUF_POOL:
                /* allocate head of pbuf chain into p */
                p = new pbuf(this, memp_malloc(mempb_t.MEMP_PBUF_POOL));
                lwip.LWIP_DEBUGF(opt.PBUF_DEBUG | lwip.LWIP_DBG_TRACE, "pbuf_alloc: allocated pbuf {0}\n", p);
                if (p == null) {
                    PBUF_POOL_IS_EMPTY();
                    return null;
                }
                p.type = type;
                p.next = null;

                /* make the payload pointer point 'offset' bytes into pbuf data memory */
                p.payload = lwip.LWIP_MEM_ALIGN((p + (pbuf.SIZEOF_STRUCT_PBUF + offset)));
                lwip.LWIP_ASSERT("pbuf_alloc: pbuf p.payload properly aligned",
                        (p.payload.offset % opt.MEM_ALIGNMENT) == 0);
                /* the total length of the pbuf chain is the requested size */
                p.tot_len = length;
                /* set the length of the first pbuf in the chain */
                p.len = Math.Min(length, (ushort)(pbuf.PBUF_POOL_BUFSIZE_ALIGNED - lwip.LWIP_MEM_ALIGN_SIZE(offset)));
                lwip.LWIP_ASSERT("check p.payload + p.len does not overflow pbuf",
                            (p.payload + p.len <=
                             p + pbuf.SIZEOF_STRUCT_PBUF + pbuf.PBUF_POOL_BUFSIZE_ALIGNED));
                lwip.LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than opt.MEM_ALIGNMENT",
                  (pbuf.PBUF_POOL_BUFSIZE_ALIGNED - lwip.LWIP_MEM_ALIGN_SIZE(offset)) > 0);
                /* set reference count (needed here in case we fail) */
                p.@ref = 1;

                /* now allocate the tail of the pbuf chain */

                /* remember first pbuf for linkage in next iteration */
                r = p;
                /* remaining length to be allocated */
                rem_len = length - p.len;
                /* any remaining pbufs to be allocated? */
                while (rem_len > 0) {
                    q = new pbuf(this, memp_malloc(mempb_t.MEMP_PBUF_POOL));
                    if (q == null) {
                        PBUF_POOL_IS_EMPTY();
                        /* free chain so far allocated */
                        pbuf_free(p);
                        /* bail out unsuccesfully */
                        return null;
                    }
                    q.type = type;
                    q.flags = 0;
                    q.next = null;
                    /* make previous pbuf point to this pbuf */
                    r.next = q;
                    /* set total length of this pbuf and next in chain */
                    lwip.LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff);
                    q.tot_len = (ushort)rem_len;
                    /* this pbuf length is pool size, unless smaller sized tail */
                    q.len = Math.Min((ushort)rem_len, (ushort)pbuf.PBUF_POOL_BUFSIZE_ALIGNED);
                    q.payload = (q + pbuf.SIZEOF_STRUCT_PBUF);
                    lwip.LWIP_ASSERT("pbuf_alloc: pbuf q.payload properly aligned",
                            (q.payload.offset % opt.MEM_ALIGNMENT) == 0);
                    lwip.LWIP_ASSERT("check p.payload + p.len does not overflow pbuf",
                                (p.payload + p.len <=
                                 p + pbuf.SIZEOF_STRUCT_PBUF + pbuf.PBUF_POOL_BUFSIZE_ALIGNED));
                    q.@ref = 1;
                    /* calculate remaining length to be allocated */
                    rem_len -= q.len;
                    /* remember this pbuf for linkage in next iteration */
                    r = q;
                }
                /* end of chain */
                /*r.next = null;*/

                break;
            case pbuf_type.PBUF_RAM:
                /* If pbuf is to be allocated in RAM, allocate memory for it. */
                p = new pbuf(this, mem_malloc(lwip.LWIP_MEM_ALIGN_SIZE((ushort)(pbuf.SIZEOF_STRUCT_PBUF + offset)) + lwip.LWIP_MEM_ALIGN_SIZE(length)));
                if (p == null) {
                    return null;
                }
                /* Set up internal structure of the pbuf. */
                p.payload = lwip.LWIP_MEM_ALIGN((p + pbuf.SIZEOF_STRUCT_PBUF + offset));
                p.len = p.tot_len = length;
                p.next = null;
                p.type = type;

                lwip.LWIP_ASSERT("pbuf_alloc: pbuf.payload properly aligned",
                       (p.payload.offset % opt.MEM_ALIGNMENT) == 0);
                break;
            /* pbuf references existing (non-volatile static constant) ROM payload? */
            case pbuf_type.PBUF_ROM:
            /* pbuf references existing (externally allocated) RAM payload? */
            case pbuf_type.PBUF_REF:
                /* only allocate memory for the pbuf structure */
                p = new pbuf(this, memp_malloc(mempb_t.MEMP_PBUF));
                if (p == null) {
                    lwip.LWIP_DEBUGF(opt.PBUF_DEBUG | lwip.LWIP_DBG_LEVEL_SERIOUS,
                                "pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_{0}.\n",
                                (type == pbuf_type.PBUF_ROM) ? "ROM" : "REF");
                    return null;
                }
                /* caller must set this field properly, afterwards */
                p.payload = null;
                p.len = p.tot_len = length;
                p.next = null;
                p.type = type;
                break;
            default:
                lwip.LWIP_ASSERT("pbuf_alloc: erroneous type", false);
                return null;
            }
            /* set reference count */
            p.@ref = 1;
            /* set flags */
            p.flags = 0;
            lwip.LWIP_DEBUGF(opt.PBUF_DEBUG | lwip.LWIP_DBG_TRACE, "pbuf_alloc(length={0}) == {1}\n", length, p);
            return p;
        }