diff --git a/CHANGELOG b/CHANGELOG index bbff6d30..3f28fa19 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,13 @@ HISTORY ++ New features: + 2007-11-01 Frédéric Bernon, Marc Chaland + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: + Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api + layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api + layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. + Note that previous "copy" parameter for "write" APIs is now called "apiflags". + 2007-10-24 Frédéric Bernon * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than TCP_EVENT_xxx macros to get a code more readable. It could also help to remove diff --git a/src/api/api_lib.c b/src/api/api_lib.c index 954f4e3e..273ad1c5 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -546,11 +546,13 @@ netconn_send(struct netconn *conn, struct netbuf *buf) * @param conn the TCP netconn over which to send data * @param dataptr pointer to the application buffer that contains the data to send * @param size size of the application data to send - * @param copy flag: 1 = copy the data, 0 = data is non-volatile, can be sent by reference + * @param apiflags combination of following flags : + * - NETCONN_COPY (0x01) data will be copied into memory belonging to the stack + * - NETCONN_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent * @return ERR_OK if data was sent, any other err_t on error */ err_t -netconn_write(struct netconn *conn, const void *dataptr, int size, u8_t copy) +netconn_write(struct netconn *conn, const void *dataptr, int size, u8_t apiflags) { struct api_msg msg; @@ -560,7 +562,7 @@ netconn_write(struct netconn *conn, const void *dataptr, int size, u8_t copy) msg.function = do_write; msg.msg.conn = conn; msg.msg.msg.w.dataptr = dataptr; - msg.msg.msg.w.copy = copy; + msg.msg.msg.w.apiflags = apiflags; msg.msg.msg.w.len = size; /* For locking the core: this _can_ be delayed on low memory/low send buffer, but if it is, this is done inside api_msg.c:do_write(), so we can use the diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 8ae8cf78..1510cc9e 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -784,7 +784,7 @@ do_writemore(struct netconn *conn) #endif } - err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.copy); + err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.apiflags); LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->write_msg->msg.w.len)); if (err == ERR_OK) { conn->write_offset += len; diff --git a/src/api/sockets.c b/src/api/sockets.c index 2f589b6a..06affdcd 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -538,7 +538,7 @@ lwip_send(int s, const void *data, int size, unsigned int flags) #endif /* (LWIP_UDP || LWIP_RAW) */ } - err = netconn_write(sock->conn, data, size, NETCONN_COPY); + err = netconn_write(sock->conn, data, size, NETCONN_COPY | ((flags & MSG_MORE)?NETCONN_MORE:0)); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%d\n", s, err, size)); sock_set_errno(sock, err_to_errno(err)); diff --git a/src/core/tcp_out.c b/src/core/tcp_out.c index 0eabea4e..c920a07a 100644 --- a/src/core/tcp_out.c +++ b/src/core/tcp_out.c @@ -83,24 +83,25 @@ tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags) * @param pcb Protocol control block of the TCP connection to enqueue data for. * @param data pointer to the data to send * @param len length (in bytes) of the data to send - * @param copy 1 if data must be copied, 0 if data is non-volatile and can be - * referenced. + * @param apiflags combination of following flags : + * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack + * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent, * @return ERR_OK if enqueued, another err_t on error * * @see tcp_write() */ err_t -tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t copy) +tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", copy=%"U16_F")\n", (void *)pcb, - data, len, (u16_t)copy)); + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", (void *)pcb, + data, len, (u16_t)apiflags)); /* connection is in valid state for data transmission? */ if (pcb->state == ESTABLISHED || pcb->state == CLOSE_WAIT || pcb->state == SYN_SENT || pcb->state == SYN_RCVD) { if (len > 0) { - return tcp_enqueue(pcb, (void *)data, len, 0, copy, NULL, 0); + return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, NULL, 0); } return ERR_OK; } else { @@ -118,14 +119,15 @@ tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t copy) * @param arg Pointer to the data to be enqueued for sending. * @param len Data length in bytes * @param flags tcp header flags to set in the outgoing segment - * @param copy 1 if data must be copied, 0 if data is non-volatile and can be - * referenced. + * @param apiflags combination of following flags : + * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack + * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent, * @param optdata * @param optlen */ err_t tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, - u8_t flags, u8_t copy, + u8_t flags, u8_t apiflags, u8_t *optdata, u8_t optlen) { struct pbuf *p; @@ -135,8 +137,8 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, void *ptr; u16_t queuelen; - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", copy=%"U16_F")\n", - (void *)pcb, arg, len, (u16_t)flags, (u16_t)copy)); + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", apiflags=%"U16_F")\n", + (void *)pcb, arg, len, (u16_t)flags, (u16_t)apiflags)); LWIP_ERROR("tcp_enqueue: len == 0 || optlen == 0 (programmer violates API)", ((len == 0) || (optlen == 0)), return ERR_ARG;); LWIP_ERROR("tcp_enqueue: arg == NULL || optdata == NULL (programmer violates API)", @@ -220,7 +222,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, seg->dataptr = seg->p->payload; } /* copy from volatile memory? */ - else if (copy) { + else if (apiflags & TCP_WRITE_FLAG_COPY) { if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_RAM)) == NULL) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); goto memerr; @@ -372,7 +374,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, /* Set the PSH flag in the last segment that we enqueued, but only if the segment has data (indicated by seglen > 0). */ - if (seg != NULL && seglen > 0 && seg->tcphdr != NULL) { + if (seg != NULL && seglen > 0 && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) { TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); } diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index d9642916..70aecd26 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -54,8 +54,10 @@ extern "C" { */ /* Flags for netconn_write */ -#define NETCONN_NOCOPY 0x00 -#define NETCONN_COPY 0x01 +#define NETCONN_NOFLAG 0x00 +#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ +#define NETCONN_COPY TCP_WRITE_FLAG_COPY +#define NETCONN_MORE TCP_WRITE_FLAG_MORE /* Helpers to process several netconn_types by the same code */ #define NETCONNTYPE_GROUP(t) (t&0xF0) @@ -164,7 +166,7 @@ err_t netconn_send (struct netconn *conn, struct netbuf *buf); err_t netconn_write (struct netconn *conn, const void *dataptr, int size, - u8_t copy); + u8_t apiflags); err_t netconn_close (struct netconn *conn); #if LWIP_IGMP diff --git a/src/include/lwip/api_msg.h b/src/include/lwip/api_msg.h index 9f25f756..dc558413 100644 --- a/src/include/lwip/api_msg.h +++ b/src/include/lwip/api_msg.h @@ -64,7 +64,7 @@ struct api_msg_msg { struct { const void *dataptr; int len; - u8_t copy; + u8_t apiflags; } w; /* do_write */ struct { u16_t len; diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h index e1da4865..6d45fa44 100644 --- a/src/include/lwip/sockets.h +++ b/src/include/lwip/sockets.h @@ -132,6 +132,7 @@ struct linger { #define MSG_WAITALL 0x02 /* Requests that the function block until the full amount of data requested can be returned */ #define MSG_OOB 0x04 /* Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ #define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ +#define MSG_MORE 0x10 /* Sender will send more */ /* diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h index d07210e0..7c11fa7d 100644 --- a/src/include/lwip/tcp.h +++ b/src/include/lwip/tcp.h @@ -89,8 +89,12 @@ err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr, struct tcp_pcb * tcp_listen (struct tcp_pcb *pcb); void tcp_abort (struct tcp_pcb *pcb); err_t tcp_close (struct tcp_pcb *pcb); + +#define TCP_WRITE_FLAG_COPY 0x01 +#define TCP_WRITE_FLAG_MORE 0x02 + err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, - u8_t copy); + u8_t apiflags); void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); @@ -483,7 +487,7 @@ struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags); err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len, - u8_t flags, u8_t copy, + u8_t flags, u8_t apiflags, u8_t *optdata, u8_t optlen); void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg);