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