Пример #1
0
IPSTACK * IPSGetIpStackFromAdaptor(const LLADP * pLLAdp, uint32_t type, IPSTATUS * pStatus)
{
    uint8_t * pIpStackBuff = NULL;
    IPSTACK * pIpStack = NULL;

    if(pLLAdp == NULL)
    {
        AssignStatusSafely(pStatus, ipsAdaptorMustBeSpecified);
        return(NULL);
    }
    else if(pLLAdp->pNwAdp->hAdpHeap == NULL)
    {
        AssignStatusSafely(pStatus, ispOutOfMemory);
        return(NULL);
    }

    if((pIpStackBuff = (u8*)RRHPAlloc(pLLAdp->pNwAdp->hAdpHeap, IPStackEntrySize)) == NULL)
    {
        AssignStatusSafely(pStatus, ipsIpStackAllInUse);
        return(NULL);
    }

    if((pIpStack = IPSInitIpStack(pLLAdp, pIpStackBuff, type)) == NULL)
    {
        AssignStatusSafely(pStatus, ipsUnsupportedTransportProtocol);
        RRHPFree(pLLAdp->pNwAdp->hAdpHeap, pIpStackBuff);
        return(NULL);
    }

    AssignStatusSafely(pStatus, ipsSuccess);
    return(pIpStack);
}
Пример #2
0
static bool DNSStartIPv4Request(const LLADP * pLLAdp, const uint8_t * pchDomainName, uint32_t cchDomanName, IPSTATUS * pStatus)
{
    uint16_t cbMax = DNSCreateIPv4QueryCB(pLLAdp, pchDomainName, cchDomanName, &pLLAdp->pDNSMem->dnsDG);

    // start a new request.
    if(cbMax > 0)
    {
        // put in network order
        pLLAdp->pDNSMem->cbDNSDG = ExDNSDG(&pLLAdp->pDNSMem->dnsDG, cbMax);

        // Go into the state machine
        pLLAdp->pDNSMem->ip.ipv4.u32 = IPv4NONE.u32;
        pLLAdp->pDNSMem->dnsState = dnsSend;
        pLLAdp->pDNSMem->pchDomainName = pchDomainName;
        pLLAdp->pDNSMem->cchDomainName = cchDomanName;
        AssignStatusSafely(pStatus, ipsDNSIsResolving);
        return(true);
    }

    // else the name did not parse
    else
    {
        AssignStatusSafely(pStatus, ipsDNSInvalidName);
        return(false);
    }
}
Пример #3
0
bool TCPServer::addSocket(TCPSocket& tcpSocket, IPSTATUS * pStatus)
{
    // if we don't have a page manager, assign the default one
    if(tcpSocket._hPMGR == NULL)
    {
        tcpSocket._hPMGR = hNetworkPMGR;
    }

    if(tcpSocket._hPMGR == NULL)
    {
        AssignStatusSafely(pStatus, ipsNoPMGRGiven);
        return(false);
    }
    else if(_pDEIPcK == NULL)
    {
        AssignStatusSafely(pStatus, ipsNotInitialized);
        return(false);
    }
    else if(tcpSocket._pDEIPcK != NULL)
    {
        AssignStatusSafely(pStatus, ipsInUse);
        return(false);
    }

    // add it to the list of sockets to listen on
    FFInPacket(&_ffptSockets, &tcpSocket._ffptInfo);
    tcpSocket._pDEIPcK = _pDEIPcK;
    return(true);
}
Пример #4
0
static uint32_t UDPPeekSMGR(UDPSOCKET * pSocket, HSMGR pSMGR, uint16_t index, uint8_t * pbRead, uint16_t cbRead, IPSTATUS * pStatus)
{
    uint32_t    cb = 0;

    if(pSocket == NULL)
    {
        AssignStatusSafely(pStatus, ipsSocketNULL);
        return(0);
    }
    else if(pbRead == NULL || cbRead == 0)
    {
        AssignStatusSafely(pStatus, ipsBufferNotDefined);
        return(0);
    }
    else if(pSocket->s.portRemote == portListen || pSocket->s.portRemote == portInvalid)
    {
        AssignStatusSafely(pStatus, ipsSocketNotResolved);
        return(0);
    }

    cb = min((pSocket->cbNextDataGram - index), cbRead);
    if(cb > 0 && SMGRRead((HSMGR) pSMGR, (sizeof(uint16_t) + index), pbRead, cb) == cb)
    {
        return(cb);
    }

    return(0);
}
Пример #5
0
static bool IsInitNotLinked(IPSTATUS * pStatus)
{
    if (wfmrf24.priv.fMRFBusy)
    {
        AssignStatusSafely(pStatus, ipsInUseW);
        return(false);
    }
    else if (wfmrf24.priv.connectionStatus != ForceIPStatus((InitMask | WF_EVENT_INITIALIZATION)))
    {
        AssignStatusSafely(pStatus, ipsInUse);
        return(false);

    }
    else if (!IsInitialized(pStatus))
    {
        return(false);
    }

    // we are not busy and we are in the initialize state and we have
    // not connected. However, in the past, we may have attempted a disconnect while
    // during a reconnect, so lets just make sure we are disconnected
    Disconnect();

    return(true);
}
Пример #6
0
/*****************************************************************************
  Function:
	void TCPClose(SOCKET *  pSocket, IPSTATUS * pStatus)

  Description:
        This politely closes a socket, making sure no data is lost

  Parameters:
	pSocket:        The socket to close, it is always safe to close, closed sockets.
        pStatus:        A pointer to a status variable to recieve the state of the socket as a status

  Returns:
        None

  ***************************************************************************/
