• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "epoll_app.h"
17 #include "spunge_app.h"
18 #include "res.h"
19 #include "fillp_flow_control.h"
20 #include "spunge_message.h"
21 #include "socket_common.h"
22 #include "fillp_common.h"
23 #include "spunge_stack.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
SpungeAllocSystemSocket(FILLP_INT domain,FILLP_INT type,FILLP_INT protocol)29 struct SockOsSocket *SpungeAllocSystemSocket(FILLP_INT domain, FILLP_INT type, FILLP_INT protocol)
30 {
31     struct SpungeInstance *curInst = SPUNGE_GET_CUR_INSTANCE();
32     struct SockOsSocket *osSock;
33 
34     osSock = (struct SockOsSocket *)SpungeAlloc(1, sizeof(struct SockOsSocket), SPUNGE_ALLOC_TYPE_CALLOC);
35     if (osSock == FILLP_NULL_PTR) {
36         FILLP_LOGERR("Failed to allocate memory for os socket \r\n");
37 
38         return FILLP_NULL_PTR;
39     }
40 
41     osSock->reference = 0;
42     osSock->addrType = domain;
43 
44     osSock->ioSock = SysIoSocketFactory(domain, type, protocol);
45     if (osSock->ioSock == FILLP_NULL_PTR) {
46         FILLP_LOGERR("Alloc osSock fail");
47         SpungeFree(osSock, SPUNGE_ALLOC_TYPE_CALLOC);
48         osSock = FILLP_NULL_PTR;
49         return osSock;
50     }
51 
52     HLIST_INIT_NODE(&osSock->osListNode);
53     HlistAddTail(&curInst->osSockist, &osSock->osListNode);
54 
55     return osSock;
56 }
57 
SpungeEpollFreeResource(struct FtSocket * sock)58 static void SpungeEpollFreeResource(struct FtSocket *sock)
59 {
60     FILLP_UINT32 i;
61 
62     HLIST_INIT(&sock->epTaskList);
63 
64     if (sock->eventEpoll != FILLP_NULL_PTR) {
65         (void)SYS_ARCH_SEM_DESTROY(&sock->eventEpoll->waitSem);
66 
67         (void)SYS_ARCH_SEM_DESTROY(&sock->eventEpoll->appCoreSem);
68 
69         (void)SYS_ARCH_SEM_DESTROY(&sock->eventEpoll->appSem);
70     }
71 
72     /* Scan the epoll instance list to which this FtSocket is associated with */
73     for (i = 0; i < FILLP_NUM_OF_EPOLL_INSTANCE_SUPPORTED; i++) {
74         /* Delete happens from higher array index to lower array index. So until
75            the 0th index is cleared, continue to remove epoll instance
76         */
77         if (sock->associatedEpollInstanceArr[0] != FILLP_INVALID_INT) {
78             struct FtSocket *epollSock = FILLP_NULL_PTR;
79             FILLP_INT assIdex = sock->associatedEpollInstanceArr[0];
80 
81             if ((assIdex < 0) || (assIdex >= SYS_ARCH_ATOMIC_READ(&g_spunge->sockTable->used))) {
82                 /* Socket index is not in range, skip and continue */
83                 continue;
84             }
85 
86             epollSock = g_spunge->sockTable->sockPool[assIdex];
87 
88             if (epollSock->allocState == SOCK_ALLOC_STATE_FREE) {
89                 SpungeDelEpInstFromFtSocket(sock, assIdex);
90 
91                 /* Socket state is in free state, skip and continue */
92                 continue;
93             }
94 
95             (void)SpungeEpollFindRemove(sock->associatedEpollInstanceArr[0], sock->index);
96         }
97     }
98 
99     sock->associatedEpollInstanceIdx = 0;
100 
101     (void)SYS_ARCH_ATOMIC_SET(&sock->rcvEvent, 0);
102     (void)SYS_ARCH_ATOMIC_SET(&sock->sendEvent, 0);
103     (void)SYS_ARCH_ATOMIC_SET(&sock->sendEventCount, 0);
104     sock->errEvent = 0;
105 
106     return;
107 }
108 
SpungeFreeAcceptBox(struct FtSocket * sock)109 void SpungeFreeAcceptBox(struct FtSocket *sock)
110 {
111     FILLP_INT i;
112     struct FtNetconn *conn = FILLP_NULL_PTR;
113     int count;
114 
115     for (i = 0; i < SPUNGE_SOCKET_BOX_SIZE; i++) {
116         count = FillpQueuePop(sock->acceptBox, (void *)&conn, 1);
117         if (count > 0) {
118             FillpNetconnDestroy(conn);
119         } else {
120             break;
121         }
122     }
123 
124     FillpQueueDestroy(sock->acceptBox);
125     sock->acceptBox = FILLP_NULL_PTR;
126     return;
127 }
128 
SpungeIncFreeCntPostEagain(struct FtSocket * sock)129 void SpungeIncFreeCntPostEagain(struct FtSocket *sock)
130 {
131     FillpErrorType ret;
132     sock->freeTimeCount++;
133     FILLP_LOGDBG("fillp_sock_id:%d,sock->freeTimeCount:%d, errno:%d",
134         sock->index, sock->freeTimeCount, FT_OS_GET_ERRNO);
135 
136     ret = SpungePostMsg(SPUNGE_GET_CUR_INSTANCE(), (void *)sock, MSG_TYPE_FREE_SOCK_EAGAIN, FILLP_FALSE);
137     if (ret != ERR_OK) {
138         FILLP_LOGERR("FAILED TO POST -- MSG_TYPE_FREE_SOCK_EAGAIN--- to CORE."
139             "Socket leak can happen : Sock ID: %d\r\n", sock->index);
140     }
141 
142     return;
143 }
144 
RecursiveRbTree(struct RbNode * node)145 static void RecursiveRbTree(struct RbNode *node)
146 {
147     struct RbNode *parent = node;
148     struct EpItem *epi = FILLP_NULL_PTR;
149     struct RbNode *right = FILLP_NULL_PTR;
150     struct FtSocket *sock = FILLP_NULL_PTR;
151     struct RbNode *left = FILLP_NULL_PTR;
152 
153     if (node == FILLP_NULL_PTR) {
154         FILLP_LOGERR("RecursiveRbTree: Inavild parameters passed.");
155 
156         return;
157     }
158 
159     left = (struct RbNode *)(parent->rbLeft);
160 
161     if (left != FILLP_NULL_PTR) {
162         RecursiveRbTree(left);
163     }
164 
165     right = (struct RbNode *)(parent->rbRight);
166     epi = EpItemEntryRbNode(parent);
167     if (epi == FILLP_NULL_PTR) {
168         FILLP_LOGERR("RecursiveRbTree: EpItemEntryRbNode returns NULL. ");
169 
170         return;
171     }
172 
173     sock = SockGetSocket(epi->fileDespcriptor);
174     if (sock != FILLP_NULL_PTR) {
175         (void)SYS_ARCH_ATOMIC_DEC(&sock->epollWaiting, 1);
176 
177         if (SYS_ARCH_SEM_WAIT(&sock->epollTaskListLock)) {
178             FILLP_LOGERR("Error to wait epoll_task_list");
179             return;
180         }
181         HlistDelNode(&epi->sockWaitNode);
182         DympFree(epi);
183         (void)SYS_ARCH_SEM_POST(&sock->epollTaskListLock);
184     }
185 
186     if (right != FILLP_NULL_PTR) {
187         RecursiveRbTree(right);
188     }
189 
190     return;
191 }
192 
193 /*
194  * @Description : Closes the epoll socket and releases all associated resources.
195  * @param : epoll ft sock index
196  * @return : success: ERR_OK  fail: error code
197  * @NOTE: caller must have acquired (wait) the close semaphore to protect from MT scenarios. this
198  * function on completion will post the event back to semaphore once execution is completed.
199  */
SpungEpollClose(struct FtSocket * sock)200 void SpungEpollClose(struct FtSocket *sock)
201 {
202     struct EventPoll *ep = (sock->eventEpoll);
203     struct RbRoot rtNoe;
204     struct RbNode *parent = FILLP_NULL_PTR;
205     SYS_ARCH_RW_SEM *sockConnSem = &sock->sockConnSem;
206 
207     if (ep == FILLP_NULL_PTR) {
208         sock->allocState = SOCK_ALLOC_STATE_FREE;
209         FILLP_LOGERR("eventEpoll is NULL. fillp_sock_id:%d", sock->index);
210         return;
211     }
212 
213     if (SYS_ARCH_RWSEM_TRYWRWAIT(sockConnSem) != ERR_OK) {
214         int ret;
215         sock->allocState = SOCK_ALLOC_STATE_EPOLL_TO_CLOSE;
216         (void)SYS_ARCH_SEM_POST(&ep->waitSem);
217         ret = SpungePostMsg(SPUNGE_GET_CUR_INSTANCE(), (void *)sock, MSG_TYPE_FREE_SOCK_EAGAIN, FILLP_FALSE);
218         if (ret != ERR_OK) {
219             FILLP_LOGERR("FAILED TO POST -- MSG_TYPE_FREE_SOCK_EAGAIN--- to CORE."
220                 "Socket leak can happen : Sock ID: %d", sock->index);
221         }
222         return;
223     }
224 
225     rtNoe = ep->rbr;
226     parent = rtNoe.rbNode;
227     if (parent != FILLP_NULL_PTR) {
228         RecursiveRbTree(parent);
229     }
230 
231     SpungeEpollFreeResource(sock);
232 
233     DympFree(sock->eventEpoll);
234     sock->eventEpoll = FILLP_NULL_PTR;
235 
236     sock->flags = 0;
237     sock->traceFlag = 0;
238     sock->allocState = SOCK_ALLOC_STATE_FREE;
239     sock->freeTimeCount = FILLP_NULL_NUM;
240     (void)SYS_ARCH_RWSEM_WRPOST(&sock->sockConnSem);
241 
242     (void)FillpQueuePush(g_spunge->sockTable->freeQueqe, (void *)&sock, FILLP_FALSE, 1);
243     return;
244 }
SpungeCloseCBSocket(struct FtSocket * sock)245 static void SpungeCloseCBSocket(struct FtSocket *sock)
246 {
247     if ((FILLP_SOCKETCLOSE_CBK != FILLP_NULL_PTR) && (sock->isListenSock == FILLP_FALSE) &&
248         (sock->netconn != FILLP_NULL_PTR) && (sock->netconn->pcb != FILLP_NULL_PTR) &&
249         (sock->netconn->state == CONN_STATE_CLOSED)) {
250         SysIoUdpSock *udpSock = FILLP_NULL_PTR;
251         struct SockOsSocket *osSock = NETCONN_GET_OSSOCK(sock->netconn, sock->inst->instIndex);
252         if (osSock != FILLP_NULL_PTR) {
253             udpSock = (SysIoUdpSock *)osSock->ioSock;
254             FILLP_SOCKETCLOSE_CBK(udpSock->udpSock, (struct sockaddr *)&sock->netconn->pcb->localAddr,
255                 (struct sockaddr *)&sock->netconn->pcb->remoteAddr);
256         }
257     }
258 }
259 
SpungeFreeSock(struct FtSocket * sock)260 void SpungeFreeSock(struct FtSocket *sock)
261 {
262     if ((sock == FILLP_NULL_PTR) || (sock->allocState == SOCK_ALLOC_STATE_FREE)) {
263         return;
264     }
265 
266     FILLP_LOGDTL("fillp_sock_id:%d", sock->index);
267     FillpErrorType ret = SYS_ARCH_RWSEM_TRYWRWAIT(&sock->sockConnSem);
268     if (ret != ERR_OK) {
269         SpungeIncFreeCntPostEagain(sock);
270         return;
271     }
272 
273     if (sock->allocState != SOCK_ALLOC_STATE_EPOLL) {
274         if ((sock->netconn != FILLP_NULL_PTR) && !SpungeConnCheckUnsendBoxEmpty(sock->netconn)) {
275             FILLP_LOGDBG("Unsend Box still not empty, fillp_sock_id:%d", sock->index);
276             SpungeIncFreeCntPostEagain(sock);
277             (void)SYS_ARCH_RWSEM_WRPOST(&sock->sockConnSem);
278             return;
279         }
280     }
281 
282     FILLP_LOGINF("spunge_free_start, fillp_sock_id:%d", sock->index);
283     SpungeCloseCBSocket(sock);
284     SpungeEpollFreeResource(sock);
285 
286     if (sock->netconn != FILLP_NULL_PTR) {
287         struct SockOsSocket *osSock = NETCONN_GET_OSSOCK(sock->netconn, sock->inst->instIndex);
288         if (OS_SOCK_OPS_FUNC_VALID(osSock, freeSock)) {
289             osSock->ioSock->ops->freeSock((void *)sock, (void *)osSock);
290         }
291         FillpNetconnDestroy(sock->netconn);
292         sock->netconn = FILLP_NULL_PTR;
293     }
294 
295     if (sock->acceptBox != FILLP_NULL_PTR) {
296         SpungeFreeAcceptBox(sock);
297     }
298 
299     sock->flags = 0;
300     sock->traceFlag = 0;
301     if (sock->isListenSock == FILLP_TRUE) {
302         (void)SYS_ARCH_SEM_DESTROY(&sock->acceptSem);
303         sock->isListenSock = FILLP_FALSE;
304     }
305 
306     sock->allocState = SOCK_ALLOC_STATE_FREE;
307     sock->freeTimeCount = FILLP_NULL_NUM;
308 
309     (void)FillpQueuePush(g_spunge->sockTable->freeQueqe, (void *)&sock, FILLP_FALSE, 1);
310     (void)SYS_ARCH_RWSEM_WRPOST(&sock->sockConnSem);
311 
312     return;
313 }
314 
SpungeShutdownSock(void * argSock,FILLP_INT how)315 void SpungeShutdownSock(void *argSock, FILLP_INT how)
316 {
317     struct FtSocket *sock = (struct FtSocket *)argSock;
318     struct FtNetconn *netconn = sock->netconn;
319     FILLP_INT connState;
320 
321     if (netconn == FILLP_NULL_PTR) {
322         FILLP_LOGERR("sock->netconn is NULL");
323         return;
324     }
325 
326     connState = NETCONN_GET_STATE(netconn);
327     FILLP_LOGINF("Shutdown,fillp_sock_id:%d,connState:%d", sock->index, connState);
328 
329     if (((how == SPUNGE_SHUT_RD) || (how == SPUNGE_SHUT_RDWR)) && !netconn->shutdownRdSet) {
330         netconn->shutdownRdSet = 1;
331 #ifdef SOCK_RECV_SEM
332         (void)SYS_ARCH_SEM_POST(&SOCK_GET_RECVSEM(sock));
333 #endif /* SOCK_RECV_SEM */
334 
335         if (sock->isListenSock == FILLP_TRUE) {
336             (void)SYS_ARCH_SEM_POST(&sock->acceptSem);
337         }
338     }
339 
340     if (((how == SPUNGE_SHUT_WR) || (how == SPUNGE_SHUT_RDWR)) && !netconn->shutdownWrSet) {
341         netconn->shutdownWrSet = 1;
342         (void)SYS_ARCH_SEM_POST(&SOCK_GET_SENDSEM(sock));
343     }
344 }
345 
SpungeConnCheckUnsendBoxEmpty(struct FtNetconn * conn)346 FILLP_BOOL SpungeConnCheckUnsendBoxEmpty(struct FtNetconn *conn)
347 {
348     FILLP_ULLONG con;
349     FILLP_ULLONG prod;
350     void *data = FILLP_NULL_PTR;
351     struct FillpPcbItem *item = FILLP_NULL_PTR;
352     FillpQueue *unsendBox = FILLP_NULL_PTR;
353 
354     if ((conn == FILLP_NULL_PTR) || (conn->pcb == FILLP_NULL_PTR)) {
355         FILLP_LOGERR("NULL Pointer");
356         return FILLP_TRUE;
357     }
358     unsendBox = conn->pcb->fpcb.send.unsendBox;
359 
360     if (unsendBox == FILLP_NULL_PTR) {
361         return FILLP_TRUE;
362     }
363 
364     con = unsendBox->ring.cons.head + 1;
365     prod = unsendBox->ring.prod.tail;
366 
367     while (((FILLP_LLONG)(prod - con)) >= 0) {
368         data = unsendBox->ring.ringCache[con % unsendBox->ring.size];
369         con++;
370 
371         if (data == FILLP_NULL_PTR) {
372             continue;
373         }
374 
375         item = (struct FillpPcbItem *)data;
376         if (item->netconn == (void *)conn) {
377             FILLP_LOGDBG("Still has data in unsedn box");
378             return FILLP_FALSE;
379         }
380     }
381 
382     return FILLP_TRUE;
383 }
384 
SpungeDestroyNoWait(struct FillpPcb * pcb,struct FtSocket * sock,struct FtNetconn * conn)385 static int SpungeDestroyNoWait(struct FillpPcb *pcb, struct FtSocket *sock, struct FtNetconn *conn)
386 {
387 #if FILLP_DEFAULT_DESTROY_STACK_WITHOUT_WAIT_SOCKET_CLOSE
388     /* for miracast, ignore the unSend unAck and unRecv packets, skip the disconnection flow,
389         because app will call FtClose once wifi disconnect, stack can't free socket until
390         10s keep alive timeout. That would lead FtDestroy block a long time. */
391     if (pcb->pcbInst->waitTobeCoreKilled == FILLP_TRUE) {
392         FILLP_LOGERR("ignore unsend packet, skip dissconnetion flow and about to free socket %d", sock->index);
393         SpungeConnClosed(conn);
394         return 1;
395     }
396 #endif
397     return 0;
398 }
399 
SpungeCheckDisconn(void * argConn)400 void SpungeCheckDisconn(void *argConn)
401 {
402     struct FtNetconn *conn = (struct FtNetconn *)argConn;
403     struct FtSocket *sock = (struct FtSocket *)conn->sock;
404     struct FillpPcb *pcb = FILLP_NULL_PTR;
405     FILLP_UINT8 connState;
406     struct FillpSendPcb *sendPcb = FILLP_NULL_PTR;
407 
408     if (sock == FILLP_NULL_PTR || conn->pcb == FILLP_NULL_PTR) {
409         FILLP_LOGERR("NULL pointer sock or conn->pcb");
410         return;
411     }
412 
413     pcb = &conn->pcb->fpcb;
414 
415     connState = NETCONN_GET_STATE(conn);
416     FILLP_LOGDBG("fillp_sock_id:%d", sock->index);
417     if (!(connState == CONN_STATE_CONNECTED || connState == CONN_STATE_CLOSING)) {
418         FILLP_LOGERR("No need to check disconn message anymore,fillp_sock_id:%d,connState:%u",
419             sock->index, connState);
420         return;
421     }
422 
423     if (connState == CONN_STATE_CONNECTED) {
424         /* Check all unsend box */
425         if (!SpungeConnCheckUnsendBoxEmpty(conn)) {
426             goto TIMER_REPEAT;
427         }
428 
429         if (SpungeDestroyNoWait(pcb, sock, conn) != 0) {
430             return;
431         }
432         /* Check if all send data are sent out */
433         sendPcb = &conn->pcb->fpcb.send;
434         FillpAckSendPcb(&conn->pcb->fpcb, 0);
435 
436         if ((sock->lingering == FILLP_FALSE) && (sendPcb->unackList.count ||
437             sendPcb->unrecvList.nodeNum || !HLIST_EMPTY(&sendPcb->unSendList) ||
438             sendPcb->itemWaitTokenLists.nodeNum || sendPcb->redunList.nodeNum)) {
439             FILLP_LOGDBG("Still has data to send");
440             goto TIMER_REPEAT;
441         }
442 
443         FILLP_LOGINF("Now all unSend data are checked.Going to send fin fillp_sock_id:%d", sock->index);
444         conn->sendBufRunOut = FILLP_TRUE;
445         /* Need to reconsider the disconn message send */
446         FillpNetconnSetState(conn, CONN_STATE_CLOSING);
447         pcb->finCheckTimer.interval =
448             (FILLP_UINT32)FILLP_UTILS_MS2US((FILLP_LLONG)sock->resConf.common.disconnectRetryTimeout);
449     } else if (SpungeDestroyNoWait(pcb, sock, conn) != 0) {
450         return;
451     }
452 
453     if (pcb->isFinAckReceived != FILLP_TRUE) {
454         FillpSendFin(pcb);
455     }
456 
457 TIMER_REPEAT:
458     FillpEnableFinCheckTimer(pcb);
459     return;
460 }
461 
SpungeSendConnectMsg(void * argConn)462 void SpungeSendConnectMsg(void *argConn)
463 {
464     struct FtNetconn *conn = (struct FtNetconn *)argConn;
465     struct FtSocket *sock = (struct FtSocket *)conn->sock;
466     struct SockOsSocket *osSock = FILLP_NULL_PTR;
467     FILLP_UINT8 connState = NETCONN_GET_STATE(conn);
468     if (connState != CONN_STATE_CONNECTING) {
469         FILLP_LOGINF("socket state = %u is not in connecting state for the conn",
470             connState);
471         return;
472     }
473 
474     if (NetconnIsConnectTimeout(conn)) {
475         if (sock == FILLP_NULL_PTR) {
476             FILLP_LOGWAR("connection state idle for the conn");
477 
478             /* No need to stop the conenct timer again, as it is already stopped upon earlier socket_clear */
479             return;
480         }
481 
482         FillpNetconnSetState(conn, CONN_STATE_IDLE);
483         SET_ERRNO(FILLP_ETIMEDOUT);
484         sock->coreErrType[MSG_TYPE_DO_CONNECT] = ERR_CONN_TIMEOUT;
485         if (SOCK_IS_NONBLOCKING(sock)) {
486             FILLP_SOCK_SET_ERR(sock, FILLP_ECONNREFUSED);
487             FillpNetconnSetSafeErr(conn, ERR_CONNREFUSED);
488         } else {
489             FillpNetconnSetSafeErr(conn, ERR_CONN_TIMEOUT);
490         }
491 
492         SpungeConnConnectFail(conn->sock);
493 
494         return;
495     }
496 
497     FillpEnableConnRetryCheckTimer(&conn->pcb->fpcb);
498 
499     osSock = NETCONN_GET_OSSOCK(conn, SPUNGE_GET_CUR_INSTANCE()->instIndex);
500     if (!OS_SOCK_OPS_FUNC_VALID(osSock, connected) || !OS_SOCK_OPS_FUNC_VALID(osSock, sendPacket)) {
501         FILLP_LOGERR("osSock is NULL");
502         return;
503     }
504     osSock->ioSock->ops->connected(sock, osSock->ioSock);
505     if (osSock->ioSock->ops->sendPacket(
506         FILLP_PKT_TYPE_CONN_REQ, (void *)osSock->ioSock, (void *)conn->pcb, FILLP_NULL_PTR) == -1) {
507         FILLP_LOGINF("send conn req fail for sockId:%d", sock->index);
508     }
509 
510     return;
511 }
512 
SpinstAddToPcbList(struct SpungeInstance * inst,struct HlistNode * node)513 void SpinstAddToPcbList(struct SpungeInstance *inst, struct HlistNode *node)
514 {
515     HlistAddTail(&inst->pcbList.list, node);
516 }
517 
SpinstDeleteFromPcbList(struct SpungeInstance * inst,struct HlistNode * node)518 void SpinstDeleteFromPcbList(struct SpungeInstance *inst, struct HlistNode *node)
519 {
520     HlistDelete(&inst->pcbList.list, node);
521 }
522 
SpungeAllocUnsendBox(struct SpungeInstance * inst)523 FillpQueue *SpungeAllocUnsendBox(struct SpungeInstance *inst)
524 {
525     return inst->unsendBox[0];
526 }
527 
SpungeFreeUnsendBox(struct FillpPcb * pcb)528 void SpungeFreeUnsendBox(struct FillpPcb *pcb)
529 {
530     FILLP_UNUSED_PARA(pcb);
531     return;
532 }
533 
534 /* This function is called when the connection is sure closed
535     For : 1) close() involked and rst send out
536           2) recved rst from peer
537           3) disconnect send out and disconn recved (local and peer send disconnect both)
538           if close() involked, the recv box data will be dropped, or the recv() still returns positive if data remains,
539           return 0 if all data taken
540  */
SpungeConnClosed(struct FtNetconn * conn)541 void SpungeConnClosed(struct FtNetconn *conn)
542 {
543     if (NETCONN_GET_STATE(conn) == CONN_STATE_CLOSED) {
544         FILLP_LOGERR("Already closed");
545         return;
546     }
547 
548     if (conn->sock == FILLP_NULL_PTR) {
549         FILLP_LOGERR("conn socket is NULL");
550         return;
551     }
552 
553     if (conn->pcb == FILLP_NULL_PTR) {
554         FILLP_LOGERR("conn pcb is NULL");
555         return;
556     }
557 
558     FILLP_LOGINF("fillp_sock_id:%d", ((struct FtSocket *)conn->sock)->index);
559 
560     FillpNetconnSetState(conn, CONN_STATE_CLOSED);
561     FillpPcbRemoveTimers(&conn->pcb->fpcb);
562 
563     if (conn->closeSet) {
564         /* Try to release the recv box data */
565         if (SpungePostMsg(SPUNGE_GET_CUR_INSTANCE(), (void *)((struct FtSocket *)conn->sock),
566             MSG_TYPE_FREE_SOCK_EAGAIN, FILLP_FALSE) != ERR_OK) {
567             FILLP_LOGERR("FAILED TO POST -- MSG_TYPE_FREE_SOCK_EAGAIN--- to CORE"
568                          " Sock ID: %d", ((struct FtSocket*)conn->sock)->index);
569         }
570     }
571 }
572 
SpungeConnConnectSuccess(void * argSock)573 void SpungeConnConnectSuccess(void *argSock)
574 {
575     struct FtSocket *sock = (struct FtSocket *)argSock;
576     if (!SOCK_IS_NONBLOCKING(sock)) {
577         (void)SYS_ARCH_SEM_POST(&sock->connBlockSem);
578     }
579 
580     sock->errEvent = 0;
581     SpungeEpollEventCallback(sock, SPUNGE_EPOLLOUT, 1);
582 }
583 
SpungeConnConnectFail(void * argSock)584 void SpungeConnConnectFail(void *argSock)
585 {
586     struct FtSocket *sock = (struct FtSocket *)argSock;
587     if (!SOCK_IS_NONBLOCKING(sock)) {
588         (void)SYS_ARCH_SEM_POST(&sock->connBlockSem);
589     }
590     sock->errEvent |= (FILLP_UINT32)SPUNGE_EPOLLHUP;
591     SpungeEpollEventCallback(sock, (FILLP_INT)SPUNGE_EPOLLOUT | (FILLP_INT)SPUNGE_EPOLLHUP, 1);
592 }
593 
594 #ifdef __cplusplus
595 }
596 #endif
597