/* ********************************************************************* * 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