void TCPClose(HSOCKET hSocket, IPSTATUS * pStatus)
{
    TCPSOCKET * pSocket = (TCPSOCKET *) hSocket;

    if(pSocket == NULL)
    {
        AssignStatusSafely(pStatus, ipsSocketNULL);
        return;
    }

    switch(TCPState(pSocket))
    {
        case  tcpListen:
            // closes, releases the socket so it can be used again
            pSocket->tcpState = tcpClosed;
            break;

        case  tcpSynSent:
            // we do not update sndEND when we send a sndNXT, but we do update the sndNXT
            // this is because a syn is a phantom byte and we don't want to point beyond zero
            // in our output buffers and attempt to send a garbabe byte.
            // but in order to terminate properly we need sndNXT == sndEND or we will loop
            // attempting to send bytes from out buffer that we don't have to send
            pSocket->sndNXT = pSocket->sndEND;  // we may have sent a syn and sndNXT > sndEND
            pSocket->tcpState = tcpWaitUserClose;
            break;

        case  tcpSynReceived:
        case  tcpSynReceivedWhileListening:
            pSocket->sndNXT = pSocket->sndEND;  // we may have sent a syn and sndNXT > sndEND
            // fall thru

        case  tcpEstablished:
            pSocket->tcpState = tcpFinWait1;
            break;

        case  tcpFinWait1:
        case  tcpFinWait2:
        case  tcpCloseWait:
        case  tcpClosing:
        case  tcpLastAck:
        case  tcpInvalid:
        case  tcpUnassigned:
        case  tcpAllocated:
        case  tcpClosed:
        case  tcpWaitUserClose:
        default:
            break;
    }
    pSocket->fSocketOpen = false;

    // get the status
    AssignStatusSafely(pStatus, IPStatusFromTCPState(pSocket->tcpState));
}
Пример #7
0
static bool Send(IPSTACK * pIpStack, IPSTATUS * pStatus)
{
    AssignStatusSafely(pStatus, ipsSuccess);
    pIpStack->fOwnedByAdp = true;
    FFInPacket(&wfmrf24.priv.ffptWrite, pIpStack);
    return(true);
}
Пример #8
0
/*****************************************************************************
  Function:
	uint32_t TCPPeekSMGR(TCPSOCKET * pSocket, HSMGR pSMGR, uint8_t * pbRead, uint16_t cbRead, IPSTATUS * pStatus)

  Description:
        Reads bytes out of the receive buffer but does not move the unread pointer,
        peek or receive will return the same data.

  Parameters:
	pSocket:        The socket to read the bytes from
        pSMGR:          pointer to an open stream
        pbRead:         A buffer to receive the data
        cbRead:         Max size of the buffer to receive the data
        pStatus:        A pointer to a status variable to recieve the state of the socket as a status

  Returns:
        Number of bytes read

  ***************************************************************************/
static uint32_t TCPPeekSMGR(TCPSOCKET * pSocket, HSMGR pSMGR, uint16_t index, uint8_t * pbRead, uint16_t cbRead, IPSTATUS * pStatus)
{
    int32_t    cb = 0;
    IPSTATUS status = ipsSuccess;

    if(pSocket == NULL)
    {
        status = ipsSocketNULL;
    }
    else if(pbRead == NULL || cbRead == 0)
    {
        status =  ipsBufferNotDefined;
    }
    else if(pSocket->s.portRemote == portListen || pSocket->s.portRemote == portInvalid)
    {
        status =  ipsSocketNotResolved;
    }
    else if(pSMGR == NULL)
    {
        status = ipsNoSMGRGiven;
    }
    else
    {
        cb = SMGRRead((HSMGR) pSMGR, index, pbRead, min((SMGRcbStream(pSMGR) - index), cbRead));
    }

    AssignStatusSafely(pStatus, status);
    return(cb);
}
Пример #9
0
bool DEWFcK::wfConnect(SECURITY security, const char * szSsid, const byte * rgbKey, int iKey, IPSTATUS * pStatus)
{
    IPSTATUS status = ipsFailed;

    deIPInit();

    if(isWFInitialized(&status))
    {
        switch(_wfState)
        {
            case idle:
            case scanReady:
            case keygenReady:
            case connecting:
                if(_pNwWF->Connect(security, (const uint8_t *) szSsid, rgbKey, iKey, true, &status))
                {
                    _wfState = connected;
                }
                else if(IsIPStatusAnError(status))
                {
                    _wfState = idle;
                }
                break;

            default:
                status = ipsInvalidOperation;
                break;
        }
    }

    AssignStatusSafely(pStatus, status);
    return(_wfState == connected);
}
Пример #10
0
const NWADP * GetMRF24GAdaptor(MACADDR *pUseThisMac, HRRHEAP hAdpHeap, IPSTATUS * pStatus)
{
    // get our pins set up
    WF_HIBERNATE_IO     = 0;
    WF_HIBERNATE_TRIS   = 0;

    WF_RESET_IO         = 0;
    WF_RESET_TRIS       = 0;

    // Enable the WiFi
    WF_CS_IO            = 1;
    WF_CS_TRIS          = 0;

    WF_INT_TRIS         = 1;

    // register our interrupt vectors
    setIntVector(WF_INT_VEC, _WFInterrupt);
    setIntPriority(WF_INT_VEC, 3, 0);

    if (hAdpHeap == NULL)
    {
        AssignStatusSafely(pStatus, ipsNoHeapGiven);
        return(NULL);
    }

    AssignStatusSafely(pStatus, ipsSuccess);
    wfmrf24.priv.initStatus = ForceIPStatus((InitMask | WF_INIT_ERROR_SPI_NOT_CONNECTED));
    wfmrf24.priv.connectionStatus = ForceIPStatus((InitMask | WF_EVENT_INITIALIZATION));
    wfmrf24.priv.cScanResults = -1;
    wfmrf24.adpMRF24G.hAdpHeap = hAdpHeap;
    wfmrf24.priv.pIpStackBeingTx = NULL;
    memset(&wfmrf24.priv.ffptRead, 0, sizeof(FFPT));
    memset(&wfmrf24.priv.ffptWrite, 0, sizeof(FFPT));

    // save away our MAC
    if (pUseThisMac != NULL)
    {
        memcpy(&wfmrf24.adpMRF24G.mac, pUseThisMac, sizeof(MACADDR));
    }
    else
    {
        memcpy(&wfmrf24.adpMRF24G.mac, &MACNONE, sizeof(MACADDR));
    }

    WF_Init();
    return(&wfmrf24.adpMRF24G);
}
Пример #11
0
/*****************************************************************************
  Function:
	uint32_t TCPAvailable(SOCKET *  pSocket, IPSTATUS * pStatus)

  Description:
            Returns the number of unread bytes in the socket receive buffer

  Parameters:
	pSocket:        The socket to get the number of unread bytes
        pStatus:        A pointer to a status variable to recieve the state of the socket as a status

  Returns:
        Number of unread bytes in the socket, or zero

  ***************************************************************************/
