1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
15 #include <sys/types.h>
24 //#define MIXER_DEBUG /* debug mixer buffer overflow and underrun */
26 class Port *port_first = NULL;
28 unsigned long port_serial = 1; /* must be 1, because 0== no port */
31 /* free epointlist relation
33 void Port::free_epointlist(struct epoint_list *epointlist)
35 struct epoint_list *temp, **tempp;
38 tempp = &p_epointlist;
41 if (temp == epointlist)
49 PERROR("SOFTWARE ERROR: epointlist not in port's list.\n");
56 PDEBUG(DEBUG_EPOINT, "PORT(%d) removed epoint from port\n", p_serial);
57 memset(temp, 0, sizeof(struct epoint_list));
63 void Port::free_epointid(unsigned long epoint_id)
65 struct epoint_list *temp, **tempp;
68 tempp = &p_epointlist;
71 if (temp->epoint_id == epoint_id)
79 PERROR("epoint_id not in port's list, exitting.\n");
86 PDEBUG(DEBUG_EPOINT, "PORT(%d) removed epoint from port\n", p_serial);
87 memset(temp, 0, sizeof(struct epoint_list));
93 /* create new epointlist relation
95 struct epoint_list *Port::epointlist_new(unsigned long epoint_id)
97 struct epoint_list *epointlist, **epointlistpointer;
99 /* epointlist structure */
100 epointlist = (struct epoint_list *)calloc(1, sizeof(struct epoint_list));
103 PERROR("no mem for allocating epoint_list\n");
107 PDEBUG(DEBUG_EPOINT, "PORT(%d) allocating epoint_list.\n", p_serial);
108 memset(epointlist, 0, sizeof(struct epoint_list));
110 /* add epoint_list to chain */
111 epointlist->next = NULL;
112 epointlistpointer = &p_epointlist;
113 while(*epointlistpointer)
114 epointlistpointer = &((*epointlistpointer)->next);
115 *epointlistpointer = epointlist;
118 epointlist->epoint_id = epoint_id;
119 epointlist->active = 1;
128 Port::Port(int type, char *portname, struct port_settings *settings)
130 class Port *temp, **tempp;
132 PDEBUG(DEBUG_PORT, "new port of type %d, name '%s'\n", type, portname);
134 /* initialize object */
136 memcpy(&p_settings, settings, sizeof(struct port_settings));
139 memset(&p_settings, 0, sizeof(p_settings));
140 SCPY(p_settings.tones_dir, options.tones_dir);
142 SCPY(p_name, portname);
143 SCPY(p_tone_dir, p_settings.tones_dir); // just to be sure
147 p_serial = port_serial++;
148 p_debug_nothingtosend = 0;
150 p_tone_fetched = NULL;
151 p_tone_name[0] = '\0';
153 // p_knock_fetched = NULL;
154 p_state = PORT_STATE_IDLE;
156 memset(&p_callerinfo, 0, sizeof(p_callerinfo));
157 memset(&p_dialinginfo, 0, sizeof(p_dialinginfo));
158 memset(&p_connectinfo, 0, sizeof(p_connectinfo));
159 memset(&p_redirinfo, 0, sizeof(p_redirinfo));
160 memset(&p_capainfo, 0, sizeof(p_capainfo));
161 memset(p_mixer_buffer, 0, sizeof(p_mixer_buffer));
162 memset(p_record_buffer, 0, sizeof(p_record_buffer));
163 memset(p_stereo_buffer, 0, sizeof(p_stereo_buffer));
171 p_record_filename[0] = '\0';
173 /* append port to chain */
192 struct mixer_relation *relation, *rtemp;
193 class Port *temp, **tempp;
194 struct message *message;
201 PDEBUG(DEBUG_PORT, "removing port of type %d, name '%s'\n", p_type, p_name);
203 /* free mixer relation chain */
204 relation = p_mixer_rel;
208 relation = relation->next;
209 memset(rtemp, 0, sizeof(struct mixer_relation));
213 p_mixer_rel = NULL; /* beeing paranoid */
215 /* disconnect port from endpoint */
218 /* send disconnect */
219 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
220 message->param.disconnectinfo.cause = 16;
221 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
222 message_put(message);
223 /* remove endpoint */
224 free_epointlist(p_epointlist);
227 /* remove port from chain */
239 PERROR("PORT(%s) port not in port's list.\n", p_name);
245 /* close open tones file */
252 p_tone_fetched = NULL;
257 /* set new endpoint state
259 void Port::new_state(int state)
261 PDEBUG(DEBUG_PORT, "PORT(%s) new state %s --> %s\n", p_name, state_name[p_state], state_name[state]);
267 * find the port with port_id
269 class Port *find_port_id(unsigned long port_id)
271 class Port *port = port_first;
275 //printf("comparing: '%s' with '%s'\n", name, port->name);
276 if (port->p_serial == port_id)
288 void Port::set_echotest(int echotest)
290 p_echotest = echotest;
295 * set the file in the tone directory with the given name
297 void Port::set_tone(char *dir, char *name)
305 /* no counter, no eof, normal speed */
309 p_tone_codec = CODEC_LAW;
317 p_tone_fetched = NULL;
323 SPRINT(p_tone_name, "%s", name);
324 p_tone_dir[0] = '\0';
327 SCPY(p_tone_dir, dir);
328 SCPY(p_tone_name, name);
332 p_tone_name[0]= '\0';
337 if (!!strncmp(name,"cause_",6))
340 /* now we check if the cause exists, otherwhise we use error tone. */
341 if ((p_tone_fetched=open_tone_fetched(p_tone_dir, p_tone_name, &p_tone_codec, 0, 0)))
343 p_tone_fetched = NULL;
346 SPRINT(filename, "%s_loop", p_tone_name);
347 if ((p_tone_fetched=open_tone_fetched(p_tone_dir, filename, &p_tone_codec, 0, 0)))
349 p_tone_fetched = NULL;
352 SPRINT(filename, "%s/%s/%s", INSTALL_DATA, p_tone_dir, p_tone_name);
353 if ((fh=open_tone(filename, &p_tone_codec, 0, 0)) >= 0)
358 SPRINT(filename, "%s/%s/%s_loop", INSTALL_DATA, p_tone_dir, p_tone_name);
359 if ((fh=open_tone(filename, &p_tone_codec, 0, 0)) >= 0)
365 if (!strcmp(name,"cause_00") || !strcmp(name,"cause_10"))
367 PDEBUG(DEBUG_PORT, "PORT(%s) Given Cause 0x%s has no tone, using release tone\n", p_name, name+6);
368 SPRINT(p_tone_name,"release");
370 if (!strcmp(name,"cause_11"))
372 PDEBUG(DEBUG_PORT, "PORT(%s) Given Cause 0x%s has no tone, using busy tone\n", p_name, name+6);
373 SPRINT(p_tone_name,"busy");
376 PDEBUG(DEBUG_PORT, "PORT(%s) Given Cause 0x%s has no tone, using error tone\n", p_name, name+6);
377 SPRINT(p_tone_name,"error");
383 * set the file in the tone directory for vbox playback
384 * also set the play_eof-flag
386 void Port::set_vbox_tone(char *dir, char *name)
392 p_tone_codec = CODEC_LAW;
401 p_tone_fetched = NULL;
403 SPRINT(p_tone_dir, dir);
404 SPRINT(p_tone_name, name);
406 /* now we check if the cause exists, otherwhise we use error tone. */
409 if ((p_tone_fetched=open_tone_fetched(p_tone_dir, p_tone_name, &p_tone_codec, &p_tone_size, &p_tone_left)))
411 PDEBUG(DEBUG_PORT, "PORT(%s) opening fetched tone: %s\n", p_name, p_tone_name);
414 SPRINT(filename, "%s/%s/%s", INSTALL_DATA, p_tone_dir, p_tone_name);
415 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) >= 0)
418 PDEBUG(DEBUG_PORT, "PORT(%s) opening tone: %s\n", p_name, filename);
423 SPRINT(filename, "%s", p_tone_name);
424 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) >= 0)
427 PDEBUG(DEBUG_PORT, "PORT(%s) opening tone: %s\n", p_name, filename);
435 * set the file in the given directory for vbox playback
436 * also set the eof-flag
437 * also set the counter-flag
439 void Port::set_vbox_play(char *name, int offset)
442 struct message *message;
444 /* use ser_box_tone() */
445 set_vbox_tone("", name);
455 /* send message with counter value */
456 if (p_tone_size>=0 && ACTIVE_EPOINT(p_epointlist))
458 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_COUNTER);
459 message->param.counter.current = offset;
460 message->param.counter.max = size;
461 message_put(message);
468 * set the playback speed (for recording playback with different speeds)
470 void Port::set_vbox_speed(int speed)
472 /* enable vbox play mode */
473 p_tone_speed = speed;
477 * read from the given file as specified in port_set_tone and return sample data
478 * silence is appended if sample ends, but only the number of samples with tones are returned
480 int Port::read_audio(unsigned char *buffer, int length)
484 int nodata=0; /* to detect 0-length files and avoid endless reopen */
486 int tone_left_before; /* temp variable to determine the change in p_tone_left */
493 codec_in = p_tone_codec;
495 /* if there is no tone set, use silence */
496 if (p_tone_name[0] == 0)
499 memset(buffer, (options.law=='a')?0x2a:0xff, len); /* silence */
503 /* if the file pointer is not open, we open it */
504 if (p_tone_fh<0 && p_tone_fetched==NULL)
508 SPRINT(filename, "%s", p_tone_name);
509 /* if file does not exist */
510 if (!(p_tone_fetched=open_tone_fetched(p_tone_dir, filename, &p_tone_codec, &p_tone_size, &p_tone_left)))
512 SPRINT(filename, "%s/%s/%s", INSTALL_DATA, p_tone_dir, p_tone_name);
513 /* if file does not exist */
514 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0)
516 PDEBUG(DEBUG_PORT, "PORT(%s) no tone: %s\n", p_name, filename);
523 SPRINT(filename, "%s", p_tone_name);
524 /* if file does not exist */
525 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0)
527 PDEBUG(DEBUG_PORT, "PORT(%s) no tone: %s\n", p_name, filename);
532 PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
536 /* file descriptor is open read data */
537 tone_left_before = p_tone_left;
540 l = read_tone(p_tone_fh, buffer, p_tone_codec, len, p_tone_size, &p_tone_left, p_tone_speed);
541 if (l<0 || l>len) /* paranoia */
548 l = read_tone_fetched(&p_tone_fetched, buffer, len, p_tone_size, &p_tone_left, p_tone_speed);
549 if (l<0 || l>len) /* paranoia */
555 /* if counter is enabled, we check if we have a change */
556 if (p_tone_counter && p_tone_size>=0 && ACTIVE_EPOINT(p_epointlist))
558 /* if we jumed to the next second */
559 if (((p_tone_size-p_tone_left)/8000) != (p_tone_size-tone_left_before)/8000)
561 //printf("\nsize=%d left=%d\n\n",p_tone_size,p_tone_left);
562 struct message *message;
563 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_COUNTER);
564 message->param.counter.current = (p_tone_size-p_tone_left)/8000;
565 message->param.counter.max = -1;
566 message_put(message);
579 p_tone_fetched = NULL;
584 /* if the file has 0-length */
587 PDEBUG(DEBUG_PORT, "PORT(%s) 0-length loop: %s\n", p_name, filename);
590 goto rest_is_silence;
593 /* if eof is reached, or if the normal file cannot be opened, continue with the loop file if possible */
595 if (p_tone_eof && ACTIVE_EPOINT(p_epointlist))
597 struct message *message;
598 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_EOF);
599 message_put(message);
604 /* if file does not exist */
605 SPRINT(filename, "%s_loop", p_tone_name);
606 if (!(p_tone_fetched=open_tone_fetched(p_tone_dir, filename, &p_tone_codec, &p_tone_size, &p_tone_left)))
608 SPRINT(filename, "%s/%s/%s_loop", INSTALL_DATA, p_tone_dir, p_tone_name);
609 /* if file does not exist */
610 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0)
612 PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename);
613 p_tone_dir[0] = '\0';
614 p_tone_name[0] = '\0';
615 // codec_in = CODEC_LAW;
616 goto rest_is_silence;
622 SPRINT(filename, "%s_loop", p_tone_name);
623 /* if file does not exist */
624 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0)
626 PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename);
627 p_tone_dir[0] = '\0';
628 p_tone_name[0] = '\0';
629 // codec_in = CODEC_LAW;
630 goto rest_is_silence;
635 PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
637 /* now we have opened the loop */
646 * dummy for transmit function, since this must be inherited
648 void Port::transmit(unsigned char *buffer, int length, int tonelength)
654 * process transmission clock */
655 int Port::handler(void)
660 /* endpoint sends messages to the port
661 * this is called by the message_epoint inherited by child classes
662 * therefor a return=1 means: stop, no more processing
664 //extern struct message *dddebug;
665 int Port::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
667 /* check if we got audio data from one remote port */
670 case MESSAGE_TONE: /* play tone */
671 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);
672 set_tone(param->tone.dir,param->tone.name);
675 case MESSAGE_DATA: /* tx-data from upper layer */
676 fromup(param->data.data, param->data.len);
679 case MESSAGE_VBOX_TONE: /* play tone of answering machine */
680 PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine tone '%s' '%s'\n", p_name, param->tone.dir, param->tone.name);
681 set_vbox_tone(param->tone.dir, param->tone.name);
684 case MESSAGE_VBOX_PLAY: /* play recording of answering machine */
685 PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine file to play '%s' (offset %d seconds)\n", p_name, param->play.file, param->play.offset);
686 set_vbox_play(param->play.file, param->play.offset);
689 case MESSAGE_VBOX_PLAY_SPEED: /* set speed of playback (recording of answering machine) */
690 PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine playback speed %d (times)\n", p_name, param->speed);
691 set_vbox_speed(param->speed);
701 * special function generate individual isdn debug logs
703 void Port::printisdn(char *fmt, ...)
711 VUNPRINT(buffer,sizeof(buffer)-1,fmt,args);
712 buffer[sizeof(buffer)-1]=0;
715 PDEBUG_RUNTIME(NULL, 0, DEBUG_PORT, "PORT(%s serial=%ld): %s\n", p_name, p_serial, buffer);
716 if (options.deb & DEBUG_LOG)
718 SPRINT(name, "%s/debug_%s.log", INSTALL_DATA, p_name);
719 if (!(fp = fopen(name, "a")))
722 fprintf(fp, "%04d.%02d.%02d %02d:%02d:%02d %s(%ld): %s", 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, p_name, p_serial, buffer);
728 /* wave header structure */
730 unsigned short stereo; /* 1 = mono, 2 = stereo */
731 unsigned short channels; /* number of channels */
732 unsigned long sample_rate; /* sample rate */
733 unsigned long data_rate; /* data rate */
734 unsigned short bytes_sample; /* bytes per sample (all channels) */
735 unsigned short bits_sample; /* bits per sample (one channel) */
740 * open record file (actually a wave file with empty header which will be
741 * written before close, because we do not know the size yet)
742 * type=1 record annoucement, type=0 record audio stream, type=2 record vbox
744 int Port::open_record(int type, int vbox, int skip, char *extension, int anon_ignore, char *vbox_email, int vbox_email_file)
746 /* RIFFxxxxWAVEfmt xxxx(fmt-size)dataxxxx... */
747 char dummyheader[8+4+8+sizeof(fmt)+8];
752 PERROR("Port(%d) not an extension\n", p_serial);
755 SCPY(p_record_extension, extension);
756 p_record_anon_ignore = anon_ignore;
757 SCPY(p_record_vbox_email, vbox_email);
758 p_record_vbox_email_file = vbox_email_file;
762 PERROR("Port(%d) already recording\n", p_serial);
767 SPRINT(filename, "%s/%s/%s/vbox", INSTALL_DATA, options.extensions_dir, p_record_extension);
769 SPRINT(filename, "%s/%s/%s/recordings", INSTALL_DATA, options.extensions_dir, p_record_extension);
770 if (mkdir(filename, 0755) < 0)
774 PERROR("Port(%d) cannot create directory '%s'\n", p_serial, filename);
780 UPRINT(strchr(filename,'\0'), "/announcement");
782 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);
785 p_record_vbox_year = now_tm->tm_year;
786 p_record_vbox_mon = now_tm->tm_mon;
787 p_record_vbox_mday = now_tm->tm_mday;
788 p_record_vbox_hour = now_tm->tm_hour;
789 p_record_vbox_min = now_tm->tm_min;
792 /* check, if file exists (especially when an extension calls the same extension) */
794 if ((p_record = fopen(filename, "r")))
797 SCAT(filename, "_2nd");
800 p_record = fopen(filename, "w");
803 PERROR("Port(%d) cannot record because file cannot be opened '%s'\n", p_serial, filename);
808 p_record_type = type;
809 p_record_vbox = vbox;
810 p_record_skip = skip;
812 switch(p_record_type)
817 fwrite(dummyheader, sizeof(dummyheader), 1, p_record);
823 UCPY(p_record_filename, filename);
825 PDEBUG(DEBUG_PORT, "Port(%d) recording started with file name '%s'\n", p_serial, filename);
831 * close the recoding file, put header in front and rename
833 void Port::close_record(int beep)
835 static signed long beep_mono[] = {-10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000, -10000, 10000};
836 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};
837 unsigned long size, wsize;
839 char filename[512], indexname[512];
842 char number[256], callerid[256];
844 struct caller_info callerinfo;
845 char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-!$%&/()=+*;~";
850 memcpy(&callerinfo, &p_callerinfo, sizeof(struct caller_info));
851 apply_callerid_restriction(p_record_anon_ignore, -1, callerinfo.id, &callerinfo.ntype, &callerinfo.present, &callerinfo.screen, callerinfo.voip, callerinfo.intern, callerinfo.name);
853 SCPY(number, p_dialinginfo.number);
854 SCPY(callerid, numberrize_callerinfo(callerinfo.id, callerinfo.ntype));
855 if (callerid[0] == '\0')
857 if (callerinfo.present == INFO_PRESENT_RESTRICTED)
858 UCPY(callerid,"anonymous");
860 UCPY(callerid,"unknown");
863 /* change verboten digits */
865 while((p=strchr(p,'*')))
868 while((p=strchr(p,'/')))
871 while((p=strchr(p,'*')))
874 while((p=strchr(p,'/')))
877 ii = strlen(callerid);
880 if (!strchr(valid_chars, callerid[i]))
888 if (!strchr(valid_chars, number[i]))
893 /* add beep to the end of recording */
895 switch(p_record_type)
901 fwrite(beep_mono, sizeof(beep_mono), 1, p_record);
902 i += sizeof(beep_mono);
903 p_record_length += sizeof(beep_mono);
910 fwrite(beep_8bit, sizeof(beep_8bit), 1, p_record);
911 i += sizeof(beep_8bit);
912 p_record_length += sizeof(beep_8bit);
920 fwrite(beep_law, sizeof(beep_law), 1, p_record);
921 i += sizeof(beep_law);
922 p_record_length += sizeof(beep_law);
927 PERROR("codec %d not supported for beep adding\n", p_record_type);
930 /* complete header */
931 switch(p_record_type)
937 fprintf(p_record, "cue %c%c%c%c%c%c%c%c", 4, 0, 0, 0, 0,0,0,0);
940 fprintf(p_record, "LIST%c%c%c%cadtl", 4, 0, 0, 0);
943 fseek(p_record, 0, SEEK_SET);
945 /* WAVEfmt xxxx(fmt-size)dataxxxx[data]cue xxxx0000LISTxxxxadtl*/
946 size = p_record_length;
947 wsize = 4+8+sizeof(fmt)+8+size+8+4+8+4;
950 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));
953 fprintf(p_record, "WAVE");
956 fprintf(p_record, "fmt %c%c%c%c", sizeof(fmt), 0, 0, 0);
957 switch(p_record_type)
962 fmt.sample_rate = 8000; /* samples/sec */
963 fmt.data_rate = 16000; /* full data rate */
964 fmt.bytes_sample = 2; /* all channels */
965 fmt.bits_sample = 16; /* one channel */
971 fmt.sample_rate = 8000; /* samples/sec */
972 fmt.data_rate = 32000; /* full data rate */
973 fmt.bytes_sample = 4; /* all channels */
974 fmt.bits_sample = 16; /* one channel */
980 fmt.sample_rate = 8000; /* samples/sec */
981 fmt.data_rate = 8000; /* full data rate */
982 fmt.bytes_sample = 1; /* all channels */
983 fmt.bits_sample = 8; /* one channel */
986 fwrite(&fmt, sizeof(fmt), 1, p_record);
989 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));
992 if (p_record_vbox == 1)
993 SPRINT(filename, "%s.wav", p_record_filename);
995 SPRINT(filename, "%s_%s-%s.wav", p_record_filename, callerid, number);
1000 if (p_record_vbox == 1)
1001 SPRINT(filename, "%s.isdn", p_record_filename);
1003 SPRINT(filename, "%s_%s-%s.isdn", p_record_filename, callerid, number);
1011 if (rename(p_record_filename, filename) < 0)
1013 PERROR("Port(%d) cannot rename from '%s' to '%s'\n", p_serial, p_record_filename, filename);
1017 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);
1019 if (p_record_vbox == 2)
1021 SPRINT(indexname, "%s/%s/%s/vbox/index", INSTALL_DATA, options.extensions_dir, p_record_extension);
1022 if ((fp = fopen(indexname,"a")))
1026 /* remove path from file name */
1028 while(strchr(p, '/'))
1029 p = strchr(p, '/')+1;
1030 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);
1036 PERROR("Port(%d) cannot open index file '%s' to append.\n", p_serial, indexname);
1039 /* send email with sample*/
1040 if (p_record_vbox_email[0])
1042 send_mail(p_record_vbox_email_file?filename:(char *)"", callerid, callerinfo.intern, 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);
1049 * recording function
1050 * Records all data from down and from up into one single stream.
1051 * Both streams may have gaps or jitter.
1052 * A Jitter buffer for both streams is used to compensate jitter.
1054 * If one stream (dir) received packets, they are stored to a
1055 * buffer to wait for the other stream (dir), so both streams can
1056 * be combined. If the buffer is full, it's read pointer is written
1057 * without mixing stream.
1058 * A flag is used to indicate what stream is currently in buffer.
1060 * NOTE: First stereo sample (odd) is from down, second is from up.
1062 alle buffer initialisieren
1063 record nur aufrufen, wenn recorded wird.
1064 restlicher buffer wegschreiben beim schliessen
1065 void Port::record(char *data, int length, int dir_fromup)
1067 unsigned char write_buffer[1024], *d;
1073 if (!p_record || !length)
1076 free = ((p_record_buffer_readp - p_record_buffer_writep - 1) & RECORD_BUFFER_MASK);
1078 /* the buffer stores the same data stream */
1079 if (dir_fromup == p_record_buffer_dir)
1083 /* first write what we can to the buffer */
1084 while(free && length)
1086 p_record_buffer[p_record_buffer_writep] = audio_law_to_s32(*data++);
1087 p_record_buffer_writep = (p_record_buffer_writep + 1) & RECORD_BUFFER_MASK;
1091 /* all written, so we return */
1094 /* still data left, buffer is full, so we need to write to file */
1095 switch(p_record_type)
1098 s = (signed short *)write_buffer;
1102 *s++ = p_record_buffer[p_record_buffer_readp];
1103 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1106 fwrite(write_buffer, 512, 1, p_record);
1110 s = (signed short *)write_buffer;
1111 if (p_record_buffer_dir)
1116 *s++ = 0; /* nothing from down */
1117 *s++ = p_record_buffer[p_record_buffer_readp];
1118 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1126 *s++ = p_record_buffer[p_record_buffer_readp];
1127 *s++ = 0; /* nothing from up */
1128 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1132 fwrite(write_buffer, 1024, 1, p_record);
1140 *d++ = (p_record_buffer[p_record_buffer_readp]+0x8000) >> 8;
1141 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1144 fwrite(write_buffer, 512, 1, p_record);
1152 *d++ = audio_s16_to_law[p_record_buffer[p_record_buffer_readp] & 0xffff];
1153 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1156 fwrite(write_buffer, 256, 1, p_record);
1159 /* because we still have data, we write again */
1160 free += sizeof(write_buffer);
1164 /* the buffer store the other stream */
1167 /* if buffer empty, change it */
1168 if (p_record_buffer_readp == p_record_buffer_writep)
1170 p_record_buffer_dir = dir_fromup;
1173 /* how much data can we mix ? */
1174 ii = (p_record_buffer_writep - p_record_buffer_readp) & RECORD_BUFFER_MASK;
1177 /* write data mixed with the buffer */
1178 switch(p_record_type)
1181 s = (signed short *)write_buffer;
1185 sample = p_record_buffer[p_record_buffer_readp]
1186 + audio_law_to_s32(*data++);
1187 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1195 fwrite(write_buffer, ii<<1, 1, p_record);
1199 s = (signed short *)write_buffer;
1200 if (p_record_buffer_dir)
1205 *s++ = audio_law_to_s32(*data++);
1206 *s++ = p_record_buffer[p_record_buffer_readp];
1207 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1215 *s++ = p_record_buffer[p_record_buffer_readp];
1216 *s++ = audio_law_to_s32(*data++);
1220 fwrite(write_buffer, ii<<2, 1, p_record);
1228 sample = p_record_buffer[p_record_buffer_readp]
1229 + audio_law_to_s32(*data++);
1230 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1235 *d++ = (sample+0x8000) >> 8;
1238 fwrite(write_buffer, ii, 1, p_record);
1246 sample = p_record_buffer[p_record_buffer_readp]
1247 + audio_law_to_s32(*data++);
1248 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1253 *d++ = audio_s16_to_law[sample & 0xffff];
1256 fwrite(write_buffer, ii, 1, p_record);
1260 /* data, but buffer empty */
1263 p_record_buffer_dir = dir_fromup;
1266 /* no data (maybe buffer) */
1273 * enque data from upper buffer
1275 iniialisieren der werte
1276 void Port::txfromup(unsigned char *data, int length)
1283 /* get free samples in buffer */
1284 free = ((p_fromup_buffer_readp - p_fromup_buffer_writep - 1) & FROMUP_BUFFER_MASK);
1287 PDEBUG(DEBUG_PORT, "Port(%d): fromup_buffer overflows, this shall not happen under normal conditions\n", p_serial);
1291 /* write data to buffer and return */
1294 p_fromup_buffer[p_fromup_buffer_writep] = *data++;
1295 p_fromup_buffer_writep = (p_fromup_buffer_writep + 1) & FROMUP_BUFFER_MASK;
1298 return; // must return, because length is 0