static bool SendNextIpStack(void) { // get the next stack to send if we have one if (wfmrf24.priv.pIpStackBeingTx == NULL) { wfmrf24.priv.pIpStackBeingTx = FFOutPacket(&wfmrf24.priv.ffptWrite); } // try and send it. if (wfmrf24.priv.pIpStackBeingTx != NULL) { IPSTACK * pIPStack = wfmrf24.priv.pIpStackBeingTx; int16_t cbTotal = pIPStack->cbFrame + pIPStack->cbIPHeader + pIPStack->cbTranportHeader + pIPStack->cbPayload; if (WF_TxPacketAllocate(cbTotal)) { // always have a frame, alwasy FRAME II (we don't support 802.3 outgoing frames; this is typical) WF_TxPacketCopy((uint8_t *) pIPStack->pFrameII, pIPStack->cbFrame); // IP Header if (pIPStack->cbIPHeader > 0) { WF_TxPacketCopy((uint8_t *) pIPStack->pIPHeader, pIPStack->cbIPHeader); } // Transport Header (TCP/UDP) if (pIPStack->cbTranportHeader > 0) { WF_TxPacketCopy((uint8_t *) pIPStack->pTransportHeader, pIPStack->cbTranportHeader); } // Payload / ARP / ICMP if (pIPStack->cbPayload > 0) { WF_TxPacketCopy((uint8_t *) pIPStack->pPayload, pIPStack->cbPayload); } // transmit WF_TxPacketTransmit(cbTotal); // we sent it, clean up pIPStack->fOwnedByAdp = false; IPSRelease(pIPStack); wfmrf24.priv.pIpStackBeingTx = NULL; return(true); } else { return(false); } } return(true); }
/***************************************************************************** Function: void TCPAbort(SOCKET * pSocket) Description: Abruptly and non in a friendly way aborts the connection right now. It does send a reset to the remote; but that is it. Parameters: pSocket: The socket to abort Returns: None ***************************************************************************/ void TCPAbort(HSOCKET hSocket) { TCPSOCKET * pSocket = (TCPSOCKET *) hSocket; // just return. if(pSocket == NULL) { return; } // send the reset // RFC 793, these are the states to send a reset. if(tcpSynReceived <= pSocket->tcpState && pSocket->tcpState <= tcpCloseWait) { IPSTACK * pIpStack = IPSRefresh(NULL, pSocket->s.pLLAdp, NULL); // <SEQ=SND.NXT><CTL=RST> // clear so there is a zero ACK pSocket->rcvIRS = 0; pSocket->rcvNXT = 0; // say this is a reset pIpStack->pTCPHdr->fRst = true; // send the reset with no ACK TCPTransmit(pIpStack, pSocket, 0, 0, false, SYSGetMilliSecond(), NULL); // when we are done, free the stack IPSRelease(pIpStack); } // we do not want to put this back on the listenging queue. // we pretty much just want to clean up pSocket->tcpState = tcpUnassigned; TCPResetSocket(pSocket); return; }
bool UDPSend(HSOCKET hSocket, const uint8_t * pbDatagram, uint16_t cbDatagram, IPSTATUS * pStatus) { UDPSOCKET * pSocket = (UDPSOCKET *) hSocket; IPSTACK * pIpStack = NULL; if(pSocket->s.portRemote == portListen || pSocket->s.portRemote == portInvalid) { AssignStatusSafely(pStatus, ipsSocketNotResolved); return(false); } else if((pIpStack = IPSGetIpStackFromAdaptor(pSocket->s.pLLAdp, ippnUDP, pStatus)) == NULL) { return(false); } else if(UDPRawSend(pSocket->s.pLLAdp, pIpStack, (void *) &pSocket->s.ipRemote, pSocket->s.portRemote, pSocket->s.portLocal, pbDatagram, cbDatagram, true, pStatus)) { return(true); } else { IPSRelease(pIpStack); return(false); } }
/***************************************************************************** Function: SOCKET * TCPOpen(const LLADP * pLLAdp, const SOCKETPOOL * pSocketPool, void * pIPvXDest, uint16_t portRemote, uint16_t portLocal, IPSTATUS * pStatus) Summary: Opens a Socket for both Client and Server. If portRemote == 0 The socket is opened for listening. Description: Precondition: Parameters: pLLAdp - The adaptor to use pSocket - A pointer to the socket to use hPMGR - A handle to the page manager to create the socket stream. pIPvXDest - The Dest IP to connect to if a client, ignored for a server open and may be NULL portRemote - The remote port to connect to if Client, MUST be 0 if this is a server open for listen portLocal - Local port to use, one will be assigned if zero pStatus - A pointer to a status variable to recieve the status of the open, This may be NULL Returns: The Socket if opened, NULL on failure ***************************************************************************/ HSOCKET TCPOpenWithSocket(const LLADP * pLLAdp, TCPSOCKET * pSocket, HPMGR hPMGR, const void * pIPvXDest, uint16_t portRemote, uint16_t portLocal, IPSTATUS * pStatus) { IPSTATUS status = ipsSuccess; IPSTACK * pIpStack = NULL; uint32_t cbOptions = 0; // make sure pIPvXDest points to something if(portRemote == 0 || pIPvXDest == NULL) { pIPvXDest = &IPv6NONE; } if(pSocket == NULL) { AssignStatusSafely(pStatus, ipsNoSocketsAvailable); return(NULL); } else if(pLLAdp == NULL) { status = ipsAdaptorMustBeSpecified; } // if this is a client open else if( (pSocket = TCPInitSocket(pLLAdp, pSocket, hPMGR, pIPvXDest, portRemote, portLocal, &status)) != NULL && portRemote != portListen && (pIpStack = TCPCreateSyn(pSocket, &cbOptions, &status)) != NULL) { pSocket->tcpState = tcpSynSent; pSocket->tLastAck = SYSGetMilliSecond(); // start the connection process TCPTransmit(pIpStack, pSocket, 1, cbOptions, false, SYSGetMilliSecond(), &status); } // else this is a server open / or an error getting the socket which we will abort below in the error check else if(pSocket != NULL) { pSocket->tcpState = tcpListen; } // we got an error somewhere; clean up if(IsIPStatusAnError(status)) { if(pSocket != NULL) { pSocket->tcpState = tcpUnassigned; TCPResetSocket(pSocket); } IPSRelease(pIpStack); pSocket = NULL; AssignStatusSafely(pStatus, status); return(NULL); } // put on the listening list. FFInPacket(&g_ffptActiveTCPSockets, pSocket); pSocket->fSocketOpen = true; AssignStatusSafely(pStatus, status); return((HSOCKET) pSocket); }