uint32_t TCPAvailable(HSOCKET hSocket, IPSTATUS * pStatus)
{
    TCPSOCKET * pSocket = (TCPSOCKET *) hSocket;
    uint32_t    rcvNXT  = 0;

    if(pSocket == NULL)
    {
        AssignStatusSafely(pStatus, ipsSocketNULL);
        return(0);
    }

    AssignStatusSafely(pStatus, IPStatusFromTCPState(pSocket->tcpState));

    switch(TCPState(pSocket))
    {
        // get rid of the FIN that is in the count
        case  tcpEstablished:
        case  tcpSynReceived:
        case  tcpSynReceivedWhileListening:
        case  tcpCloseWait:
        case  tcpLastAck:
        case  tcpWaitUserClose:
        case  tcpFinWait1:
        case  tcpFinWait2:
        case  tcpClosing:
            rcvNXT = pSocket->rcvNXT;
            if(pSocket->fGotFin)
            {
                rcvNXT--;
            }
            break;

        case  tcpListen:
        case  tcpSynSent:
        case  tcpInvalid:
        case  tcpUnassigned:
        case  tcpAllocated:
        case  tcpClosed:
        default:
            return(0);
            break;
    }

    // how much can we read
    return(rcvNXT);
}
Пример #12
0
/*****************************************************************************
  Function:
	bool TCPIsEstablished(SOCKET * pSocket, IPSTATUS * pStatus)

  Description:
        This is sort of like TCPIsConnected except it is for the established state. Think
        of being connected as being in the process of getting or closing a connection and being established.
        Established is a fully connected duplex condtion where both sides are ready to send and receive data.

  Parameters:
	pSocket:        The socket to see if it is in the established state
        pStatus:        A pointer to a status variable to recieve the status of the connection
                        This may be NULL if you don't care about the status

  Returns:
        true if the connection is established and you can send/write data,
        false if the conneciton is not established
  ***************************************************************************/
bool TCPIsEstablished(HSOCKET hSocket, IPSTATUS * pStatus)
{
    IPSTATUS    status;

    TCPIsConnected(hSocket, &status);
    AssignStatusSafely(pStatus, status);
    return(status == IPStatusFromTCPState(tcpEstablished));
}
Пример #13
0
static bool StartScan(t_scanMode filter, IPSTATUS * pStatus)
{
    if (IsInitialized(pStatus) && wfmrf24.priv.connectionStatus == ForceIPStatus((InitMask | WF_EVENT_INITIALIZATION)))
    {
        wfmrf24.priv.fMRFBusy = true;
        wfmrf24.priv.cScanResults = -1;
        WF_Scan(filter);
        AssignStatusSafely(pStatus, ipsPending);
    }
    return(true);
}
Пример #14
0
static IPSTACK * Read(IPSTATUS * pStatus)
{
    IPSTACK *   pIpStack = FFOutPacket(&wfmrf24.priv.ffptRead);

    if (pIpStack != NULL)
    {
        pIpStack->fOwnedByAdp = false;
    }

    AssignStatusSafely(pStatus, ipsSuccess);
    return(pIpStack);
}
Пример #15
0
/*****************************************************************************
  Function:
    bool DEWFcK::beginScan(void)
    bool DEWFcK::beginScan(WFSCAN scanType)
    bool DEWFcK::beginScan(int connectionID)
    bool DEWFcK::beginScan(int connectionID, WFSCAN scanType)
 
  Description:
	Scan for a WiFi SSID based on profile or connection ID.

  Parameters:
    connectionID    - Scan for the network defined by the specifed profile, or all networks if 0/WF_SCAN_ALL is specified or omitted
    scanType        - WF_ACTIVE_SCAN or WF_PASSIVE_SCAN or WF_PASSIVE_SCAN if omitted
  
  Returns:
	True if the the scan got started, false if not.. usually becasue an invalid connectionID was given.

  Remarks:
    We have to wait for a scan to finish before we can do any other hardware stuff, so this is a harsh call
    in that once connected this can cause problems or the connection can cause problem for this
    That is why once we are conneced, this call will fail, we can't run it.

 ***************************************************************************/
