1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
10 \*****************************************************************************/
15 * there are three types of states
17 * - the port state (p_state): used for current call state
18 * - the ss5 state (p_m_s_state): used for current tone
19 * - the ss5 signal state (p_m_s_signal): used for current signal state of current tone
21 * the port state differs from isdn state:
23 * - PORT_STATE_IDLE: used until number is complete. outgoing overlap dialing is received in this state.
24 * - PORT_STATE_OUT_SETUP: the seizing procedure is started.
25 * - PORT_STATE_OUT_OVERLAP: the transmitter is sending the digits.
26 * - PORT_STATE_OUT_PROCEEDING: the digits are sent, we wait until someone answers.
27 * - PORT_STATE_OUT_DISCONNECT: a clear-back is sent, after DISCONNECT was received
28 * - PORT_STATE_CONNECT: a call is answered on either side.
29 * - PORT_STATE_IN_SETUP: the seizing is received, we wait for the first digit.
30 * - PORT_STATE_IN_OVERLAP: the digits are received.
31 * - PORT_STATE_IN_PROCEEDING: the number is complete, a SETUP is indicated.
32 * - PORT_STATE_IN_DISCONNECT: a clear-back was received, an DISCONNECT is indicated.
33 * - PORT_STATE_RELEASE: the clear forward procedure is started.
39 //#define DEBUG_DETECT
41 /* ss5 signal states */
43 SS5_STATE_IDLE, /* no signal */
44 SS5_STATE_SEIZING, /* seizing */
45 SS5_STATE_PROCEED_TO_SEND, /* proceed-to-send */
46 SS5_STATE_BUSY_FLASH, /* busy-flash / clear back */
47 SS5_STATE_ACK_BUSY_FLASH, /* acknowledge of busy/answer/clear-back */
48 SS5_STATE_ANSWER, /* answer */
49 SS5_STATE_ACK_ANSWER, /* acknowledge of busy/answer/clear-back */
50 SS5_STATE_FORWARD_TRANSFER, /* forward transfer */
51 SS5_STATE_CLEAR_BACK, /* clear-back */
52 SS5_STATE_ACK_CLEAR_BACK, /* acknowledge of busy/answer/clear-back */
53 SS5_STATE_CLEAR_FORWARD, /* clear-forward */
54 SS5_STATE_RELEASE_GUARD, /* release-guard */
55 SS5_STATE_DIAL_OUT, /* dialing state (transmitter) */
56 SS5_STATE_DIAL_IN, /* dialing state (receiver) */
57 SS5_STATE_DIAL_IN_PULSE, /* dialing state (receiver with pulses) */
58 SS5_STATE_DELAY, /* after signal wait until next signal can be sent */
59 SS5_STATE_DOUBLE_SEIZE, /* in case of a double seize, we make the remote size recognize it */
61 const char *ss5_state_name[] = {
64 "STATE_PROCEED_TO_SEND",
66 "STATE_ACK_BUSY_FLASH",
69 "STATE_FORWARD_TRANSFER",
71 "STATE_ACK_CLEAR_BACK",
72 "STATE_CLEAR_FORWARD",
73 "STATE_RELEASE_GUARD",
76 "STATE_DIAL_IN_PULSE",
83 /* sending signal states */
84 SS5_SIGNAL_SEND_ON, /* sending signal, waiting for acknowledge */
85 SS5_SIGNAL_SEND_ON_RECOG, /* sending signal, receiving ack, waiting for recogition timer */
86 SS5_SIGNAL_SEND_OFF, /* silence, receiving ack, waiting for stop */
87 /* receiving signal states */
88 SS5_SIGNAL_RECEIVE_RECOG, /* receiving signal, waiting for recognition timer */
89 SS5_SIGNAL_RECEIVE, /* receiving signal / send ack, waiting for stop */
90 SS5_SIGNAL_DELAY, /* delay after release guard to prevent ping-pong */
91 /* sending / receiving digit states */
92 SS5_SIGNAL_DIGIT_PAUSE, /* pausing before sending (next) digit */
93 SS5_SIGNAL_DIGIT_ON, /* sending digit */
94 SS5_SIGNAL_PULSE_OFF, /* make */
95 SS5_SIGNAL_PULSE_ON, /* break */
97 const char *ss5_signal_name[] = {
100 "SIGNAL_SEND_ON_RECOG",
102 "SIGNAL_RECEIVE_RECOG",
105 "SIGNAL_DIGIT_PAUSE",
111 /* ss5 signal timers (in samples) */
112 #define SS5_TIMER_AFTER_SIGNAL (100*8) /* wait after signal is terminated */
113 #define SS5_TIMER_KP (100*8) /* duration of KP1 or KP2 digit */
114 #define SS5_TIMER_DIGIT (55*8) /* duration of all other digits */
115 #define SS5_TIMER_PAUSE (55*8) /* pause between digits */
116 #define SS5_TIMER_FORWARD (850*8) /* forward transfer length */
117 #define SS5_TIMER_RECOG_SEIZE (40*8) /* recognition time of seizing / proceed-to-send signal */
118 #define SS5_TIMER_RECOG_OTHER (125*8) /* recognition time of all other f1/f2 signals */
119 #define SS5_TIMER_SIGNAL_LOSS (15*8) /* minimum time of signal loss for a continous signal */
120 #define SS5_TIMER_DOUBLE_SEIZE (850*8) /* double seize length */
121 #define SS5_TIMER_RELEASE_GUARD (850*8) /* be sure to release after clear-forward */
122 #define SS5_TIMER_RELEASE_MAX (2000*8)/* maximum time for release guard to prevent 'double-releasing' */
123 #define SS5_TIMER_RELEASE_DELAY (4000*8)/* wait after release guard to prevent ping-pong */
124 #define BELL_TIMER_BREAK (50*8) /* loop open, tone */
125 #define BELL_TIMER_MAKE (50*8) /* loop closed, no tone */
126 #define BELL_TIMER_PAUSE (800*8) /* interdigit delay */
127 #define BELL_TIMER_RECOG_HANGUP (200*8) /* time to recognize hangup */
128 #define BELL_TIMER_RECOG_END (300*8) /* recognize end of digit */
131 #define SS5_TIMER_OVERLAP 10 /* timeout for overlap digits received on incomming exchange */
132 #define SS5_TIMER_RELEASE 20 /* timeout after disconnect on incomming exchange */
138 enum { /* even values are indications, odd values are requests */
141 SS5_PROCEED_TO_SEND_IND,
142 SS5_PROCEED_TO_SEND_REQ,
149 SS5_CLEAR_FORWARD_IND,
150 SS5_CLEAR_FORWARD_REQ,
151 SS5_RELEASE_GUARD_IND,
152 SS5_RELEASE_GUARD_REQ,
155 SS5_DOUBLE_SEIZURE_IND,
156 SS5_DOUBLE_SEIZURE_REQ,
159 SS5_FORWARD_TRANSFER_IND,
160 SS5_FORWARD_TRANSFER_REQ,
164 static struct isdn_message {
168 {"SEIZING RECEIVED", SS5_SEIZING_IND},
169 {"SEIZING SENDING", SS5_SEIZING_REQ},
170 {"PROCEED-TO-SEND RECEIVED", SS5_PROCEED_TO_SEND_IND},
171 {"PROCEED-TO-SEND SENDING", SS5_PROCEED_TO_SEND_REQ},
172 {"BUSY-FLASH RECEIVED", SS5_BUSY_FLASH_IND},
173 {"BUSY-FLASH SENDING", SS5_BUSY_FLASH_REQ},
174 {"ANSWER RECEIVED", SS5_ANSWER_IND},
175 {"ANSWER SENDING", SS5_ANSWER_REQ},
176 {"CLEAR-BACK RECEIVED", SS5_CLEAR_BACK_IND},
177 {"CLEAR-BACK SENDING", SS5_CLEAR_BACK_REQ},
178 {"CLEAR-FORWARD RECEIVED", SS5_CLEAR_FORWARD_IND},
179 {"CLEAR-FORWARD SENDING", SS5_CLEAR_FORWARD_REQ},
180 {"RELEASE-GUARD RECEIVED", SS5_RELEASE_GUARD_IND},
181 {"RELEASE-GUARD SENDING", SS5_RELEASE_GUARD_REQ},
182 {"ACKNOWLEDGE RECEIVED", SS5_ACKNOWLEDGE_IND},
183 {"ACKNOWLEDGE SENDING", SS5_ACKNOWLEDGE_REQ},
184 {"DOUBLE-SEIZURE RECEIVED", SS5_DOUBLE_SEIZURE_IND},
185 {"DOUBLE-SEIZURE SENDING", SS5_DOUBLE_SEIZURE_REQ},
186 {"DIALING RECEIVED", SS5_DIALING_IND},
187 {"DIALING SENDING", SS5_DIALING_REQ},
188 {"FORWARD-TRANSFER RECEIVED", SS5_FORWARD_TRANSFER_IND},
189 {"FORWARD-TRANSFER SENDING", SS5_FORWARD_TRANSFER_REQ},
190 {"TIMEOUT", SS5_TIMEOUT_IND},
191 {"QUALITY REPORT", SS5_QUALITY_IND},
194 static void ss5_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int channel)
199 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
200 /* select message and primitive text */
202 while(ss5_message[i].name) {
203 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
204 if (ss5_message[i].value == msg) {
205 SCPY(msgtext, ss5_message[i].name);
211 /* init trace with given values */
212 start_trace(mISDNport?mISDNport->portnum:-1,
213 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
214 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
215 port?port->p_dialinginfo.id:NULL,
216 (msg&1)?DIRECTION_OUT:DIRECTION_IN,
218 port?port->p_serial:0,
220 add_trace("channel", NULL, "%d", channel);
221 switch (port->p_type) {
222 case PORT_TYPE_SS5_OUT:
223 add_trace("state", NULL, "outgoing");
225 case PORT_TYPE_SS5_IN:
226 add_trace("state", NULL, "incomming");
229 add_trace("state", NULL, "idle");
236 * changes release tone into silence
237 * this makes the line sound more authentic
239 void Pss5::set_tone(const char *dir, const char *name)
241 if (name && !strcmp(name, "cause_10"))
244 PmISDN::set_tone(dir, name);
248 * creation of static channels
250 void ss5_create_channel(struct mISDNport *mISDNport, int i)
254 struct port_settings port_settings;
256 SPRINT(portname, "%s-%d", mISDNport->name, i+1);
258 memset(&port_settings, 0, sizeof(port_settings));
259 SCPY(port_settings.tones_dir, options.tones_dir);
261 ss5port = new Pss5(PORT_TYPE_SS5_IDLE, mISDNport, portname, &port_settings, mISDNport->ifport->interface, i + (i>=15) + 1, 1, B_MODE_TRANSPARENT);
263 FATAL("No memory for Pss5 class.\n");
264 if (!ss5port->p_m_b_channel)
265 FATAL("No bchannel on given index.\n");
267 /* connect channel */
268 bchannel_event(mISDNport, ss5port->p_m_b_index, B_EVENT_USE);
274 * hunt for a free line
275 * this function returns a port object in idle state.
277 class Pss5 *ss5_hunt_line(struct mISDNport *mISDNport)
281 class Pss5 *ss5port = NULL;
282 struct select_channel *selchannel;
284 PDEBUG(DEBUG_SS5, "Entered name=%s\n", mISDNport->name);
285 selchannel = mISDNport->ifport->out_channel;
287 switch(selchannel->channel) {
288 case CHANNEL_FREE: /* free channel */
289 case CHANNEL_ANY: /* any channel */
290 for (i = 0; i < mISDNport->b_num; i++) {
291 port = mISDNport->b_port[i];
292 PDEBUG(DEBUG_SS5, "Checking port %p on index\n", port, i);
295 if (port->p_type == PORT_TYPE_SS5_IN || port->p_type == PORT_TYPE_SS5_OUT)
296 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because port not idle type.\n",
298 if (port->p_type != PORT_TYPE_SS5_IDLE)
300 ss5port = (class Pss5 *)port;
301 /* is really idle ? */
302 if (ss5port->p_state == PORT_STATE_IDLE
303 && ss5port->p_m_s_state == SS5_STATE_IDLE)
305 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because p_state=%d, ss5_state=%d.\n",
306 mISDNport->name, i, ss5port->p_state,ss5port->p_m_s_state);
308 PDEBUG(DEBUG_SS5, "no free interface\n");
315 if (selchannel->channel<1 || selchannel->channel==16)
317 i = selchannel->channel-1-(selchannel->channel>=17);
318 if (i >= mISDNport->b_num)
320 port = mISDNport->b_port[i];
323 if (port->p_type == PORT_TYPE_SS5_IN || port->p_type == PORT_TYPE_SS5_OUT)
324 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because port not idle type.\n",
326 if (port->p_type != PORT_TYPE_SS5_IDLE)
328 ss5port = (class Pss5 *)port;
329 /* is really idle ? */
330 if (ss5port->p_state == PORT_STATE_IDLE
331 && ss5port->p_m_s_state == SS5_STATE_IDLE)
333 PDEBUG(DEBUG_SS5, "Checking port %s: channel %d not available, because p_state=%d, ss5_state=%d.\n",
334 mISDNport->name, i, ss5port->p_state,ss5port->p_m_s_state);
336 selchannel = selchannel->next;
338 PDEBUG(DEBUG_SS5, "no free interface in channel list\n");
342 static int timeout(struct lcr_timer *timer, void *instance, int i)
344 class Pss5 *ss5 = (class Pss5 *)instance;
346 ss5->register_timeout();
351 int queue_event(struct lcr_work *work, void *instance, int index)
353 class Pss5 *ss5port = (class Pss5 *)instance;
355 ss5port->process_queue();
363 Pss5::Pss5(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, struct interface *interface, int channel, int exclusive, int mode) : PmISDN(type, mISDNport, portname, settings, interface, channel, exclusive, mode)
365 p_callerinfo.itype = (mISDNport->ifport->interface->extension)?INFO_ITYPE_ISDN_EXTENSION:INFO_ITYPE_ISDN;
366 p_m_s_state = SS5_STATE_IDLE;
367 p_m_s_signal = SS5_SIGNAL_NULL;
368 p_m_s_dial[0] = '\0';
370 p_m_s_pulsecount = 0;
371 p_m_s_last_digit = ' ';
372 p_m_s_last_digit_used = ' ';
373 p_m_s_signal_loss = 0;
374 p_m_s_decoder_count = 0;
375 //p_m_s_decoder_buffer;
377 p_m_s_quality_value = 0;
378 p_m_s_quality_count = 0;
380 memset(&p_m_s_queue, 0, sizeof(p_m_s_queue));
381 add_work(&p_m_s_queue, queue_event, this, 0);
382 p_m_s_queued_signal = 0;
383 memset(p_m_s_delay_digits, ' ', sizeof(p_m_s_delay_digits));
384 memset(p_m_s_delay_mute, ' ', sizeof(p_m_s_delay_mute));
385 memset(&p_m_s_timer, 0, sizeof(p_m_s_timer));
386 add_timer(&p_m_s_timer, timeout, this, 0);
388 /* turn on signalling receiver */
391 PDEBUG(DEBUG_SS5, "Created new mISDNPort(%s). Currently %d objects use.\n", portname, mISDNport->use);
400 del_timer(&p_m_s_timer);
401 del_work(&p_m_s_queue);
408 void Pss5::register_timeout(void)
410 ss5_trace_header(p_m_mISDNport, this, SS5_TIMEOUT_IND, p_m_b_channel);
413 case PORT_STATE_IN_SETUP:
414 PDEBUG(DEBUG_SS5, "%s: timeout after seize\n", p_name);
415 do_release(CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL, SS5_CLEAR_BACK_REQ);
417 case PORT_STATE_IN_OVERLAP:
418 PDEBUG(DEBUG_SS5, "%s: timeout during dialing\n", p_name);
419 do_release(CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL, SS5_CLEAR_BACK_REQ);
421 case PORT_STATE_OUT_DISCONNECT:
422 PDEBUG(DEBUG_SS5, "%s: timeout after sending busy flash / clear forward\n", p_name);
423 /* always send clear forward, because release guard only works as a reply to clear forward */
424 do_release(CAUSE_UNSPECIFIED, LOCATION_PRIVATE_LOCAL, SS5_CLEAR_FORWARD_REQ);
432 void Pss5::new_state(int state)
435 case PORT_STATE_IN_SETUP:
436 case PORT_STATE_IN_OVERLAP:
437 if (SS5_TIMER_OVERLAP == 0)
439 PDEBUG(DEBUG_SS5, "%s: starting timeout timer with %d seconds\n", p_name, SS5_TIMER_OVERLAP);
440 schedule_timer(&p_m_s_timer, SS5_TIMER_OVERLAP, 0);
442 case PORT_STATE_OUT_DISCONNECT:
443 if (p_type != PORT_TYPE_SS5_IN)
445 if (SS5_TIMER_RELEASE == 0)
447 PDEBUG(DEBUG_SS5, "%s: starting timeout timer with %d seconds\n", p_name, SS5_TIMER_RELEASE);
448 schedule_timer(&p_m_s_timer, SS5_TIMER_RELEASE, 0);
451 PDEBUG(DEBUG_SS5, "%s: stopping timeout timer\n", p_name);
452 unsched_timer(&p_m_s_timer);
454 Port::new_state(state);
460 void Pss5::_new_ss5_state(int state, const char *func, int line)
462 PDEBUG(DEBUG_SS5, "%s(%s:%d): changing SS5 state from %s to %s\n", p_name, func, line, ss5_state_name[p_m_s_state], ss5_state_name[state]);
464 p_m_s_signal = SS5_SIGNAL_NULL;
466 if (p_m_s_state == SS5_STATE_IDLE && p_m_s_queued_signal)
467 trigger_work(&p_m_s_queue);
470 void Pss5::process_queue(void)
472 /* when clear forward is scheduled, we abort current state */
473 if (p_m_s_queued_signal == SS5_CLEAR_FORWARD_REQ)
474 new_ss5_state(SS5_STATE_IDLE);
476 /* if there is an ongoing signal, we wait until done */
477 if (p_m_s_state != SS5_STATE_IDLE)
480 /* this shoud not happen */
481 if (!p_m_s_queued_signal)
485 ss5_trace_header(p_m_mISDNport, this, p_m_s_queued_signal, p_m_b_channel);
487 switch(p_m_s_queued_signal) {
490 p_m_s_queued_signal = 0; /* prevent trigger loop */
491 start_signal(SS5_STATE_ANSWER);
493 case SS5_BUSY_FLASH_REQ:
495 p_m_s_queued_signal = 0; /* prevent trigger loop */
496 start_signal(SS5_STATE_BUSY_FLASH);
498 case SS5_CLEAR_BACK_REQ:
500 p_m_s_queued_signal = 0; /* prevent trigger loop */
501 start_signal(SS5_STATE_CLEAR_BACK);
503 case SS5_CLEAR_FORWARD_REQ:
505 p_m_s_queued_signal = 0; /* prevent trigger loop */
506 start_signal(SS5_STATE_CLEAR_FORWARD);
509 PERROR("unhandled event %d\n", p_m_s_queued_signal);
510 p_m_s_queued_signal = 0;
514 void Pss5::_new_ss5_signal(int signal, const char *func, int line)
517 PDEBUG(DEBUG_SS5, "%s: changing SS5 signal state from %s to %s\n", p_name, ss5_signal_name[p_m_s_signal], ss5_signal_name[signal]);
519 PDEBUG(DEBUG_SS5, "%s: changing SS5 signal state to %s\n", p_name, ss5_signal_name[signal]);
520 p_m_s_signal = signal;
525 * signalling receiver
527 * this function will be called for every audio received.
529 void Pss5::inband_receive(unsigned char *buffer, int len)
531 int count = 0, tocopy, space;
537 /* how much to copy ? */
538 tocopy = len - count;
539 space = SS5_DECODER_NPOINTS - p_m_s_decoder_count;
541 FATAL("p_m_s_decoder_count overflows\n");
545 memcpy(p_m_s_decoder_buffer+p_m_s_decoder_count, buffer+count, tocopy);
546 p_m_s_decoder_count += tocopy;
548 /* decoder buffer not completely filled ? */
552 /* decode one frame */
553 digit = ss5_decode(p_m_s_decoder_buffer, SS5_DECODER_NPOINTS, &quality);
554 p_m_s_decoder_count = 0;
556 /* indicate quality of received digit */
557 if ((p_m_mISDNport->ss5 & SS5_FEATURE_QUALITY)) {
559 p_m_s_quality_value += quality;
560 p_m_s_quality_count++;
561 } else if (p_m_s_quality_count) {
562 ss5_trace_header(p_m_mISDNport, this, SS5_QUALITY_IND, p_m_b_channel);
563 add_trace("digit", NULL, "%c", p_m_s_last_digit);
564 quality = p_m_s_quality_value/p_m_s_quality_count;
565 add_trace("quality", NULL, "%3d%%", (int)(quality*100.0));
567 p_m_s_quality_value = 0;
568 p_m_s_quality_count = 0;
573 if (p_m_s_last_digit != digit && digit != ' ')
574 PDEBUG(DEBUG_SS5, "%s: detecting signal '%c' start (state=%s signal=%s)\n", p_name, digit, ss5_state_name[p_m_s_state], ss5_signal_name[p_m_s_signal]);
577 /* ignore short loss of signal, or change within one decode window */
578 if (p_m_s_signal_loss) {
581 if (p_m_s_signal_loss >= SS5_TIMER_SIGNAL_LOSS) {
583 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost too long\n", p_name, p_m_s_last_digit);
585 /* long enough, we stop loss-timer */
586 p_m_s_signal_loss = 0;
588 /* not long enough, so we use last signal */
589 p_m_s_signal_loss += SS5_DECODER_NPOINTS;
590 digit = p_m_s_last_digit;
593 /* signal is back, we stop timer and store */
595 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost, but continues with '%c'\n", p_name, p_m_s_last_digit, digit);
597 p_m_s_signal_loss = 0;
598 p_m_s_last_digit = digit;
601 if (p_m_s_last_digit != ' ' && digit == ' ') {
603 PDEBUG(DEBUG_SS5, "%s: signal '%c' lost\n", p_name, p_m_s_last_digit);
605 /* restore last digit until signal is really lost */
606 p_m_s_last_digit = digit;
607 /* starting to loose signal */
608 p_m_s_signal_loss = SS5_DECODER_NPOINTS;
609 } else if (digit != p_m_s_last_digit) {
610 /* digit changes, but we keep old digit until it is detected twice */
612 PDEBUG(DEBUG_SS5, "%s: signal '%c' changes to '%c'\n", p_name, p_m_s_last_digit, digit);
614 p_m_s_last_digit = digit;
615 digit = p_m_s_last_digit_used;
617 /* storing last signal, in case it is lost */
618 p_m_s_last_digit = digit;
621 p_m_s_last_digit_used = digit;
623 /* delay decoded tones */
624 if ((p_m_mISDNport->ss5 & SS5_FEATURE_DELAY)) {
626 memcpy(p_m_s_delay_digits, p_m_s_delay_digits+1, sizeof(p_m_s_delay_digits)-1);
628 p_m_s_delay_digits[sizeof(p_m_s_delay_digits)-1] = digit;
630 digit = p_m_s_delay_digits[0];
633 /* clear forward is always recognized */
634 if (digit == 'C' && p_m_s_state != SS5_STATE_CLEAR_FORWARD && p_m_s_state != SS5_STATE_RELEASE_GUARD) {
636 case PORT_TYPE_SS5_OUT:
637 PDEBUG(DEBUG_SS5, "%s: received release-guard, waiting for recognition\n", p_name);
639 case PORT_TYPE_SS5_IN:
640 PDEBUG(DEBUG_SS5, "%s: received clear-forward, waiting for recognition\n", p_name);
643 PDEBUG(DEBUG_SS5, "%s: received clear-forward in idle state, waiting for recognition\n", p_name);
646 new_ss5_state(SS5_STATE_RELEASE_GUARD);
647 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
650 switch(p_m_s_state) {
652 /* seizing only recognized in port idle state */
653 if (p_state == PORT_STATE_IDLE) {
657 PDEBUG(DEBUG_SS5, "%s: received seize, waiting for recognition\n", p_name);
658 p_type = PORT_TYPE_SS5_IN;
659 new_ss5_state(SS5_STATE_PROCEED_TO_SEND);
660 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
666 if (p_type != PORT_TYPE_SS5_OUT)
668 PDEBUG(DEBUG_SS5, "%s: received answer, waiting for recognition\n", p_name);
669 new_ss5_state(SS5_STATE_ACK_ANSWER);
670 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
675 if (p_type == PORT_TYPE_SS5_IN) {
676 if ((p_m_mISDNport->ss5 & SS5_FEATURE_BELL)) {
677 new_ss5_state(SS5_STATE_DIAL_IN_PULSE); /* go pulsing state */
678 new_ss5_signal(SS5_SIGNAL_PULSE_OFF); /* we are starting with pulse off */
679 p_m_s_pulsecount = 0; /* init pulse counter */
680 p_m_s_dial[0] = '\0'; /* init dial string */
681 pulse_ind(1); /* also inits recogition timer... */
684 PDEBUG(DEBUG_SS5, "%s: received forward-transfer, waiting for recognition\n", p_name);
685 /* forward transfer on incomming lines */
686 new_ss5_state(SS5_STATE_FORWARD_TRANSFER);
687 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
691 if (p_state == PORT_STATE_CONNECT) {
692 PDEBUG(DEBUG_SS5, "%s: received clear-back, waiting for recognition\n", p_name);
693 new_ss5_state(SS5_STATE_ACK_CLEAR_BACK);
695 PDEBUG(DEBUG_SS5, "%s: received busy-flash, waiting for recognition\n", p_name);
696 new_ss5_state(SS5_STATE_ACK_BUSY_FLASH);
698 new_ss5_signal(SS5_SIGNAL_RECEIVE_RECOG);
702 /* dialing only allowed in incomming setup state */
703 if (p_state == PORT_STATE_IN_SETUP) {
704 if (!strchr("1234567890*#abc", digit))
706 PDEBUG(DEBUG_SS5, "%s: received dialing start with '%c'\n", p_name, digit);
707 new_ss5_state(SS5_STATE_DIAL_IN);
708 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
709 p_m_s_dial[0] = '\0';
714 /* sending seizing */
715 case SS5_STATE_SEIZING:
716 switch (p_m_s_signal) {
717 case SS5_SIGNAL_SEND_ON:
718 if (digit == 'A') { /* double seize */
719 PDEBUG(DEBUG_SS5, "%s: received double seizure\n", p_name, digit);
720 double_seizure_ind();
724 PDEBUG(DEBUG_SS5, "%s: received answer to outgoing seize, waiting for recognition\n", p_name);
725 /* set recognition timer */
726 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
730 case SS5_SIGNAL_SEND_ON_RECOG:
731 if (digit != 'B') { /* seize */
732 PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize is gone before recognition\n", p_name);
733 new_ss5_signal(SS5_SIGNAL_SEND_ON);
734 // p_m_s_sample_nr = 0;
738 p_m_s_recog += SS5_DECODER_NPOINTS;
739 if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
741 PDEBUG(DEBUG_SS5, "%s: answer to outgoing seize recognized, turning off, waiting for recognition\n", p_name);
742 new_ss5_signal(SS5_SIGNAL_SEND_OFF);
744 case SS5_SIGNAL_SEND_OFF:
747 PDEBUG(DEBUG_SS5, "%s: outgoing seizure is complete, proceeding...\n", p_name);
748 new_ss5_state(SS5_STATE_IDLE);
749 proceed_to_send_ind();
753 /* answer to seize */
754 case SS5_STATE_PROCEED_TO_SEND:
755 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
757 PDEBUG(DEBUG_SS5, "%s: incomming seize is gone before recognition\n", p_name);
758 new_ss5_state(SS5_STATE_IDLE);
759 p_type = PORT_TYPE_SS5_IDLE;
762 p_m_s_recog += SS5_DECODER_NPOINTS;
763 if (p_m_s_recog < SS5_TIMER_RECOG_SEIZE)
765 PDEBUG(DEBUG_SS5, "%s: incomming seize is recognized, responding...\n", p_name);
766 new_ss5_signal(SS5_SIGNAL_RECEIVE);
772 PDEBUG(DEBUG_SS5, "%s: incomming seize is gone after responding\n", p_name);
773 new_ss5_state(SS5_STATE_IDLE);
777 /* sending busy flash / answer / clear-back */
778 case SS5_STATE_BUSY_FLASH:
779 case SS5_STATE_ANSWER:
780 case SS5_STATE_CLEAR_BACK:
781 switch (p_m_s_signal) {
782 case SS5_SIGNAL_SEND_ON:
784 PDEBUG(DEBUG_SS5, "%s: received acknowledge, waiting for recognition\n", p_name);
785 /* set recognition timer */
786 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
790 case SS5_SIGNAL_SEND_ON_RECOG:
792 PDEBUG(DEBUG_SS5, "%s: acknowledge is gone before recognition\n", p_name);
793 new_ss5_signal(SS5_SIGNAL_SEND_ON);
794 // p_m_s_sample_nr = 0;
798 p_m_s_recog += SS5_DECODER_NPOINTS;
799 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
801 PDEBUG(DEBUG_SS5, "%s: acknowledge recognized, turning off, waiting for recognition\n", p_name);
802 new_ss5_signal(SS5_SIGNAL_SEND_OFF);
804 case SS5_SIGNAL_SEND_OFF:
807 PDEBUG(DEBUG_SS5, "%s: outgoing signal is complete\n", p_name);
808 new_ss5_state(SS5_STATE_IDLE);
812 /* answer to busy-flash / clear back */
813 case SS5_STATE_ACK_BUSY_FLASH:
814 case SS5_STATE_ACK_CLEAR_BACK:
815 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
817 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone before recognition\n", p_name);
818 new_ss5_state(SS5_STATE_IDLE);
821 p_m_s_recog += SS5_DECODER_NPOINTS;
822 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
824 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is recognized, responding...\n", p_name);
825 new_ss5_signal(SS5_SIGNAL_RECEIVE);
831 PDEBUG(DEBUG_SS5, "%s: incomming clear-back/busy-flash is gone after responding\n", p_name);
832 new_ss5_state(SS5_STATE_IDLE);
833 if (p_m_s_state == SS5_STATE_ACK_BUSY_FLASH)
839 /* answer to answer */
840 case SS5_STATE_ACK_ANSWER:
841 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
843 PDEBUG(DEBUG_SS5, "%s: incomming answer is gone before recognition\n", p_name);
844 new_ss5_state(SS5_STATE_IDLE);
847 p_m_s_recog += SS5_DECODER_NPOINTS;
848 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
850 PDEBUG(DEBUG_SS5, "%s: incomming answer is recognized, responding...\n", p_name);
851 new_ss5_signal(SS5_SIGNAL_RECEIVE);
857 PDEBUG(DEBUG_SS5, "%s: incomming answer is gone after responding\n", p_name);
858 new_ss5_state(SS5_STATE_IDLE);
862 /* sending clear-forward */
863 case SS5_STATE_CLEAR_FORWARD:
864 switch (p_m_s_signal) {
865 case SS5_SIGNAL_SEND_ON:
867 PDEBUG(DEBUG_SS5, "%s: received answer to clear-forward, waiting for recognition\n", p_name);
868 /* set recognition timer */
869 new_ss5_signal(SS5_SIGNAL_SEND_ON_RECOG);
873 case SS5_SIGNAL_SEND_ON_RECOG:
875 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is gone before recognition\n", p_name);
876 new_ss5_signal(SS5_SIGNAL_SEND_ON);
877 // p_m_s_sample_nr = 0;
881 p_m_s_recog += SS5_DECODER_NPOINTS;
882 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
884 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward recognized, turning off, waiting for recognition\n", p_name);
885 new_ss5_signal(SS5_SIGNAL_SEND_OFF);
887 case SS5_SIGNAL_SEND_OFF:
889 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
890 new_state(PORT_STATE_IDLE);
895 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward is complete\n", p_name);
897 new_ss5_signal(SS5_SIGNAL_DELAY);
898 p_m_s_recog = 0; /* use recog to delay */
899 PDEBUG(DEBUG_SS5, "%s: answer to clear-forward on outgoing interface starting delay to prevent ping-pong\n", p_name);
901 case SS5_SIGNAL_DELAY:
903 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward answer, continue with seize\n", p_name);
904 new_state(PORT_STATE_IDLE);
907 p_m_s_recog += SS5_DECODER_NPOINTS;
908 if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
910 PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
911 new_ss5_state(SS5_STATE_IDLE);
912 new_state(PORT_STATE_IDLE);
913 p_type = PORT_TYPE_SS5_IDLE;
917 /* answer to release-guard*/
918 case SS5_STATE_RELEASE_GUARD:
919 switch (p_m_s_signal) {
920 case SS5_SIGNAL_RECEIVE_RECOG:
922 if (p_type == PORT_TYPE_SS5_OUT)
923 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone before recognition\n", p_name);
925 PDEBUG(DEBUG_SS5, "%s: incomming clear forward is gone before recognition\n", p_name);
926 new_ss5_state(SS5_STATE_IDLE);
929 p_m_s_recog += SS5_DECODER_NPOINTS;
930 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
932 if (p_type == PORT_TYPE_SS5_OUT)
933 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is recognized, responding...\n", p_name);
935 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is recognized, responding...\n", p_name);
936 new_state(PORT_STATE_RELEASE);
937 new_ss5_signal(SS5_SIGNAL_RECEIVE);
941 case SS5_SIGNAL_RECEIVE:
943 || p_m_s_sample_nr < 256) /* small hack to keep answer for at least some time */
947 PDEBUG(DEBUG_SS5, "%s: received seize right after clear-forward is received\n", p_name);
948 new_state(PORT_STATE_IDLE);
952 /* if clear forward stops right after recognition on the incomming side,
953 * the release guard signal stops and may be too short to be recognized at the outgoing side.
954 * to prevent this, a timer can be started to force a release guard that is long
955 * enough to be recognized on the outgoing side.
956 * this will prevent braking via blueboxing (other tricks may still be possible).
958 if ((p_m_mISDNport->ss5 & SS5_FEATURE_RELEASEGUARDTIMER)
959 && p_m_s_sample_nr < SS5_TIMER_RELEASE_GUARD)
961 if (p_type == PORT_TYPE_SS5_OUT)
962 PDEBUG(DEBUG_SS5, "%s: incomming release-guard is gone after responding\n", p_name);
964 PDEBUG(DEBUG_SS5, "%s: incomming clear-forward is gone after responding\n", p_name);
965 if (p_type == PORT_TYPE_SS5_OUT) {
967 new_ss5_signal(SS5_SIGNAL_DELAY);
968 p_m_s_recog = 0; /* use recog to delay */
969 PDEBUG(DEBUG_SS5, "%s: incomming release-guard on outgoing interface starting delay to prevent ping-pong\n", p_name);
972 new_ss5_state(SS5_STATE_IDLE);
975 case SS5_SIGNAL_DELAY:
977 PDEBUG(DEBUG_SS5, "%s: received seize right after release guard is gone, continue with seize\n", p_name);
978 new_state(PORT_STATE_IDLE);
981 p_m_s_recog += SS5_DECODER_NPOINTS;
982 if (p_m_s_recog < SS5_TIMER_RELEASE_DELAY)
984 PDEBUG(DEBUG_SS5, "%s: delay time over, going idle\n", p_name);
985 new_ss5_state(SS5_STATE_IDLE);
986 new_state(PORT_STATE_IDLE);
987 p_type = PORT_TYPE_SS5_IDLE;
991 /* wait time to recognize forward transfer */
992 case SS5_STATE_FORWARD_TRANSFER:
993 if (p_m_s_signal == SS5_SIGNAL_RECEIVE_RECOG) {
995 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone before recognition\n", p_name);
996 new_ss5_state(SS5_STATE_IDLE);
999 p_m_s_recog += SS5_DECODER_NPOINTS;
1000 if (p_m_s_recog < SS5_TIMER_RECOG_OTHER)
1002 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is recognized, responding, if BELL feature was selected...\n", p_name);
1003 new_ss5_signal(SS5_SIGNAL_RECEIVE);
1005 p_m_s_sample_nr = 0;
1011 PDEBUG(DEBUG_SS5, "%s: incomming forward-transfer is gone after recognition\n", p_name);
1012 new_ss5_state(SS5_STATE_IDLE);
1013 forward_transfer_ind();
1017 /* dialing is received */
1018 case SS5_STATE_DIAL_IN:
1019 if (strchr("1234567890*#abc", digit)) {
1020 if (p_m_s_signal != SS5_SIGNAL_DIGIT_PAUSE)
1022 PDEBUG(DEBUG_SS5, "%s: incomming digit '%c' is recognized\n", p_name, digit);
1023 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1026 if (p_m_s_signal != SS5_SIGNAL_DIGIT_ON)
1028 PDEBUG(DEBUG_SS5, "%s: incomming digit is gone after recognition\n", p_name);
1029 new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1032 case SS5_STATE_DIAL_IN_PULSE:
1040 /* update mute on RX */
1041 if ((p_m_mISDNport->ss5 & SS5_FEATURE_MUTE_RX)) {
1043 memcpy(p_m_s_delay_mute, p_m_s_delay_mute+1, sizeof(p_m_s_delay_mute)-1);
1044 p_m_s_delay_mute[sizeof(p_m_s_delay_mute)-1] = digit;
1045 mdigit = p_m_s_delay_mute[0];
1046 if (mdigit == 'A' || mdigit == 'B' || mdigit == 'C')
1051 if ((p_m_mISDNport->ss5 & SS5_FEATURE_MUTE_TX)) {
1052 switch(p_m_s_signal) {
1053 case SS5_SIGNAL_SEND_ON_RECOG:
1054 case SS5_SIGNAL_RECEIVE_RECOG:
1055 if (p_m_s_recog > SS5_DELAY_MUTE)
1058 case SS5_SIGNAL_SEND_OFF:
1059 case SS5_SIGNAL_RECEIVE:
1065 /* apply mute state */
1076 /* something more to decode ? */
1085 * this function generates tones and assembles dial string with digits and pause
1086 * the result is sent to mISDN. it uses the ss5_encode() function.
1087 * except for dialing and forward-transfer, tones are continuous and will not change state.
1089 int Pss5::inband_send(unsigned char *buffer, int len)
1091 int count = 0; /* sample counter */
1096 switch(p_m_s_state) {
1097 /* turn off transmitter in idle state */
1098 case SS5_STATE_IDLE:
1102 case SS5_STATE_SEIZING:
1103 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1104 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1106 duration = -1; /* continuous */
1109 /* how much samples do we have left */
1113 tocode = duration - p_m_s_sample_nr;
1117 ss5_encode(buffer, tocode, digit, p_m_s_sample_nr);
1118 /* increase counters */
1119 p_m_s_sample_nr += tocode;
1122 /* more to come ? */
1123 if (duration > 0 && p_m_s_sample_nr >= duration) {
1124 PDEBUG(DEBUG_SS5, "%s: sending tone '%c' complete, starting delay\n", p_name, digit);
1125 if (p_m_s_state == SS5_STATE_DOUBLE_SEIZE) {
1126 do_release(CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL, SS5_CLEAR_FORWARD_REQ);
1129 new_ss5_state(SS5_STATE_DELAY);
1130 p_m_s_sample_nr = 0;
1133 /* stop sending if too long */
1134 if (duration < 0 && p_m_s_sample_nr >= SS5_TIMER_MAX_SIGNAL) {
1135 PDEBUG(DEBUG_SS5, "%s: sending tone '%c' too long, stopping\n", p_name, digit);
1141 /* incomming seizing */
1142 case SS5_STATE_PROCEED_TO_SEND:
1143 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1145 duration = -1; /* continuous */
1149 case SS5_STATE_BUSY_FLASH:
1150 case SS5_STATE_CLEAR_BACK:
1151 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1152 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1154 duration = -1; /* continuous */
1158 case SS5_STATE_ANSWER:
1159 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1160 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1162 duration = -1; /* continuous */
1166 case SS5_STATE_ACK_BUSY_FLASH:
1167 case SS5_STATE_ACK_ANSWER:
1168 case SS5_STATE_ACK_CLEAR_BACK:
1169 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1171 duration = -1; /* continuous */
1176 case SS5_STATE_FORWARD_TRANSFER:
1177 if (p_m_s_signal != SS5_SIGNAL_RECEIVE)
1179 /* only on bell systems continue and acknowledge tone */
1180 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1182 duration = SS5_TIMER_FORWARD;
1187 case SS5_STATE_CLEAR_FORWARD:
1188 if (p_m_s_signal != SS5_SIGNAL_SEND_ON
1189 && p_m_s_signal != SS5_SIGNAL_SEND_ON_RECOG)
1191 duration = -1; /* continuous */
1195 case SS5_STATE_RELEASE_GUARD:
1196 if (p_m_s_signal != SS5_SIGNAL_RECEIVE
1197 && p_m_s_signal != SS5_SIGNAL_DELAY)
1199 /* prevent from sending release guard too long */
1200 if (p_m_s_sample_nr >= SS5_TIMER_RELEASE_MAX)
1202 duration = -1; /* continuous */
1206 case SS5_STATE_DIAL_OUT:
1207 if ((p_m_mISDNport->ss5 & SS5_FEATURE_PULSEDIALING))
1208 count = inband_dial_pulse(buffer, len, count);
1210 count = inband_dial_mf(buffer, len, count);
1214 case SS5_STATE_DELAY:
1215 tosend = len - count;
1216 memset(buffer+count, audio_s16_to_law[0], tosend);
1217 p_m_s_sample_nr += tosend;
1219 if (p_m_s_sample_nr >= SS5_TIMER_AFTER_SIGNAL) {
1220 PDEBUG(DEBUG_SS5, "%s: delay done, ready for next signal\n", p_name);
1221 new_ss5_state(SS5_STATE_IDLE);
1226 case SS5_STATE_DOUBLE_SEIZE:
1227 duration = SS5_TIMER_DOUBLE_SEIZE;
1231 /* nothing to send */
1233 PERROR("inband signalling is turned on, but no signal is processed here.");
1234 new_ss5_state(SS5_STATE_IDLE);
1239 /* return (partly) filled buffer */
1244 int Pss5::inband_dial_mf(unsigned char *buffer, int len, int count)
1252 * p_m_s_dial: digits to be dialed
1253 * p_m_s_digit_i: current digit counter
1254 * p_m_s_signal: current signal state
1255 * p_m_s_sample_nr: current sample number
1258 /* get digit and duration */
1259 digit = p_m_s_dial[p_m_s_digit_i];
1260 if (!digit) { /* if end of string reached */
1261 new_ss5_state(SS5_STATE_DELAY);
1262 p_m_s_sample_nr = 0;
1265 if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1266 if (!p_m_s_digit_i) // first digit
1267 duration = SS5_TIMER_KP;
1269 duration = SS5_TIMER_DIGIT;
1271 duration = SS5_TIMER_PAUSE;
1273 /* end of digit/pause ? */
1274 if (p_m_s_sample_nr >= duration) {
1275 p_m_s_sample_nr = 0;
1276 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE)
1277 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1279 new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1284 /* how much samples do we have left */
1285 tosend = len - count;
1286 tocode = duration - p_m_s_sample_nr;
1288 FATAL("sample_nr overrun duration");
1289 if (tosend < tocode)
1291 /* digit or pause */
1292 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1293 memset(buffer+count, audio_s16_to_law[0], tocode);
1294 // printf("coding pause %d bytes\n", tocode);
1296 ss5_encode(buffer+count, tocode, digit, p_m_s_sample_nr);
1297 // printf("coding digit '%c' %d bytes\n", digit, tocode);
1299 /* increase counters */
1300 p_m_s_sample_nr += tocode;
1302 /* can we take more ? */
1309 int Pss5::inband_dial_pulse(unsigned char *buffer, int len, int count)
1317 * p_m_s_dial: digits to be dialed
1318 * p_m_s_digit_i: current digit counter
1319 * p_m_s_signal: current signal state
1320 * p_m_s_sample_nr: current sample number
1324 digit = p_m_s_dial[p_m_s_digit_i];
1325 if (!digit) { /* if end of string reached */
1326 new_ss5_state(SS5_STATE_DELAY);
1327 p_m_s_sample_nr = 0;
1330 /* convert digit to pulse */
1357 if (p_m_s_signal == SS5_SIGNAL_DIGIT_ON) {
1358 if (p_m_s_pulsecount & 1)
1359 duration = BELL_TIMER_MAKE; /* loop closed */
1361 duration = BELL_TIMER_BREAK; /* loop open, tone */
1363 duration = BELL_TIMER_PAUSE;
1365 /* end of digit/pause ? */
1366 if (p_m_s_sample_nr >= duration) {
1367 p_m_s_sample_nr = 0;
1368 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE) {
1369 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1370 PDEBUG(DEBUG_SS5, "%s: starting pusling digit '%c'\n", p_name, digit);
1372 p_m_s_pulsecount++; /* toggle pulse */
1373 if (!(p_m_s_pulsecount & 1)) {
1374 /* pulse now on again, but if end is reached... */
1375 if (p_m_s_pulsecount == (digit<<1)) {
1376 new_ss5_signal(SS5_SIGNAL_DIGIT_PAUSE);
1377 p_m_s_pulsecount = 0;
1384 /* how much samples do we have left */
1385 tosend = len - count;
1386 tocode = duration - p_m_s_sample_nr;
1388 FATAL("sample_nr overrun duration");
1389 if (tosend < tocode)
1391 /* digit or pause */
1392 if (p_m_s_signal == SS5_SIGNAL_DIGIT_PAUSE
1393 || (p_m_s_pulsecount&1)) /* ...or currently on and no pulse */
1394 memset(buffer+count, audio_s16_to_law[0], tocode);
1396 ss5_encode(buffer+count, tocode, 'B', p_m_s_sample_nr);
1397 /* increase counters */
1398 p_m_s_sample_nr += tocode;
1400 /* can we take more ? */
1410 void Pss5::start_signal(int state)
1412 PDEBUG(DEBUG_SS5, "%s: starting singal '%s'\n", p_name, ss5_state_name[state]);
1414 new_ss5_state(state);
1415 if (state == SS5_STATE_DIAL_OUT) {
1417 p_m_s_pulsecount = 0;
1418 new_ss5_signal(SS5_SIGNAL_DIGIT_ON);
1420 new_ss5_signal(SS5_SIGNAL_SEND_ON);
1422 /* double seize must continue the current seize tone, so don't reset sample_nr */
1423 if (state != SS5_STATE_DOUBLE_SEIZE) {
1424 /* (re)set sound phase to 0 */
1425 p_m_s_sample_nr = 0;
1428 /* turn on inband transmitter */
1434 * handles all indications
1436 void Pss5::seizing_ind(void)
1438 ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_IND, p_m_b_channel);
1441 new_state(PORT_STATE_IN_SETUP);
1442 set_tone("", "noise");
1445 void Pss5::digit_ind(char digit)
1448 char string[128] = "", dial[128] = "";
1449 int dash, first_digit, last_was_digit;
1452 SCCAT(p_m_s_dial, digit);
1454 if (p_state == PORT_STATE_IN_SETUP)
1455 new_state(PORT_STATE_IN_OVERLAP);
1457 /* not last digit ? */
1462 dash = 0; /* dash must be used next time */
1465 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
1466 for (i = 0; p_m_s_dial[i]; i++) {
1467 if (dash || (last_was_digit && (p_m_s_dial[i]<'0' || p_m_s_dial[i]>'9')))
1471 switch(p_m_s_dial[i]) {
1486 SCCAT(string, p_m_s_dial[i]);
1487 SCCAT(dial, p_m_s_dial[i]);
1490 SCAT(string, "C11");
1491 SCCAT(dial, p_m_s_dial[i]);
1495 SCAT(string, "C12");
1496 SCCAT(dial, p_m_s_dial[i]);
1500 SCAT(string, "KP1");
1501 SCCAT(dial, p_m_s_dial[i]);
1505 SCAT(string, "KP2");
1506 SCCAT(dial, p_m_s_dial[i]);
1517 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1518 add_trace("string", NULL, "%s", string);
1519 add_trace("number", NULL, "%s", dial);
1521 new_ss5_state(SS5_STATE_IDLE);
1524 new_state(PORT_STATE_IN_PROCEEDING);
1527 void Pss5::pulse_ind(int on)
1529 struct lcr_msg *message;
1530 char dial[3] = "a.";
1532 if (p_m_s_signal == SS5_SIGNAL_PULSE_OFF) {
1534 /* pulse turns on */
1536 new_ss5_signal(SS5_SIGNAL_PULSE_ON);
1537 /* pulse turns of, count it */
1539 PDEBUG(DEBUG_SS5, "%s: pulse turns on, counting\n", p_name);
1541 /* pulse remains off */
1542 p_m_s_recog += SS5_DECODER_NPOINTS;
1543 /* not recognized end of digit, we wait... */
1544 if (p_m_s_recog < BELL_TIMER_RECOG_END)
1546 PDEBUG(DEBUG_SS5, "%s: pulse remains off, counted %d pulses\n", p_name, p_m_s_pulsecount);
1547 if (p_m_s_pulsecount >= 12)
1549 else if (p_m_s_pulsecount == 11)
1551 else if (p_m_s_pulsecount == 10)
1554 dial[1] = p_m_s_pulsecount + '0';
1555 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1556 add_trace("digit", NULL, "%s", dial+1);
1557 add_trace("pulses", NULL, "%d", p_m_s_pulsecount);
1559 if (p_state == PORT_STATE_IN_SETUP) {
1560 /* sending digit as setup */
1561 do_setup(dial, 0); /* include 'a' == KP1 */
1562 new_state(PORT_STATE_IN_OVERLAP);
1564 /* sending digit as information */
1565 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
1566 SCPY(message->param.information.id, dial+1);
1567 message_put(message);
1569 new_ss5_state(SS5_STATE_IDLE);
1570 /* done rx pulses, return to idle */
1571 new_ss5_state(SS5_STATE_IDLE);
1575 /* pulse remains on */
1576 p_m_s_recog += SS5_DECODER_NPOINTS;
1578 /* pulse turns off */
1579 if (p_m_s_recog >= BELL_TIMER_RECOG_HANGUP) {
1580 PDEBUG(DEBUG_SS5, "%s: long pulse turns off, releasing\n", p_name);
1581 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_IND, p_m_b_channel);
1582 add_trace("longtone", NULL, "releases call");
1584 /* long pulse is gone, release current connection, if any */
1585 while(p_epointlist) {
1586 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1587 message->param.disconnectinfo.location = LOCATION_BEYOND;
1588 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1589 message_put(message);
1590 free_epointlist(p_epointlist);
1593 /* return to setup state */
1594 new_state(PORT_STATE_IN_SETUP);
1595 new_ss5_state(SS5_STATE_IDLE);
1598 PDEBUG(DEBUG_SS5, "%s: short pulse turns off, releasing\n", p_name);
1600 new_ss5_signal(SS5_SIGNAL_PULSE_OFF);
1605 void Pss5::proceed_to_send_ind(void)
1607 ss5_trace_header(p_m_mISDNport, this, SS5_PROCEED_TO_SEND_IND, p_m_b_channel);
1610 SCPY(p_m_s_dial, p_dialinginfo.id);
1611 start_signal(SS5_STATE_DIAL_OUT);
1613 new_state(PORT_STATE_OUT_OVERLAP);
1616 void Pss5::busy_flash_ind(void)
1618 struct lcr_msg *message;
1620 ss5_trace_header(p_m_mISDNport, this, SS5_BUSY_FLASH_IND, p_m_b_channel);
1623 /* busy before dialing ? */
1627 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1628 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1629 message->param.disconnectinfo.location = LOCATION_BEYOND;
1630 message->param.disconnectinfo.cause = CAUSE_BUSY;
1631 message_put(message);
1634 new_state(PORT_STATE_IN_DISCONNECT);
1637 void Pss5::answer_ind(void)
1639 struct lcr_msg *message;
1641 ss5_trace_header(p_m_mISDNport, this, SS5_ANSWER_IND, p_m_b_channel);
1644 /* answer before dialing ? */
1648 /* already connected */
1649 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
1650 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
1651 message_put(message);
1654 new_state(PORT_STATE_CONNECT);
1657 void Pss5::forward_transfer_ind(void)
1659 // struct lcr_msg *message;
1661 ss5_trace_header(p_m_mISDNport, this, SS5_FORWARD_TRANSFER_IND, p_m_b_channel);
1665 /* if BELL flavor bluebox flag is set, use it to seize a new line */
1666 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_BELL))
1669 /* special BELL flavor hack to clear a line and seize a new one */
1670 while(p_epointlist) {
1671 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1672 message->param.disconnectinfo.location = LOCATION_BEYOND;
1673 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1674 message_put(message);
1675 free_epointlist(p_epointlist);
1678 new_state(PORT_STATE_IN_SETUP);
1682 void Pss5::clear_back_ind(void)
1684 struct lcr_msg *message;
1686 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_BACK_IND, p_m_b_channel);
1693 if (!(p_m_mISDNport->ss5 & SS5_FEATURE_NODISCONNECT)) {
1694 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DISCONNECT);
1695 message->param.disconnectinfo.location = LOCATION_BEYOND;
1696 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1697 message_put(message);
1700 new_state(PORT_STATE_IN_DISCONNECT);
1703 void Pss5::clear_forward_ind(void)
1705 struct lcr_msg *message;
1707 ss5_trace_header(p_m_mISDNport, this, SS5_CLEAR_FORWARD_IND, p_m_b_channel);
1710 new_state(PORT_STATE_IDLE);
1712 p_type = PORT_TYPE_SS5_IDLE;
1718 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1719 message->param.disconnectinfo.location = LOCATION_BEYOND;
1720 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1721 message_put(message);
1722 free_epointlist(p_epointlist);
1726 void Pss5::release_guard_ind(void)
1728 struct lcr_msg *message;
1730 ss5_trace_header(p_m_mISDNport, this, SS5_RELEASE_GUARD_IND, p_m_b_channel);
1739 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
1740 message->param.disconnectinfo.location = LOCATION_BEYOND;
1741 message->param.disconnectinfo.cause = CAUSE_NORMAL;
1742 message_put(message);
1743 free_epointlist(p_epointlist);
1746 void Pss5::double_seizure_ind(void)
1748 ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_IND, p_m_b_channel);
1750 ss5_trace_header(p_m_mISDNport, this, SS5_DOUBLE_SEIZURE_REQ, p_m_b_channel);
1753 /* start double seizure sequence, so remote exchange will recognize it */
1754 start_signal(SS5_STATE_DOUBLE_SEIZE);
1759 * shuts down by sending a clear forward and releasing endpoint
1761 void Pss5::do_release(int cause, int location, int signal)
1763 struct lcr_msg *message;
1765 /* sending release to endpoint */
1766 while(p_epointlist) {
1767 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1768 message->param.disconnectinfo.location = location;
1769 message->param.disconnectinfo.cause = cause;
1770 message_put(message);
1771 free_epointlist(p_epointlist);
1774 // if (p_state != PORT_STATE_RELEASE) {
1775 p_m_s_queued_signal = signal;
1776 if (signal == SS5_CLEAR_FORWARD_REQ) {
1777 new_state(PORT_STATE_RELEASE);
1778 set_tone("", "noise");
1780 new_state(PORT_STATE_OUT_DISCONNECT);
1781 trigger_work(&p_m_s_queue);
1787 * create endpoint and send setup
1789 void Pss5::do_setup(char *dial, int complete)
1791 class Endpoint *epoint;
1792 struct lcr_msg *message;
1794 SCPY(p_dialinginfo.id, dial);
1795 p_dialinginfo.sending_complete = complete;
1796 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
1797 p_callerinfo.screen = INFO_SCREEN_NETWORK;
1798 p_callerinfo.ntype = INFO_NTYPE_NOTPRESENT;
1799 p_callerinfo.isdn_port = p_m_portnum;
1800 SCPY(p_callerinfo.interface, p_m_mISDNport->ifport->interface->name);
1802 p_capainfo.bearer_capa = INFO_BC_AUDIO;
1803 p_capainfo.bearer_info1 = (options.law=='a')?3:2;
1804 p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
1805 p_capainfo.hlc = INFO_HLC_NONE;
1806 p_capainfo.exthlc = INFO_HLC_NONE;
1807 p_capainfo.source_mode = B_MODE_TRANSPARENT;
1809 /* create endpoint */
1811 FATAL("Incoming call but already got an endpoint.\n");
1812 if (!(epoint = new Endpoint(p_serial, 0)))
1813 FATAL("No memory for Endpoint instance\n");
1814 epoint->ep_app = new_endpointapp(epoint, 0, p_m_mISDNport->ifport->interface->app); //incoming
1815 epointlist_new(epoint->ep_serial);
1817 /* send setup message to endpoit */
1818 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
1819 message->param.setup.isdn_port = p_m_portnum;
1820 message->param.setup.port_type = p_type;
1821 // message->param.setup.dtmf = !p_m_mISDNport->ifport->nodtmf;
1822 memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
1823 memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
1824 memcpy(&message->param.setup.redirinfo, &p_redirinfo, sizeof(struct redir_info));
1825 memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
1826 message_put(message);
1833 * handles all messages from endpoint
1837 void Pss5::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
1839 struct lcr_msg *message;
1841 char string[128] = "", dial[128] = "";
1842 int dash, first_digit, last_was_digit;
1845 PERROR("endpoint already exist.\n");
1846 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1847 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1848 message->param.disconnectinfo.cause = CAUSE_UNSPECIFIED;
1849 message_put(message);
1853 /* copy setup infos to port */
1854 memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
1855 memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
1856 memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
1857 memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
1858 /* screen outgoing caller id */
1859 do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_m_mISDNport->ifport->interface->name);
1860 do_screen(1, p_callerinfo.id2, sizeof(p_callerinfo.id2), &p_callerinfo.ntype2, &p_callerinfo.present2, p_m_mISDNport->ifport->interface->name);
1862 /* parse dial string */
1863 dash = 0; /* dash must be used next time */
1866 for (i = 0; p_dialinginfo.id[i]; i++) {
1867 if (dash || (last_was_digit && (p_dialinginfo.id[i]<'0' || p_dialinginfo.id[i]>'9')))
1871 switch(p_dialinginfo.id[i]) {
1882 if (i && first_digit)
1886 SCCAT(string, p_dialinginfo.id[i]);
1887 SCCAT(dial, p_dialinginfo.id[i]);
1890 SCAT(string, "C11");
1895 SCAT(string, "C12");
1900 SCAT(string, "KP1");
1905 SCAT(string, "KP2");
1915 if (p_dialinginfo.id[i] != 'P')
1918 if (p_dialinginfo.id[i] == '1') {
1919 SCAT(string, "KP1");
1924 if (p_dialinginfo.id[i] == '2') {
1925 SCAT(string, "KP2");
1933 if (p_dialinginfo.id[i] != '1')
1936 if (p_dialinginfo.id[i] == '1') {
1937 SCAT(string, "C11");
1942 if (p_dialinginfo.id[i] == '2') {
1943 SCAT(string, "C12");
1951 if (p_dialinginfo.id[i] != 'T')
1961 if (dial[0] && dial[strlen(dial)-1] == 'c')
1965 if (dial[0] && dial[strlen(dial)-1]!='c') {
1971 /* error in dial string */
1974 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1975 add_trace("string", NULL, "%s", p_dialinginfo.id);
1977 add_trace("error", NULL, "no number", dial);
1978 else if (dial[0]!='a' && dial[0]!='b')
1979 add_trace("error", NULL, "number must start with KP1/KP2", dial);
1981 add_trace("error", NULL, "illegal format", dial);
1983 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1984 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1985 message->param.disconnectinfo.cause = CAUSE_INVALID;
1986 message_put(message);
1990 /* copy new dial string */
1991 SCPY(p_dialinginfo.id, dial);
1993 /* attach only if not already */
1994 epointlist_new(epoint_id);
1996 ss5_trace_header(p_m_mISDNport, this, SS5_DIALING_REQ, p_m_b_channel);
1997 add_trace("string", NULL, "%s", string);
1998 add_trace("type", NULL, "%s", (dial[0]=='b')?"international":"national");
1999 add_trace("number", NULL, "%s", dial);
2001 /* connect auto path */
2002 if ((p_m_mISDNport->ss5 & SS5_FEATURE_CONNECT)) {
2003 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
2004 message_put(message);
2006 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
2007 message_put(message);
2011 ss5_trace_header(p_m_mISDNport, this, SS5_SEIZING_REQ, p_m_b_channel);
2013 new_ss5_state(SS5_STATE_SEIZING);
2014 new_ss5_signal(SS5_SIGNAL_SEND_ON);
2015 p_m_s_sample_nr = 0;
2018 p_type = PORT_TYPE_SS5_OUT;
2019 new_state(PORT_STATE_OUT_SETUP);
2022 /* MESSAGE_CONNECT */
2023 void Pss5::message_connect(unsigned int epoint_id, int message_id, union parameter *param)
2025 memcpy(&p_connectinfo, ¶m->connectinfo, sizeof(p_connectinfo));
2027 if (p_state != PORT_STATE_CONNECT) {
2028 p_m_s_queued_signal = SS5_ANSWER_REQ;
2029 new_state(PORT_STATE_CONNECT);
2030 trigger_work(&p_m_s_queue);
2036 /* MESSAGE_DISCONNECT */
2037 void Pss5::message_disconnect(unsigned int epoint_id, int message_id, union parameter *param)
2039 /* release and clear forward */
2040 if (p_type==PORT_TYPE_SS5_OUT) { /* outgoing exchange */
2041 do_release(param->disconnectinfo.cause, param->disconnectinfo.location, SS5_CLEAR_FORWARD_REQ);
2044 /* release and clear back */
2045 if ((p_m_mISDNport->ss5 & SS5_FEATURE_RELEASE)) {
2046 do_release(param->disconnectinfo.cause, param->disconnectinfo.location, SS5_CLEAR_BACK_REQ);
2050 /* disconnect by sending clear back (after answer) or busy flash (before answer) */
2051 if (p_state != PORT_STATE_OUT_DISCONNECT) {
2052 if (p_state == PORT_STATE_CONNECT)
2053 p_m_s_queued_signal = SS5_CLEAR_BACK_REQ;
2055 p_m_s_queued_signal = SS5_BUSY_FLASH_REQ;
2056 new_state(PORT_STATE_OUT_DISCONNECT);
2057 trigger_work(&p_m_s_queue);
2061 /* MESSAGE_RELEASE */
2062 void Pss5::message_release(unsigned int epoint_id, int message_id, union parameter *param)
2064 /* always send clear forward, because release guard only works as a reply to clear forward */
2065 do_release(param->disconnectinfo.cause, param->disconnectinfo.location, SS5_CLEAR_FORWARD_REQ);
2069 * endpoint sends messages to the port
2071 int Pss5::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
2073 if (PmISDN::message_epoint(epoint_id, message_id, param))
2076 switch(message_id) {
2077 case MESSAGE_SETUP: /* dial-out command received from epoint */
2078 if (p_state!=PORT_STATE_IDLE) {
2079 PERROR("Pss5(%s) ignoring setup because isdn port is not in idle state (or connected for sending display info).\n", p_name);
2082 if (p_epointlist && p_state==PORT_STATE_IDLE)
2083 FATAL("Pss5(%s): epoint pointer is set in idle state, how bad!!\n", p_name);
2084 message_setup(epoint_id, message_id, param);
2087 case MESSAGE_CONNECT: /* call of endpoint is connected */
2088 message_connect(epoint_id, message_id, param);
2091 case MESSAGE_DISCONNECT: /* call has been disconnected */
2092 message_disconnect(epoint_id, message_id, param);
2095 case MESSAGE_RELEASE: /* release isdn port */
2096 message_release(epoint_id, message_id, param);
2100 PDEBUG(DEBUG_SS5, "Pss5(%s) ss5 port with (caller id %s) received an unhandled message: %d\n", p_name, p_callerinfo.id, message_id);