1 /** \file alc_session.c \brief ALC session
2  *
3  *  $Author: peltotal $ $Date: 2007/02/28 08:58:00 $ $Revision: 1.103 $
4  *
5  *  MAD-ALCLIB: Implementation of ALC/LCT protocols, Compact No-Code FEC,
6  *  Simple XOR FEC, Reed-Solomon FEC, and RLC Congestion Control protocol.
7  *  Copyright (c) 2003-2007 TUT - Tampere University of Technology
8  *  main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.fi
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  *  In addition, as a special exception, TUT - Tampere University of Technology
25  *  gives permission to link the code of this program with the OpenSSL library (or
26  *  with modified versions of OpenSSL that use the same license as OpenSSL), and
27  *  distribute linked combinations including the two. You must obey the GNU
28  *  General Public License in all respects for all of the code used other than
29  *  OpenSSL. If you modify this file, you may extend this exception to your version
30  *  of the file, but you are not obligated to do so. If you do not wish to do so,
31  *  delete this exception statement from your version.
32  */
33 
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <memory.h>
37 #include <string.h>
38 #include <assert.h>
39 #include <math.h>
40 
41 #ifdef _MSC_VER
42 #include <process.h>
43 #else
44 #include <pthread.h>
45 #endif
46 
47 #include <sys/timeb.h>
48 
49 #include "alc_session.h"
50 #include "mad_rlc.h"
51 #include "alc_rx.h"
52 #include "alc_tx.h"
53 #include "transport.h"
54 #include "alc_channel.h"
55 
56 /**
57  * Use absolute path with base directory.
58  */
59 
60 #define ABSOLUTE_PATH 1
61 
62 struct alc_session *alc_session_list[MAX_ALC_SESSIONS]; /**< List which contains all ALC sessions */
63 int nb_alc_session = 0; /**< Number of ALC sessions */
64 
65 /**
66  * Global variables semaphore
67  */
68 
69 #ifdef _MSC_VER
70 RTL_CRITICAL_SECTION session_variables_semaphore;
71 #else
72 pthread_mutex_t session_variables_semaphore = PTHREAD_MUTEX_INITIALIZER;
73 #endif
74 
75 /**
76  * This is a private function, which locks the session.
77  *
78  */
79 
lock_session()80 void lock_session() {
81 #ifdef _MSC_VER
82   EnterCriticalSection(&session_variables_semaphore);
83 #else
84   pthread_mutex_lock(&session_variables_semaphore);
85 #endif
86 }
87 
88 /**
89  * This is a private function, which unlocks the session.
90  *
91  */
92 
unlock_session()93 void unlock_session() {
94 #ifdef _MSC_VER
95   LeaveCriticalSection(&session_variables_semaphore);
96 #else
97   pthread_mutex_unlock(&session_variables_semaphore);
98 #endif
99 }
100 
open_alc_session(alc_arguments_t * a)101 int open_alc_session(alc_arguments_t *a) {
102 
103   alc_session_t *s;
104   int i;
105   int retval;
106   struct timeb timeb_current_time;
107 
108 #if ABSOLUTE_PATH
109   char fullpath[MAX_PATH_LENGTH];
110 #endif
111 
112   lock_session();
113 
114   if(!lib_init) {
115     alc_init();
116     /* alc session list initialization */
117     memset(alc_session_list, 0, MAX_ALC_SESSIONS * sizeof(alc_session_t*));
118   }
119 
120   if(nb_alc_session >= MAX_ALC_SESSIONS) {
121     /* Could not create new alc session */
122     printf("Could not create new alc session: too many sessions!\n");
123     unlock_session();
124     return -1;
125   }
126 
127   if (!(s = (alc_session_t*)calloc(1, sizeof(alc_session_t)))) {
128     printf("Could not alloc memory for alc session!\n");
129     unlock_session();
130     return -1;
131   }
132 
133   memset(s, 0, sizeof(alc_session_t));
134 
135   s->mode = a->mode;
136   s->tsi = a->tsi;
137   s->state = SActive;
138   s->addr_family = a->addr_family;
139   s->addr_type = a->addr_type;
140   s->cc_id = a->cc_id;
141 
142   if(s->cc_id == RLC) {
143     retval = init_mad_rlc(s);
144 
145     if(retval < 0) {
146       unlock_session();
147       return retval;
148     }
149   }
150 
151   s->rx_memory_mode = a->rx_memory_mode;
152   s->verbosity = a->verbosity;
153   s->starttime = a->start_time;
154   s->stoptime = a->stop_time;
155   s->simul_losses = a->simul_losses;
156   s->loss_ratio1 = a->loss_ratio1;
157   s->loss_ratio2 = a->loss_ratio2;
158 
159   if(s->mode == SENDER) {
160 
161     ftime(&timeb_current_time);
162 	s->ftimestarttime = timeb_current_time.time+timeb_current_time.millitm/1000.0;
163 
164     memcpy(s->base_dir, a->base_dir, strlen(a->base_dir));
165 
166     s->nb_channel = 0;
167     s->max_channel = a->nb_channel;
168     s->def_fec_ratio = a->fec_ratio;
169     s->sent_bytes = 0;
170     s->obj_sent_bytes = 0;
171     s->last_print_tx_percent = 0;
172     s->a_flag = 0;
173     s->fdt_instance_id = 0; /*uplimit 16777215;*/
174     s->def_ttl = a->ttl;
175     s->def_fec_enc_id = a->fec_enc_id;
176     s->def_fec_inst_id = a->fec_inst_id;
177     s->def_max_sblen = a->max_sb_len;
178     s->def_eslen = a->es_len;
179     s->use_fec_oti_ext_hdr = a->use_fec_oti_ext_hdr;
180     s->def_tx_rate = a->tx_rate;
181     s->tx_queue_begin = NULL;
182     s->tx_queue_end = NULL;
183     s->tx_queue_size = 0;
184     s->first_unit_in_loop = TRUE;
185     s->nb_ready_channel = 0;
186     s->nb_sending_channel = 0;
187     s->half_word = a->half_word;
188     s->encode_content = a->encode_content;
189     s->optimize_tx_rate =  a->optimize_tx_rate;
190     s->calculate_session_size = a->calculate_session_size;
191 
192     if(((s->cc_id == RLC) || ((s->cc_id == Null) && (s->max_channel != 1)))) {
193 
194       /**** Start tx_thread ****/
195 
196 #ifdef _MSC_VER
197       s->handle_tx_thread = (HANDLE)_beginthreadex(NULL, 0, (void*)tx_thread, (void*)s, 0, &s->tx_thread_id);
198 
199       if(s->handle_tx_thread == NULL) {
200 	perror("open_alc_session: _beginthread");
201 	unlock_session();
202 	return -1;
203       }
204 #else
205       if(pthread_create(&s->tx_thread_id, NULL, tx_thread, (void*)s) != 0) {
206 	perror("open_alc_session: pthread_create");
207 	unlock_session();
208 	return -1;
209       }
210 #endif
211     }
212   }
213 
214   if(s->mode == RECEIVER) {
215 
216 #ifdef SSM
217     s->ssm = a->use_ssm;
218 #endif
219 
220 #if ABSOLUTE_PATH
221 #ifdef _MSC_VER
222     memset(fullpath, 0, MAX_PATH_LENGTH);
223 
224     if(_fullpath(fullpath, a->base_dir, MAX_PATH_LENGTH) != NULL) {
225       memcpy(s->base_dir, fullpath, strlen(fullpath));
226     }
227     else {
228       memcpy(s->base_dir, a->base_dir, strlen(a->base_dir));
229     }
230 #else
231     memset(fullpath, 0, MAX_PATH_LENGTH);
232 
233     if(a->base_dir[0] != '/') {
234 
235       if(getcwd(fullpath, MAX_PATH_LENGTH) != NULL) {
236 	memcpy(s->base_dir, fullpath, strlen(fullpath));
237 	strcat(s->base_dir, "/");
238 	strcat(s->base_dir, a->base_dir);
239       }
240       else {
241 	memcpy(s->base_dir, a->base_dir, strlen(a->base_dir));
242       }
243     }
244     else {
245       memcpy(s->base_dir, a->base_dir, strlen(a->base_dir));
246     }
247 #endif
248 #else
249 	 memcpy(s->base_dir, a->base_dir, strlen(a->base_dir));
250 #endif
251 
252     s->nb_channel = 0;
253     s->max_channel = a->nb_channel;
254     s->obj_list = NULL;
255     s->fdt_list = NULL;
256     s->wanted_obj_list = NULL;
257     s->rx_fdt_instance_list = NULL;
258     s->accept_expired_fdt_inst = a->accept_expired_fdt_inst;
259 
260     memset(s->src_addr, 0, 40);
261 
262     if(a->src_addr != NULL) {
263       memcpy(s->src_addr, a->src_addr, strlen(a->src_addr));
264     }
265 
266     /* Create receiving thread */
267 
268 #ifdef _MSC_VER
269     s->handle_rx_thread =
270       (HANDLE)_beginthreadex(NULL, 0, (void*)rx_thread, (void*)s, 0, &s->rx_thread_id);
271 
272     if(s->handle_rx_thread == NULL) {
273       perror("open_alc_session: _beginthread");
274       unlock_session();
275       return -1;
276     }
277 #else
278     if(pthread_create(&s->rx_thread_id, NULL, rx_thread, (void*)s) != 0) {
279       perror("open_alc_session: pthread_create");
280       unlock_session();
281       return -1;
282     }
283 #endif
284 
285   }
286 
287   for(i = 0; i < MAX_ALC_SESSIONS; i++) {
288     if(alc_session_list[i] == NULL) {
289       s->s_id = i;
290       alc_session_list[s->s_id] = s;
291       break;
292     }
293   }
294 
295   nb_alc_session++;
296 
297   unlock_session();
298   return s->s_id;
299 }
300 
close_alc_session(int s_id)301 void close_alc_session(int s_id) {
302 
303   int i;
304   wanted_obj_t *next_want;
305   wanted_obj_t *want;
306   rx_fdt_instance_t *next_instance;
307   rx_fdt_instance_t *instance;
308 
309   tx_queue_t *next_pkt;
310   tx_queue_t *pkt;
311 
312   trans_obj_t *to;
313 
314   alc_session_t *s;
315 
316 #ifdef USE_RETRIEVE_UNIT
317   trans_unit_container_t *tmp;
318   trans_unit_container_t *to_delete;
319 #endif
320 
321 #ifdef LINUX
322   int join_retval;
323 #endif
324 
325   /* Wait for open thread. */
326 #ifdef _MSC_VER
327   if(alc_session_list[s_id]->handle_rx_thread != NULL) {
328 	WaitForSingleObject(alc_session_list[s_id]->handle_rx_thread, INFINITE);
329 	CloseHandle(alc_session_list[s_id]->handle_rx_thread);
330 	alc_session_list[s_id]->handle_rx_thread = NULL;
331   }
332 #else
333   if(alc_session_list[s_id]->rx_thread_id != 0) {
334      join_retval = pthread_join(alc_session_list[s_id]->rx_thread_id, NULL);
335      assert(join_retval == 0);
336      pthread_detach(alc_session_list[s_id]->rx_thread_id);
337      alc_session_list[s_id]->rx_thread_id = 0;
338   }
339 #endif
340 
341   lock_session();
342   s = alc_session_list[s_id];
343   s->state = SClosed;
344 
345   for(i = 0; i < s->max_channel; i++) {
346 
347     if(s->ch_list[i] != NULL) {
348       close_alc_channel(s->ch_list[i], s);
349     }
350   }
351 
352 #ifdef USE_RETRIEVE_UNIT
353 	tmp = s->unit_pool;
354 
355 	while(tmp != NULL ) {
356 		to_delete = tmp;
357 		tmp = tmp->next;
358 		free(to_delete->u.data);
359 		free(to_delete);
360 	}
361 
362 	s->unit_pool = NULL;
363 #endif
364 
365   /* Closing, free all uncompleted objects, uncompleted fdt instances and wanted obj list */
366 
367   to = s->obj_list;
368 
369   while(to != NULL) {
370     free_object(to, s, 1);
371     to = s->obj_list;
372   }
373 
374   to = s->fdt_list;
375 
376   while(to != NULL) {
377     free_object(to, s, 0);
378     to = s->fdt_list;
379   }
380 
381   want = s->wanted_obj_list;
382 
383   while(want != NULL) {
384     next_want = want->next;
385     free(want);
386     want = next_want;
387   }
388 
389   instance = s->rx_fdt_instance_list;
390 
391   while(instance != NULL) {
392     next_instance = instance->next;
393     free(instance);
394     instance = next_instance;
395   }
396 
397   if(s->cc_id == RLC) {
398     close_mad_rlc(s);
399   }
400 
401   pkt = s->tx_queue_begin;
402 
403   while(pkt != NULL) {
404     next_pkt = pkt->next;
405     free(pkt->data);
406     free(pkt);
407     pkt = next_pkt;
408   }
409 
410   free(s);
411   alc_session_list[s_id] = NULL;
412   nb_alc_session--;
413   unlock_session();
414 }
415 
get_alc_session(int s_id)416 alc_session_t* get_alc_session(int s_id) {
417 
418   alc_session_t* alc_session;
419 
420   lock_session();
421   assert (alc_session_list != NULL);
422   assert (s_id >= 0);
423   assert (s_id < MAX_ALC_SESSIONS);
424   alc_session = alc_session_list[s_id];
425 
426   unlock_session();
427 
428   return alc_session;
429 }
430 
431 
add_alc_channel(int s_id,const char * port,const char * addr,const char * intface,const char * intface_name)432 int add_alc_channel(int s_id, const char *port, const char *addr, const char *intface, const char *intface_name) {
433 
434   alc_channel_t *ch;
435   alc_session_t *s;
436   int ret;
437 
438   lock_session();
439   ch = NULL;
440   s = alc_session_list[s_id];
441 
442   if(s->nb_channel >= s->max_channel) {
443     /* Could not add new alc channel to alc session */
444     printf("Could not create new alc channel: Max number of channels already used!\n");
445     unlock_session();
446     return -1;
447   }
448 
449   ret = open_alc_channel(ch, s, port, addr, intface, intface_name, s->def_tx_rate);
450   unlock_session();
451 
452   return ret;
453 }
454 
remove_alc_channels(int s_id)455 void remove_alc_channels(int s_id) {
456 
457   alc_session_t *s;
458   alc_channel_t *ch;
459   int i;
460 
461   lock_session();
462   s = alc_session_list[s_id];
463 
464   for(i = 0; i < s->max_channel; i++) {
465 
466     if(s->ch_list[i] != NULL) {
467       ch = s->ch_list[i];
468       close_alc_channel(ch, s);
469     }
470   }
471 
472   unlock_session();
473 }
474 
get_session_obj_list(int s_id)475 trans_obj_t* get_session_obj_list(int s_id) {
476 
477   trans_obj_t* obj_list;
478 
479   lock_session();
480   obj_list = alc_session_list[s_id]->obj_list;
481   unlock_session();
482 
483   return obj_list;
484 }
485 
get_session_fdt_list(int s_id)486 trans_obj_t* get_session_fdt_list(int s_id) {
487 
488   trans_obj_t* fdt_list;
489 
490   lock_session();
491   fdt_list = alc_session_list[s_id]->fdt_list;
492   unlock_session();
493 
494   return fdt_list;
495 }
496 
get_session_wanted_obj_list(int s_id)497 wanted_obj_t* get_session_wanted_obj_list(int s_id) {
498 
499   wanted_obj_t* wanted_obj_list;
500 
501   lock_session();
502   wanted_obj_list = alc_session_list[s_id]->wanted_obj_list;
503   unlock_session();
504 
505   return wanted_obj_list;
506 }
507 
get_session_state(int s_id)508 int get_session_state(int s_id) {
509   int state;
510 
511   lock_session();
512 
513   if(alc_session_list[s_id] == NULL) {
514     unlock_session();
515     return -1;
516   }
517 
518   state = alc_session_list[s_id]->state;
519   unlock_session();
520   return state;
521 }
522 
set_session_state(int s_id,enum alc_session_states state)523 void set_session_state(int s_id, enum alc_session_states state) {
524   lock_session();
525   alc_session_list[s_id]->state = state;
526   unlock_session();
527 }
528 
set_all_sessions_state(enum alc_session_states state)529 void set_all_sessions_state(enum alc_session_states state) {
530 
531   int i;
532   lock_session();
533 
534   for(i = 0; i < MAX_ALC_SESSIONS; i++)
535     {
536       if(alc_session_list[i] != NULL)
537         {
538 	  alc_session_list[i]->state = state;
539         }
540     }
541   unlock_session();
542 }
543 
get_session_a_flag_usage(int s_id)544 int get_session_a_flag_usage(int s_id) {
545 
546   int flag;
547   lock_session();
548   flag = alc_session_list[s_id]->a_flag;
549   unlock_session();
550 
551   return flag;
552 }
553 
set_session_a_flag_usage(int s_id)554 void set_session_a_flag_usage(int s_id) {
555 
556   lock_session();
557   alc_session_list[s_id]->a_flag = 1;
558   unlock_session();
559 }
560 
get_fdt_instance_id(int s_id)561 unsigned int get_fdt_instance_id(int s_id) {
562 
563   int instance_id;
564 
565   lock_session();
566   instance_id = alc_session_list[s_id]->fdt_instance_id;
567   unlock_session();
568 
569   return instance_id;
570 }
571 
set_fdt_instance_id(int s_id,unsigned int instance_id)572 void set_fdt_instance_id(int s_id, unsigned int instance_id) {
573   lock_session();
574   alc_session_list[s_id]->fdt_instance_id =  (instance_id & 0x00FFFFFF);
575   unlock_session();
576 }
577 
set_fdt_instance_parsed(int s_id)578 void set_fdt_instance_parsed(int s_id) {
579   lock_session();
580   alc_session_list[s_id]->waiting_fdt_instance = FALSE;
581   unlock_session();
582 }
583 
get_session_sent_bytes(int s_id)584 unsigned long long get_session_sent_bytes(int s_id) {
585   unsigned long long byte_sent;
586 
587   lock_session();
588   byte_sent = alc_session_list[s_id]->sent_bytes;
589   unlock_session();
590 
591   return byte_sent;
592 }
593 
set_session_sent_bytes(int s_id,unsigned long long sent_bytes)594 void set_session_sent_bytes(int s_id, unsigned long long sent_bytes) {
595 
596   lock_session();
597   alc_session_list[s_id]->sent_bytes = sent_bytes;
598   unlock_session();
599 }
600 
add_session_sent_bytes(int s_id,unsigned int sent_bytes)601 void add_session_sent_bytes(int s_id, unsigned int sent_bytes) {
602 
603   lock_session();
604   alc_session_list[s_id]->sent_bytes += sent_bytes;
605   unlock_session();
606 }
607 
get_object_sent_bytes(int s_id)608 unsigned long long get_object_sent_bytes(int s_id) {
609   unsigned long long byte_sent;
610 
611   lock_session();
612   byte_sent = alc_session_list[s_id]->obj_sent_bytes;
613   unlock_session();
614 
615   return byte_sent;
616 }
617 
set_object_sent_bytes(int s_id,unsigned long long sent_bytes)618  void set_object_sent_bytes(int s_id, unsigned long long sent_bytes) {
619 
620    lock_session();
621    alc_session_list[s_id]->obj_sent_bytes = sent_bytes;
622    unlock_session();
623  }
624 
add_object_sent_bytes(int s_id,unsigned int sent_bytes)625 void add_object_sent_bytes(int s_id, unsigned int sent_bytes) {
626 
627   lock_session();
628   alc_session_list[s_id]->obj_sent_bytes += sent_bytes;
629   unlock_session();
630 }
631 
get_object_last_print_tx_percent(int s_id)632 double get_object_last_print_tx_percent(int s_id) {
633   double tx_percent;
634 
635   lock_session();
636   tx_percent = alc_session_list[s_id]->last_print_tx_percent;
637   unlock_session();
638 
639   return tx_percent;
640 }
641 
set_object_last_print_tx_percent(int s_id,double last_print_tx_percent)642 void set_object_last_print_tx_percent(int s_id, double last_print_tx_percent) {
643   lock_session();
644   alc_session_list[s_id]->last_print_tx_percent = last_print_tx_percent;
645   unlock_session();
646 }
647 
set_session_tx_toi(int s_id,unsigned long long toi)648 void set_session_tx_toi(int s_id, unsigned long long toi) {
649 
650   lock_session();
651   alc_session_list[s_id]->tx_toi = toi;
652   unlock_session();
653 }
654 
get_session_tx_toi(int s_id)655 unsigned long long get_session_tx_toi(int s_id) {
656 
657   unsigned long long tx_toi;
658 
659   lock_session();
660   tx_toi = alc_session_list[s_id]->tx_toi;
661   unlock_session();
662 
663   return tx_toi;
664 }
665 
update_session_tx_rate(int s_id,int base_tx_rate)666 void update_session_tx_rate(int s_id, int base_tx_rate) {
667 	alc_session_t *s;
668 	alc_channel_t *ch;
669 	int i;
670 
671 	lock_session();
672 	s = alc_session_list[s_id];
673 
674 	for(i = 0; i < s->max_channel; i++) {
675 		if(s->ch_list[i] != NULL) {
676 			ch = s->ch_list[i];
677 
678 			if(ch->ch_id == 0) {
679         			ch->tx_rate = base_tx_rate;
680         			ch->nb_tx_units = 1;
681 			}
682 			else {
683 				ch->tx_rate = base_tx_rate * (int)pow(2.0, (double)(ch->ch_id - 1));
684 				ch->nb_tx_units = (int)pow(2.0, (double)(ch->ch_id - 1));
685 			}
686 			printf("new rate [channel: %i]: %i\n", ch->ch_id, ch->tx_rate);
687 		}
688 	}
689 	unlock_session();
690 }
691 
get_wanted_object(alc_session_t * s,unsigned long long toi)692 wanted_obj_t* get_wanted_object(alc_session_t *s, unsigned long long toi) {
693 
694 	wanted_obj_t *tmp;
695 
696 	lock_session();
697 
698 	tmp = s->wanted_obj_list;
699 
700 	while(tmp != NULL) {
701 		if(tmp->toi == toi) {
702 		  unlock_session();
703 		  return tmp;
704 		}
705 		tmp = tmp->next;
706 	}
707 
708 	unlock_session();
709 	return NULL;
710 }
711 
set_wanted_object(int s_id,unsigned long long toi,unsigned long long transfer_len,unsigned short es_len,unsigned int max_sb_len,int fec_inst_id,short fec_enc_id,unsigned short max_nb_of_es,unsigned char content_enc_algo,unsigned char finite_field,unsigned char nb_of_es_per_group)712 int set_wanted_object(int s_id, unsigned long long toi,
713 		      unsigned long long transfer_len,
714 		      unsigned short es_len, unsigned int max_sb_len, int fec_inst_id,
715 		      short fec_enc_id, unsigned short max_nb_of_es,
716 		      unsigned char content_enc_algo, unsigned char finite_field,
717 			  unsigned char nb_of_es_per_group) {
718 
719   alc_session_t *s;
720   wanted_obj_t *wanted_obj;
721   wanted_obj_t *tmp;
722 
723   lock_session();
724 
725   s = alc_session_list[s_id];
726   tmp = s->wanted_obj_list;
727 
728   if(tmp == NULL) {
729 
730     if (!(wanted_obj = (wanted_obj_t*)calloc(1, sizeof(wanted_obj_t)))) {
731       printf("Could not alloc memory for wanted object!\n");
732       unlock_session();
733       return -1;
734     }
735 
736     wanted_obj->toi = toi;
737     wanted_obj->transfer_len = transfer_len;
738     wanted_obj->es_len = es_len;
739     wanted_obj->max_sb_len = max_sb_len;
740     wanted_obj->fec_inst_id = fec_inst_id;
741     wanted_obj->fec_enc_id = fec_enc_id;
742     wanted_obj->max_nb_of_es = max_nb_of_es;
743     wanted_obj->content_enc_algo = content_enc_algo;
744 	wanted_obj->finite_field = finite_field;
745 	wanted_obj->nb_of_es_per_group = nb_of_es_per_group;
746 
747     wanted_obj->prev = NULL;
748     wanted_obj->next = NULL;
749 
750     s->wanted_obj_list = wanted_obj;
751   }
752   else {
753     for(;; tmp = tmp->next) {
754       if(tmp->toi == toi) {
755 	break;
756       }
757       else if(tmp->next == NULL) {
758 
759 	if (!(wanted_obj = (wanted_obj_t*)calloc(1, sizeof(wanted_obj_t)))) {
760 	  printf("Could not alloc memory for wanted object!\n");
761 	  unlock_session();
762 	  return -1;
763 	}
764 
765 	wanted_obj->toi = toi;
766 	wanted_obj->transfer_len = transfer_len;
767 	wanted_obj->es_len = es_len;
768 	wanted_obj->max_sb_len = max_sb_len;
769 	wanted_obj->fec_inst_id = fec_inst_id;
770 	wanted_obj->fec_enc_id = fec_enc_id;
771 	wanted_obj->max_nb_of_es = max_nb_of_es;
772 	wanted_obj->content_enc_algo = content_enc_algo;
773 	wanted_obj->finite_field = finite_field;
774 	wanted_obj->nb_of_es_per_group = nb_of_es_per_group;
775 
776 	tmp->next = wanted_obj;
777 	wanted_obj->prev = tmp;
778 	wanted_obj->next = NULL;
779 
780 	break;
781       }
782     }
783   }
784 
785   unlock_session();
786   return 0;
787 }
788 
remove_wanted_object(int s_id,unsigned long long toi)789 void remove_wanted_object(int s_id, unsigned long long toi) {
790 
791 	alc_session_t *s;
792 	wanted_obj_t *next_want;
793 	wanted_obj_t *want;
794 
795 	lock_session();
796 
797 	s = alc_session_list[s_id];
798 	next_want = s->wanted_obj_list;
799 
800 	while(next_want != NULL) {
801 
802 		want = next_want;
803 
804 	    	if(want->toi == toi) {
805 
806 	      		if(want->next != NULL) {
807 					want->next->prev = want->prev;
808 	      		}
809 	      		if(want->prev != NULL) {
810 					want->prev->next = want->next;
811 	      		}
812 	      		if(want == s->wanted_obj_list) {
813 					s->wanted_obj_list = want->next;
814 	      		}
815 
816 	      		free(want);
817 	      		break;
818 	    	}
819 	    	next_want = want->next;
820 	}
821 
822 	unlock_session();
823 }
824 
is_received_instance(alc_session_t * s,unsigned int fdt_instance_id)825 BOOL is_received_instance(alc_session_t *s, unsigned int fdt_instance_id) {
826 
827         BOOL retval = FALSE;
828         rx_fdt_instance_t *list = s->rx_fdt_instance_list;
829 
830         while(list != NULL) {
831                 if(list->fdt_instance_id == fdt_instance_id) {
832                         retval = TRUE;
833                         break;
834                 }
835                 list = list->next;
836         }
837 
838         return retval;
839 }
840 
set_received_instance(alc_session_t * s,unsigned int fdt_instance_id)841 int set_received_instance(alc_session_t *s, unsigned int fdt_instance_id) {
842 
843         rx_fdt_instance_t *rx_fdt_instance;
844         rx_fdt_instance_t *list;
845 
846 	lock_session();
847 
848         list = s->rx_fdt_instance_list;
849 
850         if(list == NULL) {
851 
852                 if (!(rx_fdt_instance = (rx_fdt_instance_t*)calloc(1, sizeof(rx_fdt_instance_t)))) {
853                         printf("Could not alloc memory for rx_fdt_instance!\n");
854 			unlock_session();
855                         return -1;
856                 }
857 
858                 rx_fdt_instance->fdt_instance_id = fdt_instance_id;
859                 rx_fdt_instance->prev = NULL;
860                 rx_fdt_instance->next = NULL;
861 
862 			s->rx_fdt_instance_list = rx_fdt_instance;
863         }
864         else {
865                 for(;; list = list->next) {
866                         if(list->fdt_instance_id == fdt_instance_id) {
867                                 break;
868                         }
869                         else if(list->next == NULL) {
870 
871 							  if (!(rx_fdt_instance = (rx_fdt_instance_t*)calloc(1, sizeof(rx_fdt_instance_t)))) {
872 								printf("Could not alloc memory for rx_fdt_instance!\n");
873 								unlock_session();
874 								return -1;
875 							  }
876 
877 							  rx_fdt_instance->fdt_instance_id = fdt_instance_id;
878 
879 							  list->next = rx_fdt_instance;
880 							  rx_fdt_instance->prev = list;
881 							  rx_fdt_instance->next = NULL;
882 
883 							  break;
884                         }
885                 }
886         }
887 
888 	unlock_session();
889         return 0;
890 }
891 
get_session_basedir(int s_id)892 char* get_session_basedir(int s_id) {
893 
894   alc_session_t *s;
895   char* base_dir;
896 
897   lock_session();
898 
899   s = alc_session_list[s_id];
900   base_dir = s->base_dir;
901 
902   unlock_session();
903 
904   return base_dir;
905 }
906 
initialize_session_handler()907 void initialize_session_handler() {
908 #ifdef _MSC_VER
909   InitializeCriticalSection(&session_variables_semaphore);
910 #else
911 #endif
912 }
913 
release_session_handler()914 void release_session_handler() {
915 #ifdef _MSC_VER
916   DeleteCriticalSection(&session_variables_semaphore);
917 #else
918 #endif
919 }
920