1 /*
2  * Author:     Denise Jorge de Oliveira <dezinha@land.ufrj.br> in Dec, 1999
3  *
4  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/wb_seg.c,v 1.2 2005/07/26 18:30:27 william Exp $
5  */
6 #ifndef  _SEG_C
7 #define  _SEG_C
8 
9 #define _INCLUDE_FROM_WB_SEG_C_
10 
11 #include "tgifdefs.h"
12 
13 #include "wb_seg.e"
14 
15 struct SegmentationList *first=NULL;
16 struct SegmentationList *last=NULL;
17 
18 /************************************************************************/
19 static
NewNodeList(struct SegmentationPack Pack)20 struct SegmentationList *NewNodeList ( struct SegmentationPack Pack )
21 {
22    struct SegmentationList *indice;
23 
24    indice = (struct SegmentationList *)malloc( sizeof(struct SegmentationList));
25 
26    memcpy(indice->id, Pack.id, SEG_ID);
27    indice->LogicalClock = Pack.LogicalClock;
28    indice->NumPackets   = Pack.NumPackets;
29    indice->ArrivedPcts  = 0;
30    indice->Frag = (struct Fragment *)malloc(Pack.NumPackets*(sizeof(struct Fragment)));
31    indice->prev = last;
32    indice->next = NULL;
33    memset( (char *)indice->Frag, 0, Pack.NumPackets*(sizeof(struct Fragment)) );
34 
35    if( last != NULL )
36    {
37        last->next = indice;
38        last       = indice;
39    }
40    else
41    {
42        first = last = indice;
43    }
44 
45    return( last );
46 }
47 /************************************************************************/
48 static
DeleteNode(struct SegmentationList * indice)49 void DeleteNode( struct SegmentationList *indice )
50 {
51     struct SegmentationList *prev, *next;
52 
53     prev = indice->prev;
54     if( prev == NULL )
55         first = indice->next;
56     else
57         prev->next = indice->next;
58 
59     next = indice->next;
60     if( next == NULL )
61         last = indice->prev;
62     else
63         next->prev = indice->prev;
64 
65     free( indice->Frag );
66     free( indice );
67 }
68 /************************************************************************/
69 static
NewPacket(struct SegmentationPack * pack,char * id,char * data,int datasize,int LogicalClock,int NumPackets,int NumSeq)70 void NewPacket ( struct SegmentationPack *pack, char *id, char *data, int datasize, int  LogicalClock, int  NumPackets, int  NumSeq)
71 {
72    /* fprintf(stderr, "\n****Antes de Converter %d\n", NumSeq ); */
73    memcpy(pack->id, id, SEG_ID);
74    memcpy(pack->data, data, SEG_DATA_SIZE);
75    pack->DataSize     = htonl(datasize);
76    pack->LogicalClock = htonl(LogicalClock);
77    pack->NumPackets   = htonl(NumPackets);
78    pack->NumSeq       = htonl(NumSeq);
79    /* fprintf(stderr, "\n&&&&DEPOS de Converter %d\n", pack->NumSeq ); */
80 }
81 /************************************************************************/
InitializeSegmentation()82 void InitializeSegmentation ()
83 {
84    first = last = NULL;
85 }
86 /************************************************************************/
Segment(char * Buffer,int BufLen,char * id,int LogicalClock,int * NPackets)87 ptrSegPack Segment (char * Buffer, int BufLen, char *id, int LogicalClock,
88                     int * NPackets)
89 {
90    int   divisor;
91    int   offset;
92    int   i;
93    int   qtd;
94    char  aux[SEG_DATA_SIZE];
95    ptrSegPack pack;
96 
97    divisor = (int) (BufLen/SEG_DATA_SIZE);
98 
99    if( BufLen % SEG_DATA_SIZE != 0 )
100      *NPackets = divisor + 1;
101    else *NPackets = divisor;
102 
103    pack = (ptrSegPack) malloc ((*NPackets)*(sizeof(SegPack)));
104 
105    offset = 0;
106    for (i = 0; i < *NPackets; i++, offset += SEG_DATA_SIZE) {
107       if( BufLen - offset > SEG_DATA_SIZE )
108           qtd = SEG_DATA_SIZE;
109       else
110           qtd = BufLen - offset;
111       memcpy (aux, &Buffer[offset], qtd );
112       NewPacket (&pack[i], id, aux, qtd, LogicalClock, *NPackets, i);
113    }
114 
115    return( pack );
116 }
117 /******************************************************************************
118     Verifica se ja� existe uma entrada para a fonte do pacote Pack. Se sim,
119 retorna TRUE e a posicao dessa entrada em indice.
120 *******************************************************************************/
121 static
Compare(struct SegmentationPack Pack)122 struct SegmentationList *Compare( struct SegmentationPack Pack )
123 {
124    int status;
125    struct SegmentationList *indice;
126 
127    status = FALSE;
128    indice = first;
129 
130    while( indice != NULL )
131    {
132        if( Pack.LogicalClock == indice->LogicalClock )
133        {
134            if( strcmp( Pack.id, indice->id ) == 0 )
135            {
136                status = TRUE;
137                break;
138            }
139        }
140 
141        indice = indice->next;
142    }
143 
144    if( !status )
145        indice = NULL;
146 
147    return( indice );
148 }
149 /**************************************************************************************
150     Copia o novo fragmento para a sua posicao na lista. Retorna TRUE se todos os
151 fragmentos de um pacote chegaram.
152 **************************************************************************************/
153 static
FillFragment(struct SegmentationPack Pack,struct SegmentationList * index)154 int FillFragment(struct SegmentationPack Pack, struct SegmentationList *index)
155 {
156     int status;
157 
158     status = FALSE;
159     if( !index->Frag[ Pack.NumSeq ].DataSize )
160     {
161         memcpy( index->Frag[ Pack.NumSeq ].data, Pack.data, Pack.DataSize );
162         index->Frag[ Pack.NumSeq ].DataSize = Pack.DataSize;
163 
164         index->ArrivedPcts++;
165 
166         if( index->ArrivedPcts == index->NumPackets )
167             status = TRUE;
168     }
169 
170     return( status );
171 }
172 /************************************************************************/
173 static
ConvertNetworkToHost(struct SegmentationPack * pack)174 void ConvertNetworkToHost (struct SegmentationPack *pack)
175 {
176    /* fprintf(stderr, "\n****Antes de desconverter %d\n", pack->NumSeq ); */
177    pack->DataSize     = ntohl(pack->DataSize);
178    pack->LogicalClock = ntohl(pack->LogicalClock);
179    pack->NumPackets   = ntohl(pack->NumPackets);
180    pack->NumSeq       = ntohl(pack->NumSeq);
181 }
182 /************************************************************************/
DeSegment(struct SegmentationPack Pack,int * NumBytes)183 char *DeSegment (struct SegmentationPack Pack, int *NumBytes )
184 {
185     struct SegmentationList *indice;
186     int packetLength;
187     char *buffer;
188     int i;
189 
190     indice = NULL;
191     buffer = NULL;
192     *NumBytes = packetLength = 0;
193     ConvertNetworkToHost(&Pack);
194     /* fprintf(stderr, "Chegou pacote %d\n", Pack.NumSeq ); */
195     /* Check if this source was already inserted */
196     if( (indice = Compare( Pack )) == NULL )
197         indice = NewNodeList( Pack );
198 
199     /* If this is the last fragment */
200     if( FillFragment( Pack, indice ) )
201     {
202         packetLength = (indice->NumPackets - 1) * SEG_DATA_SIZE +
203                         indice->Frag[indice->NumPackets - 1].DataSize;
204         buffer = (char *)malloc( packetLength );
205         for( i = 0; i < indice->NumPackets; i++ )
206             memcpy( &buffer[ i * SEG_DATA_SIZE ], (char *)indice->Frag[i].data, indice->Frag[i].DataSize );
207 
208         *NumBytes = packetLength;
209         DeleteNode( indice );
210     }
211 
212     return( buffer );
213 }
214 /************************************************************************/
215 
216 #endif  /* _SEG_C */
217