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