1195972f6Sopenharmony_ciFrom be56e9eed8acf82a862d19ef4f890f309018ddde Mon Sep 17 00:00:00 2001
2195972f6Sopenharmony_ciFrom: jiangheng <jiangheng14@huawei.com>
3195972f6Sopenharmony_ciDate: Sat, 28 Oct 2023 17:21:46 +0800
4195972f6Sopenharmony_ciSubject: [PATCH] adapt read/write for rtc mode
5195972f6Sopenharmony_ci
6195972f6Sopenharmony_ci---
7195972f6Sopenharmony_ci src/api/api_msg.c      |  14 ++--
8195972f6Sopenharmony_ci src/api/sockets.c      |  21 ++---
9195972f6Sopenharmony_ci src/core/init.c        |   2 +-
10195972f6Sopenharmony_ci src/core/pbuf.c        |   7 ++
11195972f6Sopenharmony_ci src/core/tcp_out.c     | 171 +++++++++++++++++++++++++++++++++--------
12195972f6Sopenharmony_ci src/core/udp.c         |   2 +-
13195972f6Sopenharmony_ci src/include/lwip/tcp.h |   4 +
14195972f6Sopenharmony_ci src/include/lwipopts.h |   6 +-
15195972f6Sopenharmony_ci 8 files changed, 174 insertions(+), 53 deletions(-)
16195972f6Sopenharmony_ci
17195972f6Sopenharmony_cidiff --git a/src/api/api_msg.c b/src/api/api_msg.c
18195972f6Sopenharmony_ciindex 3e982ab..d8b99ee 100644
19195972f6Sopenharmony_ci--- a/src/api/api_msg.c
20195972f6Sopenharmony_ci+++ b/src/api/api_msg.c
21195972f6Sopenharmony_ci@@ -1753,11 +1753,15 @@ lwip_netconn_do_writemore(struct netconn *conn  WRITE_DELAYED_PARAM)
22195972f6Sopenharmony_ci         write_more = 0;
23195972f6Sopenharmony_ci       }
24195972f6Sopenharmony_ci #if GAZELLE_ENABLE
25195972f6Sopenharmony_ci-      /* vector->ptr is private arg sock */
26195972f6Sopenharmony_ci-      LWIP_UNUSED_ARG(dataptr);
27195972f6Sopenharmony_ci-      write_more = 0;
28195972f6Sopenharmony_ci-      err = tcp_write(conn->pcb.tcp, conn->current_msg->msg.w.vector->ptr, len, apiflags);
29195972f6Sopenharmony_ci-      conn->current_msg->msg.w.len = len;
30195972f6Sopenharmony_ci+      if (netif_is_rtc_mode(netif_default)) {
31195972f6Sopenharmony_ci+        err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags);
32195972f6Sopenharmony_ci+      } else {
33195972f6Sopenharmony_ci+        /* vector->ptr is private arg sock */
34195972f6Sopenharmony_ci+        LWIP_UNUSED_ARG(dataptr);
35195972f6Sopenharmony_ci+        write_more = 0;
36195972f6Sopenharmony_ci+        err = tcp_write_from_stack(conn->pcb.tcp, conn->current_msg->msg.w.vector->ptr, len, apiflags);
37195972f6Sopenharmony_ci+        conn->current_msg->msg.w.len = len;
38195972f6Sopenharmony_ci+      }
39195972f6Sopenharmony_ci       conn->pcb.tcp->need_tso_send = 1;
40195972f6Sopenharmony_ci #else
41195972f6Sopenharmony_ci       err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags);
42195972f6Sopenharmony_cidiff --git a/src/api/sockets.c b/src/api/sockets.c
43195972f6Sopenharmony_ciindex 8d573aa..e374f96 100644
44195972f6Sopenharmony_ci--- a/src/api/sockets.c
45195972f6Sopenharmony_ci+++ b/src/api/sockets.c
46195972f6Sopenharmony_ci@@ -1087,7 +1087,15 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
47195972f6Sopenharmony_ci     apiflags |= NETCONN_DONTBLOCK;
48195972f6Sopenharmony_ci   }
49195972f6Sopenharmony_ci 
50195972f6Sopenharmony_ci-#if !GAZELLE_ENABLE
51195972f6Sopenharmony_ci+#if GAZELLE_ENABLE
52195972f6Sopenharmony_ci+  if (!netif_is_rtc_mode(netif_default)) {
53195972f6Sopenharmony_ci+    LWIP_UNUSED_ARG(recv_left);
54195972f6Sopenharmony_ci+    recvd = do_lwip_read_from_lwip(sock, flags, apiflags);
55195972f6Sopenharmony_ci+    if (recvd <= 0) {
56195972f6Sopenharmony_ci+      return recvd;
57195972f6Sopenharmony_ci+    }
58195972f6Sopenharmony_ci+  } else {
59195972f6Sopenharmony_ci+#endif
60195972f6Sopenharmony_ci   do {
61195972f6Sopenharmony_ci     struct pbuf *p;
62195972f6Sopenharmony_ci     err_t err;
63195972f6Sopenharmony_ci@@ -1166,15 +1174,10 @@ lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags)
64195972f6Sopenharmony_ci     apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN;
65195972f6Sopenharmony_ci     /* @todo: do we need to support peeking more than one pbuf? */
66195972f6Sopenharmony_ci   } while ((recv_left > 0) && !(flags & MSG_PEEK));
67195972f6Sopenharmony_ci-
68195972f6Sopenharmony_ci-lwip_recv_tcp_done:
69195972f6Sopenharmony_ci-#else /* GAZELLE_ENABLE */
70195972f6Sopenharmony_ci-  LWIP_UNUSED_ARG(recv_left);
71195972f6Sopenharmony_ci-  recvd = do_lwip_read_from_lwip(sock, flags, apiflags);
72195972f6Sopenharmony_ci-  if (recvd <= 0) {
73195972f6Sopenharmony_ci-    return recvd;
74195972f6Sopenharmony_ci+#if GAZELLE_ENABLE
75195972f6Sopenharmony_ci   }
76195972f6Sopenharmony_ci-#endif /* GAZELLE_ENABLE */
77195972f6Sopenharmony_ci+#endif
78195972f6Sopenharmony_ci+lwip_recv_tcp_done:
79195972f6Sopenharmony_ci   if (apiflags & NETCONN_NOAUTORCVD) {
80195972f6Sopenharmony_ci     if ((recvd > 0) && !(flags & MSG_PEEK)) {
81195972f6Sopenharmony_ci       /* ensure window update after copying all data */
82195972f6Sopenharmony_cidiff --git a/src/core/init.c b/src/core/init.c
83195972f6Sopenharmony_ciindex 7b6214f..60e1c68 100644
84195972f6Sopenharmony_ci--- a/src/core/init.c
85195972f6Sopenharmony_ci+++ b/src/core/init.c
86195972f6Sopenharmony_ci@@ -306,7 +306,7 @@ PACK_STRUCT_END
87195972f6Sopenharmony_ci #if TCP_SNDLOWAT >= TCP_SND_BUF
88195972f6Sopenharmony_ci #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
89195972f6Sopenharmony_ci #endif
90195972f6Sopenharmony_ci-#if TCP_SNDLOWAT >= (0xFFFFFFFF - (4 * TCP_MSS))
91195972f6Sopenharmony_ci+#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS))
92195972f6Sopenharmony_ci #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!"
93195972f6Sopenharmony_ci #endif
94195972f6Sopenharmony_ci #if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN
95195972f6Sopenharmony_cidiff --git a/src/core/pbuf.c b/src/core/pbuf.c
96195972f6Sopenharmony_ciindex 975e240..61690ff 100644
97195972f6Sopenharmony_ci--- a/src/core/pbuf.c
98195972f6Sopenharmony_ci+++ b/src/core/pbuf.c
99195972f6Sopenharmony_ci@@ -117,6 +117,7 @@ pbuf_skip_const(const struct pbuf *in, u16_t in_offset, u16_t *out_offset);
100195972f6Sopenharmony_ci volatile u8_t pbuf_free_ooseq_pending;
101195972f6Sopenharmony_ci #define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty()
102195972f6Sopenharmony_ci 
103195972f6Sopenharmony_ci+#if !GAZELLE_ENABLE
104195972f6Sopenharmony_ci /**
105195972f6Sopenharmony_ci  * Attempt to reclaim some memory from queued out-of-sequence TCP segments
106195972f6Sopenharmony_ci  * if we run out of pool pbufs. It's better to give priority to new packets
107195972f6Sopenharmony_ci@@ -176,6 +177,7 @@ pbuf_pool_is_empty(void)
108195972f6Sopenharmony_ci   }
109195972f6Sopenharmony_ci #endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */
110195972f6Sopenharmony_ci }
111195972f6Sopenharmony_ci+#endif /* GAZELLE_ENABLE */
112195972f6Sopenharmony_ci #endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */
113195972f6Sopenharmony_ci 
114195972f6Sopenharmony_ci /* Initialize members of struct pbuf after allocation */
115195972f6Sopenharmony_ci@@ -238,6 +240,10 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
116195972f6Sopenharmony_ci       p = pbuf_alloc_reference(NULL, length, type);
117195972f6Sopenharmony_ci       break;
118195972f6Sopenharmony_ci     case PBUF_POOL: {
119195972f6Sopenharmony_ci+#if GAZELLE_ENABLE
120195972f6Sopenharmony_ci+      // alloc from pktmbuf pool, one pbuf is enough
121195972f6Sopenharmony_ci+      p = do_lwip_alloc_pbuf(layer, length, type);
122195972f6Sopenharmony_ci+#else
123195972f6Sopenharmony_ci       struct pbuf *q, *last;
124195972f6Sopenharmony_ci       u16_t rem_len; /* remaining length */
125195972f6Sopenharmony_ci       p = NULL;
126195972f6Sopenharmony_ci@@ -273,6 +279,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
127195972f6Sopenharmony_ci         rem_len = (u16_t)(rem_len - qlen);
128195972f6Sopenharmony_ci         offset = 0;
129195972f6Sopenharmony_ci       } while (rem_len > 0);
130195972f6Sopenharmony_ci+#endif /* GAZELLE_ENABLE */
131195972f6Sopenharmony_ci       break;
132195972f6Sopenharmony_ci     }
133195972f6Sopenharmony_ci     case PBUF_RAM: {
134195972f6Sopenharmony_cidiff --git a/src/core/tcp_out.c b/src/core/tcp_out.c
135195972f6Sopenharmony_ciindex e2c9d63..073d989 100644
136195972f6Sopenharmony_ci--- a/src/core/tcp_out.c
137195972f6Sopenharmony_ci+++ b/src/core/tcp_out.c
138195972f6Sopenharmony_ci@@ -515,15 +515,18 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
139195972f6Sopenharmony_ci    * pos records progress as data is segmented.
140195972f6Sopenharmony_ci    */
141195972f6Sopenharmony_ci 
142195972f6Sopenharmony_ci-#if !GAZELLE_ENABLE
143195972f6Sopenharmony_ci   /* Find the tail of the unsent queue. */
144195972f6Sopenharmony_ci   if (pcb->unsent != NULL) {
145195972f6Sopenharmony_ci     u16_t space;
146195972f6Sopenharmony_ci     u16_t unsent_optlen;
147195972f6Sopenharmony_ci 
148195972f6Sopenharmony_ci+#if GAZELLE_ENABLE
149195972f6Sopenharmony_ci+    last_unsent = pcb->last_unsent;
150195972f6Sopenharmony_ci+#else
151195972f6Sopenharmony_ci     /* @todo: this could be sped up by keeping last_unsent in the pcb */
152195972f6Sopenharmony_ci     for (last_unsent = pcb->unsent; last_unsent->next != NULL;
153195972f6Sopenharmony_ci          last_unsent = last_unsent->next);
154195972f6Sopenharmony_ci+#endif
155195972f6Sopenharmony_ci 
156195972f6Sopenharmony_ci     /* Usable space at the end of the last unsent segment */
157195972f6Sopenharmony_ci     unsent_optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(last_unsent->flags, pcb);
158195972f6Sopenharmony_ci@@ -631,9 +634,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
159195972f6Sopenharmony_ci                 pcb->unsent_oversize == 0);
160195972f6Sopenharmony_ci #endif /* TCP_OVERSIZE */
161195972f6Sopenharmony_ci   }
162195972f6Sopenharmony_ci-#else /* GAZELLE_ENABLE */
163195972f6Sopenharmony_ci-  last_unsent = pcb->last_unsent;
164195972f6Sopenharmony_ci-#endif /* GAZELLE_ENABLE */
165195972f6Sopenharmony_ci 
166195972f6Sopenharmony_ci   /*
167195972f6Sopenharmony_ci    * Phase 3: Create new segments.
168195972f6Sopenharmony_ci@@ -651,7 +651,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
169195972f6Sopenharmony_ci     u8_t chksum_swapped = 0;
170195972f6Sopenharmony_ci #endif /* TCP_CHECKSUM_ON_COPY */
171195972f6Sopenharmony_ci 
172195972f6Sopenharmony_ci-#if !GAZELLE_ENABLE
173195972f6Sopenharmony_ci     if (apiflags & TCP_WRITE_FLAG_COPY) {
174195972f6Sopenharmony_ci       /* If copy is set, memory should be allocated and data copied
175195972f6Sopenharmony_ci        * into pbuf */
176195972f6Sopenharmony_ci@@ -698,13 +697,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
177195972f6Sopenharmony_ci       /* Concatenate the headers and data pbufs together. */
178195972f6Sopenharmony_ci       pbuf_cat(p/*header*/, p2/*data*/);
179195972f6Sopenharmony_ci     }
180195972f6Sopenharmony_ci-#else  /* GAZELLE_ENABLE */
181195972f6Sopenharmony_ci-    p = do_lwip_get_from_sendring((struct lwip_sock *)arg, len - pos, &apiflags);
182195972f6Sopenharmony_ci-    if (p == NULL) {
183195972f6Sopenharmony_ci-      break;
184195972f6Sopenharmony_ci-    }
185195972f6Sopenharmony_ci-    seglen = p->tot_len;
186195972f6Sopenharmony_ci-#endif  /* GAZELLE_ENABLE */
187195972f6Sopenharmony_ci 
188195972f6Sopenharmony_ci     queuelen += pbuf_clen(p);
189195972f6Sopenharmony_ci 
190195972f6Sopenharmony_ci@@ -714,14 +706,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
191195972f6Sopenharmony_ci     if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) {
192195972f6Sopenharmony_ci       LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n",
193195972f6Sopenharmony_ci                   queuelen, (int)TCP_SND_QUEUELEN));
194195972f6Sopenharmony_ci-#if GAZELLE_ENABLE
195195972f6Sopenharmony_ci-      if (pos > 0) {
196195972f6Sopenharmony_ci-        queuelen -= pbuf_clen(p);
197195972f6Sopenharmony_ci-        break;
198195972f6Sopenharmony_ci-      }
199195972f6Sopenharmony_ci-#else
200195972f6Sopenharmony_ci       pbuf_free(p);
201195972f6Sopenharmony_ci-#endif
202195972f6Sopenharmony_ci       goto memerr;
203195972f6Sopenharmony_ci     }
204195972f6Sopenharmony_ci 
205195972f6Sopenharmony_ci@@ -730,12 +715,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
206195972f6Sopenharmony_ci #endif
207195972f6Sopenharmony_ci 
208195972f6Sopenharmony_ci     if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) {
209195972f6Sopenharmony_ci-#if GAZELLE_ENABLE
210195972f6Sopenharmony_ci-      if (pos > 0) {
211195972f6Sopenharmony_ci-        queuelen -= pbuf_clen(p);
212195972f6Sopenharmony_ci-        break;
213195972f6Sopenharmony_ci-      }
214195972f6Sopenharmony_ci-#endif
215195972f6Sopenharmony_ci       goto memerr;
216195972f6Sopenharmony_ci     }
217195972f6Sopenharmony_ci #if TCP_OVERSIZE_DBGCHECK
218195972f6Sopenharmony_ci@@ -763,9 +742,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
219195972f6Sopenharmony_ci                 lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg)));
220195972f6Sopenharmony_ci 
221195972f6Sopenharmony_ci     pos += seglen;
222195972f6Sopenharmony_ci-#if GAZELLE_ENABLE
223195972f6Sopenharmony_ci-    do_lwip_get_from_sendring_over((struct lwip_sock*)arg);
224195972f6Sopenharmony_ci-#endif
225195972f6Sopenharmony_ci   }
226195972f6Sopenharmony_ci 
227195972f6Sopenharmony_ci   /*
228195972f6Sopenharmony_ci@@ -855,12 +831,9 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
229195972f6Sopenharmony_ci   if (queue) {
230195972f6Sopenharmony_ci     pcb->last_unsent = prev_seg;
231195972f6Sopenharmony_ci   }
232195972f6Sopenharmony_ci-  pcb->snd_lbb += pos;
233195972f6Sopenharmony_ci-  pcb->snd_buf -= pos;
234195972f6Sopenharmony_ci-#else
235195972f6Sopenharmony_ci+#endif
236195972f6Sopenharmony_ci   pcb->snd_lbb += len;
237195972f6Sopenharmony_ci   pcb->snd_buf -= len;
238195972f6Sopenharmony_ci-#endif
239195972f6Sopenharmony_ci   pcb->snd_queuelen = queuelen;
240195972f6Sopenharmony_ci 
241195972f6Sopenharmony_ci   LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n",
242195972f6Sopenharmony_ci@@ -880,14 +853,12 @@ memerr:
243195972f6Sopenharmony_ci   tcp_set_flags(pcb, TF_NAGLEMEMERR);
244195972f6Sopenharmony_ci   TCP_STATS_INC(tcp.memerr);
245195972f6Sopenharmony_ci 
246195972f6Sopenharmony_ci-#if !GAZELLE_ENABLE
247195972f6Sopenharmony_ci   if (concat_p != NULL) {
248195972f6Sopenharmony_ci     pbuf_free(concat_p);
249195972f6Sopenharmony_ci   }
250195972f6Sopenharmony_ci   if (queue != NULL) {
251195972f6Sopenharmony_ci     tcp_segs_free(queue);
252195972f6Sopenharmony_ci   }
253195972f6Sopenharmony_ci-#endif
254195972f6Sopenharmony_ci   if (pcb->snd_queuelen != 0) {
255195972f6Sopenharmony_ci     LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL ||
256195972f6Sopenharmony_ci                 pcb->unsent != NULL);
257195972f6Sopenharmony_ci@@ -896,6 +867,137 @@ memerr:
258195972f6Sopenharmony_ci   return ERR_MEM;
259195972f6Sopenharmony_ci }
260195972f6Sopenharmony_ci 
261195972f6Sopenharmony_ci+#if GAZELLE_ENABLE
262195972f6Sopenharmony_ci+err_t
263195972f6Sopenharmony_ci+tcp_write_from_stack(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
264195972f6Sopenharmony_ci+{
265195972f6Sopenharmony_ci+  struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL;
266195972f6Sopenharmony_ci+  u16_t pos = 0; /* position in 'arg' data */
267195972f6Sopenharmony_ci+  u16_t queuelen;
268195972f6Sopenharmony_ci+  u8_t optlen;
269195972f6Sopenharmony_ci+  u8_t optflags = 0;
270195972f6Sopenharmony_ci+  err_t err;
271195972f6Sopenharmony_ci+  u16_t mss_local;
272195972f6Sopenharmony_ci+
273195972f6Sopenharmony_ci+  /* don't allocate segments bigger than half the maximum window we ever received */
274195972f6Sopenharmony_ci+  mss_local = LWIP_MIN(pcb->mss, TCPWND_MIN16(pcb->snd_wnd_max / 2));
275195972f6Sopenharmony_ci+  mss_local = mss_local ? mss_local : pcb->mss;
276195972f6Sopenharmony_ci+
277195972f6Sopenharmony_ci+  err = tcp_write_checks(pcb, len);
278195972f6Sopenharmony_ci+  if (err != ERR_OK) {
279195972f6Sopenharmony_ci+    return err;
280195972f6Sopenharmony_ci+  }
281195972f6Sopenharmony_ci+  queuelen = pcb->snd_queuelen;
282195972f6Sopenharmony_ci+
283195972f6Sopenharmony_ci+  optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(0, pcb);
284195972f6Sopenharmony_ci+
285195972f6Sopenharmony_ci+  last_unsent = pcb->last_unsent;
286195972f6Sopenharmony_ci+
287195972f6Sopenharmony_ci+  /*
288195972f6Sopenharmony_ci+   * get pbuf from sendring and create new segments.
289195972f6Sopenharmony_ci+   */
290195972f6Sopenharmony_ci+  while (pos < len) {
291195972f6Sopenharmony_ci+    struct pbuf *p;
292195972f6Sopenharmony_ci+    u16_t left = len - pos;
293195972f6Sopenharmony_ci+    u16_t max_len = mss_local - optlen;
294195972f6Sopenharmony_ci+    u16_t seglen = LWIP_MIN(left, max_len);
295195972f6Sopenharmony_ci+
296195972f6Sopenharmony_ci+    p = do_lwip_get_from_sendring((struct lwip_sock *)arg, len - pos, &apiflags);
297195972f6Sopenharmony_ci+    if (p == NULL) {
298195972f6Sopenharmony_ci+      break;
299195972f6Sopenharmony_ci+    }
300195972f6Sopenharmony_ci+    seglen = p->tot_len;
301195972f6Sopenharmony_ci+
302195972f6Sopenharmony_ci+    queuelen += pbuf_clen(p);
303195972f6Sopenharmony_ci+
304195972f6Sopenharmony_ci+    /* Now that there are more segments queued, we check again if the
305195972f6Sopenharmony_ci+     * length of the queue exceeds the configured maximum or
306195972f6Sopenharmony_ci+     * overflows. */
307195972f6Sopenharmony_ci+    if (queuelen > LWIP_MIN(TCP_SND_QUEUELEN, TCP_SNDQUEUELEN_OVERFLOW)) {
308195972f6Sopenharmony_ci+      LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n",
309195972f6Sopenharmony_ci+                  queuelen, (int)TCP_SND_QUEUELEN));
310195972f6Sopenharmony_ci+      if (pos > 0) {
311195972f6Sopenharmony_ci+        queuelen -= pbuf_clen(p);
312195972f6Sopenharmony_ci+        break;
313195972f6Sopenharmony_ci+      }
314195972f6Sopenharmony_ci+      goto memerr;
315195972f6Sopenharmony_ci+    }
316195972f6Sopenharmony_ci+
317195972f6Sopenharmony_ci+    lstack_calculate_aggregate(2, p->tot_len);
318195972f6Sopenharmony_ci+
319195972f6Sopenharmony_ci+    if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) {
320195972f6Sopenharmony_ci+      if (pos > 0) {
321195972f6Sopenharmony_ci+        queuelen -= pbuf_clen(p);
322195972f6Sopenharmony_ci+        break;
323195972f6Sopenharmony_ci+      }
324195972f6Sopenharmony_ci+      goto memerr;
325195972f6Sopenharmony_ci+    }
326195972f6Sopenharmony_ci+
327195972f6Sopenharmony_ci+    /* first segment of to-be-queued data? */
328195972f6Sopenharmony_ci+    if (queue == NULL) {
329195972f6Sopenharmony_ci+      queue = seg;
330195972f6Sopenharmony_ci+    } else {
331195972f6Sopenharmony_ci+      /* Attach the segment to the end of the queued segments */
332195972f6Sopenharmony_ci+      LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL);
333195972f6Sopenharmony_ci+      prev_seg->next = seg;
334195972f6Sopenharmony_ci+    }
335195972f6Sopenharmony_ci+    /* remember last segment of to-be-queued data for next iteration */
336195972f6Sopenharmony_ci+    prev_seg = seg;
337195972f6Sopenharmony_ci+
338195972f6Sopenharmony_ci+    LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n",
339195972f6Sopenharmony_ci+                lwip_ntohl(seg->tcphdr->seqno),
340195972f6Sopenharmony_ci+                lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg)));
341195972f6Sopenharmony_ci+
342195972f6Sopenharmony_ci+    pos += seglen;
343195972f6Sopenharmony_ci+    do_lwip_get_from_sendring_over((struct lwip_sock*)arg);
344195972f6Sopenharmony_ci+  }
345195972f6Sopenharmony_ci+
346195972f6Sopenharmony_ci+  /*
347195972f6Sopenharmony_ci+   * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that
348195972f6Sopenharmony_ci+   * is harmless
349195972f6Sopenharmony_ci+   */
350195972f6Sopenharmony_ci+  if (last_unsent == NULL) {
351195972f6Sopenharmony_ci+    pcb->unsent = queue;
352195972f6Sopenharmony_ci+  } else {
353195972f6Sopenharmony_ci+    last_unsent->next = queue;
354195972f6Sopenharmony_ci+  }
355195972f6Sopenharmony_ci+
356195972f6Sopenharmony_ci+  /*
357195972f6Sopenharmony_ci+   * Finally update the pcb state.
358195972f6Sopenharmony_ci+   */
359195972f6Sopenharmony_ci+  if (queue) {
360195972f6Sopenharmony_ci+    pcb->last_unsent = prev_seg;
361195972f6Sopenharmony_ci+  }
362195972f6Sopenharmony_ci+  pcb->snd_lbb += pos;
363195972f6Sopenharmony_ci+  pcb->snd_buf -= pos;
364195972f6Sopenharmony_ci+  pcb->snd_queuelen = queuelen;
365195972f6Sopenharmony_ci+
366195972f6Sopenharmony_ci+  LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n",
367195972f6Sopenharmony_ci+                               pcb->snd_queuelen));
368195972f6Sopenharmony_ci+  if (pcb->snd_queuelen != 0) {
369195972f6Sopenharmony_ci+    LWIP_ASSERT("tcp_write: valid queue length",
370195972f6Sopenharmony_ci+                pcb->unacked != NULL || pcb->unsent != NULL);
371195972f6Sopenharmony_ci+  }
372195972f6Sopenharmony_ci+
373195972f6Sopenharmony_ci+  /* Set the PSH flag in the last segment that we enqueued. */
374195972f6Sopenharmony_ci+  if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE) == 0)) {
375195972f6Sopenharmony_ci+    TCPH_SET_FLAG(seg->tcphdr, TCP_PSH);
376195972f6Sopenharmony_ci+  }
377195972f6Sopenharmony_ci+
378195972f6Sopenharmony_ci+  return ERR_OK;
379195972f6Sopenharmony_ci+memerr:
380195972f6Sopenharmony_ci+  tcp_set_flags(pcb, TF_NAGLEMEMERR);
381195972f6Sopenharmony_ci+  TCP_STATS_INC(tcp.memerr);
382195972f6Sopenharmony_ci+
383195972f6Sopenharmony_ci+  if (pcb->snd_queuelen != 0) {
384195972f6Sopenharmony_ci+    LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL ||
385195972f6Sopenharmony_ci+                pcb->unsent != NULL);
386195972f6Sopenharmony_ci+  }
387195972f6Sopenharmony_ci+  LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen));
388195972f6Sopenharmony_ci+  return ERR_MEM;
389195972f6Sopenharmony_ci+}
390195972f6Sopenharmony_ci+#endif
391195972f6Sopenharmony_ci+
392195972f6Sopenharmony_ci /**
393195972f6Sopenharmony_ci  * Split segment on the head of the unsent queue.  If return is not
394195972f6Sopenharmony_ci  * ERR_OK, existing head remains intact
395195972f6Sopenharmony_ci@@ -2095,6 +2197,7 @@ tcp_rexmit(struct tcp_pcb *pcb)
396195972f6Sopenharmony_ci 
397195972f6Sopenharmony_ci   /* Don't take any rtt measurements after retransmitting. */
398195972f6Sopenharmony_ci   pcb->rttest = 0;
399195972f6Sopenharmony_ci+  pcb->need_tso_send = 1;
400195972f6Sopenharmony_ci 
401195972f6Sopenharmony_ci   /* Do the actual retransmission. */
402195972f6Sopenharmony_ci   MIB2_STATS_INC(mib2.tcpretranssegs);
403195972f6Sopenharmony_cidiff --git a/src/core/udp.c b/src/core/udp.c
404195972f6Sopenharmony_ciindex 937a045..828a489 100644
405195972f6Sopenharmony_ci--- a/src/core/udp.c
406195972f6Sopenharmony_ci+++ b/src/core/udp.c
407195972f6Sopenharmony_ci@@ -414,7 +414,7 @@ udp_input(struct pbuf *p, struct netif *inp)
408195972f6Sopenharmony_ci         if (udphdr->chksum != 0) {
409195972f6Sopenharmony_ci #if CHECKSUM_CHECK_UDP_HW
410195972f6Sopenharmony_ci           u64_t ret = 0;
411195972f6Sopenharmony_ci-          if (netif_get_txol_flags(inp) & DEV_RX_OFFLOAD_UDP_CKSUM) {
412195972f6Sopenharmony_ci+          if (netif_get_rxol_flags(inp) & DEV_RX_OFFLOAD_UDP_CKSUM) {
413195972f6Sopenharmony_ci             ret = is_cksum_bad(p);
414195972f6Sopenharmony_ci           } else {
415195972f6Sopenharmony_ci             ret = ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len,
416195972f6Sopenharmony_cidiff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h
417195972f6Sopenharmony_ciindex e13099c..959df3e 100644
418195972f6Sopenharmony_ci--- a/src/include/lwip/tcp.h
419195972f6Sopenharmony_ci+++ b/src/include/lwip/tcp.h
420195972f6Sopenharmony_ci@@ -567,6 +567,10 @@ err_t            tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx);
421195972f6Sopenharmony_ci 
422195972f6Sopenharmony_ci err_t            tcp_write   (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
423195972f6Sopenharmony_ci                               u8_t apiflags);
424195972f6Sopenharmony_ci+#if GAZELLE_ENABLE
425195972f6Sopenharmony_ci+err_t            tcp_write_from_stack (struct tcp_pcb *pcb, const void *dataptr, u16_t len,
426195972f6Sopenharmony_ci+                                       u8_t apiflags);
427195972f6Sopenharmony_ci+#endif
428195972f6Sopenharmony_ci 
429195972f6Sopenharmony_ci void             tcp_setprio (struct tcp_pcb *pcb, u8_t prio);
430195972f6Sopenharmony_ci 
431195972f6Sopenharmony_cidiff --git a/src/include/lwipopts.h b/src/include/lwipopts.h
432195972f6Sopenharmony_ciindex baf739e..fdd4f87 100644
433195972f6Sopenharmony_ci--- a/src/include/lwipopts.h
434195972f6Sopenharmony_ci+++ b/src/include/lwipopts.h
435195972f6Sopenharmony_ci@@ -208,8 +208,8 @@
436195972f6Sopenharmony_ci #define TCP_LISTEN_BACKLOG 1
437195972f6Sopenharmony_ci #define TCP_DEFAULT_LISTEN_BACKLOG 0xff
438195972f6Sopenharmony_ci 
439195972f6Sopenharmony_ci-#define TCP_OVERSIZE 0
440195972f6Sopenharmony_ci-#define LWIP_NETIF_TX_SINGLE_PBUF 0
441195972f6Sopenharmony_ci+#define TCP_OVERSIZE TCP_MSS
442195972f6Sopenharmony_ci+#define LWIP_NETIF_TX_SINGLE_PBUF 1
443195972f6Sopenharmony_ci 
444195972f6Sopenharmony_ci #define TCP_MSS (FRAME_MTU - IP_HLEN - TCP_HLEN)
445195972f6Sopenharmony_ci 
446195972f6Sopenharmony_ci@@ -219,7 +219,7 @@
447195972f6Sopenharmony_ci 
448195972f6Sopenharmony_ci #define TCP_SND_QUEUELEN (8191)
449195972f6Sopenharmony_ci 
450195972f6Sopenharmony_ci-#define TCP_SNDLOWAT (TCP_SND_BUF / 5)
451195972f6Sopenharmony_ci+#define TCP_SNDLOWAT (32768)
452195972f6Sopenharmony_ci 
453195972f6Sopenharmony_ci #define TCP_SNDQUEUELOWAT (TCP_SND_QUEUELEN / 5)
454195972f6Sopenharmony_ci 
455195972f6Sopenharmony_ci-- 
456195972f6Sopenharmony_ci2.27.0
457195972f6Sopenharmony_ci
458