1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
14 Audio flow has two ways:
16 * from channel to the upper layer
17 -> sound from mISDN channel
18 -> announcement from vbox channel
20 * from the upper layer to the channel
21 -> sound from remote channel
25 -> if local or remote channel is not mISDN
26 -> if call is recorded (vbox)
32 -> audio from upper layer is buffered for later transmission to channel
34 -> buffered audio from upper layer or tones are transmitted via system clock
36 -> rx-data from port to record() and upper layer
37 -> tx-data from port (dsp) to record()
39 -> streaming announcement to upper layer
40 -> recording announcement
41 * VboxPort::message_epoint
42 -> recording audio message from upper layer
50 /* enable to test conference mixing, even if only two members are bridged */
51 //#define TEST_CONFERENCE 1
53 #define SHORT_MIN -32768
54 #define SHORT_MAX 32767
56 class Port *port_first = NULL;
58 unsigned int port_serial = 1; /* must be 1, because 0== no port */
60 struct port_bridge *p_bridge_first;
62 static void remove_bridge(struct port_bridge *bridge, class Port *port);
64 /* free epointlist relation
66 void Port::free_epointlist(struct epoint_list *epointlist)
68 struct epoint_list *temp, **tempp;
71 tempp = &p_epointlist;
73 if (temp == epointlist)
80 PERROR("SOFTWARE ERROR: epointlist not in port's list.\n");
87 PDEBUG(DEBUG_EPOINT, "PORT(%d) removed epoint from port\n", p_serial);
88 FREE(temp, sizeof(struct epoint_list));
93 void Port::free_epointid(unsigned int epoint_id)
95 struct epoint_list *temp, **tempp;
98 tempp = &p_epointlist;
100 if (temp->epoint_id == epoint_id)
107 PERROR("epoint_id not in port's list.\n");
114 PDEBUG(DEBUG_EPOINT, "PORT(%d) removed epoint from port\n", p_serial);
115 FREE(temp, sizeof(struct epoint_list));
120 /* create new epointlist relation
122 struct epoint_list *Port::epointlist_new(unsigned int epoint_id)
124 struct epoint_list *epointlist, **epointlistpointer;
126 /* epointlist structure */
127 epointlist = (struct epoint_list *)MALLOC(sizeof(struct epoint_list));
129 FATAL("No memory for epointlist\n");
131 PDEBUG(DEBUG_EPOINT, "PORT(%d) allocating epoint_list.\n", p_serial);
133 /* add epoint_list to chain */
134 epointlist->next = NULL;
135 epointlistpointer = &p_epointlist;
136 while(*epointlistpointer)
137 epointlistpointer = &((*epointlistpointer)->next);
138 *epointlistpointer = epointlist;
141 epointlist->epoint_id = epoint_id;
142 epointlist->active = 1;
151 Port::Port(int type, const char *portname, struct port_settings *settings, struct interface *interface)
153 class Port *temp, **tempp;
155 /* initialize object */
157 memcpy(&p_settings, settings, sizeof(struct port_settings));
159 memset(&p_settings, 0, sizeof(p_settings));
161 SCPY(p_name, portname);
163 SCPY(p_interface_name, interface->name);
164 SCPY(p_tones_interface, interface->tones_dir);
166 p_tone_dir[0] = '\0';
168 p_serial = port_serial++;
170 p_tone_fetched = NULL;
171 p_tone_name[0] = '\0';
172 p_state = PORT_STATE_IDLE;
174 memset(&p_callerinfo, 0, sizeof(p_callerinfo));
175 memset(&p_dialinginfo, 0, sizeof(p_dialinginfo));
176 memset(&p_connectinfo, 0, sizeof(p_connectinfo));
177 memset(&p_redirinfo, 0, sizeof(p_redirinfo));
178 memset(&p_capainfo, 0, sizeof(p_capainfo));
188 p_record_filename[0] = '\0';
189 p_record_buffer_readp = 0;
190 p_record_buffer_writep = 0;
191 p_record_buffer_dir = 0;
200 /* append port to chain */
212 PDEBUG(DEBUG_PORT, "new port (%d) of type 0x%x, name '%s' interface '%s'\n", p_serial, type, portname, p_interface_name);
221 class Port *temp, **tempp;
222 struct lcr_msg *message;
224 PDEBUG(DEBUG_PORT, "removing port (%d) of type 0x%x, name '%s' interface '%s'\n", p_serial, p_type, p_name, p_interface_name);
228 vootp_destroy(p_vootp);
234 PDEBUG(DEBUG_PORT, "Removing us from bridge %u\n", p_bridge->bridge_id);
235 remove_bridge(p_bridge, this);
245 /* disconnect port from endpoint */
246 while(p_epointlist) {
247 /* send disconnect */
248 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
249 message->param.disconnectinfo.cause = 16;
250 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
251 message_put(message);
252 /* remove endpoint */
253 free_epointlist(p_epointlist);
256 /* remove port from chain */
266 FATAL("PORT(%s) port not in port's list.\n", p_name);
270 /* close open tones file */
271 if (p_tone_fh >= 0) {
276 p_tone_fetched = NULL;
281 /* set new endpoint state
283 void Port::new_state(int state)
285 PDEBUG(DEBUG_PORT, "PORT(%s) new state %s --> %s\n", p_name, state_name[p_state], state_name[state]);
291 * find the port with port_id
293 class Port *find_port_id(unsigned int port_id)
295 class Port *port = port_first;
298 //printf("comparing: '%s' with '%s'\n", name, port->name);
299 if (port->p_serial == port_id)
311 void Port::set_echotest(int echotest)
313 p_echotest = echotest;
318 * set the file in the tone directory with the given name
320 void Port::set_tone(const char *dir, const char *name)
328 if (!dir || !dir[0]) {
329 if (p_tones_interface[0])
330 dir = p_tones_interface;
332 dir = options.tones_dir; /* just in case we have no PmISDN instance */
335 /* no counter, no eof, normal speed */
339 p_tone_codec = CODEC_LAW;
341 if (p_tone_fh >= 0) {
346 p_tone_fetched = NULL;
349 if (name[0] == '/') {
350 SPRINT(p_tone_name, "%s", name);
351 p_tone_dir[0] = '\0';
353 SCPY(p_tone_dir, dir);
354 SCPY(p_tone_name, name);
356 /* trigger playback */
359 p_tone_name[0]= '\0';
364 if (!!strncmp(name,"cause_",6))
367 /* now we check if the cause exists, otherwhise we use error tone. */
368 if ((p_tone_fetched=open_tone_fetched(p_tone_dir, p_tone_name, &p_tone_codec, 0, 0))) {
369 p_tone_fetched = NULL;
372 SPRINT(filename, "%s_loop", p_tone_name);
373 if ((p_tone_fetched=open_tone_fetched(p_tone_dir, filename, &p_tone_codec, 0, 0))) {
374 p_tone_fetched = NULL;
377 SPRINT(filename, "%s/%s/%s", SHARE_DATA, p_tone_dir, p_tone_name);
378 if ((fh=open_tone(filename, &p_tone_codec, 0, 0)) >= 0) {
382 SPRINT(filename, "%s/%s/%s_loop", SHARE_DATA, p_tone_dir, p_tone_name);
383 if ((fh=open_tone(filename, &p_tone_codec, 0, 0)) >= 0) {
388 if (!strcmp(name,"cause_00") || !strcmp(name,"cause_10")) {
389 PDEBUG(DEBUG_PORT, "PORT(%s) Given Cause 0x%s has no tone, using release tone\n", p_name, name+6);
390 SPRINT(p_tone_name,"release");
392 if (!strcmp(name,"cause_11")) {
393 PDEBUG(DEBUG_PORT, "PORT(%s) Given Cause 0x%s has no tone, using busy tone\n", p_name, name+6);
394 SPRINT(p_tone_name,"busy");
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");
402 void Port::set_display(const char *text)
407 * set the file in the tone directory for vbox playback
408 * also set the play_eof-flag
410 void Port::set_vbox_tone(const char *dir, const char *name)
416 p_tone_codec = CODEC_LAW;
419 if (p_tone_fh >= 0) {
424 p_tone_fetched = NULL;
426 SPRINT(p_tone_dir, dir);
427 SPRINT(p_tone_name, name);
428 /* trigger playback */
431 /* now we check if the cause exists, otherwhise we use error tone. */
433 if ((p_tone_fetched=open_tone_fetched(p_tone_dir, p_tone_name, &p_tone_codec, &p_tone_size, &p_tone_left))) {
434 PDEBUG(DEBUG_PORT, "PORT(%s) opening fetched tone: %s\n", p_name, p_tone_name);
437 SPRINT(filename, "%s/%s/%s", SHARE_DATA, p_tone_dir, p_tone_name);
438 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) >= 0) {
440 PDEBUG(DEBUG_PORT, "PORT(%s) opening tone: %s\n", p_name, filename);
444 SPRINT(filename, "%s", p_tone_name);
445 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) >= 0) {
447 PDEBUG(DEBUG_PORT, "PORT(%s) opening tone: %s\n", p_name, filename);
455 * set the file in the given directory for vbox playback
456 * also set the eof-flag
457 * also set the counter-flag
459 void Port::set_vbox_play(const char *name, int offset)
461 struct lcr_msg *message;
463 /* use ser_box_tone() */
464 set_vbox_tone("", name);
472 if (p_tone_name[0]) {
473 /* send message with counter value */
474 if (p_tone_size>=0 && ACTIVE_EPOINT(p_epointlist)) {
475 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_COUNTER);
476 message->param.counter.current = offset;
477 message->param.counter.max = p_tone_size;
478 message_put(message);
485 * set the playback speed (for recording playback with different speeds)
487 void Port::set_vbox_speed(int speed)
489 /* enable vbox play mode */
490 p_tone_speed = speed;
494 * read from the given file as specified in port_set_tone and return sample data
495 * if the tone ends, the result may be less samples than requested
497 int Port::read_audio(unsigned char *buffer, int length)
500 int nodata=0; /* to detect 0-length files and avoid endless reopen */
502 int tone_left_before; /* temp variable to determine the change in p_tone_left */
510 /* if there is no tone set, use silence */
514 /* if the file pointer is not open, we open it */
515 if (p_tone_fh<0 && p_tone_fetched==NULL) {
517 SPRINT(filename, "%s", p_tone_name);
518 /* if file does not exist */
519 if (!(p_tone_fetched=open_tone_fetched(p_tone_dir, filename, &p_tone_codec, &p_tone_size, &p_tone_left))) {
520 SPRINT(filename, "%s/%s/%s", SHARE_DATA, p_tone_dir, p_tone_name);
521 /* if file does not exist */
522 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0) {
523 PDEBUG(DEBUG_PORT, "PORT(%s) no tone: %s\n", p_name, filename);
529 SPRINT(filename, "%s", p_tone_name);
530 /* if file does not exist */
531 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0) {
532 PDEBUG(DEBUG_PORT, "PORT(%s) no tone: %s\n", p_name, filename);
537 PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
541 /* file descriptor is open read data */
542 tone_left_before = p_tone_left;
543 if (p_tone_fh >= 0) {
544 l = read_tone(p_tone_fh, buffer, p_tone_codec, len, p_tone_size, &p_tone_left, p_tone_speed);
545 if (l<0 || l>len) /* paranoia */
550 if (p_tone_fetched) {
551 l = read_tone_fetched(&p_tone_fetched, buffer, len, p_tone_size, &p_tone_left, p_tone_speed);
552 if (l<0 || l>len) /* paranoia */
558 /* if counter is enabled, we check if we have a change */
559 if (p_tone_counter && p_tone_size>=0 && ACTIVE_EPOINT(p_epointlist)) {
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 //printf("\nsize=%d left=%d\n\n",p_tone_size,p_tone_left);
563 struct lcr_msg *message;
564 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_COUNTER);
565 message->param.counter.current = (p_tone_size-p_tone_left)/8000;
566 message->param.counter.max = -1;
567 message_put(message);
574 if (p_tone_fh >= 0) {
579 p_tone_fetched = NULL;
584 /* if the file has 0-length */
586 PDEBUG(DEBUG_PORT, "PORT(%s) 0-length loop: %s\n", p_name, filename);
592 /* if eof is reached, or if the normal file cannot be opened, continue with the loop file if possible */
594 if (p_tone_eof && ACTIVE_EPOINT(p_epointlist)) {
595 struct lcr_msg *message;
596 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TONE_EOF);
597 message_put(message);
601 /* if file does not exist */
602 SPRINT(filename, "%s_loop", p_tone_name);
603 if (!(p_tone_fetched=open_tone_fetched(p_tone_dir, filename, &p_tone_codec, &p_tone_size, &p_tone_left))) {
604 SPRINT(filename, "%s/%s/%s_loop", SHARE_DATA, p_tone_dir, p_tone_name);
605 /* if file does not exist */
606 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0) {
607 PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename);
608 p_tone_dir[0] = '\0';
609 p_tone_name[0] = '\0';
615 SPRINT(filename, "%s_loop", p_tone_name);
616 /* if file does not exist */
617 if ((p_tone_fh=open_tone(filename, &p_tone_codec, &p_tone_size, &p_tone_left)) < 0) {
618 PDEBUG(DEBUG_PORT, "PORT(%s) no tone loop: %s\n",p_name, filename);
619 p_tone_dir[0] = '\0';
620 p_tone_name[0] = '\0';
626 PDEBUG(DEBUG_PORT, "PORT(%s) opening %stone: %s\n", p_name, p_tone_fetched?"fetched ":"", filename);
628 /* now we have opened the loop */
633 /* Endpoint sends messages to the port
634 * This is called by the message_epoint, inherited by child classes.
635 * Therefor a return 1 means: "already handled here"
637 //extern struct lcr_msg *dddebug;
638 int Port::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
640 /* check if we got audio data from one remote port */
642 case MESSAGE_TONE: /* play tone */
643 PDEBUG(DEBUG_PORT, "PORT(%s) setting tone '%s' dir '%s'\n", p_name, param->tone.name, param->tone.dir);
644 set_tone(param->tone.dir,param->tone.name);
647 case MESSAGE_VBOX_TONE: /* play tone of answering machine */
648 PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine tone '%s' '%s'\n", p_name, param->tone.dir, param->tone.name);
649 set_vbox_tone(param->tone.dir, param->tone.name);
652 case MESSAGE_VBOX_PLAY: /* play recording of answering machine */
653 PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine file to play '%s' (offset %d seconds)\n", p_name, param->play.file, param->play.offset);
654 set_vbox_play(param->play.file, param->play.offset);
657 case MESSAGE_VBOX_PLAY_SPEED: /* set speed of playback (recording of answering machine) */
658 PDEBUG(DEBUG_PORT, "PORT(%s) set answering machine playback speed %d (times)\n", p_name, param->speed);
659 set_vbox_speed(param->speed);
662 case MESSAGE_BRIDGE: /* create / join / leave / destroy bridge */
663 PDEBUG(DEBUG_PORT, "PORT(%s) bridging to id %d\n", p_name, param->bridge_id);
664 bridge(param->bridge_id);
668 case MESSAGE_VOOTP: /* enable / disable VoOTP */
669 PDEBUG(DEBUG_PORT, "PORT(%s) VoOTP enabled: %d\n", p_name, param->vootp.enable);
670 set_vootp(¶m->vootp);
674 case MESSAGE_DOV_REQUEST: /* Data-Over-Voice message */
675 PDEBUG(DEBUG_PORT, "PORT(%s) sending data over voice message (len=%d)\n", p_name, param->dov.length);
676 dov_sendmsg(param->dov.data, param->dov.length, (enum dov_type)param->dov.type, param->dov.level);
679 case MESSAGE_DOV_LISTEN: /* Data-Over-Voice listen order */
680 PDEBUG(DEBUG_PORT, "PORT(%s) sending data over voice listen order\n", p_name);
681 dov_listen((enum dov_type)param->dov.type);
689 /* wave header structure */
691 unsigned short stereo; /* 1 = mono, 2 = stereo */
692 unsigned short channels; /* number of channels */
693 unsigned int sample_rate; /* sample rate */
694 unsigned int data_rate; /* data rate */
695 unsigned short bytes_sample; /* bytes per sample (all channels) */
696 unsigned short bits_sample; /* bits per sample (one channel) */
701 * open record file (actually a wave file with empty header which will be
702 * written before close, because we do not know the size yet)
703 * type=1 record annoucement, type=0 record audio stream, type=2 record vbox
705 int Port::open_record(int type, int vbox, int skip, char *extension, int anon_ignore, const char *vbox_email, int vbox_email_file)
707 /* RIFFxxxxWAVEfmt xxxx(fmt-size)dataxxxx... */
708 char dummyheader[8+4+8+sizeof(fmt)+8];
712 int __attribute__((__unused__)) ret;
715 PERROR("Port(%d) not an extension\n", p_serial);
718 SCPY(p_record_extension, extension);
719 p_record_anon_ignore = anon_ignore;
720 SCPY(p_record_vbox_email, vbox_email);
721 p_record_vbox_email_file = vbox_email_file;
724 PERROR("Port(%d) already recording\n", p_serial);
729 SPRINT(filename, "%s/%s/vbox", EXTENSION_DATA, p_record_extension);
731 SPRINT(filename, "%s/%s/recordings", EXTENSION_DATA, p_record_extension);
732 if (mkdir(filename, 0755) < 0) {
733 if (errno != EEXIST) {
734 PERROR("Port(%d) cannot create directory '%s'\n", p_serial, filename);
740 UPRINT(strchr(filename,'\0'), "/announcement");
743 now_tm = localtime(&now);
744 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);
747 p_record_vbox_year = now_tm->tm_year;
748 p_record_vbox_mon = now_tm->tm_mon;
749 p_record_vbox_mday = now_tm->tm_mday;
750 p_record_vbox_hour = now_tm->tm_hour;
751 p_record_vbox_min = now_tm->tm_min;
754 /* check, if file exists (especially when an extension calls the same extension) */
756 if ((p_record = fopen(filename, "r"))) {
758 SCAT(filename, "_2nd");
761 p_record = fopen(filename, "w");
763 PERROR("Port(%d) cannot record because file cannot be opened '%s'\n", p_serial, filename);
769 p_record_type = type;
770 p_record_vbox = vbox;
771 p_record_skip = skip;
773 switch(p_record_type) {
777 memset(&dummyheader, 0, sizeof(dummyheader));
778 ret = fwrite(dummyheader, sizeof(dummyheader), 1, p_record);
784 UCPY(p_record_filename, filename);
786 PDEBUG(DEBUG_PORT, "Port(%d) recording started with file name '%s'\n", p_serial, filename);
792 * close the recoding file, put header in front and rename
794 void Port::close_record(int beep, int mute)
796 static signed short beep_mono[256];
797 unsigned int size = 0, wsize = 0;
799 char filename[512], indexname[512];
802 char number[256], callerid[256];
804 struct caller_info callerinfo;
805 const char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-!$%&/()=+*;~";
806 int __attribute__((__unused__)) ret;
810 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);
812 memcpy(&callerinfo, &p_callerinfo, sizeof(struct caller_info));
813 // apply_callerid_restriction(p_record_anon_ignore, callerinfo.id, &callerinfo.ntype, &callerinfo.present, &callerinfo.screen, callerinfo.extension, callerinfo.name);
815 SCPY(number, p_dialinginfo.id);
816 SCPY(callerid, numberrize_callerinfo(callerinfo.id, callerinfo.ntype, options.national, options.international));
817 if (callerid[0] == '\0') {
818 if (callerinfo.present == INFO_PRESENT_RESTRICTED)
819 UCPY(callerid,"anonymous");
821 UCPY(callerid,"unknown");
824 /* change verboten digits */
826 while((p=strchr(p,'*')))
829 while((p=strchr(p,'/')))
832 while((p=strchr(p,'*')))
835 while((p=strchr(p,'/')))
838 ii = strlen(callerid);
840 if (!strchr(valid_chars, callerid[i]))
847 if (!strchr(valid_chars, number[i]))
853 if (mute && p_record_type==CODEC_MONO) {
857 fseek(p_record, -(i<<1), SEEK_END);
858 p_record_length -= (i<<1);
860 /* add beep to the end of recording */
861 if (beep && p_record_type==CODEC_MONO) {
864 beep_mono[i] = (signed short)(sin((double)i / 5.688888888889 * 2.0 * 3.1415927) * 2000.0);
869 ret = fwrite(beep_mono, sizeof(beep_mono), 1, p_record);
870 i += sizeof(beep_mono);
871 p_record_length += sizeof(beep_mono);
875 /* complete header */
876 switch(p_record_type) {
881 fprintf(p_record, "cue %c%c%c%c%c%c%c%c", 4, 0, 0, 0, 0,0,0,0);
884 fprintf(p_record, "LIST%c%c%c%cadtl", 4, 0, 0, 0);
887 fseek(p_record, 0, SEEK_SET);
889 /* WAVEfmt xxxx(fmt-size)dataxxxx[data]cue xxxx0000LISTxxxxadtl*/
890 size = p_record_length;
891 wsize = 4+8+sizeof(fmt)+8+size+8+4+8+4;
894 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));
897 fprintf(p_record, "WAVE");
900 fprintf(p_record, "fmt %c%c%c%c", (unsigned int)sizeof(fmt), 0, 0, 0);
901 switch(p_record_type) {
905 fmt.sample_rate = 8000; /* samples/sec */
906 fmt.data_rate = 16000; /* full data rate */
907 fmt.bytes_sample = 2; /* all channels */
908 fmt.bits_sample = 16; /* one channel */
914 fmt.sample_rate = 8000; /* samples/sec */
915 fmt.data_rate = 32000; /* full data rate */
916 fmt.bytes_sample = 4; /* all channels */
917 fmt.bits_sample = 16; /* one channel */
923 fmt.sample_rate = 8000; /* samples/sec */
924 fmt.data_rate = 8000; /* full data rate */
925 fmt.bytes_sample = 1; /* all channels */
926 fmt.bits_sample = 8; /* one channel */
929 ret = fwrite(&fmt, sizeof(fmt), 1, p_record);
932 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));
935 if (p_record_vbox == 1)
936 SPRINT(filename, "%s.wav", p_record_filename);
938 SPRINT(filename, "%s_%s-%s.wav", p_record_filename, callerid, number);
943 if (p_record_vbox == 1)
944 SPRINT(filename, "%s.isdn", p_record_filename);
946 SPRINT(filename, "%s_%s-%s.isdn", p_record_filename, callerid, number);
955 if (rename(p_record_filename, filename) < 0) {
956 PERROR("Port(%d) cannot rename from '%s' to '%s'\n", p_serial, p_record_filename, filename);
960 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);
962 if (p_record_vbox == 2) {
963 SPRINT(indexname, "%s/%s/vbox/index", EXTENSION_DATA, p_record_extension);
964 if ((fp = fopen(indexname,"a"))) {
967 /* remove path from file name */
969 while(strchr(p, '/'))
970 p = strchr(p, '/')+1;
971 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);
976 PERROR("Port(%d) cannot open index file '%s' to append.\n", p_serial, indexname);
979 /* send email with sample*/
980 if (p_record_vbox_email[0]) {
981 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);
989 * Records all data from down and from up into one single stream.
990 * Both streams may have gaps or jitter.
991 * A Jitter buffer for both streams is used to compensate jitter.
993 * If one stream (dir) received packets, they are stored to a
994 * buffer to wait for the other stream (dir), so both streams can
995 * be combined. If the buffer is full, it's content is written
996 * without mixing stream. (assuming only one stram (dir) exists.)
997 * A flag is used to indicate what stream is currently in buffer.
999 * NOTE: First stereo sample (odd) is from down, second is from up.
1001 void Port::record(unsigned char *data, int length, int dir_fromup)
1003 unsigned char write_buffer[1024], *d;
1007 int __attribute__((__unused__)) ret;
1010 if (!p_record || !length)
1013 /* skip data from local caller (dtmf input) */
1014 if (p_record_skip && !dir_fromup) {
1015 /* more to skip than we have */
1016 if (p_record_skip > length) {
1017 p_record_skip -= length;
1021 data += p_record_skip;
1022 length -= p_record_skip;
1026 //printf("dir=%d len=%d\n", dir_fromup, length);
1028 free = ((p_record_buffer_readp - p_record_buffer_writep - 1) & RECORD_BUFFER_MASK);
1030 //PDEBUG(DEBUG_PORT, "record(data,%d,%d): free=%d, p_record_buffer_dir=%d, p_record_buffer_readp=%d, p_record_buffer_writep=%d.\n", length, dir_fromup, free, p_record_buffer_dir, p_record_buffer_readp, p_record_buffer_writep);
1032 /* the buffer stores the same data stream */
1033 if (dir_fromup == p_record_buffer_dir) {
1036 //printf("same free=%d length=%d\n", free, length);
1037 /* first write what we can to the buffer */
1038 while(free && length) {
1039 p_record_buffer[p_record_buffer_writep] = audio_law_to_s32[*data++];
1040 p_record_buffer_writep = (p_record_buffer_writep + 1) & RECORD_BUFFER_MASK;
1044 /* all written, so we return */
1047 /* still data left, buffer is full, so we need to write a chunk to file */
1048 switch(p_record_type) {
1050 s = (signed short *)write_buffer;
1053 *s++ = p_record_buffer[p_record_buffer_readp];
1054 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1057 ret = fwrite(write_buffer, 512, 1, p_record);
1058 p_record_length += 512;
1062 s = (signed short *)write_buffer;
1063 if (p_record_buffer_dir) {
1066 *s++ = 0; /* nothing from down */
1067 *s++ = p_record_buffer[p_record_buffer_readp];
1068 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1074 *s++ = p_record_buffer[p_record_buffer_readp];
1075 *s++ = 0; /* nothing from up */
1076 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1080 ret = fwrite(write_buffer, 1024, 1, p_record);
1081 p_record_length += 1024;
1088 *d++ = ((unsigned short)(p_record_buffer[p_record_buffer_readp]+0x8000)) >> 8;
1089 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1092 ret = fwrite(write_buffer, 512, 1, p_record);
1093 p_record_length += 512;
1100 *d++ = audio_s16_to_law[p_record_buffer[p_record_buffer_readp] & 0xffff];
1101 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1104 ret = fwrite(write_buffer, 256, 1, p_record);
1105 p_record_length += 256;
1108 /* because we still have data, we write again */
1112 /* the buffer stores the other stream */
1115 /* if buffer empty, change it */
1116 if (p_record_buffer_readp == p_record_buffer_writep) {
1117 p_record_buffer_dir = dir_fromup;
1120 /* how much data can we mix ? */
1121 ii = (p_record_buffer_writep - p_record_buffer_readp) & RECORD_BUFFER_MASK;
1127 //printf("same ii=%d length=%d\n", ii, length);
1128 //PDEBUG(DEBUG_PORT, "record(data,%d,%d): free=%d, p_record_buffer_dir=%d, p_record_buffer_readp=%d, p_record_buffer_writep=%d: mixing %d bytes.\n", length, dir_fromup, free, p_record_buffer_dir, p_record_buffer_readp, p_record_buffer_writep, ii);
1130 /* write data mixed with the buffer */
1131 switch(p_record_type) {
1133 s = (signed short *)write_buffer;
1136 sample = p_record_buffer[p_record_buffer_readp]
1137 + audio_law_to_s32[*data++];
1138 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1139 if (sample < SHORT_MIN) sample = SHORT_MIN;
1140 if (sample > SHORT_MAX) sample = SHORT_MAX;
1144 ret = fwrite(write_buffer, ii<<1, 1, p_record);
1145 p_record_length += (ii<<1);
1149 s = (signed short *)write_buffer;
1150 if (p_record_buffer_dir) {
1153 *s++ = audio_law_to_s32[*data++];
1154 *s++ = p_record_buffer[p_record_buffer_readp];
1155 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1161 *s++ = p_record_buffer[p_record_buffer_readp];
1162 *s++ = audio_law_to_s32[*data++];
1163 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1167 ret = fwrite(write_buffer, ii<<2, 1, p_record);
1168 p_record_length += (ii<<2);
1175 sample = p_record_buffer[p_record_buffer_readp]
1176 + audio_law_to_s32[*data++];
1177 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1178 if (sample < SHORT_MIN) sample = SHORT_MIN;
1179 if (sample > SHORT_MAX) sample = SHORT_MAX;
1180 *d++ = (sample+0x8000) >> 8;
1183 ret = fwrite(write_buffer, ii, 1, p_record);
1184 p_record_length += ii;
1191 sample = p_record_buffer[p_record_buffer_readp]
1192 + audio_law_to_s32[*data++];
1193 p_record_buffer_readp = (p_record_buffer_readp + 1) & RECORD_BUFFER_MASK;
1194 if (sample < SHORT_MIN) sample = SHORT_MIN;
1195 if (sample > SHORT_MAX) sample = SHORT_MAX;
1196 *d++ = audio_s16_to_law[sample & 0xffff];
1199 ret = fwrite(write_buffer, ii, 1, p_record);
1200 p_record_length += ii;
1206 goto different_again;
1207 /* no data (maybe buffer) */
1212 void Port::tap(unsigned char *data, int length, int dir_fromup)
1216 void Port::update_rxoff(void)
1220 void Port::update_load(void)
1229 int bridge_timeout(struct lcr_timer *timer, void *instance, int index);
1231 static void remove_bridge(struct port_bridge *bridge, class Port *port)
1233 struct port_bridge **temp = &p_bridge_first;
1235 if (*temp == bridge) {
1236 struct port_bridge_member **memberp = &bridge->first, *member;
1238 /* loop until we are found */
1240 if ((*memberp)->port == port) {
1242 *memberp = member->next;
1243 FREE(member, sizeof(struct port_bridge_member));
1245 #ifndef TEST_CONFERENCE
1246 if (bridge->first && bridge->first->next && !bridge->first->next->next) {
1248 if (bridge->first && !bridge->first->next) {
1250 PDEBUG(DEBUG_PORT, "bridge %u is no conference anymore\n", bridge->bridge_id);
1251 del_timer(&bridge->timer);
1255 memberp = &((*memberp)->next);
1257 /* if bridge is empty, remove it */
1258 if (bridge->first == NULL) {
1259 PDEBUG(DEBUG_PORT, "Remove bridge %u\n", bridge->bridge_id);
1260 *temp = bridge->next;
1261 FREE(bridge, sizeof(struct port_bridge));
1266 temp = &((*temp)->next);
1268 PERROR("Bridge %p not found in list\n", bridge);
1271 void Port::bridge(unsigned int bridge_id)
1273 struct port_bridge_member **memberp;
1275 /* Remove bridge, if we leave bridge or if we join a different bridge. */
1276 if (p_bridge && bridge_id != p_bridge->bridge_id) {
1277 PDEBUG(DEBUG_PORT, "Remove port %u from bridge %u, because out new bridge is %u\n", p_serial, p_bridge->bridge_id, bridge_id);
1278 remove_bridge(p_bridge, this);
1282 /* if we leave bridge */
1288 struct port_bridge *temp = p_bridge_first;
1291 if (temp->bridge_id == bridge_id)
1297 PDEBUG(DEBUG_PORT, "Port %d found existing bridge %u.\n", p_serial, p_bridge->bridge_id);
1302 struct port_bridge **temp = &p_bridge_first;
1304 p_bridge = (struct port_bridge *) MALLOC(sizeof(struct port_bridge));
1306 p_bridge->bridge_id = bridge_id;
1308 /* attach bridge instance to list */
1310 temp = &((*temp)->next);
1312 PDEBUG(DEBUG_PORT, "Port %d creating not existing bridge %u.\n", p_serial, p_bridge->bridge_id);
1315 /* attach to bridge */
1316 memberp = &p_bridge->first;
1318 if ((*memberp)->port == this) {
1319 /* already joined */
1322 memberp = &((*memberp)->next);
1324 *memberp = (struct port_bridge_member *) MALLOC(sizeof(struct port_bridge_member));
1326 (*memberp)->port = this;
1327 /* check if bridge becomes a conference */
1328 #ifndef TEST_CONFERENCE
1329 if (p_bridge->first->next && p_bridge->first->next->next && !p_bridge->first->next->next->next) {
1330 p_bridge->first->next->next->write_p = 0;
1331 p_bridge->first->next->next->min_space = 0;
1332 memset(p_bridge->first->next->next->buffer, silence, sizeof((*memberp)->buffer));
1334 if (p_bridge->first->next && !p_bridge->first->next->next) {
1336 p_bridge->first->next->write_p = 0;
1337 p_bridge->first->next->min_space = 0;
1338 memset(p_bridge->first->next->buffer, silence, sizeof((*memberp)->buffer));
1339 p_bridge->first->write_p = 0;
1340 p_bridge->first->min_space = 0;
1341 memset(p_bridge->first->buffer, silence, sizeof((*memberp)->buffer));
1342 memset(p_bridge->sum_buffer, 0, sizeof(p_bridge->sum_buffer));
1343 p_bridge->read_p = 0;
1344 add_timer(&p_bridge->timer, bridge_timeout, p_bridge, 0);
1345 schedule_timer(&p_bridge->timer, 0, 20000); /* 20 MS */
1346 p_bridge->sample_count = 0;
1347 PDEBUG(DEBUG_PORT, "bridge %u became a conference\n", p_bridge->bridge_id);
1351 /* send data to remote Port or add to sum buffer */
1352 int Port::bridge_tx(unsigned char *data, int len)
1355 struct port_bridge_member *member;
1361 vootp_encrypt_stream(p_vootp, data, len);
1364 /* less than two ports, so drop */
1365 if (!p_bridge || !p_bridge->first || !p_bridge->first->next)
1367 #ifndef TEST_CONFERENCE
1368 /* two ports, so bridge */
1369 if (!p_bridge->first->next->next) {
1370 if (p_bridge->first->port == this)
1371 return p_bridge->first->next->port->bridge_rx(data, len);
1372 if (p_bridge->first->next->port == this)
1373 return p_bridge->first->port->bridge_rx(data, len);
1377 /* more than two ports... */
1378 member = p_bridge->first;
1380 if (member->port == this)
1382 member = member->next;
1386 write_p = member->write_p;
1387 /* calculate space, so write pointer will not overrun (or reach) read pointer in ring buffer */
1388 space = (p_bridge->read_p - write_p - 1) & (BRIDGE_BUFFER - 1);
1389 /* clip len, if it does not fit */
1392 /* apply audio samples to sum buffer */
1393 sum = p_bridge->sum_buffer;
1394 buf = member->buffer;
1396 sum[write_p] += audio_law_to_s32[*data];
1397 buf[write_p] = *data++;
1398 write_p = (write_p + 1) & (BRIDGE_BUFFER - 1);
1400 /* raise write pointer */
1401 member->write_p = write_p;
1406 int bridge_timeout(struct lcr_timer *timer, void *instance, int index)
1408 struct port_bridge *bridge = (struct port_bridge *)instance;
1409 struct port_bridge_member *member = bridge->first;
1410 unsigned long long timer_time;
1411 signed long *sum, sample;
1412 unsigned char buffer[160], *buf, *d;
1413 int i, read_p, space;
1415 bridge->sample_count += 160;
1417 /* schedule exactly 20ms from last schedule */
1418 timer_time = timer->timeout.tv_sec * MICRO_SECONDS + timer->timeout.tv_usec;
1419 timer_time += 20000; /* 20 MS */
1420 timer->timeout.tv_sec = timer_time / MICRO_SECONDS;
1421 timer->timeout.tv_usec = timer_time % MICRO_SECONDS;
1425 /* calculate transmit data */
1426 read_p = bridge->read_p;
1427 sum = bridge->sum_buffer;
1428 buf = member->buffer;
1430 for (i = 0; i < 160; i++) {
1431 sample = sum[read_p];
1432 sample -= audio_law_to_s32[buf[read_p]];
1433 buf[read_p] = silence;
1434 if (sample < SHORT_MIN) sample = SHORT_MIN;
1435 if (sample > SHORT_MAX) sample = SHORT_MAX;
1436 *d++ = audio_s16_to_law[sample & 0xffff];
1437 read_p = (read_p + 1) & (BRIDGE_BUFFER - 1);
1440 member->port->bridge_rx(buffer, 160);
1441 /* raise write pointer, if read pointer would overrun them */
1442 space = ((member->write_p - bridge->read_p) & (BRIDGE_BUFFER - 1)) - 160;
1445 member->write_p = read_p;
1446 // PDEBUG(DEBUG_PORT, "bridge %u member %d has buffer underrun\n", bridge->bridge_id, member->port->p_serial);
1448 /* find minimum delay */
1449 if (space < member->min_space)
1450 member->min_space = space;
1451 /* check if we should reduce buffer */
1452 if (bridge->sample_count >= 8000*5) {
1453 /* reduce buffer by minimum delay */
1454 // PDEBUG(DEBUG_PORT, "bridge %u member %d has min space of %d samples\n", bridge->bridge_id, member->port->p_serial, member->min_space);
1455 member->write_p = (member->write_p - member->min_space) & (BRIDGE_BUFFER - 1);
1456 member->min_space = 1000000; /* infinite */
1458 member = member->next;
1461 /* clear sample data */
1462 read_p = bridge->read_p;
1463 sum = bridge->sum_buffer;
1464 for (i = 0; i < 160; i++) {
1466 read_p = (read_p + 1) & (BRIDGE_BUFFER - 1);
1469 /* raise read pointer */
1470 bridge->read_p = read_p;
1472 if (bridge->sample_count >= 8000*5)
1473 bridge->sample_count = 0;
1479 /* receive data from remote Port */
1480 int Port::bridge_rx(unsigned char *data, int len)
1485 vootp_decrypt_stream(p_vootp, data, len);
1492 static void vootp_info(void *priv, const char *text)
1494 class Port *port = (class Port *)priv;
1495 char display[strlen(text) + 1];
1497 SCPY(display, text);
1499 display[strlen(display) - 1] = '\0';
1501 port->set_display(display);
1504 void Port::set_vootp(struct param_vootp *vootp)
1507 vootp_destroy(p_vootp);
1510 if (vootp->enable) {
1511 p_vootp = vootp_create(this, (options.law=='a'), options.otp_dir, NULL, NULL, vootp->id, vootp_info);
1512 // vootp_loglevel(VOOTP_LOGL_DEBUG);
1514 struct lcr_msg *message;
1516 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_VOOTP);
1517 message->param.vootp.failed = 1;
1518 message_put(message);