/* * Author: Denise Jorge de Oliveira in Dec, 1999 * * @(#)$Header: /mm2/home/cvs/bc-src/tgif/wb_seg.c,v 1.2 2005/07/26 18:30:27 william Exp $ */ #ifndef _SEG_C #define _SEG_C #define _INCLUDE_FROM_WB_SEG_C_ #include "tgifdefs.h" #include "wb_seg.e" struct SegmentationList *first=NULL; struct SegmentationList *last=NULL; /************************************************************************/ static struct SegmentationList *NewNodeList ( struct SegmentationPack Pack ) { struct SegmentationList *indice; indice = (struct SegmentationList *)malloc( sizeof(struct SegmentationList)); memcpy(indice->id, Pack.id, SEG_ID); indice->LogicalClock = Pack.LogicalClock; indice->NumPackets = Pack.NumPackets; indice->ArrivedPcts = 0; indice->Frag = (struct Fragment *)malloc(Pack.NumPackets*(sizeof(struct Fragment))); indice->prev = last; indice->next = NULL; memset( (char *)indice->Frag, 0, Pack.NumPackets*(sizeof(struct Fragment)) ); if( last != NULL ) { last->next = indice; last = indice; } else { first = last = indice; } return( last ); } /************************************************************************/ static void DeleteNode( struct SegmentationList *indice ) { struct SegmentationList *prev, *next; prev = indice->prev; if( prev == NULL ) first = indice->next; else prev->next = indice->next; next = indice->next; if( next == NULL ) last = indice->prev; else next->prev = indice->prev; free( indice->Frag ); free( indice ); } /************************************************************************/ static void NewPacket ( struct SegmentationPack *pack, char *id, char *data, int datasize, int LogicalClock, int NumPackets, int NumSeq) { /* fprintf(stderr, "\n****Antes de Converter %d\n", NumSeq ); */ memcpy(pack->id, id, SEG_ID); memcpy(pack->data, data, SEG_DATA_SIZE); pack->DataSize = htonl(datasize); pack->LogicalClock = htonl(LogicalClock); pack->NumPackets = htonl(NumPackets); pack->NumSeq = htonl(NumSeq); /* fprintf(stderr, "\n&&&&DEPOS de Converter %d\n", pack->NumSeq ); */ } /************************************************************************/ void InitializeSegmentation () { first = last = NULL; } /************************************************************************/ ptrSegPack Segment (char * Buffer, int BufLen, char *id, int LogicalClock, int * NPackets) { int divisor; int offset; int i; int qtd; char aux[SEG_DATA_SIZE]; ptrSegPack pack; divisor = (int) (BufLen/SEG_DATA_SIZE); if( BufLen % SEG_DATA_SIZE != 0 ) *NPackets = divisor + 1; else *NPackets = divisor; pack = (ptrSegPack) malloc ((*NPackets)*(sizeof(SegPack))); offset = 0; for (i = 0; i < *NPackets; i++, offset += SEG_DATA_SIZE) { if( BufLen - offset > SEG_DATA_SIZE ) qtd = SEG_DATA_SIZE; else qtd = BufLen - offset; memcpy (aux, &Buffer[offset], qtd ); NewPacket (&pack[i], id, aux, qtd, LogicalClock, *NPackets, i); } return( pack ); } /****************************************************************************** Verifica se jaŽ existe uma entrada para a fonte do pacote Pack. Se sim, retorna TRUE e a posicao dessa entrada em indice. *******************************************************************************/ static struct SegmentationList *Compare( struct SegmentationPack Pack ) { int status; struct SegmentationList *indice; status = FALSE; indice = first; while( indice != NULL ) { if( Pack.LogicalClock == indice->LogicalClock ) { if( strcmp( Pack.id, indice->id ) == 0 ) { status = TRUE; break; } } indice = indice->next; } if( !status ) indice = NULL; return( indice ); } /************************************************************************************** Copia o novo fragmento para a sua posicao na lista. Retorna TRUE se todos os fragmentos de um pacote chegaram. **************************************************************************************/ static int FillFragment(struct SegmentationPack Pack, struct SegmentationList *index) { int status; status = FALSE; if( !index->Frag[ Pack.NumSeq ].DataSize ) { memcpy( index->Frag[ Pack.NumSeq ].data, Pack.data, Pack.DataSize ); index->Frag[ Pack.NumSeq ].DataSize = Pack.DataSize; index->ArrivedPcts++; if( index->ArrivedPcts == index->NumPackets ) status = TRUE; } return( status ); } /************************************************************************/ static void ConvertNetworkToHost (struct SegmentationPack *pack) { /* fprintf(stderr, "\n****Antes de desconverter %d\n", pack->NumSeq ); */ pack->DataSize = ntohl(pack->DataSize); pack->LogicalClock = ntohl(pack->LogicalClock); pack->NumPackets = ntohl(pack->NumPackets); pack->NumSeq = ntohl(pack->NumSeq); } /************************************************************************/ char *DeSegment (struct SegmentationPack Pack, int *NumBytes ) { struct SegmentationList *indice; int packetLength; char *buffer; int i; indice = NULL; buffer = NULL; *NumBytes = packetLength = 0; ConvertNetworkToHost(&Pack); /* fprintf(stderr, "Chegou pacote %d\n", Pack.NumSeq ); */ /* Check if this source was already inserted */ if( (indice = Compare( Pack )) == NULL ) indice = NewNodeList( Pack ); /* If this is the last fragment */ if( FillFragment( Pack, indice ) ) { packetLength = (indice->NumPackets - 1) * SEG_DATA_SIZE + indice->Frag[indice->NumPackets - 1].DataSize; buffer = (char *)malloc( packetLength ); for( i = 0; i < indice->NumPackets; i++ ) memcpy( &buffer[ i * SEG_DATA_SIZE ], (char *)indice->Frag[i].data, indice->Frag[i].DataSize ); *NumBytes = packetLength; DeleteNode( indice ); } return( buffer ); } /************************************************************************/ #endif /* _SEG_C */