backup
[lcr.git] / port.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** PBX4Linux                                                                 **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** port                                                                      **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 /* HOW TO audio?
13
14 Audio flow has two ways:
15
16 * from channel to the upper layer
17   -> sound from mISDN channel
18   -> announcement from vbox channel
19
20 * from the upper layer to the channel
21   -> sound from remote channel
22   -> sound from asterisk
23
24 Audio is required:
25
26   -> if local or remote channel is not mISDN
27   -> if endpoint is linked to asterisk
28   -> if call is recorded (vbox)
29
30
31 Functions:
32
33 * PmISDN::txfromup
34   -> audio from upper layer is buffered for later transmission to channel
35 * PmISDN::handler
36   -> buffered audio from upper layer or tones are transmitted via system clock
37 * mISDN_handler
38   -> rx-data from port to record() and upper layer
39   -> tx-data from port (dsp) to record()
40 * VboxPort::handler
41   -> streaming announcement to upper layer
42   -> recording announcement
43 * VboxPort::message_epoint
44   -> recording audio message from upper layer
45   
46
47    
48 */
49
50 #include <stdio.h>
51 #include <string.h>
52 #include <stdlib.h>
53 #include <sys/types.h>
54 #include <sys/stat.h>
55 #include <fcntl.h>
56 #include <unistd.h>
57 #include <errno.h>
58 #include "main.h"
59
60 class Port *port_first = NULL;
61
62 unsigned long port_serial = 1; /* must be 1, because 0== no port */
63
64
65 /* free epointlist relation
66  */
67 void Port::free_epointlist(struct epoint_list *epointlist)
68 {
69         struct epoint_list *temp, **tempp;
70
71         temp = p_epointlist;
72         tempp = &p_epointlist;
73         while(temp)
74         {
75                 if (temp == epointlist)
76                         break;
77
78                 tempp = &temp->next;
79                 temp = temp->next;
80         }
81         if (temp == 0)
82         {
83                 PERROR("SOFTWARE ERROR: epointlist not in port's list.\n");
84                 return;
85         }
86         /* detach */
87         *tempp=temp->next;
88
89         /* free */
90         PDEBUG(DEBUG_EPOINT, "PORT(%d) removed epoint from port\n", p_serial);
91         memset(temp, 0, sizeof(struct epoint_list));
92         free(temp);
93         ememuse--;
94 }
95
96
97 void Port::free_epointid(unsigned long epoint_id)
98 {
99         struct epoint_list *temp, **tempp;
100
101         temp = p_epointlist;
102         tempp = &p_epointlist;
103         while(temp)
104         {
105                 if (temp->epoint_id == epoint_id)
106                         break;
107
108                 tempp = &temp->next;
109                 temp = temp->next;
110         }
111         if (temp == 0)
112         {
113                 PERROR("epoint_id not in port's list, exitting.\n");
114                 return;
115         }
116         /* detach */
117         *tempp=temp->next;
118
119         /* free */
120         PDEBUG(DEBUG_EPOINT, "PORT(%d) removed epoint from port\n", p_serial);
121         memset(temp, 0, sizeof(struct epoint_list));
122         free(temp);
123         ememuse--;
124 }
125
126
127 /* create new epointlist relation
128  */
129 struct epoint_list *Port::epointlist_new(unsigned long epoint_id)
130 {
131         struct epoint_list *epointlist, **epointlistpointer;
132
133         /* epointlist structure */
134         epointlist = (struct epoint_list *)calloc(1, sizeof(struct epoint_list));
135         if (!epointlist)
136         {
137                 PERROR("no mem for allocating epoint_list\n");
138                 return(0);
139         }
140         ememuse++;
141         PDEBUG(DEBUG_EPOINT, "PORT(%d) allocating epoint_list.\n", p_serial);
142         memset(epointlist, 0, sizeof(struct epoint_list));
143
144         /* add epoint_list to chain */
145         epointlist->next = NULL;
146         epointlistpointer = &p_epointlist;
147         while(*epointlistpointer)
148                 epointlistpointer = &((*epointlistpointer)->next);
149         *epointlistpointer = epointlist;
150
151         /* link to epoint */
152         epointlist->epoint_id = epoint_id;
153         epointlist->active = 1;
154
155         return(epointlist);
156 }
157
158
159 /*
160  * port constructor
161  */
162 Port::Port(int type, char *portname, struct port_settings *settings)
163 {
164         class Port *temp, **tempp;
165
166         PDEBUG(DEBUG_PORT, "new port of type %d, name '%s'\n", type, portname);
167
168         /* initialize object */
169         if (settings)
170                 memcpy(&p_settings, settings, sizeof(struct port_settings));
171         else
172         {
173                 memset(&p_settings, 0, sizeof(p_settings));
174                 SCPY(p_settings.tones_dir, options.tones_dir);
175         }
176         SCPY(p_name, portname);
177         SCPY(p_tone_dir, p_settings.tones_dir); // just to be sure
178         p_last_tv_sec = 0;
179         p_last_tv_msec = 0;
180         p_type = type;
181         p_serial = port_serial++;
182         p_debug_nothingtosend = 0;
183         p_tone_fh = -1;
184         p_tone_fetched = NULL;
185         p_tone_name[0] = '\0';
186         p_state = PORT_STATE_IDLE;
187         p_epointlist = NULL;
188         memset(&p_callerinfo, 0, sizeof(p_callerinfo));
189         memset(&p_dialinginfo, 0, sizeof(p_dialinginfo));
190         memset(&p_connectinfo, 0, sizeof(p_connectinfo));
191         memset(&p_redirinfo, 0, sizeof(p_redirinfo));
192         memset(&p_capainfo, 0, sizeof(p_capainfo));
193         p_echotest = 0;
194
195         /* call recording */
196         p_record = NULL;
197         p_record_type = 0;
198         p_record_length = 0;
199         p_record_skip = 0;
200         p_record_filename[0] = '\0';
201         p_record_buffer_readp = 0;
202         p_record_buffer_writep = 0;
203         p_record_buffer_dir = 0;
204
205         /* append port to chain */
206         next = NULL;
207         temp = port_first;
208         tempp = &port_first;
209         while(temp)
210         {
211                 tempp = &temp->next;
212                 temp = temp->next;
213         }
214         *tempp = this;
215
216         classuse++;
217 }
218
219
220 /*
221  * port destructor
222  */
223 Port::~Port(void)
224 {
225         class Port *temp, **tempp;
226         struct message *message;
227
228         if (p_record)
229                 close_record(0);
230
231         classuse--;
232
233         PDEBUG(DEBUG_PORT, "removing port of type %d, name '%s'\n", p_type, p_name);
234
235         /* disconnect port from endpoint */
236         while(p_epointlist)
237         {
238                 /* send disconnect */
239                 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
240                 message->param.disconnectinfo.cause = 16;
241                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
242                 message_put(message);
243                 /* remove endpoint */
244                 free_epointlist(p_epointlist);
245         }
246
247         /* remove port from chain */
248         temp=port_first;
249         tempp=&port_first;
250         while(temp)
251         {
252                 if (temp == this)
253                         break;
254                 tempp = &temp->next;
255                 temp = temp->next;
256         }
257         if (temp == NULL)
258         {
259                 PERROR("PORT(%s) port not in port's list.\n", p_name);
260                 exit(-1);
261         }
262         /* detach */
263         *tempp=this->next;
264
265         /* close open tones file */
266         if (p_tone_fh >= 0)
267         {
268                 close(p_tone_fh);
269                 p_tone_fh = -1;
270                 fhuse--;
271         }
272         p_tone_fetched = NULL;
273 }
274
275 PORT_STATE_NAMES
276
277 /* set new endpoint state
278  */
279 void Port::new_state(int state)
280 {
281         PDEBUG(DEBUG_PORT, "PORT(%s) new state %s --> %s\n", p_name, state_name[p_state], state_name[state]);
282         p_state = state;
283 }
284
285
286 /*
287  * find the port with port_id
288  */ 
289 class Port *find_port_id(unsigned long port_id)
290 {
291         class Port *port = port_first;
292
293         while(port)
294         {
295 //printf("comparing: '%s' with '%s'\n", name, port->name);
296                 if (port->p_serial == port_id)
297                         return(port);
298                 port = port->next;
299         }
300
301         return(NULL);
302 }
303
304
305 /*
306  * set echotest
307  */
308 void Port::set_echotest(int echotest)
309 {
310         p_echotest = echotest;
311 }
312
313
314 /*
315  * set the file in the tone directory with the given name
316  */
317 void Port::set_tone(char *dir, char *name)
318 {
319         int fh;
320         char filename[128];
321
322         if (name == NULL)
323                 name = "";
324
325         /* no counter, no eof, normal speed */
326         p_tone_counter = 0;
327         p_tone_eof = 0;
328         p_tone_speed = 1;
329         p_tone_codec = CODEC_LAW;
330
331         if (p_tone_fh >= 0)
332         {
333                 close(p_tone_fh);
334                 p_tone_fh = -1;
335                 fhuse--;
336         }
337         p_tone_fetched = NULL;
338
339         if (name[0])
340         {
341                 if (name[0] == '/')
342                 {
343                         SPRINT(p_tone_name, "%s", name);
344                         p_tone_dir[0] = '\0';
345                 } else
346                 {
347                         SCPY(p_tone_dir, dir);
348                         SCPY(p_tone_name, name);
349                 }
350         } else
351         {
352                 p_tone_name[0]= '\0';
353                 p_tone_dir[0]= '\0';
354                 return;
355         }
356
357         if (!!strncmp(name,"cause_",6))
358                 return;
359
360         /* now we check if the cause exists, otherwhise we use error tone. */
361         if ((p_tone_fetched=open_tone_fetched(p_tone_dir, p_tone_name, &p_tone_codec, 0, 0)))
362         {
363                 p_tone_fetched = NULL;
364                 return;
365         }
366         SPRINT(filename, "%s_loop", p_tone_name);
367         if ((p_tone_fetched=open_tone_fetched(p_tone_dir, filename, &p_tone_codec, 0, 0)))
368         {
369                 p_tone_fetched = NULL;
370                 return;
371         }
372         SPRINT(filename, "%s/%s/%s", INSTALL_DATA, p_tone_dir, p_tone_name);
373         if ((fh=open_tone(filename, &p_tone_codec, 0, 0)) >= 0)
374         {
375                 close(fh);
376                 return;
377         }
378         SPRINT(filename, "%s/%s/%s_loop", INSTALL_DATA, p_tone_dir, p_tone_name);
379         if ((fh=open_tone(filename, &p_tone_codec, 0, 0)) >= 0)
380         {
381                 close(fh);
382                 return;
383         }
384
385         if (!strcmp(name,"cause_00") || !strcmp(name,"cause_10"))
386         {
387                 PDEBUG(DEBUG_PORT, "PORT(%s) Given Cause 0x%s has no tone, using release tone\n", p_name, name+6);
388                 SPRINT(p_tone_name,"release");
389         } else
390         if (!strcmp(name,"cause_11"))
391         {
392                 PDEBUG(DEBUG_PORT, "PORT(%s) Given Cause 0x%s has no tone, using busy tone\n", p_name, name+6);
393                 SPRINT(p_tone_name,"busy");
394         } else
395         {
396                 PDEBUG(DEBUG_PORT, "PORT(%s) Given Cause 0x%s has no tone, using error tone\n", p_name, name+6);
397                 SPRINT(p_tone_name,"error");
398         }
399 }
400
401
402 /*
403  * set the file in the tone directory for vbox playback
404  * also set the play_eof-flag
405  */
406 void Port::set_vbox_tone(char *dir, char *name)
407 {
408         char filename[256];
409
410         p_tone_speed = 1;
411         p_tone_counter = 0;
412         p_tone_codec = CODEC_LAW;
413         p_tone_eof = 1;
414
415         if (p_tone_fh >= 0)
416         {
417                 close(p_tone_fh);
418                 p_tone_fh = -1;
419                 fhuse--;
420         }
421         p_tone_fetched = NULL;
422
423         SPRINT(p_tone_dir,  dir);
424         SPRINT(p_tone_name,  name);
425
426         /* now we check if the cause exists, otherwhise we use error tone. */
427         if (p_tone_dir[0])
428         {
429                 if ((p_tone_fetched=open_tone_fetched(p_tone_dir, p_tone_name, &p_tone_codec, &p_tone_size, &p_tone_left)))
430                 {
431                         PDEBUG(DEBUG_PORT, "PORT(%s) opening fetched tone: %s\n", p_name, p_tone_name);
432                         return;
433                 }
434                 SPRINT(filename, "%s/%s/%s", INSTALL_DATA, p_tone_dir, p_tone_name);
435                 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) >= 0)
436                 {
437                         fhuse++;
438                         PDEBUG(DEBUG_PORT, "PORT(%s) opening tone: %s\n", p_name, filename);
439                         return;
440                 }
441         } else
442         {
443                 SPRINT(filename, "%s", p_tone_name);
444                 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) >= 0)
445                 {
446                         fhuse++;
447                         PDEBUG(DEBUG_PORT, "PORT(%s) opening tone: %s\n", p_name, filename);
448                         return;
449                 }
450         }
451 }
452
453
454 /*
455  * set the file in the given directory for vbox playback
456  * also set the eof-flag
457  * also set the counter-flag
458  */
459 void Port::set_vbox_play(char *name, int offset)
460 {
461         signed long size;
462         struct message *message;
463
464         /* use ser_box_tone() */
465         set_vbox_tone("", name);
466         if (p_tone_fh < 0)
467                 return;
468
469         /* enable counter */
470         p_tone_counter = 1;
471
472         /* seek */
473         if (p_tone_name[0])
474         {
475                 /* send message with counter value */
476                 if (p_tone_size>=0 && ACTIVE_EPOINT(p_epointlist))
477                 {
478                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_COUNTER);
479                         message->param.counter.current = offset;
480                         message->param.counter.max = size;
481                         message_put(message);
482                 }
483         }
484 }
485
486
487 /*
488  * set the playback speed (for recording playback with different speeds)
489  */
490 void Port::set_vbox_speed(int speed)
491 {
492         /* enable vbox play mode */
493         p_tone_speed = speed;
494 }
495
496 /*
497  * read from the given file as specified in port_set_tone and return sample data
498  * silence is appended if sample ends, but only the number of samples with tones are returned
499  */
500 int Port::read_audio(unsigned char *buffer, int length)
501 {
502         int l,len;
503         int nodata=0; /* to detect 0-length files and avoid endless reopen */
504         char filename[128];
505         int tone_left_before; /* temp variable to determine the change in p_tone_left */
506
507         /* nothing */
508         if (length == 0)
509                 return(0);
510
511         len = length;
512
513         /* if there is no tone set, use silence */
514         if (p_tone_name[0] == 0)
515         {
516 rest_is_silence:
517                 memset(buffer, (options.law=='a')?0x2a:0xff, len); /* silence */
518                 goto done;
519         }
520
521         /* if the file pointer is not open, we open it */
522         if (p_tone_fh<0 && p_tone_fetched==NULL)
523         {
524                 if (p_tone_dir[0])
525                 {
526                         SPRINT(filename, "%s", p_tone_name);
527                         /* if file does not exist */
528                         if (!(p_tone_fetched=open_tone_fetched(p_tone_dir, filename, &p_tone_codec, &p_tone_size, &p_tone_left)))
529                         {
530                                 SPRINT(filename, "%s/%s/%s", INSTALL_DATA, p_tone_dir, p_tone_name);
531                                 /* if file does not exist */
532                                 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0)
533                                 {
534                                         PDEBUG(DEBUG_PORT, "PORT(%s) no tone: %s\n", p_name, filename);
535                                         goto try_loop;
536                                 }
537                                 fhuse++;
538                         }
539                 } else
540                 {
541                         SPRINT(filename, "%s", p_tone_name);
542                         /* if file does not exist */
543                         if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0)
544                         {
545                                 PDEBUG(DEBUG_PORT, "PORT(%s) no tone: %s\n", p_name, filename);
546                                 goto try_loop;
547                         }
548                         fhuse++;
549                 }
550                 PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
551         }
552
553 read_more:
554         /* file descriptor is open read data */
555         tone_left_before = p_tone_left;
556         if (p_tone_fh >= 0)
557         {
558                 l = read_tone(p_tone_fh, buffer, p_tone_codec, len, p_tone_size, &p_tone_left, p_tone_speed);
559                 if (l<0 || l>len) /* paranoia */
560                         l=0;
561                 buffer += l;
562                 len -= l;
563         }
564         if (p_tone_fetched)
565         {
566                 l = read_tone_fetched(&p_tone_fetched, buffer, len, p_tone_size, &p_tone_left, p_tone_speed);
567                 if (l<0 || l>len) /* paranoia */
568                         l=0;
569                 buffer += l;
570                 len -= l;
571         }
572
573         /* if counter is enabled, we check if we have a change */
574         if (p_tone_counter && p_tone_size>=0 && ACTIVE_EPOINT(p_epointlist))
575         {
576                 /* if we jumed to the next second */
577                 if (((p_tone_size-p_tone_left)/8000) != (p_tone_size-tone_left_before)/8000)
578                 {
579 //printf("\nsize=%d left=%d\n\n",p_tone_size,p_tone_left);
580                         struct message *message;
581                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_COUNTER);
582                         message->param.counter.current = (p_tone_size-p_tone_left)/8000;
583                         message->param.counter.max = -1;
584                         message_put(message);
585                 }
586         }
587
588         if (len==0)
589                 goto done;
590
591         if (p_tone_fh >= 0)
592         {
593                 close(p_tone_fh);
594                 p_tone_fh = -1;
595                 fhuse--;
596         }
597         p_tone_fetched = NULL;
598
599         if (l)
600                 nodata=0;
601
602         /* if the file has 0-length */
603         if (nodata>1)
604         {
605                 PDEBUG(DEBUG_PORT, "PORT(%s) 0-length loop: %s\n", p_name, filename);
606                 p_tone_name[0]=0;
607                 p_tone_dir[0]=0;
608                 goto rest_is_silence;
609         }
610
611         /* if eof is reached, or if the normal file cannot be opened, continue with the loop file if possible */
612 try_loop:
613         if (p_tone_eof && ACTIVE_EPOINT(p_epointlist))
614         {
615                 struct message *message;
616                 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_EOF);
617                 message_put(message);
618         }
619
620         if (p_tone_dir[0])
621         {
622                 /* if file does not exist */
623                 SPRINT(filename, "%s_loop", p_tone_name);
624                 if (!(p_tone_fetched=open_tone_fetched(p_tone_dir, filename, &p_tone_codec, &p_tone_size, &p_tone_left)))
625                 {
626                         SPRINT(filename, "%s/%s/%s_loop", INSTALL_DATA, p_tone_dir, p_tone_name);
627                         /* if file does not exist */
628                         if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0)
629                         {
630                                 PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename);
631                                 p_tone_dir[0] = '\0';
632                                 p_tone_name[0] = '\0';
633                                 goto rest_is_silence;
634                         }
635                         fhuse++;
636                 }
637         } else
638         {
639                 SPRINT(filename, "%s_loop", p_tone_name);
640                 /* if file does not exist */
641                 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0)
642                 {
643                         PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename);
644                         p_tone_dir[0] = '\0';
645                         p_tone_name[0] = '\0';
646                         goto rest_is_silence;
647                 }
648                 fhuse++;
649         }
650         nodata++;
651         PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
652
653         /* now we have opened the loop */
654         goto read_more;
655
656 done:
657         return(length-len);
658 }
659
660
661 /* port handler:
662  * process transmission clock */
663 int Port::handler(void)
664 {
665         return(0);
666 }
667
668 /* endpoint sends messages to the port
669  * this is called by the message_epoint inherited by child classes
670  * therefor a return=1 means: stop, no more processing
671  */
672 //extern struct message *dddebug;
673 int Port::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
674 {
675         /* check if we got audio data from one remote port */
676         switch(message_id)
677         {
678                 case MESSAGE_TONE: /* play tone */
679                 PDEBUG(DEBUG_PORT, "PORT(%s) isdn port with (caller id %s) setting tone '%s' dir '%s'\n", p_name, p_callerinfo.id, param->tone.name, param->tone.dir);
680                 set_tone(param->tone.dir,param->tone.name);
681                 return(1);
682
683                 case MESSAGE_VBOX_TONE: /* play tone of answering machine */
684                 PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine tone '%s' '%s'\n", p_name, param->tone.dir, param->tone.name);
685                 set_vbox_tone(param->tone.dir, param->tone.name);
686                 return(1);
687
688                 case MESSAGE_VBOX_PLAY: /* play recording of answering machine */
689                 PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine file to play '%s' (offset %d seconds)\n", p_name, param->play.file, param->play.offset);
690                 set_vbox_play(param->play.file, param->play.offset);
691                 return(1);
692
693                 case MESSAGE_VBOX_PLAY_SPEED: /* set speed of playback (recording of answering machine) */
694                 PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine playback speed %d (times)\n", p_name, param->speed);
695                 set_vbox_speed(param->speed);
696                 return(1);
697
698         }
699
700         return(0);
701 }
702
703
704 /* wave header structure */
705 struct fmt {
706         unsigned short  stereo; /* 1 = mono, 2 = stereo */
707         unsigned short  channels; /* number of channels */
708         unsigned long   sample_rate; /* sample rate */
709         unsigned long   data_rate; /* data rate */
710         unsigned short  bytes_sample; /* bytes per sample (all channels) */
711         unsigned short  bits_sample; /* bits per sample (one channel) */
712 };
713
714
715 /*
716  * open record file (actually a wave file with empty header which will be
717  * written before close, because we do not know the size yet)
718  * type=1 record annoucement,  type=0 record audio stream, type=2 record vbox
719  */
720 int Port::open_record(int type, int vbox, int skip, char *extension, int anon_ignore, char *vbox_email, int vbox_email_file)
721 {
722         /* RIFFxxxxWAVEfmt xxxx(fmt-size)dataxxxx... */
723         char dummyheader[8+4+8+sizeof(fmt)+8];
724         char filename[256];
725
726         if (!extension)
727         {
728                 PERROR("Port(%d) not an extension\n", p_serial);
729                 return(0);
730         }
731         SCPY(p_record_extension, extension);
732         p_record_anon_ignore = anon_ignore;
733         SCPY(p_record_vbox_email, vbox_email);
734         p_record_vbox_email_file = vbox_email_file;
735         
736         if (p_record)
737         {
738                 PERROR("Port(%d) already recording\n", p_serial);
739                 return(0);
740         }
741
742         if (vbox != 0)
743                 SPRINT(filename, "%s/%s/%s/vbox", INSTALL_DATA, options.extensions_dir, p_record_extension);
744         else
745                 SPRINT(filename, "%s/%s/%s/recordings", INSTALL_DATA, options.extensions_dir, p_record_extension);
746         if (mkdir(filename, 0755) < 0)
747         {
748                 if (errno != EEXIST)
749                 {
750                         PERROR("Port(%d) cannot create directory '%s'\n", p_serial, filename);
751                         return(0);
752                 }
753         }
754
755         if (vbox == 1)
756                 UPRINT(strchr(filename,'\0'), "/announcement");
757         else
758                 UPRINT(strchr(filename,'\0'), "/%04d-%02d-%02d_%02d%02d%02d", now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec);
759         if (vbox == 2)
760         {
761                 p_record_vbox_year = now_tm->tm_year;
762                 p_record_vbox_mon = now_tm->tm_mon;
763                 p_record_vbox_mday = now_tm->tm_mday;
764                 p_record_vbox_hour = now_tm->tm_hour;
765                 p_record_vbox_min = now_tm->tm_min;
766         }
767
768         /* check, if file exists (especially when an extension calls the same extension) */
769         if (vbox != 1)
770         if ((p_record = fopen(filename, "r")))
771         {
772                 fclose(p_record);
773                 SCAT(filename, "_2nd");
774         }
775                         
776         p_record = fopen(filename, "w");
777         if (!p_record)
778         {
779                 PERROR("Port(%d) cannot record because file cannot be opened '%s'\n", p_serial, filename);
780                 return(0);
781         }
782         fduse++;
783
784         p_record_type = type;
785         p_record_vbox = vbox;
786         p_record_skip = skip;
787         p_record_length = 0;
788         switch(p_record_type)
789         {
790                 case CODEC_MONO:
791                 case CODEC_STEREO:
792                 case CODEC_8BIT:
793                 fwrite(dummyheader, sizeof(dummyheader), 1, p_record);
794                 break;
795
796                 case CODEC_LAW:
797                 break;
798         }
799         UCPY(p_record_filename, filename);
800
801         PDEBUG(DEBUG_PORT, "Port(%d) recording started with file name '%s'\n", p_serial, filename);
802         return(1);
803 }
804
805
806 /*
807  * close the recoding file, put header in front and rename
808  */
809 void Port::close_record(int beep)
810 {
811         static signed long beep_mono[] = {-10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000};
812         static unsigned char beep_8bit[] = {48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208, 48, 208};
813         unsigned long size, wsize;
814         struct fmt fmt;
815         char filename[512], indexname[512];
816         FILE *fp;
817         int i, ii;
818         char number[256], callerid[256];
819         char *p;
820         struct caller_info callerinfo;
821         char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-!$%&/()=+*;~";
822
823         if (!p_record)
824                 return;
825         PDEBUG(DEBUG_PORT, "data still in record buffer: %d (dir %d)\n", (p_record_buffer_writep - p_record_buffer_readp) & RECORD_BUFFER_MASK, p_record_buffer_dir);
826
827         memcpy(&callerinfo, &p_callerinfo, sizeof(struct caller_info));
828         apply_callerid_restriction(p_record_anon_ignore, callerinfo.id, &callerinfo.ntype, &callerinfo.present, &callerinfo.screen, callerinfo.extension, callerinfo.name);
829
830         SCPY(number, p_dialinginfo.id);
831         SCPY(callerid, numberrize_callerinfo(callerinfo.id, callerinfo.ntype));
832         if (callerid[0] == '\0')
833         {
834                 if (callerinfo.present == INFO_PRESENT_RESTRICTED)
835                         UCPY(callerid,"anonymous");
836                 else
837                         UCPY(callerid,"unknown");
838         }
839
840         /* change verboten digits */
841         p = callerid;
842         while((p=strchr(p,'*')))
843                 *(p++) = 'x';
844         p = callerid;
845         while((p=strchr(p,'/')))
846                 *(p++) = 'x';
847         p = number;
848         while((p=strchr(p,'*')))
849                 *(p++) = 'x';
850         p = number;
851         while((p=strchr(p,'/')))
852                 *(p++) = 'x';
853         i = 0;
854         ii = strlen(callerid);
855         while(i < ii)
856         {
857                 if (!strchr(valid_chars, callerid[i]))
858                         callerid[i] = '_';
859                 i++;
860         }
861         i = 0;
862         ii = strlen(number);
863         while(i < ii)
864         {
865                 if (!strchr(valid_chars, number[i]))
866                         number[i] = '_';
867                 i++;
868         }
869
870         /* add beep to the end of recording */
871         if (beep)
872         switch(p_record_type)
873         {
874                 case CODEC_MONO:
875                 i = 0;
876                 while(i < beep)
877                 {
878                         fwrite(beep_mono, sizeof(beep_mono), 1, p_record);
879                         i += sizeof(beep_mono);
880                         p_record_length += sizeof(beep_mono);
881                 }
882                 break;
883                 case CODEC_8BIT:
884                 i = 0;
885                 while(i < beep)
886                 {
887                         fwrite(beep_8bit, sizeof(beep_8bit), 1, p_record);
888                         i += sizeof(beep_8bit);
889                         p_record_length += sizeof(beep_8bit);
890                 }
891                 break;
892 #if 0
893                 case CODEC_LAW:
894                 i = 0;
895                 while(i < beep)
896                 {
897                         fwrite(beep_law, sizeof(beep_law), 1, p_record);
898                         i += sizeof(beep_law);
899                         p_record_length += sizeof(beep_law);
900                 }
901                 break;
902 #endif
903                 default:
904                 PERROR("codec %d not supported for beep adding\n", p_record_type);
905         }
906
907         /* complete header */
908         switch(p_record_type)
909         {
910                 case CODEC_MONO:
911                 case CODEC_STEREO:
912                 case CODEC_8BIT:
913                 /* cue */
914                 fprintf(p_record, "cue %c%c%c%c%c%c%c%c", 4, 0, 0, 0, 0,0,0,0);
915
916                 /* LIST */
917                 fprintf(p_record, "LIST%c%c%c%cadtl", 4, 0, 0, 0);
918
919                 /* go to header */
920                 fseek(p_record, 0, SEEK_SET);
921
922                 /* WAVEfmt xxxx(fmt-size)dataxxxx[data]cue xxxx0000LISTxxxxadtl*/
923                 size = p_record_length;
924                 wsize = 4+8+sizeof(fmt)+8+size+8+4+8+4;
925
926                 /* RIFF */
927                 fprintf(p_record, "RIFF%c%c%c%c", (unsigned char)(wsize&0xff), (unsigned char)((wsize>>8)&0xff), (unsigned char)((wsize>>16)&0xff), (unsigned char)(wsize>>24));
928
929                 /* WAVE */
930                 fprintf(p_record, "WAVE");
931
932                 /* fmt */
933                 fprintf(p_record, "fmt %c%c%c%c", sizeof(fmt), 0, 0, 0);
934                 switch(p_record_type)
935                 {
936                         case CODEC_MONO:
937                         fmt.stereo = 1;
938                         fmt.channels = 1;
939                         fmt.sample_rate = 8000; /* samples/sec */
940                         fmt.data_rate = 16000; /* full data rate */
941                         fmt.bytes_sample = 2; /* all channels */
942                         fmt.bits_sample = 16; /* one channel */
943                         break;
944
945                         case CODEC_STEREO:
946                         fmt.stereo = 1;
947                         fmt.channels = 2;
948                         fmt.sample_rate = 8000; /* samples/sec */
949                         fmt.data_rate = 32000; /* full data rate */
950                         fmt.bytes_sample = 4; /* all channels */
951                         fmt.bits_sample = 16; /* one channel */
952                         break;
953
954                         case CODEC_8BIT:
955                         fmt.stereo = 1;
956                         fmt.channels = 1;
957                         fmt.sample_rate = 8000; /* samples/sec */
958                         fmt.data_rate = 8000; /* full data rate */
959                         fmt.bytes_sample = 1; /* all channels */
960                         fmt.bits_sample = 8; /* one channel */
961                         break;
962                 }
963                 fwrite(&fmt, sizeof(fmt), 1, p_record);
964
965                 /* data */
966                 fprintf(p_record, "data%c%c%c%c", (unsigned char)(size&0xff), (unsigned char)((size>>8)&0xff), (unsigned char)((size>>16)&0xff), (unsigned char)(size>>24));
967
968                 /* rename file */
969                 if (p_record_vbox == 1)
970                         SPRINT(filename, "%s.wav", p_record_filename);
971                 else
972                         SPRINT(filename, "%s_%s-%s.wav", p_record_filename, callerid, number);
973                 break;
974
975                 case CODEC_LAW:
976                 /* rename file */
977                 if (p_record_vbox == 1)
978                         SPRINT(filename, "%s.isdn", p_record_filename);
979                 else
980                         SPRINT(filename, "%s_%s-%s.isdn", p_record_filename, callerid, number);
981                 break;
982         }
983
984         fclose(p_record);
985         fduse--;
986         p_record = NULL;
987
988         if (rename(p_record_filename, filename) < 0)
989         {
990                 PERROR("Port(%d) cannot rename from '%s' to '%s'\n", p_serial, p_record_filename, filename);
991                 return;
992         }
993
994         PDEBUG(DEBUG_PORT, "Port(%d) recording is written and renamed to '%s' and must have the following size:%lu raw:%lu samples:%lu\n", p_serial, filename, wsize+8, size, size>>1);
995
996         if (p_record_vbox == 2)
997         {
998                 SPRINT(indexname, "%s/%s/%s/vbox/index", INSTALL_DATA, options.extensions_dir, p_record_extension);
999                 if ((fp = fopen(indexname,"a")))
1000                 {
1001                         fduse++;
1002
1003                         /* remove path from file name */
1004                         p = filename;
1005                         while(strchr(p, '/'))
1006                                 p = strchr(p, '/')+1;
1007                         fprintf(fp, "%s %d %d %d %d %d %s\n", p, p_record_vbox_year, p_record_vbox_mon, p_record_vbox_mday, p_record_vbox_hour, p_record_vbox_min, callerid);
1008
1009                         fclose(fp);
1010                         fduse--;
1011                 } else
1012                 {
1013                         PERROR("Port(%d) cannot open index file '%s' to append.\n", p_serial, indexname);
1014                 }
1015
1016                 /* send email with sample*/
1017                 if (p_record_vbox_email[0])
1018                 {
1019                         send_mail(p_record_vbox_email_file?filename:(char *)"", callerid, callerinfo.extension, callerinfo.name, p_record_vbox_email, p_record_vbox_year, p_record_vbox_mon, p_record_vbox_mday, p_record_vbox_hour, p_record_vbox_min, p_record_extension);
1020                 }
1021         }
1022 }
1023
1024
1025 /*
1026  * recording function
1027  * Records all data from down and from up into one single stream.
1028  * Both streams may have gaps or jitter.
1029  * A Jitter buffer for both streams is used to compensate jitter.
1030  * 
1031  * If one stream (dir) received packets, they are stored to a
1032  * buffer to wait for the other stream (dir), so both streams can 
1033  * be combined. If the buffer is full, it's content is written
1034  * without mixing stream. (assuming only one stram (dir) exists.)
1035  * A flag is used to indicate what stream is currently in buffer.
1036  *
1037  * NOTE: First stereo sample (odd) is from down, second is from up.
1038  */
1039 void Port::record(unsigned char *data, int length, int dir_fromup)
1040 {
1041         unsigned char write_buffer[1024], *d;
1042         signed short *s;
1043         int free, i, ii;
1044         signed long sample;
1045
1046         /* no recording */
1047         if (!p_record || !length)
1048                 return;
1049
1050         /* skip */
1051         if (dir_fromup)
1052         {
1053                 /* more than we have */
1054                 if (p_record_skip > length)
1055                 {
1056                         p_record_skip -= length;
1057                         return;
1058                 }
1059                 data += p_record_skip;
1060                 length -= p_record_skip;
1061         }
1062
1063         free = ((p_record_buffer_readp - p_record_buffer_writep - 1) & RECORD_BUFFER_MASK);
1064
1065         /* the buffer stores the same data stream */
1066         if (dir_fromup == p_record_buffer_dir)
1067         {
1068                 same_again:
1069
1070                 /* first write what we can to the buffer */
1071                 while(free && length)
1072                 {
1073                         p_record_buffer[p_record_buffer_writep] = audio_law_to_s32[*data++];
1074                         p_record_buffer_writep = (p_record_buffer_writep + 1) & RECORD_BUFFER_MASK;
1075                         free--;
1076                         length--;
1077                 }
1078                 /* all written, so we return */
1079                 if (!length)
1080                         return;
1081                 /* still data left, buffer is full, so we need to write to file */
1082                 switch(p_record_type)
1083                 {
1084                         case CODEC_MONO:
1085                         s = (signed short *)write_buffer;
1086                         i = 0;
1087                         while(i < 256)
1088                         {
1089                                 *s++ = p_record_buffer[p_record_buffer_readp];
1090                                 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1091                                 i++;
1092                         }
1093                         fwrite(write_buffer, 512, 1, p_record);
1094                         break;
1095
1096                         case CODEC_STEREO:
1097                         s = (signed short *)write_buffer;
1098                         if (p_record_buffer_dir)
1099                         {
1100                                 i = 0;
1101                                 while(i < 256)
1102                                 {
1103                                         *s++ = 0; /* nothing from down */
1104                                         *s++ = p_record_buffer[p_record_buffer_readp];
1105                                         p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1106                                         i++;
1107                                 }
1108                         } else
1109                         {
1110                                 i = 0;
1111                                 while(i < 256)
1112                                 {
1113                                         *s++ = p_record_buffer[p_record_buffer_readp];
1114                                         *s++ = 0; /* nothing from up */
1115                                         p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1116                                         i++;
1117                                 }
1118                         }
1119                         fwrite(write_buffer, 1024, 1, p_record);
1120                         break;
1121
1122                         case CODEC_8BIT:
1123                         d = write_buffer;
1124                         i = 0;
1125                         while(i < 256)
1126                         {
1127                                 *d++ = (p_record_buffer[p_record_buffer_readp]+0x8000) >> 8;
1128                                 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1129                                 i++;
1130                         }
1131                         fwrite(write_buffer, 512, 1, p_record);
1132                         break;
1133
1134                         case CODEC_LAW:
1135                         d = write_buffer;
1136                         i = 0;
1137                         while(i < 256)
1138                         {
1139                                 *d++ = audio_s16_to_law[p_record_buffer[p_record_buffer_readp] & 0xffff];
1140                                 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1141                                 i++;
1142                         }
1143                         fwrite(write_buffer, 256, 1, p_record);
1144                         break;
1145                 }
1146                 /* because we still have data, we write again */
1147                 free += sizeof(write_buffer);
1148                 goto same_again;
1149         }
1150         /* the buffer stores the other stream */
1151         
1152         /* if buffer empty, change it */
1153         if (p_record_buffer_readp == p_record_buffer_writep)
1154         {
1155                 p_record_buffer_dir = dir_fromup;
1156                 goto same_again;
1157         }
1158         /* how much data can we mix ? */
1159         ii = (p_record_buffer_writep - p_record_buffer_readp) & RECORD_BUFFER_MASK;
1160         if (length < ii)
1161                 ii = length;
1162         /* write data mixed with the buffer */
1163         switch(p_record_type)
1164         {
1165                 case CODEC_MONO:
1166                 s = (signed short *)write_buffer;
1167                 i = 0;
1168                 while(i < ii)
1169                 {
1170                         sample = p_record_buffer[p_record_buffer_readp]
1171                                 + audio_law_to_s32[*data++];
1172                         p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1173                         if (sample < 32767)
1174                                 sample = -32767;
1175                         if (sample > 32768)
1176                                 sample = 32768;
1177                         *s++ = sample;
1178                         i++;
1179                 }
1180                 fwrite(write_buffer, ii<<1, 1, p_record);
1181                 break;
1182                 
1183                 case CODEC_STEREO:
1184                 s = (signed short *)write_buffer;
1185                 if (p_record_buffer_dir)
1186                 {
1187                         i = 0;
1188                         while(i < ii)
1189                         {
1190                                 *s++ = audio_law_to_s32[*data++];
1191                                 *s++ = p_record_buffer[p_record_buffer_readp];
1192                                 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1193                                 i++;
1194                         }
1195                 } else
1196                 {
1197                         i = 0;
1198                         while(i < ii)
1199                         {
1200                                 *s++ = p_record_buffer[p_record_buffer_readp];
1201                                 *s++ = audio_law_to_s32[*data++];
1202                                 i++;
1203                         }
1204                 }
1205                 fwrite(write_buffer, ii<<2, 1, p_record);
1206                 break;
1207                 
1208                 case CODEC_8BIT:
1209                 d = write_buffer;
1210                 i = 0;
1211                 while(i < ii)
1212                 {
1213                         sample = p_record_buffer[p_record_buffer_readp]
1214                                 + audio_law_to_s32[*data++];
1215                         p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1216                         if (sample < 32767)
1217                                 sample = -32767;
1218                         if (sample > 32768)
1219                                 sample = 32768;
1220                         *d++ = (sample+0x8000) >> 8;
1221                         i++;
1222                 }
1223                 fwrite(write_buffer, ii, 1, p_record);
1224                 break;
1225                 
1226                 case CODEC_LAW:
1227                 d = write_buffer;
1228                 i = 0;
1229                 while(i < ii)
1230                 {
1231                         sample = p_record_buffer[p_record_buffer_readp]
1232                                 + audio_law_to_s32[*data++];
1233                         p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1234                         if (sample < 32767)
1235                                 sample = -32767;
1236                         if (sample > 32768)
1237                                 sample = 32768;
1238                         *d++ = audio_s16_to_law[sample & 0xffff];
1239                         i++;
1240                 }
1241                 fwrite(write_buffer, ii, 1, p_record);
1242                 break;
1243         }
1244         length -= ii;
1245         /* data, but buffer empty */
1246         if (length)
1247         {
1248                 p_record_buffer_dir = dir_fromup;
1249                 goto same_again;
1250         }
1251         /* no data (maybe buffer) */
1252         return;
1253
1254 }
1255
1256