bool DEWFcK::wfScan(WFSCAN scanType, int * pcNetworks, IPSTATUS * pStatus)
{
    // make sure we are initialized
    deIPInit();

    if(isWFInitialized(pStatus))
    {

        switch(_wfState)
        {
            case idle:
            case scanReady:
            case keygenReady:
                if(_pNwWF->StartScan(scanType, pStatus))
                {
                    _wfState = scanning;
                }
                break;

            case scanning:
               if(_pNwWF->IsScanDone((int32_t *) pcNetworks))
               {
                    AssignStatusSafely(pStatus, ipsSuccess);
                    _wfState = scanReady;
                    return(true);
               }
               else
               {
                    AssignStatusSafely(pStatus, ipsScanning);
               }
               break;

            default:
                AssignStatusSafely(pStatus, ipsInvalidOperation);
                break;
        }
    }

    return(false);
}
Пример #16
0
static bool IPSSetFrame(IPSTACK * pIpStack, IPSTATUS * pStatus)
{

    if(pIpStack->cbFrame != sizeof(ETHERNETII_FRAME))
    {
        AssignStatusSafely(pStatus, ipsInvalidFrameSize);
        return(false);
    }

    pIpStack->pFrameII->etherType = pIpStack->etherType;
    pIpStack->fIEEE802Frame     = false;

    // put my MAC address in. 
    memcpy(&pIpStack->pFrameII->macSrc, &pIpStack->pLLAdp->pNwAdp->mac, sizeof(MACADDR));

    // put in the broadcast address, this will be filled in at the last min before
    // transmission when we do a ARP lookup for the IP
    memcpy(&pIpStack->pFrameII->macDest, &MACBROADCAST, sizeof(MACADDR));

    AssignStatusSafely(pStatus, ipsSuccess);
    return(true);
}
Пример #17
0
// does not calculate checksum; this is calculated when we got to network order
static bool IPSSetHeader(IPSTACK * pIpStack, IPSTATUS * pStatus)
{
    if(ILIsIPv6(pIpStack->pLLAdp))
    {
        memset(pIpStack->pIPv6Hdr, 0, sizeof(IPv6HDR));
        AssignStatusSafely(pStatus, ipsIpStackNotSupportedPkt);
        return(false);
    }
    else
    {
        if(pIpStack->cbIPHeader < sizeof(IPv4HDR))
        {
            AssignStatusSafely(pStatus, ipsInvalidIPv4HedearSize);
            return(false);;
        }

        // Per RFC 791
        pIpStack->cbIPHeader            = sizeof(IPv4HDR);
        pIpStack->pIPv4Hdr->version     = 4;                    
        pIpStack->pIPv4Hdr->cdwHeader   = sizeof(IPv4HDR) / 4;                
        pIpStack->pIPv4Hdr->cbTotal     = sizeof(IPv4HDR) + pIpStack->cbTranportHeader + pIpStack->cbPayload;                
        pIpStack->pIPv4Hdr->ident       = 0; 
        pIpStack->pIPv4Hdr->u16         = 0; 
        pIpStack->pIPv4Hdr->timeToLive  = TIME_TO_LIVE;
        pIpStack->pIPv4Hdr->protocol    = pIpStack->protocol;     // typically ippnICMP, ippnTCP, ippnUDP
        pIpStack->pIPv4Hdr->hdrChecksum = 0;            // for calculations, this is set to 0, RFC 791
        pIpStack->pIPv4Hdr->ipSrc.u32   = pIpStack->pLLAdp->ipMy.ipv4.u32;
        pIpStack->pIPv4Hdr->ipDest.u32  = IPv4BROADCAST.u32; 

        // TODO: Process options
        pIpStack->fOptionPresent        = false;

        return(true);
    }

    AssignStatusSafely(pStatus, ipsIpStackParsingError);
    return(false);
}
Пример #18
0
static bool IsLinked(IPSTATUS * pStatus)
{
    IPSTATUS    status = wfmrf24.priv.connectionStatus;

    if (!IsInitialized(pStatus))
    {
        return(false);
    }

    AssignStatusSafely(pStatus, status);

    // Alternative way, but slower than polling the event data
    //     void WF_ConnectionStateGet(uint8_t *p_state);
    // This is faster and gives the same result
    return(status == ipsSuccess);
}
Пример #19
0
IPSTACK *  IPSRefresh(IPSTACK * pIpStack, const LLADP * pLLAdp, IPSTATUS * pStatus)
{
    AssignStatusSafely(pStatus, ipsSuccess);
    if(pIpStack == NULL)
    {
        pIpStack = IPSGetIpStackFromAdaptor(pLLAdp, ippnTCP, pStatus);
    }
    else
    {
        pIpStack =  IPSSwapSrcAndDest(pIpStack);        
    }

    if(pIpStack != NULL)
    {
        // the payload may have a pointer in it that we are going to clear
        // that pointer may or may not be from the heap; but if it is not from
        // the heap, the pointer will be outside of the heap ranage and be ignored
        // by the heap manager with no damage.
        if(pIpStack->fFreePayloadToAdp)
        {
            RRHPFree(pIpStack->pLLAdp->pNwAdp->hAdpHeap, pIpStack->pPayload);
        }
        pIpStack->cbPayload             = 0;
        pIpStack->pPayload              = NULL;

        switch(pIpStack->protocol)
        {
            case ippnUDP:
                pIpStack->pUDPHdr->cbHdrData    = sizeof(UDPHDR);
                pIpStack->pUDPHdr->checksum     = 0;
                break;

            case ippnTCP:
                pIpStack->pTCPHdr->u16Flags     = 0;
                pIpStack->pTCPHdr->dataOffset   = sizeof(TCPHDR)/sizeof(uint32_t);
                pIpStack->pTCPHdr->urgentPtr    = 0;
                pIpStack->pTCPHdr->checksum     = 0;
                break;

            default:
                break;
        }
    }

    return(pIpStack);
}
Пример #20
0
/*****************************************************************************
  Function:
	uint32_t TCPPeek(SOCKET *  pSocket, void * pv, uint32_t cb, IPSTATUS * pStatus)

  Description:
        Reads bytes out of the receive buffer but does not move the unread pointer,
        peek or receive will return the same data.

  Parameters:
	hSocket:        The socket to read the bytes from
        index:          Number of bytes in to start the peek
        pbRead:         A buffer to receive the data
        cbRead:         Max size of the buffer to receive the data
        pStatus:        A pointer to a status variable to recieve the state of the socket as a status

  Returns:
        Number of bytes read

  ***************************************************************************/
