/* ********************************************************************* * Broadcom Common Firmware Environment (CFE) * * TFTP Client File: net_tftp.c * * This module contains a TFTP client. * * Author: Mitch Lichtenberg (mpl@broadcom.com) * ********************************************************************* * * Copyright 2000,2001,2002,2003 * Broadcom Corporation. All rights reserved. * * This software is furnished under license and may be used and * copied only in accordance with the following terms and * conditions. Subject to these conditions, you may download, * copy, install, use, modify and distribute modified or unmodified * copies of this software in source and/or binary form. No title * or ownership is transferred hereby. * * 1) Any source code used, modified or distributed must reproduce * and retain this copyright notice and list of conditions * as they appear in the source file. * * 2) No right is granted to use any trade name, trademark, or * logo of Broadcom Corporation. The "Broadcom Corporation" * name may not be used to endorse or promote products derived * from this software without the prior written permission of * Broadcom Corporation. * * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. ********************************************************************* */ #include "lib_types.h" #include "lib_string.h" #include "lib_queue.h" #include "lib_malloc.h" #include "lib_printf.h" #include "cfe_error.h" #include "cfe_fileops.h" /* Foxconn add start by Cliff Wang, 03/23/2010 */ #include "cfe_console.h" /* Foxconn add end by Cliff Wang, 03/23/2010 */ #include "net_ebuf.h" #include "net_ether.h" #include "cfe.h" #include "cfe_loader.h" #include "net_api.h" /* ********************************************************************* * TFTP protocol ********************************************************************* */ #define UDP_PROTO_TFTP 69 #define TFTP_BLOCKSIZE 512 #define TFTP_OP_RRQ 1 #define TFTP_OP_WRQ 2 #define TFTP_OP_DATA 3 #define TFTP_OP_ACK 4 #define TFTP_OP_ERROR 5 #define TFTP_ERR_DISKFULL 3 #define TFTP_MAX_RETRIES 8 #define TFTP_RRQ_TIMEOUT 1 /* seconds */ #define TFTP_RECV_TIMEOUT 1 /* seconds */ /* ********************************************************************* * TFTP context ********************************************************************* */ typedef struct tftp_fsctx_s { int dummy; } tftp_fsctx_t; typedef struct tftp_info_s { int tftp_socket; uint8_t tftp_data[TFTP_BLOCKSIZE]; int tftp_blklen; int tftp_blkoffset; int tftp_fileoffset; uint16_t tftp_blknum; uint8_t tftp_ipaddr[IP_ADDR_LEN]; int tftp_lastblock; int tftp_error; int tftp_filemode; char *tftp_filename; } tftp_info_t; /* ********************************************************************* * Prototypes ********************************************************************* */ static int tftp_fileop_init(void **fsctx,void *devicename); static int tftp_fileop_open(void **ref,void *fsctx,char *filename,int mode); static int tftp_fileop_read(void *ref,uint8_t *buf,int len); static int tftp_fileop_write(void *ref,uint8_t *buf,int len); static int tftp_fileop_seek(void *ref,int offset,int how); static void tftp_fileop_close(void *ref); static void tftp_fileop_uninit(void *fsctx); /* Foxconn add start by Cliff Wang, 03/23/2010 */ int tftp_max_retries = TFTP_MAX_RETRIES; int tftp_rrq_timeout = TFTP_RRQ_TIMEOUT; int tftp_recv_timeout = TFTP_RECV_TIMEOUT; /* Foxconn add end by Cliff Wang, 03/23/2010 */ /* ********************************************************************* * TFTP fileio dispatch table ********************************************************************* */ const fileio_dispatch_t tftp_fileops = { "tftp", LOADFLG_NOBB | FSYS_TYPE_NETWORK, tftp_fileop_init, tftp_fileop_open, tftp_fileop_read, tftp_fileop_write, tftp_fileop_seek, tftp_fileop_close, tftp_fileop_uninit }; /* ********************************************************************* * _tftp_open(info,hostname,filename,mode) * * Open a file on a remote host, using the TFTP protocol. * * Input parameters: * info - TFTP information * hostname - host name or IP address of remote host * filename - name of file on remote system * mode - file open mode, read or write * * Return value: * 0 if ok * else error code ********************************************************************* */ static int _tftp_open(tftp_info_t *info,char *hostname,char *filename,int mode) { ebuf_t *buf = NULL; const char *datamode = "octet"; uint16_t type,error,block; int res; int retries; /* * Look up the remote host's IP address */ res = dns_lookup(hostname,info->tftp_ipaddr); if (res < 0) return res; /* * Open a UDP socket to the TFTP server */ info->tftp_socket = udp_socket(UDP_PROTO_TFTP); info->tftp_lastblock = 0; info->tftp_error = 0; info->tftp_filemode = mode; /* * Try to send the RRQ packet to open the file */ for (retries = 0; retries < TFTP_MAX_RETRIES; retries++) { buf = udp_alloc(); if (!buf) break; if (info->tftp_filemode == FILE_MODE_READ) { ebuf_append_u16_be(buf,TFTP_OP_RRQ); /* read file */ } else { ebuf_append_u16_be(buf,TFTP_OP_WRQ); /* write file */ } ebuf_append_bytes(buf,filename,strlen(filename)+1); ebuf_append_bytes(buf,datamode,strlen(datamode)+1); udp_send(info->tftp_socket,buf,info->tftp_ipaddr); buf = udp_recv_with_timeout(info->tftp_socket,TFTP_RRQ_TIMEOUT); if (buf) break; } /* * If we got no response, bail now. */ if (!buf) { udp_close(info->tftp_socket); info->tftp_socket = -1; return CFE_ERR_TIMEOUT; } /* * Otherwise, process the response. */ ebuf_get_u16_be(buf,type); switch (type) { case TFTP_OP_ACK: /* * Acks are what we get back on a WRQ command, * but are otherwise unexpected. */ if (info->tftp_filemode == FILE_MODE_WRITE) { udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata); info->tftp_blknum = 1; info->tftp_blklen = 0; udp_free(buf); return 0; break; } /* fall through */ case TFTP_OP_RRQ: case TFTP_OP_WRQ: default: /* * we aren't expecting any of these messages */ udp_free(buf); udp_close(info->tftp_socket); info->tftp_socket = -1; return CFE_ERR_PROTOCOLERR; case TFTP_OP_ERROR: /* * Process the error return (XXX: remove xprintf here) */ ebuf_get_u16_be(buf,error); xprintf("TFTP error %d: %s\n",error,ebuf_ptr(buf)); udp_free(buf); udp_close(info->tftp_socket); info->tftp_socket = -1; return CFE_ERR_PROTOCOLERR; case TFTP_OP_DATA: /* * Yay, we've got data! Store the first block. */ ebuf_get_u16_be(buf,block); udp_connect(info->tftp_socket,(uint16_t) buf->eb_usrdata); info->tftp_blknum = block; info->tftp_blklen = ebuf_length(buf); ebuf_get_bytes(buf,info->tftp_data,ebuf_length(buf)); udp_free(buf); if (info->tftp_blklen < TFTP_BLOCKSIZE) { info->tftp_lastblock = 1; /* EOF */ } return 0; break; } } /* ********************************************************************* * _tftp_readmore(info) * * Read the next block of the file. We do this by acking the * previous block. Once that block is acked, the TFTP server * should send the next block to us. * * Input parameters: * info - TFTP information * * Return value: * 0 if ok * else error code ********************************************************************* */ static int _tftp_readmore(tftp_info_t *info) { ebuf_t *buf; uint16_t cmd,block; int retries; /* * If we've already read the last block, there is no more */ if (info->tftp_lastblock) return 1; if (info->tftp_error) return CFE_ERR_TIMEOUT; /* * Otherwise, ack the current block so another one will come */ for (retries = 0; retries < TFTP_MAX_RETRIES; retries++) { buf = udp_alloc(); if (!buf) return -1; /* * Send the ack */ ebuf_append_u16_be(buf,TFTP_OP_ACK); ebuf_append_u16_be(buf,info->tftp_blknum); udp_send(info->tftp_socket,buf,info->tftp_ipaddr); /* * Wait for some response, retransmitting as necessary */ /* Foxconn add start by Cliff Wang, 03/23/2010 */ buf = udp_recv_with_timeout(info->tftp_socket,tftp_recv_timeout); // buf = udp_recv_with_timeout(info->tftp_socket,TFTP_RECV_TIMEOUT); /* Foxconn add end by Cliff Wang, 03/23/2010 */ if (buf == NULL) continue; /* * Got a response, make sure it's right */ ebuf_get_u16_be(buf,cmd); if (cmd != TFTP_OP_DATA) { udp_free(buf); continue; } ebuf_get_u16_be(buf,block); if (block != (info->tftp_blknum+1)) { udp_free(buf); continue; } /* * It's the correct response. Copy the user data */ info->tftp_blknum = block; info->tftp_blklen = ebuf_length(buf); ebuf_get_bytes(buf,info->tftp_data,ebuf_length(buf)); udp_free(buf); break; } /* * If the block is less than 512 bytes long, it's the EOF block. */ if (retries == TFTP_MAX_RETRIES) { info->tftp_error = 1; return CFE_ERR_TIMEOUT; } if (info->tftp_blklen < TFTP_BLOCKSIZE) { info
/**CFile****************************************************************

  FileName    [abcSense.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Network and node package.]

  Synopsis    []

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

  Revision    [$Id: abc_.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

***********************************************************************/