uint32_t TCPPeekIdx(HSOCKET hSocket, uint32_t index, void * pbRead, uint32_t cbRead, IPSTATUS * pStatus)
{
    TCPSOCKET *     pSocket     = (TCPSOCKET *) hSocket;
    IPSTATUS        status      = ipsSocketNULL;

    if(pSocket != NULL && pSocket->cbRxSMGR > 0)
    {
        SMGR *  pSMGR = (SMGR*)alloca(pSocket->cbRxSMGR);

        if(SMGRRead((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR)
        {
            // because we are only READing, no need to update the stream tables
            return(TCPPeekSMGR(pSocket, (HSMGR) pSMGR, (uint16_t) index, (u8*)pbRead, cbRead, pStatus));
        }
        status = ipsFailedToReadStreamBuffer;
    }

    AssignStatusSafely(pStatus, status);
    return(0);
}
Пример #21
0
/*****************************************************************************
  Function:
	uint32_t TCPRead(SOCKET *  pSocket, void * pv, uint32_t cb, IPSTATUS * pStatus)

  Description:
        Reads bytes out of the receive buffer. We call this receive instead of read because RFC 793 calls it receive.

  Parameters:
	pSocket:        The socket to read the bytes from
        pv:             A buffer to receive the data
        cb:             Max size of the buffer to receive the data
        pStatus:        A pointer to a status variable to recieve the state of the socket as a status

  Returns:
        Number of bytes read

  ***************************************************************************/
uint32_t TCPRead(HSOCKET hSocket, void * pbRead, uint32_t cbRead, IPSTATUS * pStatus)
{
    TCPSOCKET *     pSocket     = (TCPSOCKET *) hSocket;
    IPSTATUS        status      = ipsSocketNULL;
    uint32_t cb = 0;

    if(pSocket != NULL && pSocket->cbRxSMGR > 0)
    {
        SMGR *  pSMGR = (SMGR*)alloca(pSocket->cbRxSMGR);

        if(SMGRRead((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR) == pSocket->cbRxSMGR)
        {
            cb = TCPPeekSMGR(pSocket, (HSMGR) pSMGR, 0, (u8*)pbRead, cbRead, &status);

            if(cb > 0)
            {
                // move the begining to after what we read
                SMGRMoveEnd((HSMGR) pSMGR, cb, SMGRAtBegining);

                // apply the read bytes to our base
                pSocket->rcvIRS += cb;

                // and now fix up to the base
                pSocket->rcvNXT -= cb;
                pSocket->rcvUP  -= cb;
//                pSocket->rcvSeqAhead -= cb;
            }

            // save away the table that is stored on the stack
            // this should not fail! It is a fixed size and already allocated
            SMGRWrite((HSMGR) &pSocket->smgrRxTxBuff, 0, pSMGR, pSocket->cbRxSMGR);
        }
        else
        {
            status = ipsFailedToReadStreamBuffer;
        }
    }

    AssignStatusSafely(pStatus, status);
    return(cb);
}
Пример #22
0
static bool IsInitialized(IPSTATUS * pStatus)
{
    // we ONLY DO THIS ONCE
    static bool fInitSetup = false;

    AssignStatusSafely(pStatus, wfmrf24.priv.initStatus);

    // Run the task because we might not be in the Adaptor yet
    WF_Task();

    if (!fInitSetup && wfmrf24.priv.initStatus == (InitMask | WF_INIT_SUCCESSFUL))
    {
        uint8_t channels[] = {};
        t_scanContext scanContext = {WF_ACTIVE_SCAN, 1, 200, 400, 20};

        WF_RegionalDomainSet(WF_DOMAIN_FCC);
        WF_NetworkTypeSet(WF_NETWORK_TYPE_INFRASTRUCTURE);
        WF_ChannelListSet(channels, sizeof(channels));
        WF_ReconnectModeSet(3, WF_ATTEMPT_TO_RECONNECT, 40, WF_ATTEMPT_TO_RECONNECT);
        WF_ScanContextSet(&scanContext);

        // fixup the MAC
        if (memcmp(&wfmrf24.adpMRF24G.mac, &MACNONE, sizeof(MACADDR)) == 0)
        {
            WF_MacAddressGet((uint8_t *) &wfmrf24.adpMRF24G.mac);
        }
        else
        {
            WF_MacAddressSet((uint8_t *) &wfmrf24.adpMRF24G.mac);
        }

        // set up the hardware filters
        //WF_SetHwMultiCastFilter(WF_MULTICAST_FILTER_1, (uint8_t *) &wfmrf24.adpMRF24G.mac);
        WF_SetHwMultiCastFilter(WF_MULTICAST_FILTER_2, (uint8_t *) &MACNONE);

        // we are done
        fInitSetup = true;
    }
    return(wfmrf24.priv.initStatus == (InitMask | WF_INIT_SUCCESSFUL));
}
Пример #23
0
/*****************************************************************************
  Function:
	uint32_t TCPSend(SOCKET *  pSocket, const void * pv, uint32_t cb, IPSTATUS * pStatus)

  Description:
         Stuff data into the socket to be sent on the next regularly scheduled send. Because of congestion
         control, this may take up to a fraction of a second to send. If you want it to go out immediately
         then call TCPFlush on the socket immediately after this call.

  Parameters:
	pSocket:        The socket to send the data on

        pv:             a pointer to a buffer of data to send

        cbReq:          The number of bytes to send.

        pStatus:        A pointer to a status variable to recieve the state of the send

  Returns:
        Number of bytes actually sent, could be less than requested if the socket is full.

  ***************************************************************************/
uint32_t TCPWrite(HSOCKET hSocket, const void * pv, uint32_t cbReq, IPSTATUS * pStatus)
{
    TCPSOCKET * pSocket = (TCPSOCKET *) hSocket;
    uint32_t    cb      = 0;

    if(pSocket == NULL)
    {
        AssignStatusSafely(pStatus, ipsSocketNULL);
        return(0);
    }

    // we can only write data if we are in the established state
    if(TCPIsEstablished(pSocket, pStatus))
    {
        SMGR *  pSMGR = (SMGR*)alloca(pSocket->cbTxSMGR);

        if(cbReq > 0 && pSMGR != NULL && (SMGRRead((HSMGR) &pSocket->smgrRxTxBuff, pSocket->cbRxSMGR, pSMGR, pSocket->cbTxSMGR) == pSocket->cbTxSMGR))
        {

            // This may seem like an odd place to do this, but I will update the sndUNA pointers here
            // I do this here instead of in the ACK processing because I do not want to take the time to open up the
            // stream in the ACK process, I just want to update the sndUNA pointer and move on. The downside of this is that
            // we may hold some pages longer than we need, but before I take MORE memory in the write, I will free those pages
            // which is why I will do that here before we WRITE our data below.
            TCPScaleSndIndexes(pSocket, pSMGR);

            // after we have scaled our pointers and potentially released some memory, we can
            // write as much data as we can to the stream
            cb  = SMGRWrite((HSMGR) pSMGR, SMGRcbStream(pSMGR), pv, cbReq);
            pSocket->sndEND += cb;

            // save away the table that is stored on the stack
            // this should not fail! It is a fixed size and already allocated
            SMGRWrite((HSMGR) &pSocket->smgrRxTxBuff, pSocket->cbRxSMGR, pSMGR, pSocket->cbTxSMGR);
        }
    }

    return(cb);
}
Пример #24
0
/***	int TCPServer::availableClients(void)
**
**	Synopsis:   
**      Checks to see how many pending clients are availabe to be accepted.
**
**	Parameters:
**      None
**
**	Return Values:
**      The number of waiting TCPSockets to be accepted.
**
**	Errors:
**      None
**
**  Notes:
**
**      This is the workhorse of the TCPServer Class
**      It will update pending clients if a connection is detected
**      It will attempt to start listening if a socket comes avalialbe for listening
**      It will clean up disconnected clients
*/
int TCPServer::availableClients(int& cListening, int& cWaiting, IPSTATUS * pStatus)
{
    int cAvailable = 0;
    cWaiting = 0;
    cListening = 0;

    FFLL *      pffllSocket = NULL;

   if(_pDEIPcK == NULL)
   {
       AssignStatusSafely(pStatus, ipsNotInitialized);
       return(0);
   }

    if(ILIsIPNetworkReady(_pDEIPcK->_pLLAdp, pStatus))
    {
        while((pffllSocket = (FFLL *) FFNext(&_ffptSockets, pffllSocket)) != NULL)
        {
            TCPSocket& tcpSocket = *((TCPSocket *) (pffllSocket->_this));   // for syntax sake

            if(TCPIsEstablished(&tcpSocket._socket, NULL))
            {
                cAvailable++;
            }
            else if(TCPIsConnected(&tcpSocket._socket, NULL))
            {
                cWaiting++;
            }
            else if(tcpSocket._socket.tcpState == tcpListen)
            {
                cListening++;
            }
         }
    }

    return(cAvailable);
}
Пример #25
0
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);
    }
}
Пример #26
0
// this will free the socket if it can't open it
TCPSOCKET * TCPInitSocket(const LLADP * pLLAdp, TCPSOCKET * pSocketOpen, HPMGR hPMGR, const void * pIPvXDest, uint16_t portRemote, uint16_t portLocal, IPSTATUS * pStatus)
{
    IPSTATUS    status          = ipsSuccess;
    SMGR *      pSMGR           = NULL;
    uint32_t    cb              = 0;
    uint32_t    cPages          = 0;

    if(pSocketOpen == NULL)
    {
        AssignStatusSafely(pStatus, ipsSocketNULL);
        return(NULL);
    }
    else if(hPMGR == NULL)
    {
        AssignStatusSafely(pStatus, ipsNoPMGRGiven);
    }

    // find a port
    if(portLocal == portDynamicallyAssign)
    {
        portLocal = GetEphemeralPort(&g_ffptActiveTCPSockets, &g_nextTCPEphemeralPort);
    }

    // get the sequence number
    // we have to get this BEFORE we memset the socket
    // as the timewait may be the socket we are clearing.
    // also, if we are listening, we can only assign the sequence number
    // when we now our remote port and IP as to not duplicate and to watch seq numbers.
    if(portRemote != portListen)
    {
        SKTPORTPAIR portPair;    // remote, local
        portPair.portRemote =   portRemote;
        portPair.portLocal  =   portLocal;

        // worry about the 2MSL timewait issue, get an appropriate sequence number
        if(TCPIsInUse(pLLAdp, portPair.portPair, pIPvXDest))
        {
            AssignStatusSafely(pStatus, ipsPortPairAndIPAlreadyActive);
            return(NULL);
        }
    }

    // build the stream manager to point to the page handler
    // first build the stream to the RxStream and TxStream
    // Rx is the 1st
    pSocketOpen->hPMGR = hPMGR;
    
    // calculate the size of the 2 embedded streams and how to partition the socket stream, stream
    // the Rx is the first indirect stream follwed by the Tx indirect stream in the socket stream
    cb                      = (1 << ((PMGR *) hPMGR)->pf2PerPage);
    cPages                  = ((PMGR *) hPMGR)->cPages;
    pSocketOpen->cbRxSMGR   = GetSMGRSize(min(((cTCPRXPages * cb) - sizeof(SMGR)), cPages));
    pSocketOpen->cbTxSMGR   = GetSMGRSize(min(((cTCPTXPages * cb) - sizeof(SMGR)), cPages));
    cb                      = pSocketOpen->cbRxSMGR + pSocketOpen->cbTxSMGR;

    if(SMGRInit(&pSocketOpen->smgrRxTxBuff, cbMAXTCPSreamRecord, hPMGR) != (HSMGR) &pSocketOpen->smgrRxTxBuff)
    {
        status = ispOutOfMemory;
    }
    else if((pSMGR = (SMGR*)alloca(cb)) == NULL)
    {
        status = ispOutOfMemory;
    }
    else if(SMGRInit(pSMGR, pSocketOpen->cbRxSMGR, hPMGR) == NULL || SMGRInit((SMGR *) (((uint8_t *) pSMGR) + pSocketOpen->cbRxSMGR), pSocketOpen->cbTxSMGR, hPMGR) == NULL)
    {
        status = ispOutOfMemory;
    }
    else if(SMGRWrite(&pSocketOpen->smgrRxTxBuff, 0, pSMGR, cb) != cb)
    {
        status = ispOutOfMemory;
    }

    AssignStatusSafely(pStatus, status);
    if(IsIPStatusAnError(status))
    {
        SMGRFree((HSMGR) pSMGR);
        SMGRFree((HSMGR) (((uint8_t *) pSMGR) + pSocketOpen->cbRxSMGR));
        SMGRFree((HSMGR) &pSocketOpen->smgrRxTxBuff);
        IPSReleaseSocket(pSocketOpen);
        return(NULL);
    }

    // make the socket
    pSocketOpen->tcpState       = tcpAllocated;
    pSocketOpen->s.portLocal    = portLocal;
    pSocketOpen->s.portRemote   = portRemote;
    pSocketOpen->s.pLLAdp       = pLLAdp;
    memcpy(&pSocketOpen->s.ipRemote, pIPvXDest, ILIPSize(pLLAdp));

    // get a new seq nbr
    pSocketOpen->sndISS = TCPGetSeqNumber(pLLAdp);

    // max I will allow to come in. RFC 1122 4.2.2.6
    pSocketOpen->cbLocalMSS     = min((PMGRMaxAlloc(hPMGR) >> 2), (uint16_t) (LLGetMTUR(pLLAdp) - 20));

    // Jacobson rule
    pSocketOpen->RTTsa          = RTTsaINIT;
    pSocketOpen->RTTsv          = RTTsvINIT;
    pSocketOpen->tRTO_SET       = RTO(pSocketOpen);
    pSocketOpen->tRTOCur        = pSocketOpen->tRTO_SET;

    return(pSocketOpen);
}
Пример #27
0
/*****************************************************************************
  Function:
	bool TCPIsConnected(SOCKET * pSocket, IPSTATUS * pStatus)

  Description:
        This is sort of like TCPIsEstablished except it is for any connected state. Think
        of being connected as being in the process of getting or closing a connection and being established.
        Established is a fully connected duplex condtion where both sides are ready to send and receive data.

  Parameters:
	pSocket:        The socket to see if it is in the established state
        pStatus:        A pointer to a status variable to recieve the status of the connection
                        This may be NULL if you don't care about the status

  Returns:
        true if the connection is in the process of connecting, half or full duplex
        connection, or in the process of closing but not yet closed.
        false if the conneciton is not in any kind of active condition.
  ***************************************************************************/
bool TCPIsConnected(HSOCKET hSocket, IPSTATUS * pStatus)
{
    TCPSOCKET * pSocket = (TCPSOCKET *) hSocket;
    IPSTATUS    status  = ipsUnknowTCPState;

    // check to see if we are even connected
    if(pSocket == NULL)
    {
        AssignStatusSafely(pStatus, ipsSocketNULL);
        return(false);
    }

    // Otherwise, what is our state?
    switch(pSocket->tcpState)
    {
        case tcpListen:
        case tcpSynSent:
        case tcpSynReceivedWhileListening:
        case tcpSynReceived:
        case tcpEstablished:
        case tcpFinWait1:
        case tcpFinWait2:
        case tcpCloseWait:
        case tcpClosing:
        case tcpLastAck:
            status = IPStatusFromTCPState(pSocket->tcpState);
            break;

        case tcpWaitUserClose:
            if(TCPAvailable(pSocket, NULL) > 0)
            {
                status = IPStatusFromTCPState(pSocket->tcpState);
            }
            else
            {
                status = IPErrorFromTCPState(pSocket->tcpState);
            }
            break;

        case tcpUnassigned:
        case tcpAllocated:
        case tcpInvalid:
        case tcpClosed:
            status = IPErrorFromTCPState(pSocket->tcpState);
            break;

        default:
            status = ipsUnknowTCPState;
            break;
    }

    AssignStatusSafely(pStatus, status);
    if(IsIPStatusAnError(status))
    {
        return(false);
    }
    else if(!ILIsIPNetworkReady(pSocket->s.pLLAdp, &status))
    {
        AssignStatusSafely(pStatus, status);
        return(false);
    }
    else if(pSocket->tcpState == tcpListen)
    {
        return(false);
    }

    return(true);
}
Пример #28
0
/*****************************************************************************
  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);
 }
Пример #29
0
bool DNSInit(const LLADP * pLLAdp, void * rgbDNSMem, uint32_t cbDNSMem, HPMGR hPMGR, IPSTATUS * pStatus)
{
    IPSTATUS    status = ipsSuccess;
    DNSMEM *    pDNSMem = (DNSMEM *) rgbDNSMem;
    uint32_t    i = 0;

    if(pLLAdp == NULL)
    {
        status = ipsAdaptorMustBeSpecified;
    }
    else if(hPMGR == NULL)
    {
        status = ipsNoPMGRGiven;
    }
    else if(rgbDNSMem == NULL)
    {
        status = ipsDNSMemIsNULL;
    }
    else if(cbDNSMem < sizeof(DNSMEM))
    {
        status = ipsDNSNotEnoughMem;
    }
    else if(pLLAdp->pDNSMem != NULL)
    {
        status = ipsDNSAlreadyInitialized;
    }
    else if(ILIsIPv6(pLLAdp))
    {
        status = ipsIPv6NotSupported;
    }

    if(IsIPStatusAnError(status))
    {
        AssignStatusSafely(pStatus, status);
        return(false);
    }

    memset(pDNSMem, 0, cbDNSMem);
    if(&pDNSMem->socket != UDPOpenWithSocket(pLLAdp, &pDNSMem->socket, hPMGR, &IPv4BROADCAST, portDNSServer, portDynamicallyAssign, &status) ||
       IsIPStatusAnError(status))
    {
        UDPClose(&pDNSMem->socket);
        AssignStatusSafely(pStatus, status);
        return(false);
    }

    pDNSMem->dnsNSMax = (cbDNSMem - sizeof(DNSMEM)) / sizeof(IPv4or6);
    pDNSMem->cDhcpNS = 0;
    pDNSMem->iDNSCur = DNSiInvalid;
    pDNSMem->iDNSWorks = DNSiInvalid;
    pDNSMem->dnsState = dnsReady;
    pDNSMem->cTry = 0;
    ((LLADP *) pLLAdp)->pDNSMem = pDNSMem;

    // initialize them all to the Google NS
    // that way there is something in all of the slots
    // this will get over written if DHCP is used.
    for(i=0; i<pDNSMem->dnsNSMax; i++)
    {
        if((i % 2) == 0)
        {
            pDNSMem->dnsNS[i].ipv4.u32 = 0x04040808; // Google public DNS server
        }
        else
        {
            pDNSMem->dnsNS[i].ipv4.u32 = 0x08080808; // Google public DNS server
        }
    }

    AssignStatusSafely(pStatus, status);
    return(true);
}
Пример #30
0
// This is not a URL, this must be a domain nume such as www.foo.bar.com with an optional . at the end.
bool DNSResolve(const LLADP * pLLAdp, uint8_t const * const pchDomainName, uint32_t cchDomanName, void * pIPvX, IPSTATUS * pStatus)
{
    IPSTATUS    status = ipsSuccess;

    // see if we are initialized
    if(pLLAdp == NULL)
    {
        status = ipsAdaptorMustBeSpecified;
    }
    else if( !ILIsIPSetup(pLLAdp, &status) )
    {
        // do nothing, I got the status
    }
    else if(pLLAdp->pDNSMem == NULL || pLLAdp->pDNSMem->dnsState == dnsUninit)
    {
        status = ipsDNSIsNotInitialized;
    }
    else if(pchDomainName == NULL)
    {
        status = ipsDomainNameIsNULL;
    }
    else if(pIPvX == NULL)
    {
        status = ipsIPIsNULL;
    }

    // we are currently processing a DNS reqeust
    else if(pLLAdp->pDNSMem->dnsState != dnsReady)
    {
        // this is not the one we are working on!
        if(pLLAdp->pDNSMem->pchDomainName != pchDomainName)
        {
            status = ipsDNSIsInUse;
        }

        // this is the one we are working on, check to see if it is done.
        else
        {
            // go into the state machine.
            status = ipsDNSIsResolving;
        }
    }

    // we are done, see if we got it or not
    else if(pLLAdp->pDNSMem->pchDomainName == pchDomainName && pLLAdp->pDNSMem->cchDomainName == cchDomanName && strncmp((char *) pLLAdp->pDNSMem->pchDomainName, (char *) pchDomainName, cchDomanName) == 0)
    {
        if(ILIsIPv6(pLLAdp))
        {
            // have no idea
            if(memcmp(&pLLAdp->pDNSMem->ip.ipv6, &IPv6NONE, sizeof(IPv6)) == 0)
            {
                status = ipsDNSFailedToResolve;
            }
            // got it
            else
            {
                memcpy(pIPvX, &pLLAdp->pDNSMem->ip.ipv6, sizeof(IPv6));
            }
        }
        // IPv4
        else
        {
            // have no idea
            if(pLLAdp->pDNSMem->ip.ipv4.u32 == IPv4NONE.u32)
            {
                status = ipsDNSFailedToResolve;
            }
            // got it
            else
            {
                memcpy(pIPvX, &pLLAdp->pDNSMem->ip.ipv4, sizeof(IPv4));
            }
        }
    }

    // if we are ready, but he is asking for something else, start a new request.
    // check to see if the domain name starts with a number; as in IP address
    // TODO: IPv6 support
    else if(isdigit(*pchDomainName))
    {
        uint32_t i = 0;
        uint32_t j = 0;
        uint32_t k = 0;
        uint8_t const * pch = pchDomainName;
        
        if(ILIsIPv6(pLLAdp))
        {
            // TODO: do IPv6 support
        }
        else
        {    
            for(i=0; i<4; i++)
            {
                for(j=0, k=0; j<3 && isdigit(*pch); j++, pch++)
                {
                    k *= 10;
                    k += (*pch - '0');                    
                }
                
                if((i<3 && *pch == '.') || (i == 3 && (*pch == '/' || *pch == '\0')))
                {
                    ((IPv4 *) pIPvX)->u8[i] = (uint8_t) k;
                    pch++;
                }

                // if is clearly not an IP address
                // try it as a domain name
                else
                {
                    DNSStartIPv4Request(pLLAdp, pchDomainName, cchDomanName, &status);
                    break;
                }
            }
        
            if(status == ipsSuccess)
            {
                // pretend we got the IP
                pLLAdp->pDNSMem->ip.ipv4.u32 = ((IPv4 *) pIPvX)->u32;
                pLLAdp->pDNSMem->pchDomainName = pchDomainName;
                pLLAdp->pDNSMem->cchDomainName = cchDomanName;
            }
            else
            {
                memcpy(pIPvX, &IPv4NONE, sizeof(IPv4));
            }
        }
    }

    // otherwise we need to go look it up.
    else
    {
        DNSStartIPv4Request(pLLAdp, pchDomainName, cchDomanName, &status);
    }

    AssignStatusSafely(pStatus, status);
    return(status == ipsSuccess);
}