#include "base/abc/abc.h"
#include "proof/fraig/fraig.h"

ABC_NAMESPACE_IMPL_START


////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    [Copies the topmost levels of the network.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Obj_t * Abc_NtkSensitivityMiter_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode )
{
    assert( !Abc_ObjIsComplement(pNode) );
    if ( pNode->pCopy )
        return pNode->pCopy;
    Abc_NtkSensitivityMiter_rec( pNtkNew, Abc_ObjFanin0(pNode) );
    Abc_NtkSensitivityMiter_rec( pNtkNew, Abc_ObjFanin1(pNode) );
    return pNode->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
}

/**Function*************************************************************

  Synopsis    [Creates miter for the sensitivity analysis.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Abc_NtkSensitivityMiter( Abc_Ntk_t * pNtk, int iVar )
{
    Abc_Ntk_t * pMiter;
    Vec_Ptr_t * vNodes;
    Abc_Obj_t * pObj, * pNext, * pFanin, * pOutput, * pObjNew;
    int i;
    assert( Abc_NtkIsStrash(pNtk) );
    assert( iVar < Abc_NtkCiNum(pNtk) );

    // duplicate the network
    pMiter = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
    pMiter->pName = Extra_UtilStrsav(pNtk->pName);
    pMiter->pSpec = Extra_UtilStrsav(pNtk->pSpec);

    // assign the PIs
    Abc_NtkCleanCopy( pNtk );
    Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pMiter);
    Abc_AigConst1(pNtk)->pData = Abc_AigConst1(pMiter);
    Abc_NtkForEachCi( pNtk, pObj, i )
    {
        pObj->pCopy = Abc_NtkCreatePi( pMiter );
        pObj->pData = pObj->pCopy;
    }
    Abc_NtkAddDummyPiNames( pMiter );

    // assign the cofactors of the CI node to be constants
    pObj = Abc_NtkCi( pNtk, iVar );
    pObj->pCopy = Abc_ObjNot( Abc_AigConst1(pMiter) ); 
    pObj->pData = Abc_AigConst1(pMiter); 

    // collect the internal nodes
    vNodes = Abc_NtkDfsReverseNodes( pNtk, &pObj, 1 );
    Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
    {
        for ( pNext = pObj? pObj->pCopy : pObj; pObj; pObj = pNext, pNext = pObj? pObj->pCopy : pObj )
        {
            pFanin = Abc_ObjFanin0(pObj);
            if ( !Abc_NodeIsTravIdCurrent(pFanin) )
                pFanin->pData = Abc_NtkSensitivityMiter_rec( pMiter, pFanin );
            pFanin = Abc_ObjFanin1(pObj);
            if ( !Abc_NodeIsTravIdCurrent(pFanin) )
                pFanin->pData = Abc_NtkSensitivityMiter_rec( pMiter, pFanin );
            pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pMiter->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
            pObj->pData = Abc_AigAnd( (Abc_Aig_t *)pMiter->pManFunc, Abc_ObjChild0Data(pObj), Abc_ObjChild1Data(pObj) );
        }
    }
    Vec_PtrFree( vNodes );

    // update the affected COs
    pOutput = Abc_ObjNot( Abc_AigConst1(pMiter) ); 
    Abc_NtkForEachCo( pNtk, pObj, i )
    {
        if ( !Abc_NodeIsTravIdCurrent(pObj) )
            continue;
        // get the result of quantification
        if ( i == Abc_NtkCoNum(pNtk) - 1 )
        {
            pOutput = Abc_AigAnd( (Abc_Aig_t *)pMiter->pManFunc, pOutput, Abc_ObjChild0Data(pObj) );
            pOutput = Abc_AigAnd( (Abc_Aig_t *)pMiter->pManFunc, pOutput, Abc_ObjChild0Copy(pObj) );
        }
        else
        {
            pNext   = Abc_AigXor( (Abc_Aig_t *)pMiter->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild0Data(pObj) );
            pOutput = Abc_AigOr( (Abc_Aig_t *)pMiter->pManFunc, pOutput, pNext );
        }
    }
    // add the PO node and name
    pObjNew = Abc_NtkCreatePo(pMiter);
    Abc_ObjAddFanin( pObjNew, pOutput );
    Abc_ObjAssignName( pObjNew, "miter", NULL );
    // make sure everything is okay
    if ( !Abc_NtkCheck( pMiter ) )
    {
        printf( "Abc_NtkSensitivityMiter: The network check has failed.\n" );
        Abc_NtkDelete( pMiter );
        return NULL;
    }
    return pMiter;
}

/**Function*************************************************************

  Synopsis    [Computing sensitivity of POs to POs under constraints.]

  Description [The input network is a combinatonal AIG. The last output
  is a constraint. The procedure returns the list of number of PIs, 
  such that at least one PO depends on this PI, under the constraint.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Abc_NtkSensitivity( Abc_Ntk_t * pNtk, int nConfLim, int fVerbose )
{
    ProgressBar * pProgress;
    Prove_Params_t Params, * pParams = &Params;
    Vec_Int_t * vResult = NULL;
    Abc_Ntk_t * pMiter;
    Abc_Obj_t * pObj;
    int RetValue, i;
    assert( Abc_NtkIsStrash(pNtk) );
    assert( Abc_NtkLatchNum(pNtk) == 0 );
    // set up solving parameters
    Prove_ParamsSetDefault( pParams );
    pParams->nItersMax = 3;
    pParams->nMiteringLimitLast = nConfLim;
    // iterate through the PIs
    vResult = Vec_IntAlloc( 100 );
    pProgress = Extra_ProgressBarStart( stdout, Abc_NtkCiNum(pNtk) );
    Abc_NtkForEachCi( pNtk, pObj, i )
    {
        Extra_ProgressBarUpdate( pProgress, i, NULL );
        // generate the sensitivity miter
        pMiter = Abc_NtkSensitivityMiter( pNtk, i );
        // solve the miter using CEC engine
        RetValue = Abc_NtkIvyProve( &pMiter, pParams );
        if ( RetValue == -1 ) // undecided
            Vec_IntPush( vResult, i );
        else if ( RetValue == 0 )
        {
            int * pSimInfo = Abc_NtkVerifySimulatePattern( pMiter, pMiter->pModel );
            if ( pSimInfo[0] != 1 )
                printf( "ERROR in Abc_NtkMiterProve(): Generated counter-example is invalid.\n" );
//            else
//                printf( "Networks are NOT EQUIVALENT.\n" );
            ABC_FREE( pSimInfo );
            Vec_IntPush( vResult, i );
        }
        Abc_NtkDelete( pMiter );
    }
    Extra_ProgressBarStop( pProgress );
    if ( fVerbose )
    {
        printf( "The outputs are sensitive to %d (out of %d) inputs:\n", 
            Vec_IntSize(vResult), Abc_NtkCiNum(pNtk) );
        Vec_IntForEachEntry( vResult, RetValue, i )
            printf( "%d ", RetValue );
        printf( "\n" );
    }
    return vResult;
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END